mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 14:58: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:
parent
b575d7f863
commit
80891d7ec1
@ -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:
|
||||||
|
@ -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
1
emul/forth/run.fs
Normal file
@ -0,0 +1 @@
|
|||||||
|
: INIT (c<$) INTERPRET ;
|
Binary file not shown.
@ -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
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user