diff --git a/dictionary.txt b/dictionary.txt index 5bce4a7..a8f9a86 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -207,3 +207,7 @@ CR LF SPC +*** Disk *** + +LIST n -- Prints the contents of the block n on screen in the + form of 16 lines of 64 columns. diff --git a/emul/.gitignore b/emul/.gitignore index 8843965..280ca55 100644 --- a/emul/.gitignore +++ b/emul/.gitignore @@ -4,3 +4,4 @@ /forth/forth /*/*-bin.h /*/*.bin +/blkfs diff --git a/emul/Makefile b/emul/Makefile index d07c76b..2ec8b2c 100644 --- a/emul/Makefile +++ b/emul/Makefile @@ -1,5 +1,4 @@ TARGETS = forth/forth -BIN2C = ../tools/bin2c # Those Forth source files are in a particular order BOOTSRCS = ./forth/conf.fs \ ../forth/xcomp.fs \ @@ -10,11 +9,13 @@ BOOTSRCS = ./forth/conf.fs \ ./forth/xstop.fs FORTHSRCS = core.fs cmp.fs print.fs str.fs parse.fs readln.fs fmt.fs z80a.fs \ - link.fs + link.fs blk.fs FORTHSRC_PATHS = ${FORTHSRCS:%=../forth/%} forth/run.fs OBJS = emul.o libz80/libz80.o SLATEST = ../tools/slatest STRIPFC = ../tools/stripfc +BIN2C = ../tools/bin2c +BLKPACK = ../tools/blkpack .PHONY: all all: $(TARGETS) @@ -22,6 +23,7 @@ all: $(TARGETS) $(STRIPFC): $(SLATEST): $(BIN2C): +$(BLKPACK): $(MAKE) -C ../tools # z80c.bin is not in the prerequisites because it's a bootstrap @@ -55,7 +57,10 @@ forth/forth1-bin.h: forth/forth1.bin $(BIN2C) forth/stage2: forth/stage.c $(OBJS) forth/forth1-bin.h $(CC) -DSTAGE2 forth/stage.c $(OBJS) -o $@ -forth/forth: forth/forth.c $(OBJS) forth/forth1-bin.h +blkfs: $(BLKPACK) + $(BLKPACK) ../blk > $@ + +forth/forth: forth/forth.c $(OBJS) forth/forth1-bin.h blkfs $(CC) forth/forth.c $(OBJS) -o $@ libz80/libz80.o: libz80/z80.c diff --git a/emul/forth/forth.c b/emul/forth/forth.c index b1a9314..067618a 100644 --- a/emul/forth/forth.c +++ b/emul/forth/forth.c @@ -11,10 +11,15 @@ // This binary is also used for automated tests and those tests, when // failing, send a non-zero value to RET_PORT to indicate failure #define RET_PORT 0x01 +// Port for block reads. Write 2 bytes, MSB first, on that port and then +// read 1024 bytes from the same port. +#define BLK_PORT 0x03 static int running; static FILE *fp; +static FILE *blkfp; static int retcode = 0; +static uint16_t blkid = 0; static uint8_t iord_stdio() { @@ -39,6 +44,27 @@ static void iowr_ret(uint8_t val) retcode = val; } +static uint8_t iord_blk() +{ + uint8_t res = 0; + if (blkfp != NULL) { + int c = getc(blkfp); + if (c != EOF) { + res = c; + } + } + return res; +} + +static void iowr_blk(uint8_t val) +{ + blkid <<= 8; + blkid |= val; + if (blkfp != NULL) { + fseek(blkfp, blkid*1024, SEEK_SET); + } +} + int main(int argc, char *argv[]) { @@ -67,11 +93,14 @@ int main(int argc, char *argv[]) fprintf(stderr, "Usage: ./forth [filename]\n"); return 1; } + blkfp = fopen("blkfs", "r+"); Machine *m = emul_init(); m->ramstart = RAMSTART; m->iord[STDIO_PORT] = iord_stdio; m->iowr[STDIO_PORT] = iowr_stdio; m->iowr[RET_PORT] = iowr_ret; + m->iord[BLK_PORT] = iord_blk; + m->iowr[BLK_PORT] = iowr_blk; // initialize memory for (int i=0; imem[i] = KERNEL[i]; @@ -89,6 +118,7 @@ int main(int argc, char *argv[]) tcsetattr(0, TCSAFLUSH, &termInfo); emul_printdebug(); } + fclose(blkfp); fclose(fp); return retcode; } diff --git a/emul/forth/run.fs b/emul/forth/run.fs index de051f0..b5dc796 100644 --- a/emul/forth/run.fs +++ b/emul/forth/run.fs @@ -1 +1,15 @@ -: INIT CURRENT @ HERE ! RDLN$ Z80A$ INTERPRET ; +: EFS@ + 256 /MOD 3 PC! 3 PC! + 1024 0 DO + 3 PC@ + BLK( I + C! + LOOP +; +: INIT + CURRENT @ HERE ! + BLK$ + ['] EFS@ BLK@* ! + RDLN$ + Z80A$ + INTERPRET +; diff --git a/forth/blk.fs b/forth/blk.fs new file mode 100644 index 0000000..c64ed6c --- /dev/null +++ b/forth/blk.fs @@ -0,0 +1,32 @@ +( I/O blocks ) + +: BLKMEM+ 0x57 RAM+ @ + ; +( n -- Fetches block n and write it to BLK( ) +: BLK@* 0 BLKMEM+ ; +( n -- Write back BLK( to storage at block n ) +: BLK!* 2 BLKMEM+ ; +( Current blk pointer in ( ) +: BLK> 4 BLKMEM+ ; +: BLK( 6 BLKMEM+ ; + +: BLK$ + H@ 0x57 RAM+ ! + 1030 ALLOT + -1 BLK> ! +; + +: BLK@ + DUP BLK> = IF DROP EXIT THEN + DUP BLK> ! BLK@* @ EXECUTE +; + +: .2 DUP 10 < IF SPC THEN . ; + +: LIST + BLK@ + 16 0 DO + I 1 + .2 SPC + 64 I * BLK( + (print) + CRLF + LOOP +; diff --git a/forth/fmt.fs b/forth/fmt.fs index c9378f2..db3744b 100644 --- a/forth/fmt.fs +++ b/forth/fmt.fs @@ -62,7 +62,7 @@ EMIT 1 + LOOP - LF + CRLF ; ( n a -- ) diff --git a/forth/print.fs b/forth/print.fs index 3781215..f758e4d 100644 --- a/forth/print.fs +++ b/forth/print.fs @@ -32,4 +32,5 @@ : BS 8 EMIT ; : LF 10 EMIT ; : CR 13 EMIT ; +: CRLF CR LF ; : SPC 32 EMIT ; diff --git a/notes.txt b/notes.txt index 25774f2..85c4044 100644 --- a/notes.txt +++ b/notes.txt @@ -71,7 +71,7 @@ other fields, the only one they have is the "flags" field. There are some core variables in the core system that are referred to directly by their address in memory throughout the code. The place where they live is configurable by the RAMSTART constant in conf.fs, but their relative offset is -not. In fact, they're mostlly referred to directly as their numerical offset +not. In fact, they're mostly referred to directly as their numerical offset along with a comment indicating what this offset refers to. This system is a bit fragile because every time we change those offsets, we @@ -91,7 +91,7 @@ RAMSTART INITIAL_SP +51 CURRENTPTR +53 readln's variables +55 adev's variables -+57 FUTURE USES ++57 blk's variables +59 z80a's variables +5b FUTURE USES +70 DRIVERS