Very nice, Andrew! A couple of respectful but off-the-cuff comments:
It looks like you forgot a PLY in CMOVE>.
Your X register seems to be underutilized, and you're doing a lot of TDC ... TCD operations to modify your data stack pointer, which is a very common activity. Have you weighed the possibility of going back to X as a data stack pointer? Or how about using X for IP, and leaving Y as a scratch register for your primitives?
Code:
CONTINUE:
inx
inx
jmp (-2,x)
If you try X (or even Y) for your data stack pointer, what would TOS-in-A look like?
Code:
PLUS:
clc
adc 1,x
inx
inx
CONTINUE
...
MINUS:
eor #$ffff
inc a
bra PLUS
If you keep Y as IP:
Code:
CONTINUE:
iny
phy
iny
rts
... oh, wait, that's not quite correct ... or is it? I still get confused ...
Keep the DTC candle burning brightly, my 65xx brother!
Mike B.