From: Manoel Trapier Date: Mon, 4 Mar 2013 18:00:38 +0000 (+0100) Subject: Copy pc86 platform to nes platform, and make change accordingly. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=cc534493fda273b5b5fd0754c1b6e4d91af79537;p=ack.git Copy pc86 platform to nes platform, and make change accordingly. --- diff --git a/plat/nes/.distr b/plat/nes/.distr new file mode 100644 index 000000000..9bcdd612a --- /dev/null +++ b/plat/nes/.distr @@ -0,0 +1,24 @@ +descr +boot.s +pmfile +README +include/ack/config.h +include/unistd.h +libsys/pmfile +libsys/_hol0.s +libsys/brk.c +libsys/close.c +libsys/creat.c +libsys/errno.s +libsys/getpid.c +libsys/isatty.c +libsys/kill.c +libsys/libsys.h +libsys/lseek.c +libsys/open.c +libsys/read.c +libsys/signal.c +libsys/time.c +libsys/write.c +libsys/_sys_rawread.s +libsys/_sys_rawwrite.s diff --git a/plat/nes/README b/plat/nes/README new file mode 100644 index 000000000..8e6f49ae3 --- /dev/null +++ b/plat/nes/README @@ -0,0 +1,15 @@ +# $Source$ +# $State$ +# $Revision$ + + +The NES platform +================= + +NES is a platform for the Nintendo Entertainment System. + +Example command line +==================== + +ack -mnes -O -o nes.img examples/paranoia.c + diff --git a/plat/nes/boot.s b/plat/nes/boot.s new file mode 100644 index 000000000..9bf155c16 --- /dev/null +++ b/plat/nes/boot.s @@ -0,0 +1,36 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + + +start2: + jmp _main + +.define __exit +.extern __exit +.define EXIT +.extern EXIT +__exit: +EXIT: + +.define begtext, begdata, begbss +.sect .data; begdata: +.sect .rom; begrom: +.sect .bss; begbss: + +! Some magic data. All EM systems need these. + +.define .trppc, .ignmask, _errno +.comm .trppc, 4 +.comm .ignmask, 4 +.comm _errno, 4 diff --git a/plat/nes/descr b/plat/nes/descr new file mode 100644 index 000000000..3f4a1a323 --- /dev/null +++ b/plat/nes/descr @@ -0,0 +1,69 @@ +# $Source$ +# $State$ +# $Revision$ + +var w=2 +var p=2 +var s=2 +var l=4 +var f=4 +var d=8 +var ARCH=6500 +var PLATFORM=nes +var PLATFORMDIR={EM}/lib/{PLATFORM} +var CPP_F= +var ALIGN=-a0:1 -a1:1 -a2:1 -a3:1 +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 + program {EM}/lib.bin/{PLATFORM}/ncg + args < + stdout + need .e +end +name as + from .s.so + to .o + program {EM}/lib.bin/{PLATFORM}/as + args - -o > < + prep cond +end +name led + from .o.a + to .out + program {EM}/lib.bin/em_led + mapflag -l* LNAME={PLATFORMDIR}/lib* + mapflag -i SEPID=-b1:0 + mapflag -fp FLOATS={EM}/{ILIB}fp + args {ALIGN} {SEPID?} \ + (.e:{HEAD}={PLATFORMDIR}/boot.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 > < \ + (.p:{TAIL}={PLATFORMDIR}/libpascal.a) \ + (.b:{TAIL}={PLATFORMDIR}/libbasic.a) \ + (.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \ + (.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \ + (.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \ + {FLOATS?} \ + (.e:{TAIL}={PLATFORMDIR}/libem.a \ + {PLATFORMDIR}/libsys.a \ + {PLATFORMDIR}/libend.a) + linker +end +name cv + from .out + to .img + program {EM}/bin/aslod + args < > + outfile nes.img +end diff --git a/plat/nes/include/ack/config.h b/plat/nes/include/ack/config.h new file mode 100644 index 000000000..dac9af4c1 --- /dev/null +++ b/plat/nes/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 diff --git a/plat/nes/include/unistd.h b/plat/nes/include/unistd.h new file mode 100644 index 000000000..2af9db921 --- /dev/null +++ b/plat/nes/include/unistd.h @@ -0,0 +1,71 @@ +/* + * unistd.h - standard system calls + */ +/* $Id$ */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include + +/* 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 SIGILL 11 /* Illegal instruction */ + +#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 diff --git a/plat/nes/libsys/_hol0.s b/plat/nes/libsys/_hol0.s new file mode 100644 index 000000000..f01566fe8 --- /dev/null +++ b/plat/nes/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 diff --git a/plat/nes/libsys/_sys_rawread.s b/plat/nes/libsys/_sys_rawread.s new file mode 100644 index 000000000..480727b55 --- /dev/null +++ b/plat/nes/libsys/_sys_rawread.s @@ -0,0 +1,23 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Reads a single byte. + +.define __sys_rawread +__sys_rawread: + xorb ah, ah + int 0x16 + xorb ah, ah + ret + \ No newline at end of file diff --git a/plat/nes/libsys/_sys_rawwrite.s b/plat/nes/libsys/_sys_rawwrite.s new file mode 100644 index 000000000..75f75aae1 --- /dev/null +++ b/plat/nes/libsys/_sys_rawwrite.s @@ -0,0 +1,29 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Writes a single byte to the console. + +.define __sys_rawwrite +.extern __sys_rawwrite + +__sys_rawwrite: + push bp + mov bp, sp + + movb al, 4(bp) + movb ah, 0x0E + mov bx, 0x0007 + int 0x10 + jmp .cret + \ No newline at end of file diff --git a/plat/nes/libsys/brk.c b/plat/nes/libsys/brk.c new file mode 100644 index 000000000..02e213399 --- /dev/null +++ b/plat/nes/libsys/brk.c @@ -0,0 +1,43 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +#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; +} diff --git a/plat/nes/libsys/close.c b/plat/nes/libsys/close.c new file mode 100644 index 000000000..1c570029b --- /dev/null +++ b/plat/nes/libsys/close.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +int close(int fd) +{ + errno = EBADF; + return -1; +} diff --git a/plat/nes/libsys/creat.c b/plat/nes/libsys/creat.c new file mode 100644 index 000000000..34ace747c --- /dev/null +++ b/plat/nes/libsys/creat.c @@ -0,0 +1,15 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int open(const char* path, int access, ...) +{ + errno = EACCES; + return -1; +} diff --git a/plat/nes/libsys/errno.s b/plat/nes/libsys/errno.s new file mode 100644 index 000000000..9858d2640 --- /dev/null +++ b/plat/nes/libsys/errno.s @@ -0,0 +1,28 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +#define D(e) .define e; e + +.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 +D(EHEAP) = 17 +D(EILLINS) = 18 +D(EODDZ) = 19 +D(ECASE) = 20 +D(EBADMON) = 25 + diff --git a/plat/nes/libsys/getpid.c b/plat/nes/libsys/getpid.c new file mode 100644 index 000000000..5e6eb003e --- /dev/null +++ b/plat/nes/libsys/getpid.c @@ -0,0 +1,13 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +pid_t getpid(void) +{ + return 0; +} diff --git a/plat/nes/libsys/hello.c b/plat/nes/libsys/hello.c new file mode 100644 index 000000000..1da533f98 --- /dev/null +++ b/plat/nes/libsys/hello.c @@ -0,0 +1,4 @@ +int hello(void) +{ + return 42; +} diff --git a/plat/nes/libsys/isatty.c b/plat/nes/libsys/isatty.c new file mode 100644 index 000000000..ad01e343f --- /dev/null +++ b/plat/nes/libsys/isatty.c @@ -0,0 +1,13 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +int isatty(int fd) +{ + return 1; +} diff --git a/plat/nes/libsys/kill.c b/plat/nes/libsys/kill.c new file mode 100644 index 000000000..4a179c47c --- /dev/null +++ b/plat/nes/libsys/kill.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +int kill(pid_t pid, int sig) +{ + errno = EINVAL; + return -1; +} diff --git a/plat/nes/libsys/libsys.h b/plat/nes/libsys/libsys.h new file mode 100644 index 000000000..fee2fc76d --- /dev/null +++ b/plat/nes/libsys/libsys.h @@ -0,0 +1,16 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#ifndef LIBSYS_H +#define LIBSYS_H + +extern void _sys_rawwrite(unsigned char b); +extern unsigned char _sys_rawread(void); + +extern void _sys_write_tty(char c); + +/* extern int _sys_ttyflags; */ + +#endif diff --git a/plat/nes/libsys/lseek.c b/plat/nes/libsys/lseek.c new file mode 100644 index 000000000..ecbc4b520 --- /dev/null +++ b/plat/nes/libsys/lseek.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include + +off_t lseek(int fd, off_t offset, int whence) +{ + errno = EINVAL; + return -1; +} diff --git a/plat/nes/libsys/open.c b/plat/nes/libsys/open.c new file mode 100644 index 000000000..8f18317c5 --- /dev/null +++ b/plat/nes/libsys/open.c @@ -0,0 +1,14 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int creat(const char* path, int mode) +{ + return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode); +} diff --git a/plat/nes/libsys/pmfile b/plat/nes/libsys/pmfile new file mode 100644 index 000000000..84cd02f62 --- /dev/null +++ b/plat/nes/libsys/pmfile @@ -0,0 +1,31 @@ +-- $Source$ +-- $State$ +-- $Revision$ + +local d = ROOTDIR.."plat/nes/libsys/" + +libsys_nes = acklibrary { + ACKBUILDFLAGS = {PARENT, "-ansi"}, + ACKINCLUDES = {"%BINDIR%include"}, + +-- ackfile (d.."errno.s"), +-- ackfile (d.."_hol0.s"), +-- ackfile (d.."_sys_rawread.s"), +-- ackfile (d.."_sys_rawwrite.s"), +-- ackfile (d.."open.c"), +-- ackfile (d.."creat.c"), +-- ackfile (d.."close.c"), +-- ackfile (d.."read.c"), +-- ackfile (d.."write.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"), + + ackfile (d.."hello.c"), + + install = pm.install("%BINDIR%lib/%PLATFORM%/libsys.a"), +} diff --git a/plat/nes/libsys/read.c b/plat/nes/libsys/read.c new file mode 100644 index 000000000..968124784 --- /dev/null +++ b/plat/nes/libsys/read.c @@ -0,0 +1,43 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +int read(int fd, void* buffer, size_t count) +{ + char i; + + /* We're only allowed to read from fd 0, 1 or 2. */ + + if ((fd < 0) || (fd > 2)) + { + errno = EBADF; + return -1; + } + + /* Empty buffer? */ + + 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); + + *(char*)buffer = i; + return 1; +} diff --git a/plat/nes/libsys/signal.c b/plat/nes/libsys/signal.c new file mode 100644 index 000000000..a87b9ced2 --- /dev/null +++ b/plat/nes/libsys/signal.c @@ -0,0 +1,15 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include +#include "libsys.h" + +sighandler_t signal(int signum, sighandler_t handler) +{ + return SIG_DFL; +} diff --git a/plat/nes/libsys/time.c b/plat/nes/libsys/time.c new file mode 100644 index 000000000..5ef17b841 --- /dev/null +++ b/plat/nes/libsys/time.c @@ -0,0 +1,17 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include +#include "libsys.h" + +time_t time(time_t* t) +{ + if (t) + *t = 0; + return 0; +} diff --git a/plat/nes/libsys/write.c b/plat/nes/libsys/write.c new file mode 100644 index 000000000..8d2dd0d74 --- /dev/null +++ b/plat/nes/libsys/write.c @@ -0,0 +1,48 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +#include +#include +#include +#include "libsys.h" + +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 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 ((fd < 0) || (fd > 2)) + { + errno = EBADF; + return -1; + } + + /* Write all data. */ + + i = 0; + while (i < count) + { + _sys_write_tty(*p++); + + i++; + } + + /* No failures. */ + + return count; +} diff --git a/plat/nes/pmfile b/plat/nes/pmfile new file mode 100644 index 000000000..8a8257e31 --- /dev/null +++ b/plat/nes/pmfile @@ -0,0 +1,45 @@ +-- $Source$ +-- $State$ +-- $Revision$ + +local d = ROOTDIR.."plat/nes/" + +include (d.."libsys/pmfile") + +local bootsector = ackfile { + file (d.."boot.s"), + install = pm.install("%BINDIR%lib/nes/boot.o"), +} + +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_nes = group { + ARCH = "6500", + PLATFORM = "nes", + OPTIMISATION = "-O", + + -- Ensure the descr and headers are installed first because we'll need + -- them to build the libraries. + + descr, + headers, + + -- Build the back-end support. + + mach_6500, + support_6500, + lang_runtimes, + -- Build the NES library. + + libsys_nes, + bootsector +}