From 80891d7ec172bc22e5dc7594b1b87dbdea92ffdb Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Fri, 3 Apr 2020 08:31:30 -0400 Subject: [PATCH] Add in-memory bootstrapping system This should help with the bootstrapping of non-emulated environment. For example, I have a problem with the RC2014: I can't send it bootstrap info until the ACIA is up. I need to find a way... --- emul/Makefile | 11 ++++++----- emul/forth/emul.fs | 21 ++++----------------- emul/forth/run.fs | 1 + emul/forth/z80c.bin | Bin 1741 -> 1720 bytes forth/icore.fs | 17 +++++++++++++---- forth/notes.txt | 37 ++++++++++++++++++++++++++++++++++++- 6 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 emul/forth/run.fs diff --git a/emul/Makefile b/emul/Makefile index 54270c4..3b2e0ac 100644 --- a/emul/Makefile +++ b/emul/Makefile @@ -1,7 +1,7 @@ TARGETS = runbin/runbin forth/forth # Those Forth source files are in a particular order FORTHSRCS = core.fs str.fs parse.fs readln.fs fmt.fs z80a.fs -FORTHSRC_PATHS = ${FORTHSRCS:%=../forth/%} +FORTHSRC_PATHS = ${FORTHSRCS:%=../forth/%} forth/run.fs OBJS = emul.o libz80/libz80.o SLATEST = ../tools/slatest @@ -16,6 +16,7 @@ $(SLATEST): forth/forth0.bin: $(SLATEST) cat forth/boot.bin forth/z80c.bin > $@ $(SLATEST) $@ + cat forth/emul.fs >> $@ forth/forth0-bin.h: forth/forth0.bin ./bin2c.sh KERNEL < forth/forth0.bin | tee $@ > /dev/null @@ -24,13 +25,13 @@ forth/stage1: forth/stage.c $(OBJS) forth/forth0-bin.h $(CC) forth/stage.c $(OBJS) -o $@ forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h - $(CC) -DDEBUG -DBOOT forth/stage.c $(OBJS) -o $@ + $(CC) -DDEBUG forth/stage.c $(OBJS) -o $@ forth/core.bin: $(FORTHSRC_PATHS) forth/stage1 cat $(FORTHSRC_PATHS) ./forth/stop.fs | ./forth/stage1 | tee $@ > /dev/null -forth/forth1.bin: forth/forth0.bin forth/core.bin $(SLATEST) - cat forth/forth0.bin forth/core.bin > $@ +forth/forth1.bin: forth/core.bin $(SLATEST) + cat forth/boot.bin forth/z80c.bin forth/core.bin > $@ $(SLATEST) $@ forth/forth1-bin.h: forth/forth1.bin @@ -56,7 +57,7 @@ emul.o: emul.c .PHONY: updatebootstrap updatebootstrap: forth/stage2 cat ./forth/conf.fs ../forth/boot.fs | ./forth/stage2 | tee forth/boot.bin > /dev/null - cat ./forth/conf.fs ../forth/z80c.fs forth/emul.fs ../forth/icore.fs | ./forth/stage2 | tee forth/z80c.bin > /dev/null + cat ./forth/conf.fs ../forth/z80c.fs ../forth/icore.fs | ./forth/stage2 | tee forth/z80c.bin > /dev/null .PHONY: clean clean: diff --git a/emul/forth/emul.fs b/emul/forth/emul.fs index 0f4607b..245a80b 100644 --- a/emul/forth/emul.fs +++ b/emul/forth/emul.fs @@ -1,17 +1,4 @@ -( Implementation fo KEY and EMIT in the emulator - stdio port is 0 -) - -CODE EMIT - HL POPqq, - chkPS, - A L LDrr, - 0 OUTnA, -;CODE - -CODE KEY - 0 INAn, - H 0 LDrn, - L A LDrr, - HL PUSHqq, -;CODE +HERE @ 256 /MOD 2 PC! 2 PC! +: EMIT 0 PC! ; +: KEY 0 PC@ ; +CURRENT @ 12 RAM+ ! diff --git a/emul/forth/run.fs b/emul/forth/run.fs new file mode 100644 index 0000000..7dccc06 --- /dev/null +++ b/emul/forth/run.fs @@ -0,0 +1 @@ +: INIT (c<$) INTERPRET ; diff --git a/emul/forth/z80c.bin b/emul/forth/z80c.bin index 1cfc35a2d4fa61b1609410783ab827d884ab5af0..c5137a6351623c1ed6e4b68909661fc84e03b846 100644 GIT binary patch delta 657 zcmX|8J!lj`7=5!dJG(h@dx_u?E)q6J#GDBzLJD`~m2I$?ZS6hZx!Jh_m+2Z9d>kgB2gQIY0ke@LVVq9GVazJA^^GVU z7Xi)Uo4hWzijkb1?vuiUI)sN;%7;L|m{kjnzMY|kkznN9IxAu|fAtMvHQcp)00sl% zCh)O%t->c~_7^K7^JCI7!4xd^oh08>o>1v>gXIId8ObO2bZ!ND=q=h^<=VdoZyW;HmURb?hHv<8Ch z{)i#jrm{=l(8~2YUER2mC{Dwqn}q2@On88Esxr(_41uO?jwlDmreE2EizN~`K@UGJ z$#^^H+^)vIUPc~>19GZ5^}!hHKU!N$7r3lF-eL!*Y9yA3$ delta 704 zcmYjPJ!lhQ7=FI{zPn3GaL?!cwfXd_f7$F2H$WT4}K7^vYN+J2PK?1xSkzlcH(ogyjV3gs?ptzhih}S zy~uER3JhL#1J{9KK#c*t6a;P~oQBPqF~)8#dEtZv)Z>@(n0Ow4l!vDKq;N40;ozAn zL7*T1k(EN=;k;1-pfR9Y7GL6)a&K*$?~I6szalNYum=Xu z&C%RYc8NM)VEGoEwB$E?+A>8hUCZe4-Mvy1+-iTaF0y3yh0tY!gDK!jy<)SyE8|Wq1uQ+yz<$zOXeGy|8gF z&7_3HN-T|f9#0(HwmFByN^S3_wH0?MCRUSHnwmbFNo`*^!+j;%TQ0GF%aPDnp#}a2 D$Lx_6 diff --git a/forth/icore.fs b/forth/icore.fs index 9299a36..c82be2c 100644 --- a/forth/icore.fs +++ b/forth/icore.fs @@ -189,13 +189,22 @@ AGAIN ; +( system c< simply reads source from binary, starting at + LATEST. Convenient way to bootstrap a new system. ) +: (c<) + ( 51 == SYSTEM SCRATCHPAD ) + 0x51 _c RAM+ _c @ ( a ) + _c DUP _c C@ ( a c ) + _c SWAP 1 _c + ( c a+1 ) + 0x51 _c RAM+ _c ! ( c ) +; + : BOOT LIT< (parse) _c (find) _c DROP _c (parse*) _c ! - LIT< (c<) _c (find) _c - NOT IF LIT< KEY _c (find) _c DROP THEN + ( 51 == SYSTEM SCRATCHPAD ) + _c CURRENT _c @ 0x51 _c RAM+ _c ! ( 0c == CINPTR ) - 0x0c _c RAM+ _c ! - LIT< (c<$) _c (find) IF EXECUTE ELSE _c DROP THEN + LIT< (c<) _c (find) _c DROP 0x0c _c RAM+ _c ! LIT< INIT _c (find) IF EXECUTE ELSE _c DROP _c INTERPRET THEN diff --git a/forth/notes.txt b/forth/notes.txt index f178961..a685068 100644 --- a/forth/notes.txt +++ b/forth/notes.txt @@ -88,7 +88,8 @@ RAMSTART INITIAL_SP +0e WORDBUF +2e SYSVNXT +4e INTJUMP -+51 RAMEND ++51 SYSTEM SCRATCHPAD ++60 RAMEND INITIAL_SP holds the initial Stack Pointer value so that we know where to reset it on ABORT @@ -113,3 +114,37 @@ INTJUMP All RST offsets (well, not *all* at this moment, I still have to free those slots...) in boot binaries are made to jump to this address. If you use one of those slots for an interrupt, write a jump to the appropriate offset in that RAM location. + +SYSTEM SCRATCHPAD is reserved for temporary system storage. + +*** Initialization sequence + +On boot, we jump to the "main" routine in boot.fs which does very few things. +It sets up the SP register, CURRENT and HERE to LATEST (saved in stable ABI), +then look for the BOOT word and calls it. + +In a normal system, BOOT is in icore and does a few things: + +1. Find "(parse)" and set "(parse*)" to it. +2. Find "(c<)" a set CINPTR to it (what C< calls). +3. Write LATEST in SYSTEM SCRATCHPAD ( see below ) +4. Find "INIT". If found, execute. Otherwise, execute "INTERPRET" + +On a bare system (only boot+icore), this sequence will result in "(parse)" +reading only decimals and (c<) reading characters from memory starting from +CURRENT (this is why we put CURRENT in SYSTEM SCRATCHPAD, it tracks current +pos ). + +This means that you can put initialization code in source form right into your +binary, right after your last compiled dict entry and it's going to be executed +as such until you set a new (c<). + +Note that there is no EMIT in a bare system. You have to take care of supplying +one before your load core.fs and its higher levels. + +Also note that this initialization code is fighting for space with HERE: New +entries to the dict will overwrite that code! Also, because we're barebone, we +can't have comments. This leads to peculiar code in this area. If you see weird +whitespace usage, it's probably because not using those whitespace would result +in dict entry creation overwriting the code before it has the chance to be +interpreted.