diff --git a/emul/forth/boot.bin b/emul/forth/boot.bin index c5e2c36..54d3ae6 100644 Binary files a/emul/forth/boot.bin and b/emul/forth/boot.bin differ diff --git a/emul/forth/z80c.bin b/emul/forth/z80c.bin index 107bc6b..c27d937 100644 Binary files a/emul/forth/z80c.bin and b/emul/forth/z80c.bin differ diff --git a/forth/boot.fs b/forth/boot.fs index 15e0d3b..92eb1dc 100644 --- a/forth/boot.fs +++ b/forth/boot.fs @@ -25,17 +25,17 @@ JP(IY), NOP, ( 17, nativeWord ) 0 JPnn, ( 1d, chkPS ) NOP, NOP, ( 20, numberWord ) NOP, NOP, ( 22, litWord ) -RAMSTART , ( 24, INITIAL_SP ) -RAMSTART 0x0e + , ( 26, WORDBUF ) +RAMSTART , ( 24, RAMSTART ) +NOP, NOP, ( 26, unused ) 0 JPnn, ( 28, flagsToBC ) 0 JPnn, ( 2b, doesWord ) RS_ADDR , ( 2e, RS_ADDR ) -RAMSTART 0x0c + , ( 30, CINPTR ) -RAMSTART 0x2e + , ( 32, SYSVNXT ) -RAMSTART 0x08 + , ( 34, FLAGS ) -RAMSTART 0x0a + , ( 36, PARSEPTR ) -RAMSTART 0x04 + , ( 38, HERE ) -RAMSTART 0x02 + , ( 3a, CURRENT ) +NOP, NOP, ( 30, unused ) +NOP, NOP, ( 32, unused ) +NOP, NOP, ( 34, unused ) +NOP, NOP, ( 36, unused ) +NOP, NOP, ( 38, unused ) +NOP, NOP, ( 3a, unused ) ( BOOT DICT There are only 5 words in the boot dict, but these words' @@ -116,14 +116,14 @@ PC ORG @ 1 + ! ( main ) stack underflow. ) SP 0xfffa LDddnn, - 0x24 @ SP LD(nn)dd, ( 24 == INITIAL_SP ) + RAMSTART SP LD(nn)dd, ( RAM+00 == INITIAL_SP ) IX RS_ADDR LDddnn, ( LATEST is a label to the latest entry of the dict. It is written at offset 0x08 by the process or person building Forth. ) 0x08 LDHL(nn), - 0x3a @ LD(nn)HL, ( 3a == CURRENT ) - 0x38 @ LD(nn)HL, ( 38 == HERE ) + RAMSTART 0x02 + LD(nn)HL, ( RAM+02 == CURRENT ) + RAMSTART 0x04 + LD(nn)HL, ( RAM+04 == HERE ) HL L1 @ LDddnn, 0x03 CALLnn, ( 03 == find ) DE PUSHqq, @@ -155,7 +155,7 @@ PC ORG @ 4 + ! ( find ) adjust. Because the compare loop pre-decrements, instead of DECing HL twice, we DEC it once. ) HL DECss, - DE 0x3a @ LDdd(nn), ( 3a == CURRENT ) + DE RAMSTART 0x02 + LDdd(nn), ( RAM+02 == CURRENT ) L3 BSET ( inner ) ( DE is a wordref, first step, do our len correspond? ) HL PUSHqq, ( --> lvl 1 ) @@ -249,7 +249,7 @@ L1 BSET ( abortUnderflow ) PC ORG @ 0x1e + ! ( chkPS ) HL PUSHqq, - 0x24 @ LDHL(nn), ( 24 == INITIAL_SP ) + RAMSTART LDHL(nn), ( RAM+00 == INITIAL_SP ) ( We have the return address for this very call on the stack and protected registers. Let's compensate ) HL DECss, diff --git a/forth/core.fs b/forth/core.fs index 49c60e1..a587790 100644 --- a/forth/core.fs +++ b/forth/core.fs @@ -106,16 +106,16 @@ : (sysv) ( Get new sysv addr ) - ( 50 == SYSVNXT ) - 50 @ @ + ( RAM+46 (2e) == SYSVNXT ) + 46 RAM+ @ CONSTANT ( increase current sysv counter ) - 2 50 @ +! + 2 46 RAM+ +! ; ( Set up initial SYSVNXT value, which is 2 bytes after its own address ) -50 @ DUP 2 + SWAP ! +46 RAM+ DUP 2 + SWAP ! : ." LIT diff --git a/forth/icore.fs b/forth/icore.fs index 5afaff4..d0582a9 100644 --- a/forth/icore.fs +++ b/forth/icore.fs @@ -55,25 +55,15 @@ , ( write! ) ; IMMEDIATE -: FLAGS - ( 52 == FLAGS ) - [ 52 @ LITN ] +: RAM+ + ( 0x24 == RAMSTART ) + [ 0x24 @ LITN ] _c + ; -: (parse*) - ( 54 == PARSEPTR ) - [ 54 @ LITN ] -; - -: HERE - ( 56 == HERE ) - [ 56 @ LITN ] -; - -: CURRENT - ( 58 == CURRENT ) - [ 58 @ LITN ] -; +: FLAGS 0x08 _c RAM+ ; +: (parse*) 0x0a _c RAM+ ; +: HERE 0x04 _c RAM+ ; +: CURRENT 0x02 _c RAM+ ; : QUIT 0 _c FLAGS _c ! _c (resRS) @@ -142,8 +132,8 @@ ; : C< - ( 48 == CINPTR ) - [ 48 @ LITN ] _c @ EXECUTE + ( 0c == CINPTR ) + 0x0c _c RAM+ _c @ EXECUTE ; : , @@ -170,8 +160,8 @@ ( Read word from C<, copy to WORDBUF, null-terminate, and return, make HL point to WORDBUF. ) : WORD - ( 38 == WORDBUF ) - [ 38 @ LITN ] ( a ) + ( 0e == WORDBUF ) + 0x0e _c RAM+ ( a ) _c TOWORD ( a c ) BEGIN ( We take advantage of the fact that char MSB is @@ -184,7 +174,7 @@ ( a this point, PS is: a WS ) ( null-termination is already written ) _c 2DROP - [ 38 @ LITN ] + 0x0e _c RAM+ ; : (entry) @@ -220,8 +210,8 @@ LIT< (parse) _c (find) _c DROP _c (parse*) _c ! LIT< (c<) _c (find) _c NOT IF LIT< KEY _c (find) _c DROP THEN - ( 48 == CINPTR ) - [ 48 @ LITN ] _c ! + ( 0c == CINPTR ) + 0x0c _c RAM+ _c ! LIT< (c<$) _c (find) IF EXECUTE ELSE _c DROP THEN _c INTERPRET ; diff --git a/forth/notes.txt b/forth/notes.txt index 02ced83..1767368 100644 --- a/forth/notes.txt +++ b/forth/notes.txt @@ -66,3 +66,44 @@ also "special words", for example NUMBER, LIT, FBR, that have a slightly different structure. They're also a pointer to an executable, but as for the other fields, the only one they have is the "flags" field. +*** System variables + +There are some core variables in the core system that are referred to directly +by their address in memory throughout the code. The place where they live is +configurable by the RAMSTART constant in conf.fs, but their relative offset is +not. In fact, they're mostlly referred to directly as their numerical offset +along with a comment indicating what this offset refers to. + +This system is a bit fragile because every time we change those offsets, we +have to be careful to adjust all system variables offsets, but thankfully, +there aren't many system variables. Here's a list of them: + +RAMSTART INITIAL_SP ++02 CURRENT ++04 HERE ++06 IP ++08 FLAGS ++0a PARSEPTR ++0c CINPTR ++0e WORDBUF ++2e SYSVNXT ++4e RAMEND + +INITIAL_SP holds the initial Stack Pointer value so that we know where to reset +it on ABORT + +CURRENT points to the last dict entry. + +HERE points to current write offset. + +IP is the Interpreter Pointer + +FLAGS holds global flags. Only used for prompt output control for now. + +PARSEPTR holds routine address called on (parse) + +CINPTR holds routine address called on C< + +WORDBUF is the buffer used by WORD + +SYSVNXT is the buffer+tracker used by (sysv)