Brad:
Again thanks for the reply.
I am a bit slow on the uptake. I was editing my previous post to include a "Never Mind". IOW, your M65C02A code fragment finally clicked, and I came to understand why you wrote it the way you did. However, I was taking too long to add that comment to my previous post because I could not see how that implementation of EXECUTE would be able to execute a secondary like CONSTANT or VARIABLE, so I canceled.
I think that I can see how your code fragment works for an ITC Forth:
(a) If the target is a secondary, then ITC EXECUTE will jump into the code for ENTER / DOCOL. The secondary will terminate with an ITC EXIT / SEMIS, and the VM will continue with the IP popped from the RS;
(b) If the target is a primitive, then ITC EXECUTE will jump directly into the code of the primitive. The primitive will terminate with an ITC NEXT, i.e. an inxt instruction, and the VM will continue with the word pointed to by IP.
I am thinking that for a DTC Forth it will work in a similar manner:
(a) If the target is a secondary, then DTC EXECUTE will jump into a secondary whose first instruction is either the ent instruction or a jsr ENTER. The secondary will terminate with an DTC EXIT / SEMIS, and the VM will continue with the IP popped from the RS;
(b) If the target is a primitive, then DTC EXECUTE will jump directly into the code of the primitive. The primitive will terminate with an DTC NEXT, i.e. a nxt instruction, and the VM will continue with the word pointed to by IP.
To have an efficient EXECUTE, I need to find a way to implement an
exe instruction that performs the operations you describe in the code fragment you provided above. Given my incorrect understanding of this operation, I have filled the opcode space and defined basic operations that will make implementing such an instruction a bit more difficult. It will be somewhat of a challenge, but since the implementation is supposed to be flexible, i.e. microprogrammed, I suppose that I will just have to make the change. It would be a bit of a bummer if ENTER, NEXT, EXIT are efficient, and EXECUTE is significantly less efficient.
My original thinking on the ip-relative instructions was that the constants and pointers to variables would be embedded directly in the VM instruction stream, i.e. thread. This thinking is somewhat out of step with the standard implementations. Although the ip-relative instructions may not be as applicable as I originally envisioned for Forth, the register indirect addressing mode represented has certainly proven useful in the implementation of certain operations in my Pascal compiler.
Although
jmp (abs,X) can be coerced to work for ITC EXECUTE with A as the index value, it appears that one instruction missing from the M65C02A's repertoire is a register indirect jump, W could be used for such an instruction, and would likely benefit not just Forth but other languages as well. What form that instruction may take remains to be determined, but there are currently 4 unused column 2 opcodes that have not been defined. I was reserving them for defining various signed/unsigned multiplication / division instructions, but those operations could be implemented using the co-processor instruction, 0x02.
One final note is that I probably should use the IND flag to control whether or not the W register is adjusted during the ENTER instruction. Currently, W is incremented by 1 during each push operation, which leaves it pointing to offset 2 of the current word. That operation could be conditional on whether the IND flag is set or not. If not set, as in a DTC Forth, then W would not be incremented. If set as in an ITC Forth, then W would be doubly incremented and point to first word in the parameter field. I think this modification would then make W behave in a manner more consistent with expectations for DTC and ITC Forth implementations.
Michael:
Not drifting at all. I essentially had the same idea as you describe above in your post. I feel I am a bit more of a newbie on this subject, since the only Forth that I've done is getting the figForth model from the forum's archives running on my previous 6502/65C02 core, and typing in some examples from Leo Brodie's "Thinking Forth". Getting a Forth VM running is a far cry from truly understanding the nuances of the VM like Brad has pointed out above.
I think now would be a good time to clear up any misconceptions about how the Forth VM should operate that either one of us may harbor.