From 6c5f39806bf0fbc32f87169414a7bd1cb5710673 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Tue, 24 Mar 2020 21:13:02 -0400 Subject: [PATCH] forth: improve bootstrap process --- emul/Makefile | 31 ++++++++++++------------------- emul/README.md | 30 ++++++++++++++---------------- emul/forth/forth.c | 2 +- emul/forth/stage0.asm | 2 +- emul/forth/stage1.asm | 2 +- emul/forth/stage2.asm | 10 ---------- 6 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 emul/forth/stage2.asm diff --git a/emul/Makefile b/emul/Makefile index a18d58c..6f92073 100644 --- a/emul/Makefile +++ b/emul/Makefile @@ -27,8 +27,10 @@ shell/shell-bin.h: shell/shell.bin shell/shell: shell/shell.c $(SHELLOBJS) shell/shell-bin.h $(CC) shell/shell.c $(SHELLOBJS) -o $@ +# z80c.bin is not in the prerequisites because its a bootstrap binary that +# should be updated manually through make fbootstrap. forth/forth0.bin: forth/stage0.asm $(ZASMBIN) - $(ZASMBIN) $(KERNEL) ../forth forth/stagec.asm < forth/stage0.asm | tee $@ > /dev/null + $(ZASMBIN) $(KERNEL) ../forth forth/z80c.bin forth/stagec.asm < forth/stage0.asm | tee $@ > /dev/null forth/forth0-bin.h: forth/forth0.bin ./bin2c.sh KERNEL < forth/forth0.bin | tee $@ > /dev/null @@ -39,10 +41,11 @@ forth/stage1: forth/stage.c $(OBJS) forth/forth0-bin.h forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h $(CC) -DDEBUG forth/stage.c $(OBJS) -o $@ -# z80c.bin is not in the prerequisites because its a bootstrap binary that -# should be updated manually through make fbootstrap. +forth/core.bin: $(FORTHSRC_PATHS) forth/stage1 + cat $(FORTHSRC_PATHS) | ./forth/stage1 | tee $@ > /dev/null + forth/forth1.bin: forth/stage1.asm forth/forth0.bin $(ZASMBIN) - $(ZASMBIN) $(KERNEL) ../forth forth/z80c.bin forth/stagec.asm < forth/stage1.asm | tee $@ > /dev/null + $(ZASMBIN) $(KERNEL) ../forth forth/z80c.bin forth/core.bin forth/stagec.asm < forth/stage1.asm | tee $@ > /dev/null forth/forth1-bin.h: forth/forth1.bin ./bin2c.sh KERNEL < forth/forth1.bin | tee $@ > /dev/null @@ -50,19 +53,7 @@ forth/forth1-bin.h: forth/forth1.bin forth/stage2: forth/stage.c $(OBJS) forth/forth1-bin.h $(CC) -DSTAGE2 forth/stage.c $(OBJS) -o $@ -forth/stage2dbg: forth/stage.c $(OBJS) forth/forth1-bin.h - $(CC) -DSTAGE2 -DDEBUG forth/stage.c $(OBJS) -o $@ - -forth/core.bin: $(FORTHSRC_PATHS) forth/stage2 - cat $(FORTHSRC_PATHS) | ./forth/stage2 | tee $@ > /dev/null - -forth/forth2.bin: forth/stage2.asm forth/core.bin $(ZASMBIN) - $(ZASMBIN) $(KERNEL) ../forth forth/core.bin forth/z80c.bin forth/stagec.asm < forth/stage2.asm | tee $@ > /dev/null - -forth/forth2-bin.h: forth/forth2.bin - ./bin2c.sh KERNEL < forth/forth2.bin | tee $@ > /dev/null - -forth/forth: forth/forth.c $(OBJS) forth/forth2-bin.h +forth/forth: forth/forth.c $(OBJS) forth/forth1-bin.h $(CC) forth/forth.c $(OBJS) -o $@ zasm/kernel-bin.h: zasm/kernel.bin @@ -108,9 +99,11 @@ updatebootstrap: $(ZASMBIN) $(ZASMBIN) $(KERNEL) < zasm/glue.asm > zasm/kernel.bin $(ZASMBIN) $(KERNEL) $(APPS) zasm/user.h < $(APPS)/zasm/glue.asm > zasm/zasm.bin +# We need to double wrap around dummy.fs because at stage3, we have high-level +# words and they write to HERE at initialization. .PHONY: fbootstrap -fbootstrap: forth/stage1 - cat $(FORTHSRC_PATHS) ../forth/z80c.fs ../forth/dummy.fs | ./forth/stage1 | tee forth/z80c.bin > /dev/null +fbootstrap: forth/stage2 + cat ../forth/dummy.fs ../forth/z80c.fs ../forth/dummy.fs | ./forth/stage2 | tee forth/z80c.bin > /dev/null .PHONY: clean clean: diff --git a/emul/README.md b/emul/README.md index 1e67a58..dc2b313 100644 --- a/emul/README.md +++ b/emul/README.md @@ -90,28 +90,26 @@ Because of that aim, it currently builds in a particular manner. There are 3 build stages. **Stage 0**: This stage is created with zasm by assembling `forth/forth.asm` -through `stage0.asm`. This yields `forth0.bin`. We then wrap this binary with -`stage.c` to create the `stage1` binary, which allows us to get to the next -stage. +and `z80c.bin` through `stage0.asm`. This yields `forth0.bin`. We then wrap +this binary with `stage.c` to create the `stage1` binary, which allows us to +get to the next stage. -The long term goal is to gradually extract contents from `forth.asm` and have -nothing but Forth source files. +`z80c.bin` is a "chicken-and-egg" typf of binary that is committed in the repo. +It is the result of compiling `z80c.fs`, but this needs stage2. **Stage 1**: The `stage1` binary allows us to augment `forth0.bin` with -contents from `z80c.fs`, which compiles native words using Forth's Z80 -assembler. This yields `z80c.bin`. +the compiled dictionary of a full Forth interpreter. We feed it with +`$(FORTHSRCS)` and then dump the resulting compiled dict. -This is where there's a chiken-and-egg issue: Forth's assembler needs our full -Forth interpreter, but that interpreter needs native words from `z80c.fs`. This -is why `z80c.bin` is committed into the git repo and it's built automatically -with `make`. Updating `z80c.bin` is a specific make rule, `fbootstrap`. +From there, we can create `forth1.bin`, which is wrapped by both the `forth` +and `stage2` executables. `forth` is the interpreter you'll use. -Then, from there, we augment `forth0.bin` with `z80c.bin` and yield -`forth1.bin`, from which we create `stage2`. +**Stage 2**: `stage2` is used to resolve the chicken-and-egg problem and use +the power of a full Forth intepreter, including an assembler, to assemble +`z80c.bin`. This is a manual step executed through `make fbootstrap`. -**Stage 2**: From there, the way is clear to compile the dict of our full Forth -interpreter, which we do using `stage2` and produce `forth2.bin`, from which we -can create our final `forth` executable. +Normally, running this step should yield the exact same `z80c.bin` as before, +unless of course you've changed the source. ## Problems? diff --git a/emul/forth/forth.c b/emul/forth/forth.c index b2084a3..873b4c1 100644 --- a/emul/forth/forth.c +++ b/emul/forth/forth.c @@ -3,7 +3,7 @@ #include #include #include "../emul.h" -#include "forth2-bin.h" +#include "forth1-bin.h" // in sync with glue.asm #define RAMSTART 0x900 diff --git a/emul/forth/stage0.asm b/emul/forth/stage0.asm index 2895ac0..4679133 100644 --- a/emul/forth/stage0.asm +++ b/emul/forth/stage0.asm @@ -3,5 +3,5 @@ .inc "stagec.asm" .inc "forth.asm" +.bin "z80c.bin" CODE_END: -.out $ ; should be the same as in stage{1,2} diff --git a/emul/forth/stage1.asm b/emul/forth/stage1.asm index 4cb46b2..539aa9e 100644 --- a/emul/forth/stage1.asm +++ b/emul/forth/stage1.asm @@ -3,6 +3,6 @@ .inc "stagec.asm" .inc "forth.asm" -.out $ ; should be the same as in stage{0,2} .bin "z80c.bin" +.bin "core.bin" CODE_END: diff --git a/emul/forth/stage2.asm b/emul/forth/stage2.asm deleted file mode 100644 index 73612ad..0000000 --- a/emul/forth/stage2.asm +++ /dev/null @@ -1,10 +0,0 @@ - jp init - -.inc "stagec.asm" -.inc "forth.asm" - -.out $ ; should be the same as in stage{0,1} -.bin "z80c.bin" -.bin "core.bin" -CODE_END: -