diff --git a/dictionary.txt b/dictionary.txt index d526565..70e658d 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -43,6 +43,7 @@ DELW a -- Delete wordref at a. If it shadows another DOES> -- See description at top of file IMMED? a -- f Checks whether wordref at a is immediate. IMMEDIATE -- Flag the latest defined word as immediate. +LITA n -- Write address n as a literal. LITN n -- Write number n as a literal. VARIABLE c -- Creates cell x with 2 bytes allocation. diff --git a/emul/forth/z80c.bin b/emul/forth/z80c.bin index de2db0c..3e8646b 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 c990d5f..8a6eb5e 100644 --- a/forth/boot.fs +++ b/forth/boot.fs @@ -25,7 +25,7 @@ JP(IY), NOP, ( 17, nativeWord ) 0 JPnn, ( 1d, chkPS ) NOP, NOP, ( 20, numberWord ) NOP, NOP, ( 22, litWord ) -NOP, NOP, ( 24, unused ) +NOP, NOP, ( 24, addrWord ) NOP, NOP, ( 26, unused ) 0 JPnn, ( 28, flagsToBC ) 0 JPnn, ( 2b, doesWord ) @@ -334,7 +334,10 @@ PC ORG @ 0x2c + ! ( doesWord ) 0x0e JPnn, ( 0e == compiledWord ) +( addrWord is the exact same thing as a numberWord except that + it is treated differently by meta-tools. See notes.txt ) PC ORG @ 0x20 + ! ( numberWord ) +PC ORG @ 0x24 + ! ( addrWord ) ( This is not a word, but a number literal. This works a bit differently than others: PF means nothing and the actual number is placed next to the numberWord reference in the diff --git a/forth/core.fs b/forth/core.fs index 6d1947a..97e1664 100644 --- a/forth/core.fs +++ b/forth/core.fs @@ -5,15 +5,15 @@ ; : [ INTERPRET 1 FLAGS ! ; IMMEDIATE : ] R> DROP ; -: LIT 34 , ; -: LITS LIT SCPY ; +: LITS 34 , SCPY ; : LIT< WORD LITS ; IMMEDIATE +: LITA 36 , , ; : ' WORD (find) (?br) [ 4 , ] EXIT LIT< (wnf) (find) DROP EXECUTE ; -: ['] ' LITN ; IMMEDIATE -: COMPILE ' LITN ['] , , ; IMMEDIATE +: ['] ' LITA ; IMMEDIATE +: COMPILE ' LITA ['] , , ; IMMEDIATE : [COMPILE] ' , ; IMMEDIATE : BEGIN H@ ; IMMEDIATE : AGAIN COMPILE (br) H@ - , ; IMMEDIATE @@ -27,9 +27,10 @@ "_": words starting with "_" are meant to be "private", that is, only used by their immediate surrondings. - LIT: 34 == LIT + LITS: 34 == litWord + LITA: 36 == addrWord COMPILE: Tough one. Get addr of caller word (example above - (br)) and then call LITN on it. ) + (br)) and then call LITA on it. ) : +! SWAP OVER @ + SWAP ! ; : -^ SWAP - ; diff --git a/forth/print.fs b/forth/print.fs index 88842a0..3781215 100644 --- a/forth/print.fs +++ b/forth/print.fs @@ -14,7 +14,7 @@ ; : ." - LIT + 34 , ( 34 == litWord ) BEGIN C< DUP ( c c ) ( 34 is ASCII for " ) diff --git a/notes.txt b/notes.txt index 7ba2cf6..ec6a066 100644 --- a/notes.txt +++ b/notes.txt @@ -140,6 +140,39 @@ known usages: * 0x70-0x78: ACIA buffer pointers in RC2014 recipes. +*** Word routines + +This is the description of all word routine you can encounter in this Forth +implementation. That is, a wordref will always point to a memory offset +containing one of these numbers. + +0x17: nativeWord. This words PFA contains native binary code and is jumped to +directly. + +0x0e: compiledWord. This word's PFA contains an atom list and its execution is +described in "EXECUTION MODEL" above. + +0x0b: cellWord. This word is usually followed by a 2-byte value in its PFA. +Upon execution, the *address* of the PFA is pushed to PS. + +0x2b: doesWord. This word is created by "DOES>" and is followed by a 2-byte +value as well as the adress where "DOES>" was compiled. At that address is an +atom list exactly like in a compiled word. Upon execution, after having pushed +its cell addr to PSP, it execute its reference exactly like a compiledWord. + +0x20: numberWord. No word is actually compiled with this routine, but atoms are. +Atoms with a reference to the number words routine are followed, *in the atom +list*, of a 2-byte number. Upon execution, that number is fetched and IP is +avdanced by an extra 2 bytes. + +0x24: addrWord. Exactly like a numberWord, except that it is treated +differently by meta-tools. + +0x22: litWord. Similar to a number word, except that instead of being followed +by a 2 byte number, it is followed by a null-terminated string. Upon execution, +the address of that null-terminated string is pushed on the PSP and IP is +advanced to the address following the null. + *** Initialization sequence On boot, we jump to the "main" routine in boot.fs which does very few things.