From 68a7be370795794ea178fa7404db39a7356f0f7c Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Thu, 2 Apr 2020 09:58:02 -0400 Subject: [PATCH] forth: Remove RAM offsets from stable ABI Doing this was a bit stupid. These offsets are constants. Moreover, having them in stable ABI had us construct the boot binary from the stable ABI of the host, making it very difficult to change RAMSTART for a new system. --- emul/forth/boot.bin | Bin 451 -> 451 bytes emul/forth/z80c.bin | Bin 1748 -> 1781 bytes forth/boot.fs | 26 +++++++++++++------------- forth/core.fs | 8 ++++---- forth/icore.fs | 38 ++++++++++++++------------------------ forth/notes.txt | 41 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 41 deletions(-) diff --git a/emul/forth/boot.bin b/emul/forth/boot.bin index c5e2c3681a863a47dd6af48f0e59a1e665a236e5..54d3ae626cbcb39c4437c7591e3996c41ee1cf8f 100644 GIT binary patch delta 33 fcmX@ie3*HHnivDaVNS-wU5pGL7?8k5n|4M3isJ^^ delta 33 pcmX@ie3*HHni$`U!<>wVyBHZh@VwA_!SRCY1!)nXM47 zZ(Ur1=_3GsjHJTt&GkFmWmt^3s8|a1w72(iccrlem%)V`yc@-lU+~NvP&;uPwUb3S z+$3}C{!S~IHvub_G9H*UwAzXOV4S-2nnvIBAbh+t4@kH<{|+#l4XL(PDrx})hWfX$ zTpn5}s+bB!M)F9XH_x5;MA!nZNwN=xG1WYL(GShYJF*UB3KIi8H1BP_w+A#+HBUpb zzhmStG5SPVEwfCAPRigndmqUTnWgsCDz`KIY+hvLj$X6s)}cKX7xZ)M%s$Q9aLQ5< zm&Ww){Ma`tFNYdv6+-IUOF?b3U7en!rSk1?&A46VgqLr}Ru@W_wO?VkZ<@ z6nEk%3E}zZIRi6Ah4v5>>!PAXcz;f~OP3bv<91Di`l@}Fy(y!H`jh5z1I%*KN0(xm zitmoXW-DoL7uOgdv-yv>Ucy@++F|RNT}YjzWUK#?GrLQvhh(&mM{XB~Gld&hm={o_ Onf=R{3WdiMt@sD=5P53= delta 573 zcmYjOL2DC17=5!dJG-gLrc#tP7P~DG6T3I@plJ&-O|)7oO}Dy*LJ=w6WU0CIqKLgG zFjxHnLJvI^JW1^@SP%pucuYO$NjS+Oe*=`o0xKvb{&33!F7MI~M;t;aFxe}if zfGPV)UK88)hrDvJ=Nc@PAOgHoAq0B%f~uB#Zi)&zHC6-TPxQ>|p^s+REEB`fTI-%qvvew0-pWr*~-?+tnAqAW1pK>G&cFGWc0V2h9f&c&j 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)