1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-12-24 14:28:06 +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
# 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:

View File

@ -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+ !

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
;
( 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

View File

@ -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.