barrym95838 wrote:
Your stack comment for stream is ( -- adr ). I may be wrong, but it looks like the first thing XSTREAM does is LDA VBLK, which has the side-effect of DROPping your initial TOS in A, something I didn't expect to see. A word that grows the stack is inevitably going to include a DEX DEX STA 0,X sooner or later.
I'm a big fan of TOS in A, but every time you LDA you need to spend a thought over what you may be discarding in A.
Turning bunches of secondaries into primitives is fine for the do-it-yourselfer looking for performance, but finding a point of equilibrium may not be obvious, and may vary widely between different applications and implementers.
Now I know how a real teacher feels. It is not even the first day of class and already the students are correcting the teacher.
I was hoping just to produce the theory behind converting Forth to Assembly before handing over my very efficient code. But like everything else in Forth, I see now that it might be better to work in reverse. Otherwise a lot of the routines may not make sense and I will get bombarded with people correcting my mistakes.
Here is one of my most powerful routines, and I might even argue, as powerful as the NEXT routine, as it will almost see as much usage as NEXT.
Code:
DUP DEX
DEX
PUT STY $00,X
JMP NEXT
Now we can truly start to appreciate the reason for duplicating TOS in the Y-reg.
Preserving the Acc becomes as easy as:
Code:
STREAM JSR XSTREAM
JMP DUP
The Acc is now the new TOS and the Y-reg being the old TOS, gets pushed onto the stack.
STREAM ( -- adr ) should now makes sense.
As we saw ( -- 1-output ) we can use the entry to JMP DUP
If we see ( -- ) as a comment following a definition, then instead of JMP DUP, we can use TYA and JMP NEXT as long as the Y-reg is not used within the sub-routine.
( 1-input -- ) we do JMP NIP as long as the Acc has not changed.
( 1-input -- 1-output ) TYA and JMP NEXT.
( 2-inputs -- 1-output ) we do a JMP POP, with the Acc holding the value that is in TOS on exit
( 2-inputs -- ) we can just do a JMP POPTWO.
( 3-inputs -- ) JMP POPTHREE
( 1-input -- 3 outputs ) DEX DEX STA $02,X LDA N JMP DUP ( N is used as a temp variable when both Acc and Y-reg are used)
This is all I will explain for now. After all the teacher cannot be doing the students homework.
One conversion I missed before the IF statement is if IF is preceded by
Code:
0=
, then the branch that follows the IF, could be either BEQ or BNE depending on the value you think is being loaded.