Note that is little need for the counterparts LD2/LDW2 because the combination LDWI+PEEK/DEEK is only four bytes long and exactly equivalent.
Context: I was trying to write python code to implement a pseudo-instruction _MOV(s,d) where s and d can be registers, addresses, or [AC].
Here is the best I could do. In this code, _LDI is either LDI(d) or LDWI(dd), _LDW is either LDW(d) or LDWI(dd);DEEK(), and T2/T3 are temporaries
You'll note how DOKEA/DEEKA simplifies some paths. See how MOV(anything,[AC]) or MOV(anything,zp) are compact but MOV([AC],dddd) require swapping AC and two scratch registers...
Code: Select all
@vasm
def _MOV(s,d):
'''Move word from reg/addr s to d.
Also accepts [AC] for s or d.'''
s = v(s)
d = v(d)
if s != d:
if args.cpu > 5 and s == [AC] and is_zeropage(d):
DEEKA(d)
elif args.cpu > 5 and is_zeropage(s) and d == [AC]:
DOKEA(s)
elif d == [AC]:
STW(T3)
if s != AC:
_LDW(s)
DOKE(T3)
elif is_zeropage(d):
if s == [AC]:
DEEK()
elif s != AC:
_LDW(s)
if d != AC:
STW(d)
elif s == AC or s == [AC]:
if s == [AC]:
DEEK()
STW(T3); _LDI(d)
if args.cpu > 5:
DOKEA(T3)
else:
STW(T2); LDW(T3); DOKE(T2)
else:
_LDI(d); STW(T2); _LDW(s); DOKE(T2)
Code: Select all
def _LMOV(s,d):
'''Move long from reg/addr s to d.
Also accepts [AC] as s, and [AC] or [T2] as d.'''
s = v(s)
d = v(d)
if s != d:
if is_zeropage(d, 3):
if is_zeropage(s, 3):
_LDW(s); STW(d); _LDW(s+2); STW(d+2) # 8 bytes
elif args.cpu > 5:
if s != [AC]:
_LDI(s)
DEEKA(d); ADDI(2); DEEKA(d+2) # 6-9 bytes
elif s != [AC]:
_LDW(s); STW(d); _LDW(s+2); STW(d+2) # 12 bytes
else:
STW(T3); DEEK(); STW(d)
_LDW(T3); ADDI(2); DEEK(); STW(d+2); # 12 bytes
elif is_zeropage(s, 3) and args.cpu > 5:
if d == [T2]:
_LDW(T2)
elif s != [AC]:
_LDI(s)
DOKEA(s); ADDI(2); DOKEA(s+2) # 6-9 bytes
else:
if d == [AC]:
STW(T2)
if s == [AC]:
STW(T3)
if d != [AC] and d != [T2]:
_LDI(d); STW(T2)
if s != [AC] and s != [T3]: # call sequence
_LDI(s); STW(T3) # 5-13 bytes
extern('_@_lcopy')
_CALLI('_@_lcopy') # [T3..T3+4) --> [T2..T2+4)