1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-23 23:48:05 +11:00

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...
This commit is contained in:
Virgil Dupras 2020-04-03 08:31:30 -04:00
parent b575d7f863
commit 80891d7ec1
6 changed files with 60 additions and 27 deletions

View File

@ -1,7 +1,7 @@
TARGETS = runbin/runbin forth/forth TARGETS = runbin/runbin forth/forth
# Those Forth source files are in a particular order # Those Forth source files are in a particular order
FORTHSRCS = core.fs str.fs parse.fs readln.fs fmt.fs z80a.fs 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 OBJS = emul.o libz80/libz80.o
SLATEST = ../tools/slatest SLATEST = ../tools/slatest
@ -16,6 +16,7 @@ $(SLATEST):
forth/forth0.bin: $(SLATEST) forth/forth0.bin: $(SLATEST)
cat forth/boot.bin forth/z80c.bin > $@ cat forth/boot.bin forth/z80c.bin > $@
$(SLATEST) $@ $(SLATEST) $@
cat forth/emul.fs >> $@
forth/forth0-bin.h: forth/forth0.bin forth/forth0-bin.h: forth/forth0.bin
./bin2c.sh KERNEL < forth/forth0.bin | tee $@ > /dev/null ./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 $@ $(CC) forth/stage.c $(OBJS) -o $@
forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h 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 forth/core.bin: $(FORTHSRC_PATHS) forth/stage1
cat $(FORTHSRC_PATHS) ./forth/stop.fs | ./forth/stage1 | tee $@ > /dev/null cat $(FORTHSRC_PATHS) ./forth/stop.fs | ./forth/stage1 | tee $@ > /dev/null
forth/forth1.bin: forth/forth0.bin forth/core.bin $(SLATEST) forth/forth1.bin: forth/core.bin $(SLATEST)
cat forth/forth0.bin forth/core.bin > $@ cat forth/boot.bin forth/z80c.bin forth/core.bin > $@
$(SLATEST) $@ $(SLATEST) $@
forth/forth1-bin.h: forth/forth1.bin forth/forth1-bin.h: forth/forth1.bin
@ -56,7 +57,7 @@ emul.o: emul.c
.PHONY: updatebootstrap .PHONY: updatebootstrap
updatebootstrap: forth/stage2 updatebootstrap: forth/stage2
cat ./forth/conf.fs ../forth/boot.fs | ./forth/stage2 | tee forth/boot.bin > /dev/null 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 .PHONY: clean
clean: clean:

View File

@ -1,17 +1,4 @@
( Implementation fo KEY and EMIT in the emulator HERE @ 256 /MOD 2 PC! 2 PC!
stdio port is 0 : EMIT 0 PC! ;
) : KEY 0 PC@ ;
CURRENT @ 12 RAM+ !
CODE EMIT
HL POPqq,
chkPS,
A L LDrr,
0 OUTnA,
;CODE
CODE KEY
0 INAn,
H 0 LDrn,
L A LDrr,
HL PUSHqq,
;CODE

1
emul/forth/run.fs Normal file
View File

@ -0,0 +1 @@
: INIT (c<$) INTERPRET ;

Binary file not shown.

View File

@ -189,13 +189,22 @@
AGAIN 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 : BOOT
LIT< (parse) _c (find) _c DROP _c (parse*) _c ! LIT< (parse) _c (find) _c DROP _c (parse*) _c !
LIT< (c<) _c (find) _c ( 51 == SYSTEM SCRATCHPAD )
NOT IF LIT< KEY _c (find) _c DROP THEN _c CURRENT _c @ 0x51 _c RAM+ _c !
( 0c == CINPTR ) ( 0c == CINPTR )
0x0c _c RAM+ _c ! LIT< (c<) _c (find) _c DROP 0x0c _c RAM+ _c !
LIT< (c<$) _c (find) IF EXECUTE ELSE _c DROP THEN
LIT< INIT _c (find) LIT< INIT _c (find)
IF EXECUTE IF EXECUTE
ELSE _c DROP _c INTERPRET THEN ELSE _c DROP _c INTERPRET THEN

View File

@ -88,7 +88,8 @@ RAMSTART INITIAL_SP
+0e WORDBUF +0e WORDBUF
+2e SYSVNXT +2e SYSVNXT
+4e INTJUMP +4e INTJUMP
+51 RAMEND +51 SYSTEM SCRATCHPAD
+60 RAMEND
INITIAL_SP holds the initial Stack Pointer value so that we know where to reset INITIAL_SP holds the initial Stack Pointer value so that we know where to reset
it on ABORT 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 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 one of those slots for an interrupt, write a jump to the appropriate offset in
that RAM location. 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.