Here is fbForth’s inner interpreter (sans DODOES):
DOCOL DECT R
$NEXT MOV *IP+,W
DOEXEC MOV *W+,R1
$SEMIS MOV *R+,IP
Obviously, this is indirect threading, but I show it for comparison because it is going to take me awhile to wrap my head around direct threading and machine Forth (mainly, because I have never thought about them seriously). At the risk of stating the obvious, B *NEXT (NEXT contains $NEXT most of the time) ends ALC bodies and the cfa of ; ends all : word bodies, causing execution to continue at $SEMIS. Pardon any ineptitude in my attempts to understand what you are doing. I promise to try harder.
I am playing games really. I am creating assembler macros to simulate Forth words and tieing it all together with yet another macro called "CALL"
and ending each sub-routine with RT, . I was just amazed at how much faster native code goes.
CALL RP DECT
MOV R11 *RP
BL @> "some code"
MOV *RP+ R11
The fun thing is that the Forth Assembler is so flexible that you can do this with little effort.
The other piece that you need is a target compiler.
It works just like the Forth compiler.
And for your interest a basic target compiler starts like this:
VARIABLE TARGMEM 64k ALLOT
VARIABLE TDP \ target dictionary pointer
: THERE ( -- addr) TARGMEM TDP @ + ; \ Target memory so not HERE but THERE :-)
: TALLOT ( u -- ) TDP +! ;
: T! ( n addr -- ) TARGMEM + ! ;
: TC! ( n addr -- ) TARGMEM + C! ;
: T, ( n addr -- ) THERE ! 2 TALLOT ; \ like "comma"
: TC, ( c addr -- ) THERE C! 1 TALLOT ; \ like C,
That's about it. That's the basic framework for a target compiler.
Rewrite the basic parts of Forth but use T, and TC, and you have a system in a new memory space.
*edit* Actually re-write your FORTH assembler first, and using T, and TC, etc...
At MPE they name these things like this: ,(t) C,(t) HERE(t) ALLOT(t)
Pretty, but more typing.
Edited by TheBF, Sat Mar 11, 2017 3:26 PM.