J1VM
Posted: Fri Feb 15, 2013 8:40 am
I took a quick look at the design document
Here are some notes that might help Forth novices figure out what is going on.
There is a data stack and a return stack. These are both push down stacks, and words operate on the top most entries
Word definitions start with : wordname and end with ;
The ; indicates the word returns to its caller at that point and ends the definition. The word EXIT has the same return to caller function and would be compiled into the definition by ; The J1 machine code often allows the EXIT to be merged into the preceding instruction.
Here are some explanations of the Forth words mentioned in TABLE III
The stack before and after is shown by -- separating the two. The text on the right of each half is the top of the stack. There may be other more deeply nested values on the stack but they are unaffected by the word.
So + (plus) is shown as n1 n2 -- n3
DUP "dupe" duplicates the top entry of the stack pushing a copy of the top entry onto the stack
n1 -- n1 n1
OVER makes a copy of the secondmost entry f the stack pushing it onto the stack
n1 n2 -- n1 n2 n1
INVERT bitwise inversion of the top of stack
n1 -- n2
+ "plus" add together the top two entries of the stack and put the result there
n1 n2 -- n3
SWAP exchange the top two entries of the stack
n1 n2 -- n2 n1
NIP remove the secondmost entry from the stack
n1 n2 -- n2
DROP discard the top of stack
n1 --
; (well actually EXIT) Pull the top entry off the return stack and resume execution at that location
R: n1 --
>R "to R" take the top entry off the data stack and push it onto the return stack. Rather specialist this one.
n1 -- R:vv -- n1
R> "R from" take the top entry off the return stack and push it onto the data stack. If you use >R must do R> before doing an EXIT or you'll have a crash most likely.
R: n1 -- -- n1
R@ "r fetch" make a copy of the top of the return stack and put it on the data stack
R: n1 -- n1 -- n1
@ "fetch" the top of the data has a memory address. Fetch a word of data and replace top of stack with it
a1 -- n1
! "store" the top of the data stack has a value and a memory address. Store the value there
n1 a1 --
OK onto J1 itself
T seems to be a register holding the top of the stack (a common optimisation). I don't think it changes as the stack does but might be wrong
N seems to be whatever the rest of the data stack has at the top at the moment. Changes as data stack depth changes
R seems to be whatever the top of the Return stack has at that moment. Changes as return stack depth changes
Conditional jumps use zero for FALSE any other value is TRUE. The formal value for TRUE is all bits set and is returned by words like <
So it is a matter of writing an emulator for it.
Hope this helps
Tim
Here are some notes that might help Forth novices figure out what is going on.
There is a data stack and a return stack. These are both push down stacks, and words operate on the top most entries
Word definitions start with : wordname and end with ;
The ; indicates the word returns to its caller at that point and ends the definition. The word EXIT has the same return to caller function and would be compiled into the definition by ; The J1 machine code often allows the EXIT to be merged into the preceding instruction.
Here are some explanations of the Forth words mentioned in TABLE III
The stack before and after is shown by -- separating the two. The text on the right of each half is the top of the stack. There may be other more deeply nested values on the stack but they are unaffected by the word.
So + (plus) is shown as n1 n2 -- n3
DUP "dupe" duplicates the top entry of the stack pushing a copy of the top entry onto the stack
n1 -- n1 n1
OVER makes a copy of the secondmost entry f the stack pushing it onto the stack
n1 n2 -- n1 n2 n1
INVERT bitwise inversion of the top of stack
n1 -- n2
+ "plus" add together the top two entries of the stack and put the result there
n1 n2 -- n3
SWAP exchange the top two entries of the stack
n1 n2 -- n2 n1
NIP remove the secondmost entry from the stack
n1 n2 -- n2
DROP discard the top of stack
n1 --
; (well actually EXIT) Pull the top entry off the return stack and resume execution at that location
R: n1 --
>R "to R" take the top entry off the data stack and push it onto the return stack. Rather specialist this one.
n1 -- R:vv -- n1
R> "R from" take the top entry off the return stack and push it onto the data stack. If you use >R must do R> before doing an EXIT or you'll have a crash most likely.
R: n1 -- -- n1
R@ "r fetch" make a copy of the top of the return stack and put it on the data stack
R: n1 -- n1 -- n1
@ "fetch" the top of the data has a memory address. Fetch a word of data and replace top of stack with it
a1 -- n1
! "store" the top of the data stack has a value and a memory address. Store the value there
n1 a1 --
OK onto J1 itself
T seems to be a register holding the top of the stack (a common optimisation). I don't think it changes as the stack does but might be wrong
N seems to be whatever the rest of the data stack has at the top at the moment. Changes as data stack depth changes
R seems to be whatever the top of the Return stack has at that moment. Changes as return stack depth changes
Conditional jumps use zero for FALSE any other value is TRUE. The formal value for TRUE is all bits set and is returned by words like <
So it is a matter of writing an emulator for it.
Hope this helps
Tim