Compare commits

...

2 Commits

Author SHA1 Message Date
Virgil Dupras
d259b725ad 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...
2020-04-03 08:31:30 -04:00
Virgil Dupras
b575d7f863 Move (print) and (uflw) from icore to core 2020-04-03 07:44:44 -04:00
8 changed files with 66 additions and 43 deletions

View File

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

Binary file not shown.

View File

@ -1,17 +1,3 @@
( 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
: EMIT 0 PC! ;
: KEY 0 PC@ ;
: (c<) KEY ;

Binary file not shown.

View File

@ -30,10 +30,10 @@ NOP, NOP, ( 26, unused )
0 JPnn, ( 28, flagsToBC )
0 JPnn, ( 2b, doesWord )
NOP, NOP, ( 2e, unused )
RAMSTART 0x51 + JPnn, ( RST 30 )
RAMSTART 0x4e + JPnn, ( RST 30 )
NOP, NOP, NOP, ( unused )
NOP, NOP, ( unused )
RAMSTART 0x51 + JPnn, ( RST 38 )
RAMSTART 0x4e + JPnn, ( RST 38 )
NOP, ( unused )
( BOOT DICT

View File

@ -5,8 +5,10 @@
: LIT 34 , ;
: LITS LIT SCPY ;
: LIT< WORD LITS ; IMMEDIATE
: _err LIT< word-not-found (print) ABORT ;
: ' WORD (find) NOT (?br) [ 4 , ] _err ;
: '
WORD (find) (?br) [ 4 , ] EXIT
LIT< (wnf) (find) DROP EXECUTE
;
: ['] ' LITN ; IMMEDIATE
: COMPILE ' LITN ['] , , ; IMMEDIATE
: [COMPILE] ' , ; IMMEDIATE
@ -117,6 +119,16 @@
own address )
46 RAM+ DUP 2 + SWAP !
: (print)
BEGIN
DUP C@ ( a c )
( exit if null )
DUP NOT IF 2DROP EXIT THEN
EMIT ( a )
1 + ( a+1 )
AGAIN
;
: ."
LIT
BEGIN
@ -129,3 +141,6 @@
; IMMEDIATE
: ABORT" [COMPILE] ." COMPILE ABORT ; IMMEDIATE
: (uflw) ABORT" stack underflow" ;
: (wnf) ABORT" word not found" ;

View File

@ -114,22 +114,6 @@
_c (parsed) _c NOT IF _c ABORT THEN
;
( a -- )
: (print)
BEGIN
_c DUP ( a a )
_c C@ ( a c )
( exit if null )
_c DUP _c NOT IF _c 2DROP EXIT THEN
_c EMIT ( a )
1 _c + ( a+1 )
AGAIN
;
: (uflw)
LIT< stack-underflow _c (print) _c ABORT
;
: C<
( 0c == CINPTR )
0x0c _c RAM+ _c @ EXECUTE
@ -205,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,30 @@ 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.