diff --git a/emul/.gitignore b/emul/.gitignore index 9ee7d93..c099a28 100644 --- a/emul/.gitignore +++ b/emul/.gitignore @@ -1,5 +1,5 @@ /shell/shell -/bshell/shell +/forth/forth /zasm/zasm /zasm/avra /runbin/runbin @@ -7,6 +7,4 @@ /*/*.bin /cfsin/zasm /cfsin/ed -/cfsin/basic -/cfsin/forth /cfsin/user.h diff --git a/emul/Makefile b/emul/Makefile index 5cd6d13..3bd7dde 100644 --- a/emul/Makefile +++ b/emul/Makefile @@ -1,10 +1,10 @@ CFSPACK_OBJ = ../tools/cfspack/libcfs.o -TARGETS = shell/shell zasm/zasm runbin/runbin +TARGETS = shell/shell zasm/zasm runbin/runbin forth/forth KERNEL = ../kernel APPS = ../apps ZASMBIN = zasm/zasm AVRABIN = zasm/avra -SHELLAPPS = zasm ed forth +SHELLAPPS = zasm ed SHELLTGTS = ${SHELLAPPS:%=cfsin/%} CFSIN_CONTENTS = $(SHELLTGTS) cfsin/user.h OBJS = emul.o libz80/libz80.o @@ -24,6 +24,15 @@ shell/shell-bin.h: shell/shell.bin shell/shell: shell/shell.c $(SHELLOBJS) shell/shell-bin.h $(CC) shell/shell.c $(SHELLOBJS) -o $@ +forth/forth.bin: forth/glue.asm $(ZASMBIN) + $(ZASMBIN) $(KERNEL) $(APPS) < forth/glue.asm | tee $@ > /dev/null + +forth/forth-bin.h: forth/forth.bin + ./bin2c.sh KERNEL < forth/forth.bin | tee $@ > /dev/null + +forth/forth: forth/forth.c $(OBJS) forth/forth-bin.h + $(CC) forth/forth.c $(OBJS) -o $@ + zasm/kernel-bin.h: zasm/kernel.bin ./bin2c.sh KERNEL < zasm/kernel.bin | tee $@ > /dev/null diff --git a/emul/forth/forth.c b/emul/forth/forth.c new file mode 100644 index 0000000..1848772 --- /dev/null +++ b/emul/forth/forth.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include "../emul.h" +#include "forth-bin.h" + +// in sync with glue.asm +#define RAMSTART 0x2000 +#define STDIO_PORT 0x00 + +static int running; + +static uint8_t iord_stdio() +{ + int c = getchar(); + if (c == EOF) { + running = 0; + } + return (uint8_t)c; +} + +static void iowr_stdio(uint8_t val) +{ + if (val == 0x04) { // CTRL+D + running = 0; + } else { + putchar(val); + } +} + +int main(int argc, char *argv[]) +{ + bool tty = isatty(fileno(stdin)); + struct termios termInfo; + if (tty) { + // Turn echo off: the shell takes care of its own echoing. + if (tcgetattr(0, &termInfo) == -1) { + printf("Can't setup terminal.\n"); + return 1; + } + termInfo.c_lflag &= ~ECHO; + termInfo.c_lflag &= ~ICANON; + tcsetattr(0, TCSAFLUSH, &termInfo); + } + + Machine *m = emul_init(); + m->ramstart = RAMSTART; + m->iord[STDIO_PORT] = iord_stdio; + m->iowr[STDIO_PORT] = iowr_stdio; + // initialize memory + for (int i=0; imem[i] = KERNEL[i]; + } + // Run! + running = 1; + + while (running && emul_step()); + + if (tty) { + printf("Done!\n"); + termInfo.c_lflag |= ECHO; + termInfo.c_lflag |= ICANON; + tcsetattr(0, TCSAFLUSH, &termInfo); + emul_printdebug(); + } + return 0; +} diff --git a/emul/forth/glue.asm b/emul/forth/glue.asm new file mode 100644 index 0000000..d46846d --- /dev/null +++ b/emul/forth/glue.asm @@ -0,0 +1,40 @@ +.inc "ascii.h" +.equ RAMSTART 0x2000 +.equ STDIO_PORT 0x00 + + jp init + +.inc "core.asm" +.inc "str.asm" + +.equ STDIO_RAMSTART RAMSTART +.equ STDIO_GETC emulGetC +.equ STDIO_PUTC emulPutC +.inc "stdio.asm" + +.inc "lib/util.asm" +.inc "lib/parse.asm" +.inc "lib/ari.asm" +.inc "lib/fmt.asm" +.equ FORTH_RAMSTART STDIO_RAMEND +.inc "forth/main.asm" +.inc "forth/util.asm" +.inc "forth/stack.asm" +.inc "forth/dict.asm" + +init: + di + ; setup stack + ld sp, 0xffff + call forthMain + halt + +emulGetC: + ; Blocks until a char is returned + in a, (STDIO_PORT) + cp a ; ensure Z + ret + +emulPutC: + out (STDIO_PORT), a + ret