Browse Source

Updated to work with the new libmon-less setup.

dtrg 17 years ago
parent
commit
42c2cdb985

+ 7 - 14
plat/pc86/README

@@ -2,6 +2,7 @@
 # $State$
 # $Revision$
 
+
 The pc86 platform
 =================
 
@@ -15,28 +16,20 @@ This means that there's not very much memory available. It would be very easy
 to change it to run in SMALL mode, where CS occupies one segment and DS and SS
 another, which would give 64kB for nearly all programs; I just haven't done it.
 
-This port uses a syscall interface, which means you get *all* of the ACK's
-builtin libc with no shortcuts. File descriptors 0, 1 and 2 represent the
-console. All reads block. There's enough TTY emulation to allow \n conversion
-(set RAW to turn off) and local echo (unset ECHO to turn off); this is needed
-to make Basic work.
-
-Language support
-================
+This port only implements a very limited set of syscalls --- and most of those
+are stubs required to make the demo apps link. File descriptors 0, 1 and 2
+represent the console. All reads block. There's enough TTY emulation to allow
+\n conversion and local echo (but it can't be turned off).
 
-Tested with C (both), Basic, Pascal, Occam, Modula-2.
-
-Basic works, but because Basic programs require access to a data file to work,
-and pc86 doesn't (of course) have a file system, programs won't start unless
-you hack the compiler not to try and open it.
 
 Example command line
 ====================
 
-ack -mpc86 -O -ansi -o pc86.img test.c
+ack -mpc86 -O -o pc86.img examples/paranoia.c
 
 The file pc86.img can then be copied onto a floppy and booted, or run via qemu
 or somesuch emulator.
 
+
 David Given
 dg@cowlark.com

+ 8 - 15
plat/pc86/boot.s

@@ -244,7 +244,6 @@ write_hex4:
 finished:
 	mov si, running_msg
 	call write_string
-	call pause
 	
 	! Wipe the bss. (I'm a little suprised that __m_a_i_n doesn't do this.)
 	
@@ -256,11 +255,9 @@ finished:
 	
 	! Push standard parameters onto the stack and go.
 	
-	mov ax, 1
-	push ax                  ! argc
-	mov ax, 2
+	xor ax, ax
 	push ax                  ! argc
-	mov ax, 3
+	push ax                  ! argv
 	push ax                  ! envp
 	call __m_a_i_n
 	! fall through into the exit routine.
@@ -301,22 +298,18 @@ running_msg: .asciz '\n\rRunning.\n\r'
 
 
 .define begtext,begdata,begbss
-.define hol0,.trppc,.ignmask
 .define ERANGE,ESET,EHEAP,ECASE,EILLINS,EIDIVZ,EODDZ
 .extern _end
 
-.sect .data
-hol0:
-	.data2   0,0
-	.data2   0,0
-.ignmask:
-	.data2   0
-.trppc:
-	.data2   0
-
 ! Define symbols at the beginning of our various segments, so that we can find
 ! them. (Except .text, which has already been done.)
 
 .sect .data;       begdata:
 .sect .rom;        begrom:
 .sect .bss;        begbss:
+
+! Some magic data. All EM systems need these.
+
+.define .trppc, .ignmask
+.comm .trppc, 4
+.comm .ignmask, 4

+ 9 - 10
plat/pc86/descr

@@ -13,9 +13,13 @@ var PLATFORM=pc86
 var PLATFORMDIR={EM}/lib/{PLATFORM}
 var CPP_F=-D__unix
 var ALIGN=-a0:1 -a1:1 -a2:1 -a3:1
-var C_LIB={PLATFORMDIR}/libc-stdio-knr.a {PLATFORMDIR}/libc-knr.a
-var OLD_C_LIB={C_LIB}
 var MACHOPT_F=-m8
+
+# Override the setting in fe so that files compiled for linux386 can see
+# the platform-specific headers.
+
+var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/include/ansi
+
 name be
 	from .m.g
 	to .s
@@ -38,12 +42,10 @@ name led
 	mapflag -l* LNAME={PLATFORMDIR}/lib*
 	mapflag -i SEPID=-b1:0
 	mapflag -fp FLOATS={EM}/{ILIB}fp
-	mapflag -ansi C_LIB={PLATFORMDIR}/libc-ansi.a
 	args {ALIGN} {SEPID?} \
 	    (.e:{HEAD}={PLATFORMDIR}/boot.o) \
-		({RTS}:.ocm.b={PLATFORMDIR}/c-knr.o) \
-		({RTS}{ANSI?}:.c={PLATFORMDIR}/c-knr.o) \
-		({RTS}{ANSI?}:.cansi={PLATFORMDIR}/c-ansi.o) \
+		({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \
+		({RTS}:.c={PLATFORMDIR}/c-ansi.o) \
 		({RTS}:.mod={PLATFORMDIR}/modula2.o) \
 		({RTS}:.p={PLATFORMDIR}/pascal.o) \
 		-o > < \
@@ -51,12 +53,9 @@ name led
 		(.b:{TAIL}={PLATFORMDIR}/libbasic.a) \
 		(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
 		(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
-		(.ocm.b:{TAIL}={OLD_C_LIB}) \
-		(.c:{TAIL}={C_LIB}) \
+		(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
 		{FLOATS?} \
 		(.e:{TAIL}={PLATFORMDIR}/libsys.a \
-		           {PLATFORMDIR}/libmon.a \
-		           {PLATFORMDIR}/libsys.a \
 		           {PLATFORMDIR}/libem.a \
 		           {PLATFORMDIR}/libend.a)
 	linker

+ 14 - 0
plat/pc86/include/ack/config.h

@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#ifndef _ACK_CONFIG_H
+#define _ACK_CONFIG_H
+
+/* We're providing a time() system call rather than wanting a wrapper around
+ * gettimeofday() in the libc. */
+ 
+#define ACKCONF_TIME_IS_A_SYSCALL
+
+#endif

+ 70 - 0
plat/pc86/include/unistd.h

@@ -0,0 +1,70 @@
+/*
+ * unistd.h - standard system calls
+ */
+/* $Id$ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#include <stddef.h>
+
+/* Types */
+
+typedef int pid_t;
+typedef int mode_t;
+
+/* Constants for file access (open and friends) */
+
+enum
+{
+	O_ACCMODE = 0x3,
+	
+	O_RDONLY = 0,
+	O_WRONLY = 1,
+	O_RDWR = 2,
+	
+	O_CREAT = 0100,
+	O_TRUNC = 01000,
+	O_APPEND = 02000,
+	O_NONBLOCK = 04000
+};
+
+/* Special variables */
+
+extern char** environ;
+
+/* Implemented system calls */
+
+extern void _exit(int);
+extern pid_t getpid(void);
+extern void* sbrk(intptr_t increment);
+extern int isatty(int d);
+extern off_t lseek(int fildes, off_t offset, int whence);
+extern int close(int d);
+extern int open(const char* path, int access, ...);
+extern int creat(const char* path, mode_t mode);
+extern int read(int fd, void* buffer, size_t count);
+extern int write(int fd, void* buffer, size_t count);
+
+/* Unimplemented system calls (these are just prototypes to let the library
+ * compile). */
+
+extern int fcntl(int fd, int op, ...);
+
+/* Signal handling */
+
+typedef int sig_atomic_t;
+
+#define SIG_ERR ((__sighandler_t) -1)           /* Error return.  */
+#define SIG_DFL ((__sighandler_t) 0)            /* Default action.  */
+#define SIG_IGN ((__sighandler_t) 1)            /* Ignore signal.  */
+
+#define SIGABRT         6       /* Abort (ANSI).  */
+
+#define _NSIG           32      /* Biggest signal number + 1
+                                   (not including real-time signals).  */
+typedef void (*sighandler_t)(int);
+extern sighandler_t signal(int signum, sighandler_t handler);
+extern int raise(int signum);
+
+#endif

+ 0 - 55
plat/pc86/libsys/_brk.s

@@ -1,55 +0,0 @@
-#
-! $Source$
-! $State$
-! $Revision$
-
-! Declare segments (the order is important).
-
-.sect .text
-.sect .rom
-.sect .data
-.sect .bss
-
-! This file contains the code necessary to extend the ACK heap. This is called
-! by a i86/libem helper function called .strhp, which takes care of updating
-! some magic global variables --- defined here.
-
-! Pointer to the current top of the heap.
-
-.sect .data
-.define .reghp
-.reghp:
-	.data2 endbss
-	
-! Pointer to the current top of memory.
-
-.sect .data
-.define .limhp
-.limhp:
-	.data2 endbss
-	
-! Claims more memory from the system, but does not actually change those
-! global variables (.strhp does that). This does not use the C calling
-! convention!
-!
-! Stack: ( desired_limhp : actual_limhp )
-! Also returns: ax = -1 on failure
-
-.sect .text
-.define BRK
-BRK:
-	pop bx ! holds return address
-	pop ax ! holds desired limhp
-
-	cmp ax, sp               ! compare sp with si
-	jae fail                 ! si too big? (Overlaps stack?)
-	cmp ax, endbss           ! compare with bottom of heap
-	jb fail                  ! si too small? (Overlaps bss?)
-	
-return:
-	push ax                  ! success
-	jmp bx
-	
-fail:
-	mov ax, -1
-	jmp return

+ 19 - 0
plat/pc86/libsys/_hol0.s

@@ -0,0 +1,19 @@
+#
+! $Source$
+! $State$
+! $Revision$
+
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+.sect .bss
+
+! This data block is used to store information about the current line number
+! and file.
+
+.define hol0
+.comm hol0, 8

+ 0 - 166
plat/pc86/libsys/_mon.s

@@ -1,166 +0,0 @@
-#
-! $Source$
-! $State$
-! $Revision$
-
-! Declare segments (the order is important).
-
-.sect .text
-.sect .rom
-.sect .data
-.sect .bss
-
-.sect .bss
-
-.define __sys_params_in
-.comm __sys_params_in, 6
-
-.define __sys_params_out
-.comm __sys_params_out, 2
-	
-.comm opcode, 2
-.comm returnto, 2
-	
-.sect .text
-
-
-! Called on system call. This does *not* use the C calling convention:
-!   ax: syscall number
-!   stack: ( param3 param2 param1 - result ) 
-
-.define .mon
-.mon:
-	mov (opcode), ax
-	pop (returnto)
-	
-	cmp ax, 1
-	je exit
-	cmp ax, 3
-	je read
-	cmp ax, 4
-	je write
-	cmp ax, 5
-	je open
-	cmp ax, 6
-	je nop_1 ! close
-	cmp ax, 20
-	je nop_0 ! getpid
-	cmp ax, 35
-	je nop_1 ! time
-	cmp ax, 48
-	je sigtrp
-	cmp ax, 54
-	je ioctl
-	
-	! Syscall not supported --- write out an error message and halt.	
-
-unsupported:
-	mov si, msg
-1:
-	lodsb
-	andb al, al
-	jz 2f
-	movb ah, 0xE   ! service
-	mov bx, 0x0007 ! page 0, white
-	int 0x10
-	jmp 1b
-2:
-
-	! Write out the syscall number.
-
-	mov dx, (opcode)	
-	mov cx, 4       ! 4 hex digits
-1:
-	rol	dx, 1       ! rotate so that highest 4 bits are at the bottom
-	rol dx, 1
-	rol dx, 1
-	rol dx, 1
-	mov	ax, 0xE0F	! ah = request, al = mask for nybble
-	andb al, dl
-	addb al, 0x90	! convert al to ascii hex (four instructions)
-	daa
-	adcb al, 0x40
-	daa
-	int	0x10
-	loop 1b
-
-	! Exit.
-	
-	jmp EXIT
-	
-.sect .rom
-msg:
-	.asciz 'NOSYS'
-	
-.sect .text
-
-exit:
-	jmp EXIT
-	
-read:
-	mov ax, __sys_read
-	jmp in_3_out_1
-	
-write:
-	mov ax, __sys_write
-	jmp in_3_out_1
-
-open:
-	add sp, 2*2
-	jmp unimplemented
-	
-ioctl:
-	mov ax, __sys_ioctl
-	jmp in_3_out_0
-
-sigtrp:
-	add sp, 4
-	jmp unimplemented
-
-in_3_out_0:
-	pop (__sys_params_in+0)
-	pop (__sys_params_in+2)
-	pop (__sys_params_in+4)
-	call ax
-	jmp out_0
-	
-in_3_out_1:
-	pop (__sys_params_in+0)
-	pop (__sys_params_in+2)
-	pop (__sys_params_in+4)
-	call ax
-	jmp out_1
-	
-out_0:
-	or ax, ax
-	jnz failed
-	push ax
-	jmp return
-	
-out_1:
-	or ax, ax
-	jnz failed
-	push (__sys_params_out)
-	push ax
-	jmp return
-
-unimplemented:	
-	mov ax, EBADMON
-failed:
-	push ax
-	push ax
-	jmp return
-
-nop_1:
-	add sp, 1*2
-	jmp nop_0
-nop_3:
-	add sp, 3*2
-nop_0:
-	mov ax, 0
-	push ax
-	jmp return
-	
-return:
-	jmp (returnto)
-	

+ 43 - 0
plat/pc86/libsys/brk.c

@@ -0,0 +1,43 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#define	OUT_OF_MEMORY (void*)(-1)	/* sbrk returns this on failure */
+#define STACK_BUFFER 128 /* number of bytes to leave for stack */
+
+extern char _end[1];
+static char* current = _end;
+
+int brk(void* newend)
+{
+	/* This variable is used to figure out the current stack pointer,
+	 * by taking its address. */
+	char dummy;
+	char* p = newend;
+	
+	if ((p > (&dummy - STACK_BUFFER)) ||
+	    (p < _end))	
+		return -1;
+		
+	current = p;
+	return 0;
+}
+
+void* sbrk(intptr_t increment)
+{
+	char* old;
+	
+	if (increment == 0)
+		return current;
+		
+	old = current;
+	if (brk(old + increment) < 0)
+		return OUT_OF_MEMORY;
+		
+	return old;
+}

+ 14 - 0
plat/pc86/libsys/close.c

@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+int close(int fd)
+{
+	errno = EBADF;
+	return -1;
+}

+ 15 - 0
plat/pc86/libsys/creat.c

@@ -0,0 +1,15 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "libsys.h"
+
+int open(const char* path, int access, ...)
+{
+	errno = EACCES;
+	return -1;
+}

+ 3 - 0
plat/pc86/libsys/errno.s

@@ -14,6 +14,9 @@
 
 .sect .data
 
+! Define various ACK error numbers. Note that these are *not* ANSI C
+! errnos, and are used for different purposes.
+
 D(ERANGE)         = 1
 D(ESET)           = 2
 D(EIDIVZ)         = 6

+ 13 - 0
plat/pc86/libsys/getpid.c

@@ -0,0 +1,13 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+pid_t getpid(void)
+{
+	return 0;
+}

+ 13 - 0
plat/pc86/libsys/isatty.c

@@ -0,0 +1,13 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+int isatty(int fd)
+{
+	return 1;
+}

+ 14 - 0
plat/pc86/libsys/kill.c

@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+int kill(pid_t pid, int sig)
+{
+	errno = EINVAL;
+	return -1;
+}

+ 1 - 1
plat/pc86/libsys/libsys.h

@@ -11,6 +11,6 @@ extern unsigned char _sys_rawread(void);
 
 extern void _sys_write_tty(char c);
 
-extern int _sys_ttyflags;
+/* extern int _sys_ttyflags; */
 
 #endif

+ 14 - 0
plat/pc86/libsys/lseek.c

@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+	errno = EINVAL;
+	return -1;
+}

+ 14 - 0
plat/pc86/libsys/open.c

@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "libsys.h"
+
+int creat(const char* path, int mode)
+{
+	return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}

+ 14 - 5
plat/pc86/libsys/pmfile

@@ -9,13 +9,22 @@ libsys_pc86 = acklibrary {
 	ACKINCLUDES = {"%BINDIR%include"},
 	
 	ackfile (d.."errno.s"),
-	ackfile (d.."_mon.s"),
-	ackfile (d.."_brk.s"),
+	ackfile (d.."_hol0.s"),
 	ackfile (d.."_sys_rawread.s"),
 	ackfile (d.."_sys_rawwrite.s"),
-	ackfile (d.."_sys_read.c"),
-	ackfile (d.."_sys_write.c"),
-	ackfile (d.."_sys_ioctl.c"),
+	ackfile (d.."open.c"),
+	ackfile (d.."creat.c"),
+	ackfile (d.."close.c"),
+	ackfile (d.."read.c"),
+	ackfile (d.."write.c"),
+--	ackfile (d.."_sys_ioctl.c"),
+	ackfile (d.."brk.c"),
+	ackfile (d.."getpid.c"),
+	ackfile (d.."kill.c"),
+	ackfile (d.."isatty.c"),
+	ackfile (d.."lseek.c"),
+	ackfile (d.."time.c"),
+	ackfile (d.."signal.c"),
 	
 	install = pm.install("%BINDIR%lib/%PLATFORM%/libsys.a"),
 }

+ 15 - 26
plat/pc86/libsys/_sys_read.c → plat/pc86/libsys/read.c

@@ -5,50 +5,39 @@
 
 #include <stdlib.h>
 #include <errno.h>
-#include <sgtty.h>
+#include <unistd.h>
 #include "libsys.h"
 
-extern struct
-{
-	int fd;
-	char* buffer;
-	size_t count;
-} _sys_params_in;
-
-extern struct
-{
-	size_t bytesread;
-} _sys_params_out;
-
-#define P _sys_params_in
-
-int _sys_read(void)
+int read(int fd, void* buffer, size_t count)
 {
 	char i;
 	
 	/* We're only allowed to read from fd 0, 1 or 2. */
 	
-	if ((P.fd < 0) || (P.fd > 2))
-		return EBADF;
+	if ((fd < 0) || (fd > 2))
+	{
+		errno = EBADF;
+		return -1;
+	}
 	
 	/* Empty buffer? */
 	
-	if (P.count == 0)
-	{
-		_sys_params_out.bytesread = 0;
+	if (count == 0)
 		return 0;
-	}
 	
 	/* Read one byte. */
 	
 	i = _sys_rawread();
+#if 0
 	if ((i == '\r') && !(_sys_ttyflags & RAW)) 
 		i = '\n';
 	if (_sys_ttyflags & ECHO)
 		_sys_write_tty(i);
+#endif
+	if (i == '\r') 
+		i = '\n';
+	_sys_write_tty(i);
 	
-	*P.buffer = i;
-		
-	_sys_params_out.bytesread = 1;
-	return 0;
+	*(char*)buffer = i;
+	return 1;
 }

+ 15 - 0
plat/pc86/libsys/signal.c

@@ -0,0 +1,15 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include "libsys.h"
+
+sighandler_t signal(int signum, sighandler_t handler)
+{
+	return SIG_DFL;
+}

+ 17 - 0
plat/pc86/libsys/time.c

@@ -0,0 +1,17 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include "libsys.h"
+
+time_t time(time_t* t)
+{
+	if (t)
+		*t = 0;
+	return 0;
+}

+ 15 - 22
plat/pc86/libsys/_sys_write.c → plat/pc86/libsys/write.c

@@ -5,51 +5,44 @@
 
 #include <stdlib.h>
 #include <errno.h>
-#include <sgtty.h>
+#include <unistd.h>
 #include "libsys.h"
 
-extern struct
-{
-	int fd;
-	const char* buffer;
-	size_t count;
-} _sys_params_in;
-
-extern struct
-{
-	size_t byteswritten;
-} _sys_params_out;
-
-#define P _sys_params_in
-
 void _sys_write_tty(char c)
 {
 	_sys_rawwrite(c);
+#if 0
 	if ((c == '\n') && !(_sys_ttyflags & RAW))
 		_sys_rawwrite('\r');
+#endif
+	if (c == '\n')
+		_sys_rawwrite('\r');
 }
 
-int _sys_write(void)
+int write(int fd, void* buffer, size_t count)
 {
 	int i;
+	char* p = buffer;
 	
 	/* We're only allowed to write to fd 0, 1 or 2. */
 	
-	if ((P.fd < 0) || (P.fd > 2))
-		return EBADF;
+	if ((fd < 0) || (fd > 2))
+	{
+		errno = EBADF;
+		return -1;
+	}
 	
 	/* Write all data. */
 	
 	i = 0;
-	while (i < P.count)
+	while (i < count)
 	{
-		_sys_write_tty(*P.buffer++);
+		_sys_write_tty(*p++);
 			
 		i++;
 	}
 	
 	/* No failures. */
 	
-	_sys_params_out.byteswritten = P.count;
-	return 0;
+	return count;
 }

+ 10 - 2
plat/pc86/pmfile

@@ -15,15 +15,23 @@ local descr = group {
 	install = pm.install(d.."descr", "%BINDIR%%PLATIND%/%PLATFORM%/descr")
 }
 
+local headers = group {
+	install = {
+		pm.install(d.."include/ack/config.h", "%BINDIR%%PLATIND%/%PLATFORM%/include/ack/config.h"),
+		pm.install(d.."include/unistd.h",     "%BINDIR%%PLATIND%/%PLATFORM%/include/unistd.h"),
+	}
+}
+
 platform_pc86 = group {
 	ARCH = "i86",
 	PLATFORM = "pc86",
 	OPTIMISATION = "-O",
 	
-	-- Ensure the descr file is installed first because we'll need it
-	-- to build the libraries.
+	-- Ensure the descr and headers are installed first because we'll need
+	-- them to build the libraries.
 	
 	descr,
+	headers,
 	
 	-- Build the back-end support.