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.
This commit is contained in:
Virgil Dupras 2020-04-02 09:58:02 -04:00
parent d0c5d3a741
commit 68a7be3707
6 changed files with 72 additions and 41 deletions

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

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

View File

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