diff --git a/arch-8608-template.asm b/arch-8608-template.asm new file mode 100644 index 0000000..286747e --- /dev/null +++ b/arch-8608-template.asm @@ -0,0 +1,5 @@ + +; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua) +#ruledef { + %s +} diff --git a/arch-8608.asm b/arch-8608.asm new file mode 100644 index 0000000..ff43bef --- /dev/null +++ b/arch-8608.asm @@ -0,0 +1,792 @@ + +; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua) +#ruledef { + rst => $00 + hlt => $F0 + run => $F1 + int => $F2 + brk => $F3 + irt => $F4 + nop => $FF + ien => $F5 + idi => $F6 + inc p => $12 + dec p => $15 + inc q => $13 + dec q => $16 + inc a => $10 + dec a => $11 + icc a => $1B + inc b => $19 + dec b => $1A + icc b => $1C + inc c => $17 + dec c => $18 + icc c => $1D + tst a => $14 + tst b => $1E + tst c => $1F + inc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $2B @ value`8 + } + inc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $2B @ mvalue`8 + } + dec *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $2C @ value`8 + } + dec *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $2C @ mvalue`8 + } + icc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $2D @ value`8 + } + icc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $2D @ mvalue`8 + } + tst *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $2E @ value`8 + } + tst *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $2E @ mvalue`8 + } + adp {value: i8} => $4A @ value + adq {value: i8} => $4B @ value + ads {value: i8} => $4C @ value + adp b => $E6 + adq b => $E7 + ads b => $E8 + add {value: i8} => $24 @ value + adb {value: i8} => $72 @ value + adc {value: i8} => $73 @ value + sub {value: i8} => $70 @ value + sbb {value: i8} => $99 @ value + sbc {value: i8} => $9A @ value + acc {value: i8} => $78 @ value + scc {value: i8} => $79 @ value + cmp {value: i8} => $71 @ value + and {value: i8} => $74 @ value + ior {value: i8} => $75 @ value + xor {value: i8} => $76 @ value + ann {value: i8} => $77 @ value + shl {value: i8} => $D0 @ value + shr {value: i8} => $D1 @ value + rol {value: i8} => $D2 @ value + ror {value: i8} => $D3 @ value + sra {value: i8} => $D4 @ value + add *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $AE @ value`8 + } + add *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $AE @ mvalue`8 + } + adb *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $9B @ value`8 + } + adb *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $9B @ mvalue`8 + } + adc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $9C @ value`8 + } + adc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $9C @ mvalue`8 + } + sub *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $AF @ value`8 + } + sub *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $AF @ mvalue`8 + } + sbb *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $9D @ value`8 + } + sbb *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $9D @ mvalue`8 + } + sbc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $9E @ value`8 + } + sbc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $9E @ mvalue`8 + } + acc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B5 @ value`8 + } + acc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B5 @ mvalue`8 + } + scc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B7 @ value`8 + } + scc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B7 @ mvalue`8 + } + cmp *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B0 @ value`8 + } + cmp *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B0 @ mvalue`8 + } + and *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B1 @ value`8 + } + and *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B1 @ mvalue`8 + } + ior *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B2 @ value`8 + } + ior *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B2 @ mvalue`8 + } + xor *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B3 @ value`8 + } + xor *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B3 @ mvalue`8 + } + ann *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $B4 @ value`8 + } + ann *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $B4 @ mvalue`8 + } + shl *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $D5 @ value`8 + } + shl *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $D5 @ mvalue`8 + } + shr *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $D6 @ value`8 + } + shr *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $D6 @ mvalue`8 + } + rol *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $D7 @ value`8 + } + rol *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $D7 @ mvalue`8 + } + ror *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $D8 @ value`8 + } + ror *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $D8 @ mvalue`8 + } + sra *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $D9 @ value`8 + } + sra *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $D9 @ mvalue`8 + } + add b => $A0 + adc b => $9F + sub b => $A1 + sbc b => $B6 + acc b => $B8 + scc b => $B9 + cmp b => $A2 + and b => $A3 + ior b => $A4 + xor b => $A5 + ann b => $A6 + shl b => $DA + shr b => $DB + rol b => $DC + ror b => $DD + sra b => $DE + add c => $A7 + adb c => $BD + sub c => $A8 + sbb c => $BC + acc c => $BA + scc c => $BB + cmp c => $A9 + and c => $AA + ior c => $AB + xor c => $AC + ann c => $AD + shl c => $DF + shr c => $4D + rol c => $3E + ror c => $3F + sra c => $2F + adb a => $BE + sbb a => $BF + adc a => $4E + sbc a => $4F + jmp {value: i16} => $60 @ value + jsr {value: i16} => $63 @ value + jss {value: i16} => $E2 @ value + jmp p => $64 + jmp q => $66 + ret => $66 + jsr p => $65 + jsr q => $67 + jss p => $E4 + jss q => $E5 + rts => $E1 + jpr {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jpr: Relative jump target is too far away") + assert(reladdr >= -128, "jpr: Relative jump target is too far away") + $31 @ reladdr`8 + } + jnz {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jnz: Relative jump target is too far away") + assert(reladdr >= -128, "jnz: Relative jump target is too far away") + $30 @ reladdr`8 + } + jne {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jne: Relative jump target is too far away") + assert(reladdr >= -128, "jne: Relative jump target is too far away") + $30 @ reladdr`8 + } + jpz {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jpz: Relative jump target is too far away") + assert(reladdr >= -128, "jpz: Relative jump target is too far away") + $32 @ reladdr`8 + } + jeq {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jeq: Relative jump target is too far away") + assert(reladdr >= -128, "jeq: Relative jump target is too far away") + $32 @ reladdr`8 + } + jlt {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jlt: Relative jump target is too far away") + assert(reladdr >= -128, "jlt: Relative jump target is too far away") + $33 @ reladdr`8 + } + jge {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jge: Relative jump target is too far away") + assert(reladdr >= -128, "jge: Relative jump target is too far away") + $34 @ reladdr`8 + } + jgt {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jgt: Relative jump target is too far away") + assert(reladdr >= -128, "jgt: Relative jump target is too far away") + $35 @ reladdr`8 + } + jle {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "jle: Relative jump target is too far away") + assert(reladdr >= -128, "jle: Relative jump target is too far away") + $36 @ reladdr`8 + } + psh a => $40 + psh b => $44 + psh c => $45 + psh f => $E9 + psh p => $41 + psh q => $46 + pop a => $42 + pop b => $47 + pop c => $48 + pop f => $EA + pop p => $43 + pop q => $49 + psh {value: i8} => $3B @ value + phw {value: i16} => $3C @ value + lda {value: i8} => $20 @ value + ldb {value: i8} => $26 @ value + ldc {value: i8} => $27 @ value + lda *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $28 @ value`8 + } + lda *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $28 @ mvalue`8 + } + ldb *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $29 @ value`8 + } + ldb *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $29 @ mvalue`8 + } + ldc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $2A @ value`8 + } + ldc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $2A @ mvalue`8 + } + sta *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $96 @ value`8 + } + sta *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $96 @ mvalue`8 + } + stb *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $97 @ value`8 + } + stb *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $97 @ mvalue`8 + } + stc *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $98 @ value`8 + } + stc *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $98 @ mvalue`8 + } + lda *{value: i16} => $51 @ value + ldb *{value: i16} => $56 @ value + ldc *{value: i16} => $57 @ value + sta *{value: i16} => $50 @ value + stb *{value: i16} => $58 @ value + stc *{value: i16} => $59 @ value + lda *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $01 @ value`16 + } + lda *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $01 @ mvalue`16 + } + ldb *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $F7 @ value`16 + } + ldb *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $F7 @ mvalue`16 + } + ldc *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $FE @ value`16 + } + ldc *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $FE @ mvalue`16 + } + lda *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $EB @ value`16 + } + lda *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $EB @ mvalue`16 + } + ldb *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $08 @ value`16 + } + ldb *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $08 @ mvalue`16 + } + ldc *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $09 @ value`16 + } + ldc *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $09 @ mvalue`16 + } + sta *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $0A @ value`16 + } + sta *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $0A @ mvalue`16 + } + stb *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $0B @ value`16 + } + stb *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $0B @ mvalue`16 + } + stc *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $0C @ value`16 + } + stc *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $0C @ mvalue`16 + } + sta *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $0D @ value`16 + } + sta *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $0D @ mvalue`16 + } + stb *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $0E @ value`16 + } + stb *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $0E @ mvalue`16 + } + stc *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $0F @ value`16 + } + stc *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $0F @ mvalue`16 + } + lda *p => $53 + ldb *p => $5E + ldc *p => $5F + lda *q => $55 + ldb *q => $61 + ldc *q => $62 + sta *p => $52 + stb *p => $5A + stc *p => $5B + sta *q => $54 + stb *q => $5C + stc *q => $5D + lda *p++ => $C6 + ldb *p++ => $C7 + ldc *p++ => $C8 + lda *q++ => $C9 + ldb *q++ => $CA + ldc *q++ => $CB + sta *p++ => $C0 + stb *p++ => $C1 + stc *p++ => $C2 + sta *q++ => $C3 + stb *q++ => $C4 + stc *q++ => $C5 + ldp {value: i16} => $21 @ value + ldq {value: i16} => $23 @ value + lds {value: i16} => $25 @ value + ldv {value: i16} => $22 @ value + ldp *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $7A @ value`8 + } + ldp *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $7A @ mvalue`8 + } + ldq *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $7B @ value`8 + } + ldq *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $7B @ mvalue`8 + } + stp *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $7E @ value`8 + } + stp *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $7E @ mvalue`8 + } + stq *s+{value: i8} => { + assert(value <= 127, "Relative address is too far away") + assert(value >= -128, "Relative address is too far away") + $7F @ value`8 + } + stq *s-{value: i8} => { + mvalue = -value + assert(mvalue <= 127, "Relative address is too far away") + assert(mvalue >= -128, "Relative address is too far away") + $7F @ mvalue`8 + } + ldp *{value: i16} => $68 @ value + ldq *{value: i16} => $6A @ value + stp *{value: i16} => $6C @ value + stq *{value: i16} => $6E @ value + ldp *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $EC @ value`16 + } + ldp *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $EC @ mvalue`16 + } + ldq *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $EE @ value`16 + } + ldq *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $EE @ mvalue`16 + } + ldp *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $F8 @ value`16 + } + ldp *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $F8 @ mvalue`16 + } + ldq *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $FA @ value`16 + } + ldq *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $FA @ mvalue`16 + } + stq *p+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $06 @ value`16 + } + stq *p-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $06 @ mvalue`16 + } + stp *q+{value: i16} => { + assert(value <= 32767, "Relative address is too far away") + assert(value >= -32768, "Relative address is too far away") + $FC @ value`16 + } + stp *q-{value: i16} => { + mvalue = -value + assert(mvalue <= 32767, "Relative address is too far away") + assert(mvalue >= -32768, "Relative address is too far away") + $FC @ mvalue`16 + } + ldp *p => $92 + ldq *p => $93 + ldp *q => $94 + ldq *q => $95 + stp *q => $7C + stq *p => $7D + ldq *p++ => $CC + ldp *q++ => $CD + stp *q++ => $CE + stq *p++ => $CF + lda b => $80 + lda c => $81 + ldb a => $82 + ldb c => $83 + ldc a => $84 + ldc b => $85 + lda pl => $86 + lda ph => $87 + lda ql => $88 + lda qh => $89 + ldb pl => $37 + ldc ph => $38 + ldb ql => $39 + ldc qh => $3A + ldp q => $8A + ldp s => $8B + ldp v => $8C + ldp i => $8D + ldp cb => $91 + ldq cb => $E0 + ldq p => $8E + lds p => $8F + ldv p => $90 +} diff --git a/assembler-8608-deprecated.lua b/assembler-8608-deprecated.lua new file mode 100644 index 0000000..cdea5e0 --- /dev/null +++ b/assembler-8608-deprecated.lua @@ -0,0 +1,723 @@ + +local function loadutf8table(fn) + local tt = {} + for l in io.lines(fn) do if l~="" then + local c, d = l:match("^([^ ]+) (.+)$") + local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end; + tt[c] = t + end end + return tt +end +local utf8table = loadutf8table((RelPath or "./").."utf8table.txt") + +local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end +local function getutf8len(c) + local d = c:byte() + if bit.band(d, 0xE0)==0xC0 then return 2 + elseif bit.band(d, 0xF0)==0xE0 then return 3 + elseif bit.band(d, 0xF8)==0xF0 then return 4 + else error("invalid utf8 first byte: "..string.format("%02X", d)) end +end +local function validWordsFromInstrs(instrs) + local words = {} + for mnem, _ in pairs(instrs) do + for word in mnem:gmatch("[^ ]+") do + words[word] = true + end + end + return words +end +local function lobyte(n) return n%256 end +local function hibyte(n) return math.floor(n/256) end +local function decodeNumber(n) + n = trim(n) + local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end; + if n:sub(1, 1)=="$" then return sign*(tonumber(n:sub(2, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2) + elseif n:sub(1, 2)=="0x" then return sign*(tonumber(n:sub(3, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2) + elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2) + elseif n:sub(1, 2)=="0b" then return sign*(tonumber(n:sub(3, #n ), 2) or error("invalid binary number "..n)), math.ceil((#n-2)/8) + elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$") then return sign*(tonumber(n:sub(1, #n-1), 2) or error("invalid binary number "..n)), math.ceil((#n-1)/8) + elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")" then return lobyte(decodeNumber(n:sub(4, #n-1))), 1 + elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")" then return hibyte(decodeNumber(n:sub(4, #n-1))), 1 + elseif n:find("^[0-9]+$") then + local v = sign*(tonumber(n) or error("invalid decimal number "..n)) + if v>=-128 and v<=255 then return v, 1 + elseif v>=-32768 and v<=65535 then return v, 2 + else error("out-of-range number "..v) end + else + return nil + end +end +local function mnemFromLine(line, instrs, validWords) + local imms = {} + local function addNum(n) + n = trim(n) + local val, len = decodeNumber(n) + assert(val and len, "invalid number "..n) + local linei8 = line:gsub(n, "imm8", 1, true):lower() + local linei16 = line:gsub(n, "imm16", 1, true):lower() + if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end + table.insert(imms, { val = val, len = len } ) + return " imm"..(len*8).." " + end + local function addLabel(n) + n = trim(n) + local len = 2 + local linei8 = line:gsub(n, "imm8", 1, true):lower() + if instrs[linei8] then len = 1 end + table.insert(imms, { label = n, len = len } ) + return " imm"..(len*8).." " + end + + local mnem = " "..line:gsub(" ", " ").." " + mnem = mnem:gsub("%- *", " %+%-") + mnem = mnem:gsub("([%*%+])", " %1 ") + mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ " , function(n) return addNum (n) end) + mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ " , function(n) return addNum (n) end) + mnem = mnem:gsub(" %-?0b[01]+ " , function(n) return addNum (n) end) + mnem = mnem:gsub(" %-?[0-9a-fA-F]+h " , function(n) if not validWords[trim(n)] then return addNum (n) end end) + mnem = mnem:gsub(" %-?[01]+b " , function(n) if not validWords[trim(n)] then return addNum (n) end end) + mnem = mnem:gsub(" %-?[0-9]+ " , function(n) if not validWords[trim(n)] then return addNum (n) end end) + mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end) + mnem = trim(mnem):gsub(" +", " "):lower() + + if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end + + return mnem, imms +end +local function addByte(state, val, code) + assert(val>=-128 and val<=255, "invalid byte "..val) + assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) + state.memory[state.curAddr] = val%256 + if code then state.codeMap[state.curAddr] = true end + state.curAddr = state.curAddr + 1 +end +local function addWord(state, val, code) + assert(val>=0 and val<=65535, "invalid word "..val) + addByte(state, math.floor(val/256), code) + addByte(state, val%256, code) +end +local function addSpace(state, len) + for i = 1, len do + assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) + state.memory[state.curAddr] = false + state.curAddr = state.curAddr + 1 + end +end +local function assembleInstruction(line, state, instrs, validWords) + local mnem, imms = mnemFromLine(line, instrs, validWords) + local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")") + local writeimms = true + local padlen = 0 + local isInstr + if type(opcode)=="function" then + padlen, writeimms = opcode(imms) + addSpace(state, padlen) + elseif opcode>=0 then + isInstr = true + addByte(state, opcode, isInstr) + end + if writeimms then + for _, imm in ipairs(imms) do + if imm.val then + if imm.len==1 then addByte(state, imm.val, isInstr) + elseif imm.len==2 then addWord(state, imm.val, isInstr) + else error("invalid imm len") end + elseif imm.label then + table.insert(state.labelReplacements, { + name = imm.label, + addr = state.curAddr, + len = imm.len, + rel = imm.len==1, + isCode = isInstr, + }) + state.curAddr = state.curAddr + imm.len + else error("invalid imm") end + end + end +end +local directiveFunctions = { + fn = function(state, fn) state.fileName = fn end, + ln = function(state, ln) state.lineNum = tonumber(ln) end, + org = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end, + align = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end, + define = true, + space = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end, +} +local function postEvaluateExpression(expr, labels) + +end +local function assembleCode(code, instrs, uexprs) + local validWords = validWordsFromInstrs(instrs) + + local state = { + lineNum = 0, + fileName = "", + curAddr = 0, + memory = {}, + codeMap = {}, + labelReplacements = {}, + labelAddrs = {}, + } + + for line in code:gmatch("[^\n]+") do + line = trim(line) + if line:sub(1, 1)=="." then -- directive + local dir, rest = line:match("^%.([^ ]+) *(.*)$") + assert(dir and rest, "no directive on line "..line) + local dirf = directiveFunctions[dir] or error("invalid directive "..dir) + dirf(state, rest) + elseif line:sub(#line, #line)==":" then -- label + local name = line:sub(1, #line-1) + assert(not state.labelAddrs[name], "redefinition of label "..name) + state.labelAddrs[name] = state.curAddr + elseif line:find("[^ ]") then + assembleInstruction(line, state, instrs, validWords) + end + end + + for _, rep in ipairs(state.labelReplacements) do + local expr = uexprs[rep.name] + if expr then + local val = postEvaluateExpression(expr, state.labelAddrs) + if rep.len==1 then addByte(state, val, rep.isCode) + elseif rep.len==2 then addWord(state, val, rep.isCode) + else error("invalid expr replace len "..rep.len) end + else + local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name) + state.curAddr = rep.addr + if rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode) + elseif rep.len==2 then addWord(state, labelAddr , rep.isCode) + else error("invalid labelreplace len "..rep.len) end + end + end + + return state.memory, state.codeMap +end + +local function readFile(fn) + local fi, err = io.open(fn, "r") + if not fi then error("could not open file "..fn..": "..err) end + local text = fi:read("*a") + fi:close() + return text +end + +local function separateCommas(l) + local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c; +end +local function evaluateExpression(expr, uexprs) + expr = expr:gsub("[^%+%-%*%/]+", function(word) + local val = decodeNumber(word) or error("invalid number in expression: "..word) + return val + end) + assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr) + local exprf = loadstring("return "..expr) + local eval = exprf() or error("invalid expr: "..expr) + return eval +end +local function preprocessCode(code) + code = "\n"..code.."\n" + + -- apply brace labels and scoped labels + local curscope = "" + local codet = {} + local wordt = {} + local lastword = "" + local function addword(word) + lastword = word + if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end + table.insert(codet, word) + end + for i = 1, #code do + local c = code:sub(i, i) + if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c) + else + if #wordt>0 then + addword(table.concat(wordt)) + wordt = {} + end + if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then + curscope = lastword + end + table.insert(codet, c) + end + end + + code = "\n"..table.concat(codet).."\n" + + -- apply function macros + local funcmacros = {} + code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl) + local argt = separateCommas(args) + for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end + repl = " "..repl.." " + local invoc = 0 + funcmacros[name] = function(b, callargs) + invoc = invoc + 1 + local callargt = separateCommas(callargs) + local callrepl = repl + for argidx, arg in ipairs(argt) do + local callarg = callargt[argidx] + callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2") + end + callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_") + return b..callrepl + end + return "" + end) + for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end + + -- apply simple macros + local simplemacros = {} + code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl) + assert(not simplemacros[name], "Redefinition of macro "..name) + simplemacros[name] = repl + return "" + end) + --for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end + for name, repl in pairs(simplemacros) do + local invoc = 0 + code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a) + invoc = invoc+1 + return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a + end) + print(name, code) + end + + code = code:gsub("\\\\", "\n") + + local uexprs = {} + + local codet = {} + local exprt = {} + local parenLevel = 0 + for i = 1, #code do + local c = code:sub(i, i) + if c=="(" then + if parenLevel>0 then table.insert(exprt, c) end + parenLevel = parenLevel+1 + elseif c==")" then + parenLevel = parenLevel-1 + if parenLevel==0 then + table.insert(codet, evaluateExpression(table.concat(exprt), uexprs)) + exprt = {} + else + table.insert(exprt, c) + end + else + if parenLevel==0 then table.insert(codet, c) + else table.insert(exprt, c) end + end + end + code = table.concat(codet) + + return code, uexprs +end +local function fixCode(code) + code = code:gsub(",", " ") + code = code:gsub(":([^\\/])", ":\n%1") + code = code:gsub("[ \t]+:", ":") + code = code:gsub("%]", " %] ") + code = code:gsub("%[", " %[ ") + code = code:gsub("%*", " %* ") + code = code:gsub("\n[ \t\r\n]*", "\n") + code = code:gsub(" +", " ") + + return code +end +local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", } +local prefixIdx = 0 +local function prefixCode(code, fn) -- fix strings, add line numbers + prefixIdx = prefixIdx + 1 + + local outt = {} + local outnextnl = {} + local linenum = 1 + local skipnl = false + local function last() return outt[#outt] end + local function out(c) assert(type(c)=="string"); table.insert(outt, c); end + local function outn(n) out("$"..string.format("%02X", n)) out("\\") end + local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end + local state = "code" -- code, comment, string, stringesc, commentml + + local lastbracelabel = 0 + local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end + local bracestack = {} + local bracehasmid = {} + local lastnl = false + + local utf8str = "" + local utf8len = 0 + + local function newline() + lastnl = true + for _, v in ipairs(outnextnl) do + if v=="\n" and skipnl then out("\\") + else out(v) end + end; outnextnl = {}; + end + + out(".ln 1"); out("\n"); + local i = 1 + while i <= #code do + local c = code:sub(i, i) + local cn = code:sub(i+1, i+1) + local cp = code:sub(i-1, i-1) + + if state=="code" then + if c=="\r" then + elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*") + linenum = linenum+1 + if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end + newline() + skipnl = false + elseif c=="#" or c==";" or (c=="/" and cn=="/") then state = "comment" + elseif c=="/" and cn=="*" then state = "commentml" + elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end + elseif c=="\"" then state = "string" lastnl = false + elseif c=="\\" then skipnl = true; out("\\"); + elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true; + elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false + elseif c=="{" then + table.insert(bracestack, bracelabel()) + if not lastnl then out(bracestack[#bracestack].."MID") end + outnext(bracestack[#bracestack].."START:"); outnext("\n"); + elseif c=="}" then + if not lastnl then out(bracestack[#bracestack].."START") end + if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end + outnext(bracestack[#bracestack].."END:"); outnext("\n"); + bracehasmid[#bracestack] = nil + bracestack[#bracestack] = nil + elseif c=="|" then + if not lastnl then out(bracestack[#bracestack].."END") end + outnext(bracestack[#bracestack].."MID:"); outnext("\n"); + bracehasmid[#bracestack] = true + else error("invalid char "..c) end + elseif state=="comment" then + if c=="\n" then state = "code" out("\n") newline() end + elseif state=="commentml" then + if c=="/" and cp=="*" then state = "code" end + elseif state=="string" then + if c=="\\" then state = "stringesc" + elseif c=="\"" then state = "code" + elseif c:byte()>=128 then + utf8str = c + utf8len = getutf8len(c) + state = "stringutf8" + else outn(c:byte()) end + elseif state=="stringesc" then + outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string"; + elseif state=="stringutf8" then + utf8str = utf8str..c + if #utf8str == utf8len then + local valt = utf8table[utf8str] + if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end; + error("Unrecognized UTF-8 character: "..datastr); end + for i, v in ipairs(valt) do outn(v) end + state = "string" + end + end + + i = i+1 + end + assert(#bracestack==0, "unclosed brace") + local code2 = table.concat(outt) + + return code2 +end +local function fixFilename(fn) + fn = fn:gsub("[^a-zA-Z0-9_]", "_") + return fn +end +local function includeFile(fn) + local code = readFile(fn) + code = prefixCode(code, fn) + local fnf = fixFilename(fn) + code = ".fn "..fnf.."\n"..code + code = code:gsub(".include ([^\r\n]+)", function(fn2) + fn2 = fn:gsub("[^\\/]+$", "")..fn2 + return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n" + end) + return code +end +local function instrsFromArch(arch) + local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end + local instrs = { + imm8 = function() return 0, true end, + imm16 = function() return 0, true end, + byte = function() return 1, false end, + word = function() return 2, false end, + ["byte imm8"] = function() return 0, true end, + ["word imm16"] = function() return 0, true end, + ["byte [ imm8 ]" ] = function(imms) return arraySize(imms) , false end, + ["byte [ imm16 ]"] = function(imms) return arraySize(imms) , false end, + ["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end, + ["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end, + } + local function addMnem(mnem, opcode) + instrs[mnem] = opcode + if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end + end + for _, instr in ipairs(arch.instructions) do + if instr.mnem then + local mnem = instr.mnem + mnem = mnem:gsub("([%*%+%-])", " %1 ") + mnem = trim(mnem):gsub(" +", " ") + addMnem(mnem, instr.opcode) + local alias = arch.aliases[trim(mnem)] + if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end + end + end + return instrs +end +local function assembleFile(fn, arch) + local code = includeFile(fn) + code, uexprs = preprocessCode(code) + code = fixCode(code) + local instrs = instrsFromArch(arch) + local mem, code = assembleCode(code, instrs, uexprs) + return mem, code +end + +local function mnemsFromArch(arch) + local mnems = {} + for _, instr in ipairs(arch.instructions) do + if instr.mnem then + local len = 1 + for l in instr.mnem:gmatch("imm([0-9]+)") do len = len + tonumber(l)/8 end + mnems[instr.opcode] = { mnem = instr.mnem, rel = instr.rel, jmp = instr.jmp, len = len, } + end + end + return mnems +end +local function toSigned8(x) return x>=128 and x-256 or x end +local function disassembleMemory(mem, code, arch) + local mnems = mnemsFromArch(arch) + + local addr = 0 + local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end + local lastaddr = 0 + local jmpaddrs = {} + while addr<=0xFFFF do + local startaddr = addr + local opcode = nextByte() + if opcode and ((not code) or code[startaddr]) then + local mnem = mnems[opcode] + if mnem then + if mnem.jmp then + local jmpdest + if mnem.rel then jmpdest = toSigned8(nextByte(0)) + addr + else jmpdest = nextByte(0)*256 + nextByte(0) + end + if jmpdest then + if not jmpaddrs[jmpdest] then + jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, } + end + table.insert(jmpaddrs[jmpdest].from, startaddr) + jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel + end + else + addr = addr + mnem.len - 1 + end + end + end + end + local labelnum, subnum = 0, 0 + for _, jmp in pairs(jmpaddrs) do + if jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1; + else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end + end + + local lines = {} + addr = 0 + while addr<=0xFFFF do + local startaddr = addr + local opcode = nextByte() + if opcode and ((not code) or code[startaddr]) then + local line = {} + local mnem = mnems[opcode].mnem or "???" + table.insert(line, trim(mnem:gsub("imm[0-9]+", ""))) + local tlen = 1 + for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8 + if len==1 then + local data = nextByte(0) + local jmp + if mnems[opcode].rel then + local jmpdest = (addr + toSigned8(data))%65536 + jmp = jmpaddrs[jmpdest] + if jmp then + table.insert(line, jmp.name) + --table.insert(line, ";") + --table.insert(line, "$"..string.format("%04X", jmpdest)..",") + end + end + if not jmp then table.insert(line, "$"..string.format("%02X", data)) end + elseif len==2 then + local data = nextByte(0)*256 + nextByte(0) + local jmp + if mnems[opcode].jmp then + local jmpdest = data + jmp = jmpaddrs[jmpdest] + if jmp then + table.insert(line, jmp.name) + --table.insert(line, ";") + end + end + if not jmp then table.insert(line, "$"..string.format("%04X", data)) end + else error("invalid imm len") end + tlen = tlen + len + end + local lineb = {} + for i = addr-tlen, addr-1 do + table.insert(lineb, string.format("%02X", mem[i] or 0)) + end + local label = "" + local jmp = jmpaddrs[startaddr] + if jmp then label = jmp.name..":" end + local lb = table.concat(lineb, " ") + if lastaddr~=addr-tlen then table.insert(lines, "...") end + table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " ")) + lastaddr = addr + end + end + return table.concat(lines, "\n") +end +local function memToHex(hex) + local mem = {} + local addr = 0 + for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do + mem[addr] = tonumber(d, 16) + addr = addr+1 + end + return mem +end +local function disassembleHex(hex, arch) + return disassembleMemory(memToHex(hex), arch) +end + +local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> " +local printableChars = {}; for i = 1, #printableCharsS do printableChars[printableCharsS:sub(i, i)] = true end; +local function toPrintableChar(n) + local c = string.char(n) + return printableChars[c] and c or "?" +end +local function printMemory(mem) + local anynonempty = false + local lastbase = -16 + local lastline = "" + local numreps = 0 + local lines = {} + local function closereps(base) + if numreps~=0 then + table.insert(lines, "(repeated "..numreps.." more times, up to "..string.format("%04X", base+15)..")") + numreps = 0 + end + end + for base = 0, 0xFFF0, 16 do + local line = {} + local strt = {} + local nonempty = false + for addr = base, base+15 do + if addr%4==0 then table.insert(line, " ") end + if mem[addr]==false then + nonempty = true + table.insert(line, "XX ") + table.insert(strt, "X") + elseif mem[addr] then + nonempty = true + table.insert(line, string.format("%02X", mem[addr]).." ") + table.insert(strt, toPrintableChar(mem[addr])) + else + table.insert(line, "-- ") + table.insert(strt, "-") + end + end + if nonempty then + local l = table.concat(line) + if l~=lastline or base~=lastbase+16 then + closereps(base-16) + if base ~= lastbase+16 then table.insert(lines, "...") end + table.insert(lines, string.format("%04X", base).." | "..l.." | "..table.concat(strt)) + else + numreps = numreps+1 + end + lastline = l + lastbase = base + anynonempty = true + end + end + closereps(lastbase) + if not anynonempty then table.insert(lines, "Empty") end + + return table.concat(lines, "\n") +end + +local HasTs = ts~=nil +local ts = ts or { + call = function() end, + eval = function() end, +} +ts.eval [[ + function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); } + function commandPlantBrick() { commandToServer('plantBrick'); } +]] +local function plantBrickAt(brickpos, pos) + local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3] + ts.call("commandShiftBrick", dy, -dx, dz) + ts.call("commandPlantBrick") + brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3] +end +local function buildMemory(mem, romsize, offset, len) + offset = offset or 0 + + local rombytes = romsize[1]*romsize[2]*romsize[3]/8 + if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end + if not len then + for i = 0, 0xFFFF do + if mem[i] and (i=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end + end + end + + local brickpos = {0, 0, 0} + for x = 0, romsize[1]-1 do + for y = 0, romsize[2]-1 do + for z = 0, romsize[3]-1 do + local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8)) + local pow = math.pow(2, z%8) + local data = (addr>=offset and ((not len) or addr=-128 and v<=255 then return v, 1 - elseif v>=-32768 and v<=65535 then return v, 2 - else error("out-of-range number "..v) end - else - return nil - end -end -local function mnemFromLine(line, instrs, validWords) - local imms = {} - local function addNum(n) - n = trim(n) - local val, len = decodeNumber(n) - assert(val and len, "invalid number "..n) - local linei8 = line:gsub(n, "imm8", 1, true):lower() - local linei16 = line:gsub(n, "imm16", 1, true):lower() - if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end - table.insert(imms, { val = val, len = len } ) - return " imm"..(len*8).." " - end - local function addLabel(n) - n = trim(n) - local len = 2 - local linei8 = line:gsub(n, "imm8", 1, true):lower() - if instrs[linei8] then len = 1 end - table.insert(imms, { label = n, len = len } ) - return " imm"..(len*8).." " - end - - local mnem = " "..line:gsub(" ", " ").." " - mnem = mnem:gsub("%- *", " %+%-") - mnem = mnem:gsub("([%*%+])", " %1 ") - mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ " , function(n) return addNum (n) end) - mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ " , function(n) return addNum (n) end) - mnem = mnem:gsub(" %-?0b[01]+ " , function(n) return addNum (n) end) - mnem = mnem:gsub(" %-?[0-9a-fA-F]+h " , function(n) if not validWords[trim(n)] then return addNum (n) end end) - mnem = mnem:gsub(" %-?[01]+b " , function(n) if not validWords[trim(n)] then return addNum (n) end end) - mnem = mnem:gsub(" %-?[0-9]+ " , function(n) if not validWords[trim(n)] then return addNum (n) end end) - mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end) - mnem = trim(mnem):gsub(" +", " "):lower() - - if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end - - return mnem, imms -end -local function addByte(state, val, code) - assert(val>=-128 and val<=255, "invalid byte "..val) - assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) - state.memory[state.curAddr] = val%256 - if code then state.codeMap[state.curAddr] = true end - state.curAddr = state.curAddr + 1 -end -local function addWord(state, val, code) - assert(val>=0 and val<=65535, "invalid word "..val) - addByte(state, math.floor(val/256), code) - addByte(state, val%256, code) -end -local function addSpace(state, len) - for i = 1, len do - assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) - state.memory[state.curAddr] = false - state.curAddr = state.curAddr + 1 - end -end -local function assembleInstruction(line, state, instrs, validWords) - local mnem, imms = mnemFromLine(line, instrs, validWords) - local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")") - local writeimms = true - local padlen = 0 - local isInstr - if type(opcode)=="function" then - padlen, writeimms = opcode(imms) - addSpace(state, padlen) - elseif opcode>=0 then - isInstr = true - addByte(state, opcode, isInstr) - end - if writeimms then - for _, imm in ipairs(imms) do - if imm.val then - if imm.len==1 then addByte(state, imm.val, isInstr) - elseif imm.len==2 then addWord(state, imm.val, isInstr) - else error("invalid imm len") end - elseif imm.label then - table.insert(state.labelReplacements, { - name = imm.label, - addr = state.curAddr, - len = imm.len, - rel = imm.len==1, - isCode = isInstr, - }) - state.curAddr = state.curAddr + imm.len - else error("invalid imm") end - end - end -end -local directiveFunctions = { - fn = function(state, fn) state.fileName = fn end, - ln = function(state, ln) state.lineNum = tonumber(ln) end, - org = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end, - align = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end, - define = true, - space = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end, -} -local function postEvaluateExpression(expr, labels) - -end -local function assembleCode(code, instrs, uexprs) - local validWords = validWordsFromInstrs(instrs) - - local state = { - lineNum = 0, - fileName = "", - curAddr = 0, - memory = {}, - codeMap = {}, - labelReplacements = {}, - labelAddrs = {}, - } - - for line in code:gmatch("[^\n]+") do - line = trim(line) - if line:sub(1, 1)=="." then -- directive - local dir, rest = line:match("^%.([^ ]+) *(.*)$") - assert(dir and rest, "no directive on line "..line) - local dirf = directiveFunctions[dir] or error("invalid directive "..dir) - dirf(state, rest) - elseif line:sub(#line, #line)==":" then -- label - local name = line:sub(1, #line-1) - assert(not state.labelAddrs[name], "redefinition of label "..name) - state.labelAddrs[name] = state.curAddr - elseif line:find("[^ ]") then - assembleInstruction(line, state, instrs, validWords) - end - end - - for _, rep in ipairs(state.labelReplacements) do - local expr = uexprs[rep.name] - if expr then - local val = postEvaluateExpression(expr, state.labelAddrs) - if rep.len==1 then addByte(state, val, rep.isCode) - elseif rep.len==2 then addWord(state, val, rep.isCode) - else error("invalid expr replace len "..rep.len) end - else - local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name) - state.curAddr = rep.addr - if rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode) - elseif rep.len==2 then addWord(state, labelAddr , rep.isCode) - else error("invalid labelreplace len "..rep.len) end - end - end - - return state.memory, state.codeMap + +local function getCodeDir() + local f0 = arg[0]:gsub("/", "\\") + local d0 = f0:match("(.+)[\\][^\\]+$") or "." + return d0 end -local function readFile(fn) - local fi, err = io.open(fn, "r") - if not fi then error("could not open file "..fn..": "..err) end - local text = fi:read("*a") - fi:close() - return text +local function popenResult(cmd) + local fp = io.popen(cmd) + local out = fp:read("*a") + fp:close() + return out end -local function separateCommas(l) - local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c; -end -local function evaluateExpression(expr, uexprs) - expr = expr:gsub("[^%+%-%*%/]+", function(word) - local val = decodeNumber(word) or error("invalid number in expression: "..word) - return val - end) - assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr) - local exprf = loadstring("return "..expr) - local eval = exprf() or error("invalid expr: "..expr) - return eval -end -local function preprocessCode(code) - code = "\n"..code.."\n" - - -- apply brace labels and scoped labels - local curscope = "" - local codet = {} - local wordt = {} - local lastword = "" - local function addword(word) - lastword = word - if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end - table.insert(codet, word) - end - for i = 1, #code do - local c = code:sub(i, i) - if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c) - else - if #wordt>0 then - addword(table.concat(wordt)) - wordt = {} - end - if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then - curscope = lastword - end - table.insert(codet, c) +local function memFromCustomasmHexstr(out) + local mem = {} + local addr = 0 + for hexS in out:gmatch("[0-9a-fA-F][0-9a-fA-F]") do + local val = tonumber(hexS, 16) + if val~=0 then + mem[addr] = val end + addr = addr + 1 end - - code = "\n"..table.concat(codet).."\n" - - -- apply function macros - local funcmacros = {} - code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl) - local argt = separateCommas(args) - for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end - repl = " "..repl.." " - local invoc = 0 - funcmacros[name] = function(b, callargs) - invoc = invoc + 1 - local callargt = separateCommas(callargs) - local callrepl = repl - for argidx, arg in ipairs(argt) do - local callarg = callargt[argidx] - callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2") - end - callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_") - return b..callrepl - end - return "" - end) - for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end - - -- apply simple macros - local simplemacros = {} - code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl) - assert(not simplemacros[name], "Redefinition of macro "..name) - simplemacros[name] = repl - return "" - end) - --for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end - for name, repl in pairs(simplemacros) do - local invoc = 0 - code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a) - invoc = invoc+1 - return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a - end) - print(name, code) + local code = nil + local symbols = nil + return mem, code, symbols +end + +local function toData(s) + local d = {} + for p in s:gmatch("[0-9a-zA-Z][0-9a-zA-Z]") do + table.insert(d, tonumber(p, 16)) end + return d +end +local function memFromCustomasmAnnotated(out) + local mem = {} + local code = {} + local symbols = {} - code = code:gsub("\\\\", "\n") + local lastLabel = {} - local uexprs = {} - - local codet = {} - local exprt = {} - local parenLevel = 0 - for i = 1, #code do - local c = code:sub(i, i) - if c=="(" then - if parenLevel>0 then table.insert(exprt, c) end - parenLevel = parenLevel+1 - elseif c==")" then - parenLevel = parenLevel-1 - if parenLevel==0 then - table.insert(codet, evaluateExpression(table.concat(exprt), uexprs)) - exprt = {} + for line in out:gmatch("[^\r\n]+") do + if not line:find("^ outp | addr | data %(base 16%)$") then + local addrS, dataS, comment = line:match("^[^|]+ | ([^|]+) | ([^;]+) ; (.+)$") + local addr = tonumber(addrS, 16) + local data = toData(dataS) + if comment:sub(#comment, #comment)==":" then + assert(#data==0) + local label = comment:sub(1, #comment-1) + local noDots = label:gsub("^%.+", "") + local numDots = #label - #noDots + local fullLabel = numDots>0 and lastLabel[numDots-1].."."..noDots or label + lastLabel[numDots] = fullLabel + symbols[addr] = fullLabel else - table.insert(exprt, c) - end - else - if parenLevel==0 then table.insert(codet, c) - else table.insert(exprt, c) end - end - end - code = table.concat(codet) - - return code, uexprs -end -local function fixCode(code) - code = code:gsub(",", " ") - code = code:gsub(":([^\\/])", ":\n%1") - code = code:gsub("[ \t]+:", ":") - code = code:gsub("%]", " %] ") - code = code:gsub("%[", " %[ ") - code = code:gsub("%*", " %* ") - code = code:gsub("\n[ \t\r\n]*", "\n") - code = code:gsub(" +", " ") - - return code -end -local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", } -local prefixIdx = 0 -local function prefixCode(code, fn) -- fix strings, add line numbers - prefixIdx = prefixIdx + 1 - - local outt = {} - local outnextnl = {} - local linenum = 1 - local skipnl = false - local function last() return outt[#outt] end - local function out(c) assert(type(c)=="string"); table.insert(outt, c); end - local function outn(n) out("$"..string.format("%02X", n)) out("\\") end - local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end - local state = "code" -- code, comment, string, stringesc, commentml - - local lastbracelabel = 0 - local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end - local bracestack = {} - local bracehasmid = {} - local lastnl = false - - local utf8str = "" - local utf8len = 0 - - local function newline() - lastnl = true - for _, v in ipairs(outnextnl) do - if v=="\n" and skipnl then out("\\") - else out(v) end - end; outnextnl = {}; - end - - out(".ln 1"); out("\n"); - local i = 1 - while i <= #code do - local c = code:sub(i, i) - local cn = code:sub(i+1, i+1) - local cp = code:sub(i-1, i-1) - - if state=="code" then - if c=="\r" then - elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*") - linenum = linenum+1 - if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end - newline() - skipnl = false - elseif c=="#" or c==";" or (c=="/" and cn=="/") then state = "comment" - elseif c=="/" and cn=="*" then state = "commentml" - elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end - elseif c=="\"" then state = "string" lastnl = false - elseif c=="\\" then skipnl = true; out("\\"); - elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true; - elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false - elseif c=="{" then - table.insert(bracestack, bracelabel()) - if not lastnl then out(bracestack[#bracestack].."MID") end - outnext(bracestack[#bracestack].."START:"); outnext("\n"); - elseif c=="}" then - if not lastnl then out(bracestack[#bracestack].."START") end - if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end - outnext(bracestack[#bracestack].."END:"); outnext("\n"); - bracehasmid[#bracestack] = nil - bracestack[#bracestack] = nil - elseif c=="|" then - if not lastnl then out(bracestack[#bracestack].."END") end - outnext(bracestack[#bracestack].."MID:"); outnext("\n"); - bracehasmid[#bracestack] = true - else error("invalid char "..c) end - elseif state=="comment" then - if c=="\n" then state = "code" out("\n") newline() end - elseif state=="commentml" then - if c=="/" and cp=="*" then state = "code" end - elseif state=="string" then - if c=="\\" then state = "stringesc" - elseif c=="\"" then state = "code" - elseif c:byte()>=128 then - utf8str = c - utf8len = getutf8len(c) - state = "stringutf8" - else outn(c:byte()) end - elseif state=="stringesc" then - outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string"; - elseif state=="stringutf8" then - utf8str = utf8str..c - if #utf8str == utf8len then - local valt = utf8table[utf8str] - if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end; - error("Unrecognized UTF-8 character: "..datastr); end - for i, v in ipairs(valt) do outn(v) end - state = "string" + if comment:match("^[a-z]+") then + for i, v in ipairs(data) do + mem [addr+i-1] = v + code[addr+i-1] = true + end + else + for i, v in ipairs(data) do + mem [addr+i-1] = v + end + end end end - - i = i+1 end - assert(#bracestack==0, "unclosed brace") - local code2 = table.concat(outt) - return code2 + return mem, code, symbols end -local function fixFilename(fn) - fn = fn:gsub("[^a-zA-Z0-9_]", "_") - return fn -end -local function includeFile(fn) - local code = readFile(fn) - code = prefixCode(code, fn) - local fnf = fixFilename(fn) - code = ".fn "..fnf.."\n"..code - code = code:gsub(".include ([^\r\n]+)", function(fn2) - fn2 = fn:gsub("[^\\/]+$", "")..fn2 - return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n" - end) - return code -end -local function instrsFromArch(arch) - local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end - local instrs = { - imm8 = function() return 0, true end, - imm16 = function() return 0, true end, - byte = function() return 1, false end, - word = function() return 2, false end, - ["byte imm8"] = function() return 0, true end, - ["word imm16"] = function() return 0, true end, - ["byte [ imm8 ]" ] = function(imms) return arraySize(imms) , false end, - ["byte [ imm16 ]"] = function(imms) return arraySize(imms) , false end, - ["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end, - ["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end, - } - local function addMnem(mnem, opcode) - instrs[mnem] = opcode - if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end - end - for _, instr in ipairs(arch.instructions) do - if instr.mnem then - local mnem = instr.mnem - mnem = mnem:gsub("([%*%+%-])", " %1 ") - mnem = trim(mnem):gsub(" +", " ") - addMnem(mnem, instr.opcode) - local alias = arch.aliases[trim(mnem)] - if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end - end - end - return instrs + +local function fullPath(fn) + return popenResult(getCodeDir().."\\fullPath.bat \""..fn.."\"") end + local function assembleFile(fn, arch) - local code = includeFile(fn) - code, uexprs = preprocessCode(code) - code = fixCode(code) - local instrs = instrsFromArch(arch) - local mem, code = assembleCode(code, instrs, uexprs) - return mem, code + local fnf = fullPath(fn) + --local out = popenResult("customasm -p -q --format hexstr \""..fnf.."\"") + --return memFromCustomasmHexstr(out) + local out = popenResult("customasm -p -q --format annotated,base:16,group:2 \""..fnf.."\"") + return memFromCustomasmAnnotated(out) end local function mnemsFromArch(arch) @@ -491,8 +97,11 @@ local function mnemsFromArch(arch) end return mnems end + +local function symbolCrunchDots(s) return s:gsub("[^%.]+%.", "%.").."" end + local function toSigned8(x) return x>=128 and x-256 or x end -local function disassembleMemory(mem, code, arch) +local function disassembleMemory(arch, mem, code, symbols) local mnems = mnemsFromArch(arch) local addr = 0 @@ -524,11 +133,13 @@ local function disassembleMemory(mem, code, arch) end end local labelnum, subnum = 0, 0 - for _, jmp in pairs(jmpaddrs) do - if jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1; - else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end + for dest, jmp in pairs(jmpaddrs) do + if symbols[dest] then jmp.name = symbolCrunchDots(symbols[dest]) + elseif jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1; + else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end end + local maxLabelLen = 20 local lines = {} addr = 0 while addr<=0xFFFF do @@ -574,11 +185,14 @@ local function disassembleMemory(mem, code, arch) end local label = "" local jmp = jmpaddrs[startaddr] - if jmp then label = jmp.name..":" end + if symbols[startaddr] then label = symbolCrunchDots(symbols[startaddr])..":" + elseif jmp then label = jmp.name..":" end local lb = table.concat(lineb, " ") if lastaddr~=addr-tlen then table.insert(lines, "...") end - table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " ")) + table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(maxLabelLen-#label)..label.." "..table.concat(line, " ")) lastaddr = addr + elseif opcode and opcode~=0 then + table.insert(lines, "data: "..string.format("%02X", opcode)) end end return table.concat(lines, "\n") @@ -593,7 +207,7 @@ local function memToHex(hex) return mem end local function disassembleHex(hex, arch) - return disassembleMemory(memToHex(hex), arch) + return disassembleMemory(arch, memToHex(hex), nil, nil) end local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> " @@ -693,31 +307,15 @@ local function buildMemory(mem, romsize, offset, len) end end -local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end -if HasTs or (not AsmIncluded) then - function AssembleBuildFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes); - local arch = require("rom-8608-defs") - local mem, code = assembleFile(fn, arch) - print(""..fn:match("[^/\\]+$").."\n") - - print("Memory Dump:") - print(printMemory(mem)) - print() - print("Disassembly:") - print(disassembleMemory(mem, code, arch)) - print() - - assert(#romsize==3, "incorrect rom size") - buildMemory(mem, romsize, offset, len) - end - ts.eval [[ - function AssembleBuildFile(%fn, %romsize, %offset, %len) { luacall("AssembleBuildFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); } - ]] - if not HasTs then AssembleBuildFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end +if arg[1] then + local fn = arg[1] + local mem, code, symbols = assembleFile(fn) + local arch = dofile(getCodeDir().."\\rom-8608-defs.lua") + print(disassembleMemory(arch, mem, code, symbols)) +else + return { + assembleFile = assembleFile, + disassembleMemory = disassembleMemory, + printMemory = printMemory, + } end - -return { - assembleFile = assembleFile, - disassembleMemory = disassembleMemory, - printMemory = printMemory, -} diff --git a/bin-builder.lua b/bin-builder.lua new file mode 100644 index 0000000..e0092c7 --- /dev/null +++ b/bin-builder.lua @@ -0,0 +1,70 @@ + +local ts = ts or { + call = function() end, + eval = function() end, +} + +ts.eval [[ + function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); } + function commandPlantBrick() { commandToServer('plantBrick'); } +]] +local function plantBrickAt(brickpos, pos) + local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3] + ts.call("commandShiftBrick", dy, -dx, dz) + ts.call("commandPlantBrick") + brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3] +end +local function buildMemory(mem, romsize, offset, len) + if type(romsize)~="table" or #romsize<3 then error("You must specify a ROM size.") end + offset = offset or 0 + + local rombytes = romsize[1]*romsize[2]*romsize[3]/8 + if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end + if not len then + for i = 0, 0xFFFF do + if mem[i] and (i=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end + end + end + + local brickpos = {0, 0, 0} + for x = 0, romsize[1]-1 do + for y = 0, romsize[2]-1 do + for z = 0, romsize[3]-1 do + local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8)) + local pow = math.pow(2, z%8) + local data = (addr>=offset and ((not len) or addrp) -#define loadpinc readmemory(cpu->p++) -#define loadpp1 readmemory((cpu->p+1)%65536) #define loadq readmemory(cpu->q) -#define loadqinc readmemory(cpu->q++) +#define loadpinc readmemory((cpu->p++)%65536) +#define loadqinc readmemory((cpu->q++)%65536) +#define loadpp1 readmemory((cpu->p+1)%65536) #define loadqp1 readmemory((cpu->q+1)%65536) +#define loadput readmemory((cpu->p+wordut)%65536) +#define loadqut readmemory((cpu->q+wordut)%65536) #define signed8(x) (x>=128 ? x|0xFF00 : x) - #define setzf(x) cpu->nz=(x!=0); #define loadimmedt cpu->t = loadimmed; #define loadimm161 cpu->u = loadimmed; @@ -31,11 +32,13 @@ #define storeut(x) writememory(wordut, x); #define storeutp1(x) writememory((wordut+1)%65536, x); #define storep(x) writememory(cpu->p, x); -#define storepinc(x) writememory(cpu->p++, x); -#define storepp1(x) writememory((cpu->p+1)%65536, x); #define storeq(x) writememory(cpu->q, x); +#define storepinc(x) writememory(cpu->p++, x); #define storeqinc(x) writememory(cpu->q++, x); +#define storepp1(x) writememory((cpu->p+1)%65536, x); #define storeqp1(x) writememory((cpu->q+1)%65536, x); +#define storeput(x) writememory((cpu->p+wordut)%65536, x); +#define storequt(x) writememory((cpu->q+wordut)%65536, x); #define pushretaddr1 writememory(cpu->s++, hibyte((cpu->i-1)%65536)); #define pushretaddr2 writememory(cpu->s++, lobyte((cpu->i-1)%65536)); #define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0; diff --git a/emulator/8608emulator.dll b/emulator/8608emulator.dll index 38a3815..bc03b77 100644 Binary files a/emulator/8608emulator.dll and b/emulator/8608emulator.dll differ diff --git a/emulator/8608emulator.lua b/emulator/8608emulator.lua index 8e60bc6..3ea4b96 100644 --- a/emulator/8608emulator.lua +++ b/emulator/8608emulator.lua @@ -241,7 +241,7 @@ local function pdLinesFromDasm(dasm) end return lines, addrLines, lineAddrs end -local function InitProgramDisplay(pd, data, code, arch) +local function InitProgramDisplay(pd, arch, data, code, symbols) pd.width = 256 pd.height = 12+pd.fontHeight*pd.numLines-3 lg.print("Program", pd.scrX, pd.scrY-16) @@ -249,7 +249,7 @@ local function InitProgramDisplay(pd, data, code, arch) pd.firstLine = 1 pd.data = data pd.code = code - local dasm = asm.disassembleMemory(data, code, arch) + local dasm = asm.disassembleMemory(arch, data, code, symbols) pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm) pd.midLine = math.floor(pd.numLines/2) end @@ -490,13 +490,13 @@ WriteMemory = function(mem, addr, val) end end local function AssembleToMemory(mem, fn, arch) - local data, code = asm.assembleFile(fn, arch) + local data, code, symbols = asm.assembleFile(fn) for addr = 0, 65535 do if data[addr] then mem.c.data[addr] = data[addr] end end - return data, code + return data, code, symbols end ffi.cdef [[ @@ -631,8 +631,8 @@ function love.load() InitCharDisplay(CharDisplay) InitRegDisplay(RegDisplay) InitStackDisplay(StackDisplay) - local data, code = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch) - InitProgramDisplay(ProgramDisplay, data, code, Arch) + local data, code, symbols = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch) + InitProgramDisplay(ProgramDisplay, Arch, data, code, symbols) for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end RedrawWindow() lg.setCanvas() diff --git a/emulator/instructions_gen.c b/emulator/instructions_gen.c index b87367a..d474d06 100644 --- a/emulator/instructions_gen.c +++ b/emulator/instructions_gen.c @@ -1,6 +1,47 @@ // Auto-generated by gendefs.lua void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; } +void cpu_instr_1_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_1_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_1_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadput; setzf(cpu->a); cpu->cycle++; } +void cpu_instr_1_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_6_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_6_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_6_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; } +void cpu_instr_6_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; } +void cpu_instr_6_4(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_8_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_8_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_8_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqut; setzf(cpu->b); cpu->cycle++; } +void cpu_instr_8_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_9_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_9_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_9_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqut; setzf(cpu->c); cpu->cycle++; } +void cpu_instr_9_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_10_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_10_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_10_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->a); cpu->cycle++; } +void cpu_instr_10_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_11_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_11_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_11_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->b); cpu->cycle++; } +void cpu_instr_11_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_12_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_12_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_12_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->c); cpu->cycle++; } +void cpu_instr_12_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_13_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_13_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_13_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->a); cpu->cycle++; } +void cpu_instr_13_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_14_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_14_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_14_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->b); cpu->cycle++; } +void cpu_instr_14_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_15_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_15_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_15_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->c); cpu->cycle++; } +void cpu_instr_15_3(struct CPU* const cpu, struct Memory* const mem) { lni; } void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; } void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1 ); lni; } void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; } @@ -440,6 +481,20 @@ void cpu_instr_233_0(struct CPU* const cpu, struct Memory* const mem) { int f = void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { lni; } void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { int f=popbyte; cpu->nz = f&1; cpu->cf = (f>>1)&1; cpu->cycle++; } void cpu_instr_234_1(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_235_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_235_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_235_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqut; setzf(cpu->a); cpu->cycle++; } +void cpu_instr_235_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_236_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_236_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_236_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; } +void cpu_instr_236_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } +void cpu_instr_236_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } +void cpu_instr_238_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_238_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_238_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; } +void cpu_instr_238_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } +void cpu_instr_238_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; } void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; } void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; } @@ -447,25 +502,48 @@ void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg void cpu_instr_244_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; } void cpu_instr_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; } void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; } +void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_247_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_247_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadput; setzf(cpu->b); cpu->cycle++; } +void cpu_instr_247_3(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_248_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_248_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_248_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; } +void cpu_instr_248_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } +void cpu_instr_248_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } +void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_250_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_250_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; } +void cpu_instr_250_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } +void cpu_instr_250_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } +void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_252_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_252_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; } +void cpu_instr_252_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; } +void cpu_instr_252_4(struct CPU* const cpu, struct Memory* const mem) { lni; } +void cpu_instr_254_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } +void cpu_instr_254_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } +void cpu_instr_254_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadput; setzf(cpu->c); cpu->cycle++; } +void cpu_instr_254_3(struct CPU* const cpu, struct Memory* const mem) { lni; } void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; } CPUInstruction CPUInstructions[256][8] = { {cpu_instr_0_0,0,0,0,0,0,0,0}, + {cpu_instr_1_0,cpu_instr_1_1,cpu_instr_1_2,cpu_instr_1_3,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, + {cpu_instr_6_0,cpu_instr_6_1,cpu_instr_6_2,cpu_instr_6_3,cpu_instr_6_4,0,0,0}, {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, + {cpu_instr_8_0,cpu_instr_8_1,cpu_instr_8_2,cpu_instr_8_3,0,0,0,0}, + {cpu_instr_9_0,cpu_instr_9_1,cpu_instr_9_2,cpu_instr_9_3,0,0,0,0}, + {cpu_instr_10_0,cpu_instr_10_1,cpu_instr_10_2,cpu_instr_10_3,0,0,0,0}, + {cpu_instr_11_0,cpu_instr_11_1,cpu_instr_11_2,cpu_instr_11_3,0,0,0,0}, + {cpu_instr_12_0,cpu_instr_12_1,cpu_instr_12_2,cpu_instr_12_3,0,0,0,0}, + {cpu_instr_13_0,cpu_instr_13_1,cpu_instr_13_2,cpu_instr_13_3,0,0,0,0}, + {cpu_instr_14_0,cpu_instr_14_1,cpu_instr_14_2,cpu_instr_14_3,0,0,0,0}, + {cpu_instr_15_0,cpu_instr_15_1,cpu_instr_15_2,cpu_instr_15_3,0,0,0,0}, {cpu_instr_16_0,0,0,0,0,0,0,0}, {cpu_instr_17_0,0,0,0,0,0,0,0}, {cpu_instr_18_0,0,0,0,0,0,0,0}, @@ -685,10 +763,10 @@ CPUInstruction CPUInstructions[256][8] = { {cpu_instr_232_0,0,0,0,0,0,0,0}, {cpu_instr_233_0,cpu_instr_233_1,0,0,0,0,0,0}, {cpu_instr_234_0,cpu_instr_234_1,0,0,0,0,0,0}, + {cpu_instr_235_0,cpu_instr_235_1,cpu_instr_235_2,cpu_instr_235_3,0,0,0,0}, + {cpu_instr_236_0,cpu_instr_236_1,cpu_instr_236_2,cpu_instr_236_3,cpu_instr_236_4,0,0,0}, {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, + {cpu_instr_238_0,cpu_instr_238_1,cpu_instr_238_2,cpu_instr_238_3,cpu_instr_238_4,0,0,0}, {0,0,0,0,0,0,0,0}, {cpu_instr_240_0,0,0,0,0,0,0,0}, {cpu_instr_241_0,0,0,0,0,0,0,0}, @@ -697,13 +775,13 @@ CPUInstruction CPUInstructions[256][8] = { {cpu_instr_244_0,0,0,0,0,0,0,0}, {cpu_instr_245_0,0,0,0,0,0,0,0}, {cpu_instr_246_0,0,0,0,0,0,0,0}, + {cpu_instr_247_0,cpu_instr_247_1,cpu_instr_247_2,cpu_instr_247_3,0,0,0,0}, + {cpu_instr_248_0,cpu_instr_248_1,cpu_instr_248_2,cpu_instr_248_3,cpu_instr_248_4,0,0,0}, {0,0,0,0,0,0,0,0}, + {cpu_instr_250_0,cpu_instr_250_1,cpu_instr_250_2,cpu_instr_250_3,cpu_instr_250_4,0,0,0}, {0,0,0,0,0,0,0,0}, + {cpu_instr_252_0,cpu_instr_252_1,cpu_instr_252_2,cpu_instr_252_3,cpu_instr_252_4,0,0,0}, {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, + {cpu_instr_254_0,cpu_instr_254_1,cpu_instr_254_2,cpu_instr_254_3,0,0,0,0}, {cpu_instr_255_0,0,0,0,0,0,0,0}, }; diff --git a/emulator/keycodes.lua b/emulator/keycodes.lua index 1ff3625..d797e97 100644 --- a/emulator/keycodes.lua +++ b/emulator/keycodes.lua @@ -1,4 +1,6 @@ +-- copied from Brick_LuaLogic/bricks/input/keyboard-global.luas + return { ["backspace"] = 8, ["tab"] = 9, diff --git a/fullPath.bat b/fullPath.bat new file mode 100644 index 0000000..b1d7fba --- /dev/null +++ b/fullPath.bat @@ -0,0 +1 @@ +@echo %~dpnx1 diff --git a/instructionList.txt b/instructionList.txt index 0cddae1..37bf07c 100644 --- a/instructionList.txt +++ b/instructionList.txt @@ -129,10 +129,10 @@ rts E1 3 I=*(----S)+1 jpr imm8 31 2 I+=imm8 jnz imm8 30 2 I+=imm8 if !Zero jpz imm8 32 2 I+=imm8 if Zero -jge imm8 33 2 I+=imm8 if !Carry -jlt imm8 34 2 I+=imm8 if Carry -jgt imm8 35 2 I+=imm8 if !Zero & !Carry -jle imm8 36 2 I+=imm8 if Zero | Carry +jlt imm8 33 2 I+=imm8 if !Carry +jge imm8 34 2 I+=imm8 if Carry +jgt imm8 35 2 I+=imm8 if !Zero & Carry +jle imm8 36 2 I+=imm8 if Zero | !Carry Stack (S): psh a 40 2 *(S++)=A @@ -166,30 +166,42 @@ ldc *imm16 57 4 C=*imm16, update zero flag sta *imm16 50 4 *imm16=A stb *imm16 58 4 *imm16=B stc *imm16 59 4 *imm16=C -sta *p 52 2 *P=A -stb *p 5A 2 *P=B -stc *p 5B 2 *P=C -sta *q 54 2 *Q=A -stb *q 5C 2 *Q=B -stc *q 5D 2 *Q=C +lda *p+imm16 01 4 A=*P+imm16, update zero flag +ldb *p+imm16 F7 4 B=*P+imm16, update zero flag +ldc *p+imm16 FE 4 C=*P+imm16, update zero flag +lda *q+imm16 EB 4 A=*Q+imm16, update zero flag +ldb *q+imm16 08 4 B=*Q+imm16, update zero flag +ldc *q+imm16 09 4 C=*Q+imm16, update zero flag +sta *p+imm16 0A 4 *P+imm16=A +stb *p+imm16 0B 4 *P+imm16=B +stc *p+imm16 0C 4 *P+imm16=C +sta *q+imm16 0D 4 *Q+imm16=A +stb *q+imm16 0E 4 *Q+imm16=B +stc *q+imm16 0F 4 *Q+imm16=C lda *p 53 2 A=*P, update zero flag ldb *p 5E 2 B=*P, update zero flag ldc *p 5F 2 C=*P, update zero flag lda *q 55 2 A=*Q, update zero flag ldb *q 61 2 B=*Q, update zero flag ldc *q 62 2 C=*Q, update zero flag -sta *p++ C0 2 *P++=A -stb *p++ C1 2 *P++=B -stc *p++ C2 2 *P++=C -sta *q++ C3 2 *Q++=A -stb *q++ C4 2 *Q++=B -stc *q++ C5 2 *Q++=C +sta *p 52 2 *P=A +stb *p 5A 2 *P=B +stc *p 5B 2 *P=C +sta *q 54 2 *Q=A +stb *q 5C 2 *Q=B +stc *q 5D 2 *Q=C lda *p++ C6 2 A=*P++, update zero flag ldb *p++ C7 2 B=*P++, update zero flag ldc *p++ C8 2 C=*P++, update zero flag lda *q++ C9 2 A=*Q++, update zero flag ldb *q++ CA 2 B=*Q++, update zero flag ldc *q++ CB 2 C=*Q++, update zero flag +sta *p++ C0 2 *P++=A +stb *p++ C1 2 *P++=B +stc *p++ C2 2 *P++=C +sta *q++ C3 2 *Q++=A +stb *q++ C4 2 *Q++=B +stc *q++ C5 2 *Q++=C 16-bit Load/Store (W): ldp imm16 21 3 P=imm16 @@ -204,6 +216,12 @@ ldp *imm16 68 5 P=*imm16 ldq *imm16 6A 5 Q=*imm16 stp *imm16 6C 5 *imm16=P stq *imm16 6E 5 *imm16=Q +ldp *p+imm16 EC 5 P=*P+imm16 +ldq *p+imm16 EE 5 Q=*P+imm16 +ldp *q+imm16 F8 5 P=*Q+imm16 +ldq *q+imm16 FA 5 Q=*Q+imm16 +stq *p+imm16 06 5 *P+imm16=Q +stp *q+imm16 FC 5 *Q+imm16=P ldp *p 92 3 P=*P ldq *p 93 3 Q=*P ldp *q 94 3 P=*Q @@ -240,9 +258,9 @@ ldq p 8E 1 Q=P lds p 8F 1 S=P ldv p 90 1 V=P -Opcodes used: 228/255 +Opcodes used: 252/255 0123456789ABCDEF -00 | C--------------- +00 | CB----WWBBBBBBBB 10 | UUIIUIIUUUUUUUUU 20 | BWWWAWBBBBBUUUUA 30 | JJJJJJJMMMMSSSAA @@ -256,5 +274,5 @@ A0 | AAAAAAAAAAAAAAAA B0 | AAAAAAAAAAAAAAAA C0 | BBBBBBBBBBBBWWWW D0 | AAAAAAAAAAAAAAAA -E0 | MJJJJJXXXSS----- -F0 | CCCCCCC--------C +E0 | MJJJJJXXXSSBWWWW +F0 | CCCCCCCBWWWWWWBC diff --git a/rom-8608.lua b/rom-8608-build.lua similarity index 69% rename from rom-8608.lua rename to rom-8608-build.lua index 17964bb..180f25e 100644 --- a/rom-8608.lua +++ b/rom-8608-build.lua @@ -70,6 +70,70 @@ local function sigsFromRoms(roms) return sigs end +local relJmpStr = [[ +%s {addr} => { + reladdr = addr - $ - 2 + assert(reladdr <= 127, "%s: Relative jump target is too far away") + assert(reladdr >= -128, "%s: Relative jump target is too far away") + %s @ reladdr`8 + }]] +local wordRelStr = [[ +%s+{value: i%i} => { + assert(value <= %i, "Relative address is too far away") + assert(value >= %i, "Relative address is too far away") + %s @ value`%i + } + %s-{value: i%i} => { + mvalue = -value + assert(mvalue <= %i, "Relative address is too far away") + assert(mvalue >= %i, "Relative address is too far away") + %s @ mvalue`%i + }]] + +local function getAsmCode(mnem, instr) + local reljmp = instr.jmp and instr.rel + local opcodeS = string.format("$%02X", instr.opcode) + + if reljmp then + assert(mnem:find("imm8"), "relative jump without imm8") + local mnemPart = mnem:gsub(" imm8", "") + return string.format(relJmpStr, + mnemPart, mnemPart, mnemPart, + opcodeS + ) + elseif mnem:find("%+imm") then + local mnemPart, bitsS = mnem:match("^([^%+]+)%+imm([0-9]+)$") + local bits = tonumber(bitsS) + local maxVal = math.pow(2, bits-1)-1 + local minVal = -math.pow(2, bits-1) + return string.format(wordRelStr, + mnemPart, bits, maxVal, minVal, opcodeS, bits, + mnemPart, bits, maxVal, minVal, opcodeS, bits + ) + elseif mnem:find("imm8") then + mnem = mnem:gsub("imm8", "{value: i8}") + return mnem.." => "..opcodeS.." @ value" + elseif mnem:find("imm16") then + mnem = mnem:gsub("imm16", "{value: i16}") + return mnem.." => "..opcodeS.." @ value" + else + return mnem.." => "..opcodeS + end +end +local function getAsmsFromInstr(instr, aliases) + local mnem = instr.mnem + local t = {} + if mnem then + table.insert(t, getAsmCode(mnem, instr)) + if aliases[mnem] then + for _, mnem2 in ipairs(aliases[mnem]) do + table.insert(t, getAsmCode(mnem2, instr)) + end + end + end + return t +end + local function archToUcode(arch) local sigs = sigsFromRoms(arch.roms) local ops = arch.operations @@ -78,6 +142,7 @@ local function archToUcode(arch) local opcodesUsed = {} local numOpcodesUsed = 0 local infolines = {} + local asmlines = {} local catlet = "X" for _, instr in ipairs(arch.instructions) do if instr.category then @@ -105,6 +170,9 @@ local function archToUcode(arch) if instr.desc then table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).." "..ncycles.." "..instr.desc.."\n") end + + local asms = getAsmsFromInstr(instr, arch.aliases) + for _, a in ipairs(asms) do table.insert(asmlines, a) end end end @@ -120,15 +188,28 @@ local function archToUcode(arch) table.insert(lt, "\n") end + -- Output instruction list local info = table.concat(infolines).."\n"..table.concat(lt) - print(info) - + --print(info) local fo = io.open("instructionList.txt", "w") if fo then fo:write(info) fo:close() end + + -- Output customASM definitions + local fi = io.open("arch-8608-template.asm") + local asmDataStr = fi:read("*a") + fi:close() + + local asmTable = string.format(asmDataStr, table.concat(asmlines, "\n\t")) + local fo = io.open("arch-8608.asm", "w") + if fo then + fo:write(asmTable) + fo:close() + end + return ucode end diff --git a/rom-8608-defs.lua b/rom-8608-defs.lua index 9309b7b..366a301 100644 --- a/rom-8608-defs.lua +++ b/rom-8608-defs.lua @@ -72,14 +72,20 @@ operations = { load162 = {"adrInc","loadReg","memSaveT"}, store161 = { "storeReg"}, store162 = {"adrInc","storeReg"}, - loadUTU = {"adrrUT","loadReg","memSaveU"}, - storeUT = {"adrrUT","storeReg"}, + loadUTU = {"adrrUT", "loadReg","memSaveU"}, + loadUTUP = {"adrrUT","adrlP","loadReg","memSaveU"}, + loadUTUQ = {"adrrUT","adrlQ","loadReg","memSaveU"}, + storeUT = {"adrrUT", "storeReg"}, + storeUTP = {"adrrUT","adrlP","storeReg"}, + storeUTQ = {"adrrUT","adrlQ","storeReg"}, memSaveFlags = {"memSaveNZ"}, adwrUT = {"adwrhU","adwrlT"}, adrrUT = {"adrrhU","adrrlT"}, adwrCB = {"adwrhC","adwrlB"}, - adwIncUT = {"adwrUT","adwInc"}, + adwIncUT = {"adwrUT", "adwInc"}, + adwIncUTP = {"adwrUT","adwlP","adwInc"}, + adwIncUTQ = {"adwrUT","adwlQ","adwInc"}, adwP = {"adwlP","adwSaveP"}, adwQ = {"adwlQ","adwSaveQ"}, adwS = {"adwlS","adwSaveS"}, @@ -130,252 +136,270 @@ operations = { instructions = { { category = "Control", catlet="C" }, - { mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} }, - { mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} }, - { mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} }, - { mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} }, - { mnem="brk" , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, - { mnem="irt" , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, - { mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, }, - { mnem="ien" , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo - { mnem="idi" , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo + { mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} }, + { mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} }, + { mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} }, + { mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} }, + { mnem="brk" , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, + { mnem="irt" , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, + { mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, }, + { mnem="ien" , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo + { mnem="idi" , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo { category = "16-bit Inc/Dec", catlet="I" }, - { mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, - { mnem="dec p" , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} }, - { mnem="inc q" , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} }, - { mnem="dec q" , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} }, + { mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, + { mnem="dec p" , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} }, + { mnem="inc q" , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} }, + { mnem="dec q" , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} }, { category = "8-bit Unary", catlet="U" }, - { mnem="inc a" , opcode=0x10, {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags" , ccode={"addf(cpu.a, 1 ); lni;"} }, - { mnem="dec a" , opcode=0x11, {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags" , ccode={"addf(cpu.a,-1 ); lni;"} }, - { mnem="icc a" , opcode=0x1B, {"aluA", "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} }, - { mnem="inc b" , opcode=0x19, {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags" , ccode={"addf(cpu.b, 1 ); lni;"} }, - { mnem="dec b" , opcode=0x1A, {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags" , ccode={"addf(cpu.b,-1 ); lni;"} }, - { mnem="icc b" , opcode=0x1C, {"aluB", "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} }, - { mnem="inc c" , opcode=0x17, {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags" , ccode={"addf(cpu.c, 1 ); lni;"} }, - { mnem="dec c" , opcode=0x18, {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags" , ccode={"addf(cpu.c,-1 ); lni;"} }, - { mnem="icc c" , opcode=0x1D, {"aluC", "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} }, - { mnem="tst a" , opcode=0x14, {"alulA", "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} }, - { mnem="tst b" , opcode=0x1E, {"alulB", "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} }, - { mnem="tst c" , opcode=0x1F, {"alulC", "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} }, - { mnem="inc *s+imm8", opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1 );","instrloadpre"} }, - { mnem="dec *s+imm8", opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1 );","instrloadpre"} }, - { mnem="icc *s+imm8", opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU", "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} }, - { mnem="tst *s+imm8", opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU", "aluOpCmp" ,"instrNext"}, desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} }, + { mnem="inc a" , opcode=0x10, {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags" , ccode={"addf(cpu.a, 1 ); lni;"} }, + { mnem="dec a" , opcode=0x11, {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags" , ccode={"addf(cpu.a,-1 ); lni;"} }, + { mnem="icc a" , opcode=0x1B, {"aluA", "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} }, + { mnem="inc b" , opcode=0x19, {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags" , ccode={"addf(cpu.b, 1 ); lni;"} }, + { mnem="dec b" , opcode=0x1A, {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags" , ccode={"addf(cpu.b,-1 ); lni;"} }, + { mnem="icc b" , opcode=0x1C, {"aluB", "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} }, + { mnem="inc c" , opcode=0x17, {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags" , ccode={"addf(cpu.c, 1 ); lni;"} }, + { mnem="dec c" , opcode=0x18, {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags" , ccode={"addf(cpu.c,-1 ); lni;"} }, + { mnem="icc c" , opcode=0x1D, {"aluC", "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} }, + { mnem="tst a" , opcode=0x14, {"alulA", "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} }, + { mnem="tst b" , opcode=0x1E, {"alulB", "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} }, + { mnem="tst c" , opcode=0x1F, {"alulC", "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} }, + { mnem="inc *s+imm8" , opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1 );","instrloadpre"} }, + { mnem="dec *s+imm8" , opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1 );","instrloadpre"} }, + { mnem="icc *s+imm8" , opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU", "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} }, + { mnem="tst *s+imm8" , opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU", "aluOpCmp" ,"instrNext"}, desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} }, { category = "16-bit Arithmetic", catlet = "X"}, - { mnem="adp imm8" , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} }, - { mnem="adq imm8" , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} }, - { mnem="ads imm8" , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} }, - { mnem="adp b" , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} }, - { mnem="adq b" , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} }, - { mnem="ads b" , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} }, + { mnem="adp imm8" , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} }, + { mnem="adq imm8" , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} }, + { mnem="ads imm8" , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} }, + { mnem="adp b" , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} }, + { mnem="adq b" , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} }, + { mnem="ads b" , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} }, { category = "8-bit Arithmetic/Logic", catlet="A" }, - { mnem="add imm8" , opcode=0x24, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} }, - { mnem="adb imm8" , opcode=0x72, {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} }, - { mnem="adc imm8" , opcode=0x73, {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} }, - { mnem="sub imm8" , opcode=0x70, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} }, - { mnem="sbb imm8" , opcode=0x99, {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.b,cpu.t); lni;"} }, - { mnem="sbc imm8" , opcode=0x9A, {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.c,cpu.t); lni;"} }, - { mnem="acc imm8" , opcode=0x78, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} }, - { mnem="scc imm8" , opcode=0x79, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=imm8+CF, set flags" , ccode={"loadimmedt","addf(cpu.a,-cpu.t+cpu.cf); lni;"} }, - { mnem="cmp imm8" , opcode=0x71, {"loadImmedT","instrSub1"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8" , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} }, - { mnem="and imm8" , opcode=0x74, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag" , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} }, - { mnem="ior imm8" , opcode=0x75, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag" , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} }, - { mnem="xor imm8" , opcode=0x76, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag" , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} }, - { mnem="ann imm8" , opcode=0x77, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~imm8, set zero flag" , ccode={"loadimmedt","cpu.a&=~cpu.t; setzf(cpu.a); lni;"} }, - { mnem="shl imm8" , opcode=0xD0, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} }, - { mnem="shr imm8" , opcode=0xD1, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} }, - { mnem="rol imm8" , opcode=0xD2, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, - { mnem="ror imm8" , opcode=0xD3, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, - { mnem="sra imm8" , opcode=0xD4, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, - { mnem="add *s+imm8", opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} }, - { mnem="adb *s+imm8", opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} }, - { mnem="adc *s+imm8", opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} }, - { mnem="sub *s+imm8", opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} }, - { mnem="sbb *s+imm8", opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} }, - { mnem="sbc *s+imm8", opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} }, - { mnem="acc *s+imm8", opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} }, - { mnem="scc *s+imm8", opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} }, - { mnem="cmp *s+imm8", opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} }, - { mnem="and *s+imm8", opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} }, - { mnem="ior *s+imm8", opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} }, - { mnem="xor *s+imm8", opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} }, - { mnem="ann *s+imm8", opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} }, - { mnem="shl *s+imm8", opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} }, - { mnem="shr *s+imm8", opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} }, - { mnem="rol *s+imm8", opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, - { mnem="ror *s+imm8", opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, - { mnem="sra *s+imm8", opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, - { mnem="add b" , opcode=0xA0, {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags" , ccode={"addf(cpu.a,cpu.b); lni;"} }, - { mnem="adc b" , opcode=0x9F, {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags" , ccode={"addf(cpu.c,cpu.b); lni;"} }, - { mnem="sub b" , opcode=0xA1, {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags" , ccode={"subf(cpu.a,cpu.b); lni;"} }, - { mnem="sbc b" , opcode=0xB6, {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags" , ccode={"subf(cpu.c,cpu.b); lni;"} }, - { mnem="acc b" , opcode=0xB8, {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags" , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} }, - { mnem="scc b" , opcode=0xB9, {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags" , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} }, - { mnem="cmp b" , opcode=0xA2, {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B" , ccode={"cmpf(cpu.a,cpu.b); lni;"} }, - { mnem="and b" , opcode=0xA3, {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag" , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} }, - { mnem="ior b" , opcode=0xA4, {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag" , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} }, - { mnem="xor b" , opcode=0xA5, {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag" , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} }, - { mnem="ann b" , opcode=0xA6, {"aluA", "alurB","aluOpAnn" ,"instrNext"}, desc="A&=~B, set zero flag" , ccode={"cpu.a&=~cpu.b; setzf(cpu.a); lni;"} }, - { mnem="shl b" , opcode=0xDA, {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag" , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} }, - { mnem="shr b" , opcode=0xDB, {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag" , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} }, - { mnem="rol b" , opcode=0xDC, {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, - { mnem="ror b" , opcode=0xDD, {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, - { mnem="sra b" , opcode=0xDE, {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, - { mnem="add c" , opcode=0xA7, {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags" , ccode={"addf(cpu.a,cpu.c); lni;"} }, - { mnem="adb c" , opcode=0xBD, {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags" , ccode={"addf(cpu.b,cpu.c); lni;"} }, - { mnem="sub c" , opcode=0xA8, {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags" , ccode={"subf(cpu.a,cpu.c); lni;"} }, - { mnem="sbb c" , opcode=0xBC, {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags" , ccode={"subf(cpu.b,cpu.c); lni;"} }, - { mnem="acc c" , opcode=0xBA, {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags" , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} }, - { mnem="scc c" , opcode=0xBB, {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags" , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} }, - { mnem="cmp c" , opcode=0xA9, {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C" , ccode={"cmpf(cpu.a,cpu.c); lni;"} }, - { mnem="and c" , opcode=0xAA, {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag" , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} }, - { mnem="ior c" , opcode=0xAB, {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag" , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} }, - { mnem="xor c" , opcode=0xAC, {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag" , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} }, - { mnem="ann c" , opcode=0xAD, {"aluA", "alurC","aluOpAnn" ,"instrNext"}, desc="A&=~C, set zero flag" , ccode={"cpu.a&=~cpu.c; setzf(cpu.a); lni;"} }, - { mnem="shl c" , opcode=0xDF, {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag" , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} }, - { mnem="shr c" , opcode=0x4D, {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag" , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} }, - { mnem="rol c" , opcode=0x3E, {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, - { mnem="ror c" , opcode=0x3F, {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, - { mnem="sra c" , opcode=0x2F, {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, - { mnem="adb a" , opcode=0xBE, {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags" , ccode={"addf(cpu.b,cpu.a); lni;"} }, - { mnem="sbb a" , opcode=0xBF, {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags" , ccode={"subf(cpu.b,cpu.a); lni;"} }, - { mnem="adc a" , opcode=0x4E, {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags" , ccode={"addf(cpu.c,cpu.a); lni;"} }, - { mnem="sbc a" , opcode=0x4F, {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags" , ccode={"subf(cpu.c,cpu.a); lni;"} }, + { mnem="add imm8" , opcode=0x24, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} }, + { mnem="adb imm8" , opcode=0x72, {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} }, + { mnem="adc imm8" , opcode=0x73, {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} }, + { mnem="sub imm8" , opcode=0x70, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} }, + { mnem="sbb imm8" , opcode=0x99, {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.b,cpu.t); lni;"} }, + { mnem="sbc imm8" , opcode=0x9A, {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.c,cpu.t); lni;"} }, + { mnem="acc imm8" , opcode=0x78, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} }, + { mnem="scc imm8" , opcode=0x79, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=imm8+CF, set flags" , ccode={"loadimmedt","addf(cpu.a,-cpu.t+cpu.cf); lni;"} }, + { mnem="cmp imm8" , opcode=0x71, {"loadImmedT","instrSub1"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8" , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} }, + { mnem="and imm8" , opcode=0x74, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag" , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} }, + { mnem="ior imm8" , opcode=0x75, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag" , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} }, + { mnem="xor imm8" , opcode=0x76, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag" , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} }, + { mnem="ann imm8" , opcode=0x77, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~imm8, set zero flag" , ccode={"loadimmedt","cpu.a&=~cpu.t; setzf(cpu.a); lni;"} }, + { mnem="shl imm8" , opcode=0xD0, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} }, + { mnem="shr imm8" , opcode=0xD1, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} }, + { mnem="rol imm8" , opcode=0xD2, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, + { mnem="ror imm8" , opcode=0xD3, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, + { mnem="sra imm8" , opcode=0xD4, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, + { mnem="add *s+imm8" , opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} }, + { mnem="adb *s+imm8" , opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} }, + { mnem="adc *s+imm8" , opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} }, + { mnem="sub *s+imm8" , opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} }, + { mnem="sbb *s+imm8" , opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} }, + { mnem="sbc *s+imm8" , opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} }, + { mnem="acc *s+imm8" , opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} }, + { mnem="scc *s+imm8" , opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} }, + { mnem="cmp *s+imm8" , opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} }, + { mnem="and *s+imm8" , opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} }, + { mnem="ior *s+imm8" , opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} }, + { mnem="xor *s+imm8" , opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} }, + { mnem="ann *s+imm8" , opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} }, + { mnem="shl *s+imm8" , opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} }, + { mnem="shr *s+imm8" , opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} }, + { mnem="rol *s+imm8" , opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, + { mnem="ror *s+imm8" , opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, + { mnem="sra *s+imm8" , opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, + { mnem="add b" , opcode=0xA0, {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags" , ccode={"addf(cpu.a,cpu.b); lni;"} }, + { mnem="adc b" , opcode=0x9F, {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags" , ccode={"addf(cpu.c,cpu.b); lni;"} }, + { mnem="sub b" , opcode=0xA1, {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags" , ccode={"subf(cpu.a,cpu.b); lni;"} }, + { mnem="sbc b" , opcode=0xB6, {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags" , ccode={"subf(cpu.c,cpu.b); lni;"} }, + { mnem="acc b" , opcode=0xB8, {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags" , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} }, + { mnem="scc b" , opcode=0xB9, {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags" , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} }, + { mnem="cmp b" , opcode=0xA2, {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B" , ccode={"cmpf(cpu.a,cpu.b); lni;"} }, + { mnem="and b" , opcode=0xA3, {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag" , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} }, + { mnem="ior b" , opcode=0xA4, {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag" , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} }, + { mnem="xor b" , opcode=0xA5, {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag" , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} }, + { mnem="ann b" , opcode=0xA6, {"aluA", "alurB","aluOpAnn" ,"instrNext"}, desc="A&=~B, set zero flag" , ccode={"cpu.a&=~cpu.b; setzf(cpu.a); lni;"} }, + { mnem="shl b" , opcode=0xDA, {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag" , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} }, + { mnem="shr b" , opcode=0xDB, {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag" , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} }, + { mnem="rol b" , opcode=0xDC, {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, + { mnem="ror b" , opcode=0xDD, {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, + { mnem="sra b" , opcode=0xDE, {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, + { mnem="add c" , opcode=0xA7, {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags" , ccode={"addf(cpu.a,cpu.c); lni;"} }, + { mnem="adb c" , opcode=0xBD, {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags" , ccode={"addf(cpu.b,cpu.c); lni;"} }, + { mnem="sub c" , opcode=0xA8, {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags" , ccode={"subf(cpu.a,cpu.c); lni;"} }, + { mnem="sbb c" , opcode=0xBC, {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags" , ccode={"subf(cpu.b,cpu.c); lni;"} }, + { mnem="acc c" , opcode=0xBA, {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags" , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} }, + { mnem="scc c" , opcode=0xBB, {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags" , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} }, + { mnem="cmp c" , opcode=0xA9, {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C" , ccode={"cmpf(cpu.a,cpu.c); lni;"} }, + { mnem="and c" , opcode=0xAA, {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag" , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} }, + { mnem="ior c" , opcode=0xAB, {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag" , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} }, + { mnem="xor c" , opcode=0xAC, {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag" , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} }, + { mnem="ann c" , opcode=0xAD, {"aluA", "alurC","aluOpAnn" ,"instrNext"}, desc="A&=~C, set zero flag" , ccode={"cpu.a&=~cpu.c; setzf(cpu.a); lni;"} }, + { mnem="shl c" , opcode=0xDF, {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag" , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} }, + { mnem="shr c" , opcode=0x4D, {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag" , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} }, + { mnem="rol c" , opcode=0x3E, {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, + { mnem="ror c" , opcode=0x3F, {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, + { mnem="sra c" , opcode=0x2F, {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, + { mnem="adb a" , opcode=0xBE, {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags" , ccode={"addf(cpu.b,cpu.a); lni;"} }, + { mnem="sbb a" , opcode=0xBF, {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags" , ccode={"subf(cpu.b,cpu.a); lni;"} }, + { mnem="adc a" , opcode=0x4E, {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags" , ccode={"addf(cpu.c,cpu.a); lni;"} }, + { mnem="sbc a" , opcode=0x4F, {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags" , ccode={"subf(cpu.c,cpu.a); lni;"} }, - { category = "Jumps", catlet="J" }, - { mnem="jmp imm16" , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="I=imm16" , ccode={"loadimm161","loadimm162","jmpabsut"} }, - { mnem="jsr imm16" , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} }, - { mnem="jss imm16" , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} }, - { mnem="jmp p" , opcode=0x64, {"jmpAbsP" }, desc="I=P" , ccode={"jmpabsp"} }, - { mnem="jmp q" , opcode=0x66, {"jmpAbsQ" }, desc="I=Q" , ccode={"jmpabsq"} }, - { mnem="jsr p" , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} }, - { mnem="jsr q" , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} }, - { mnem="jss p" , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} }, - { mnem="jss q" , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} }, - { mnem="rts" , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} }, - { mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} }, - { mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" , ccode={"loadimmedt","if( cpu.nz ) { jmprelt } else { lni }"} }, - { mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" , ccode={"loadimmedt","if(!cpu.nz ) { jmprelt } else { lni }"} }, - { mnem="jlt imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} }, - { mnem="jge imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} }, - { mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && cpu.cf ) { jmprelt } else { lni }"} }, - { mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} }, + { category = "Jumps" , catlet="J" }, + { mnem="jmp imm16" , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="I=imm16" , ccode={"loadimm161","loadimm162","jmpabsut"} }, + { mnem="jsr imm16" , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} }, + { mnem="jss imm16" , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} }, + { mnem="jmp p" , opcode=0x64, {"jmpAbsP" }, desc="I=P" , ccode={"jmpabsp"} }, + { mnem="jmp q" , opcode=0x66, {"jmpAbsQ" }, desc="I=Q" , ccode={"jmpabsq"} }, + { mnem="jsr p" , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} }, + { mnem="jsr q" , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} }, + { mnem="jss p" , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} }, + { mnem="jss q" , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} }, + { mnem="rts" , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} }, + { mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} }, + { mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" , ccode={"loadimmedt","if( cpu.nz ) { jmprelt } else { lni }"} }, + { mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" , ccode={"loadimmedt","if(!cpu.nz ) { jmprelt } else { lni }"} }, + { mnem="jlt imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} }, + { mnem="jge imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} }, + { mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && cpu.cf ) { jmprelt } else { lni }"} }, + { mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} }, - { category = "Stack", catlet="S" }, - { mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} }, - { mnem="psh b" , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} }, - { mnem="psh c" , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} }, - { mnem="psh f" , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} }, - { mnem="psh p" , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} }, - { mnem="psh q" , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} }, - { mnem="pop a" , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} }, - { mnem="pop b" , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} }, - { mnem="pop c" , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} }, - { mnem="pop f" , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} }, - { mnem="pop p" , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} }, - { mnem="pop q" , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} }, - { mnem="psh imm8" , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} }, - { mnem="phw imm16" , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D + { category = "Stack" , catlet="S" }, + { mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} }, + { mnem="psh b" , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} }, + { mnem="psh c" , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} }, + { mnem="psh f" , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} }, + { mnem="psh p" , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} }, + { mnem="psh q" , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} }, + { mnem="pop a" , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} }, + { mnem="pop b" , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} }, + { mnem="pop c" , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} }, + { mnem="pop f" , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} }, + { mnem="pop p" , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} }, + { mnem="pop q" , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} }, + { mnem="psh imm8" , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} }, + { mnem="phw imm16" , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D { category = "8-bit Load/Store", catlet="B" }, - { mnem="lda imm8" , opcode=0x20, {"loadImmed", "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} }, - { mnem="ldb imm8" , opcode=0x26, {"loadImmed", "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} }, - { mnem="ldc imm8" , opcode=0x27, {"loadImmed", "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} }, - { mnem="lda *s+imm8", opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} }, - { mnem="ldb *s+imm8", opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} }, - { mnem="ldc *s+imm8", opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} }, - { mnem="sta *s+imm8", opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, - { mnem="stb *s+imm8", opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, - { mnem="stc *s+imm8", opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, - { mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);","lni;"} }, - { mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);","lni;"} }, - { mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);","lni;"} }, - { mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurA","instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);","lni;"} }, - { mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurB","instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);","lni;"} }, - { mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurC","instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);","lni;"} }, - { mnem="sta *p" , opcode=0x52, {"adrlP","storeReg","alurA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} }, - { mnem="stb *p" , opcode=0x5A, {"adrlP","storeReg","alurB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} }, - { mnem="stc *p" , opcode=0x5B, {"adrlP","storeReg","alurC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} }, - { mnem="sta *q" , opcode=0x54, {"adrlQ","storeReg","alurA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} }, - { mnem="stb *q" , opcode=0x5C, {"adrlQ","storeReg","alurB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} }, - { mnem="stc *q" , opcode=0x5D, {"adrlQ","storeReg","alurC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} }, - { mnem="lda *p" , opcode=0x53, {"adrlP","loadReg","memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} }, - { mnem="ldb *p" , opcode=0x5E, {"adrlP","loadReg","memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} }, - { mnem="ldc *p" , opcode=0x5F, {"adrlP","loadReg","memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} }, - { mnem="lda *q" , opcode=0x55, {"adrlQ","loadReg","memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} }, - { mnem="ldb *q" , opcode=0x61, {"adrlQ","loadReg","memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} }, - { mnem="ldc *q" , opcode=0x62, {"adrlQ","loadReg","memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} }, - { mnem="sta *p++" , opcode=0xC0, {"adrlP","storeReg","alurA", "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} }, - { mnem="stb *p++" , opcode=0xC1, {"adrlP","storeReg","alurB", "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} }, - { mnem="stc *p++" , opcode=0xC2, {"adrlP","storeReg","alurC", "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} }, - { mnem="sta *q++" , opcode=0xC3, {"adrlQ","storeReg","alurA", "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} }, - { mnem="stb *q++" , opcode=0xC4, {"adrlQ","storeReg","alurB", "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} }, - { mnem="stc *q++" , opcode=0xC5, {"adrlQ","storeReg","alurC", "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} }, - { mnem="lda *p++" , opcode=0xC6, {"adrlP","loadReg","memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} }, - { mnem="ldb *p++" , opcode=0xC7, {"adrlP","loadReg","memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} }, - { mnem="ldc *p++" , opcode=0xC8, {"adrlP","loadReg","memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} }, - { mnem="lda *q++" , opcode=0xC9, {"adrlQ","loadReg","memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} }, - { mnem="ldb *q++" , opcode=0xCA, {"adrlQ","loadReg","memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} }, - { mnem="ldc *q++" , opcode=0xCB, {"adrlQ","loadReg","memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} }, + { mnem="lda imm8" , opcode=0x20, {"loadImmed", "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} }, + { mnem="ldb imm8" , opcode=0x26, {"loadImmed", "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} }, + { mnem="ldc imm8" , opcode=0x27, {"loadImmed", "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} }, + { mnem="lda *s+imm8" , opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} }, + { mnem="ldb *s+imm8" , opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} }, + { mnem="ldc *s+imm8" , opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} }, + { mnem="sta *s+imm8" , opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, + { mnem="stb *s+imm8" , opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, + { mnem="stc *s+imm8" , opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, + { mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);", "lni;"} }, + { mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);", "lni;"} }, + { mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);", "lni;"} }, + { mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);", "lni;"} }, + { mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);", "lni;"} }, + { mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);", "lni;"} }, + { mnem="lda *p+imm16", opcode=0x01, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadput; setzf(cpu.a);","lni;"} }, + { mnem="ldb *p+imm16", opcode=0xF7, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadput; setzf(cpu.b);","lni;"} }, + { mnem="ldc *p+imm16", opcode=0xFE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadput; setzf(cpu.c);","lni;"} }, + { mnem="lda *q+imm16", opcode=0xEB, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadqut; setzf(cpu.a);","lni;"} }, + { mnem="ldb *q+imm16", opcode=0x08, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadqut; setzf(cpu.b);","lni;"} }, + { mnem="ldc *q+imm16", opcode=0x09, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadqut; setzf(cpu.c);","lni;"} }, + { mnem="sta *p+imm16", opcode=0x0A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*P+imm16=A", ccode={"loadimm161","loadimm162","storeput(cpu.a);", "lni;"} }, + { mnem="stb *p+imm16", opcode=0x0B, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*P+imm16=B", ccode={"loadimm161","loadimm162","storeput(cpu.b);", "lni;"} }, + { mnem="stc *p+imm16", opcode=0x0C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*P+imm16=C", ccode={"loadimm161","loadimm162","storeput(cpu.c);", "lni;"} }, + { mnem="sta *q+imm16", opcode=0x0D, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=A", ccode={"loadimm161","loadimm162","storequt(cpu.a);", "lni;"} }, + { mnem="stb *q+imm16", opcode=0x0E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=B", ccode={"loadimm161","loadimm162","storequt(cpu.b);", "lni;"} }, + { mnem="stc *q+imm16", opcode=0x0F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=C", ccode={"loadimm161","loadimm162","storequt(cpu.c);", "lni;"} }, + { mnem="lda *p" , opcode=0x53, {"adrlP","loadReg", "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} }, + { mnem="ldb *p" , opcode=0x5E, {"adrlP","loadReg", "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} }, + { mnem="ldc *p" , opcode=0x5F, {"adrlP","loadReg", "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} }, + { mnem="lda *q" , opcode=0x55, {"adrlQ","loadReg", "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} }, + { mnem="ldb *q" , opcode=0x61, {"adrlQ","loadReg", "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} }, + { mnem="ldc *q" , opcode=0x62, {"adrlQ","loadReg", "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} }, + { mnem="sta *p" , opcode=0x52, {"adrlP","storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} }, + { mnem="stb *p" , opcode=0x5A, {"adrlP","storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} }, + { mnem="stc *p" , opcode=0x5B, {"adrlP","storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} }, + { mnem="sta *q" , opcode=0x54, {"adrlQ","storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} }, + { mnem="stb *q" , opcode=0x5C, {"adrlQ","storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} }, + { mnem="stc *q" , opcode=0x5D, {"adrlQ","storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} }, + { mnem="lda *p++" , opcode=0xC6, {"adrlP","loadReg", "memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} }, + { mnem="ldb *p++" , opcode=0xC7, {"adrlP","loadReg", "memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} }, + { mnem="ldc *p++" , opcode=0xC8, {"adrlP","loadReg", "memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} }, + { mnem="lda *q++" , opcode=0xC9, {"adrlQ","loadReg", "memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} }, + { mnem="ldb *q++" , opcode=0xCA, {"adrlQ","loadReg", "memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} }, + { mnem="ldc *q++" , opcode=0xCB, {"adrlQ","loadReg", "memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} }, + { mnem="sta *p++" , opcode=0xC0, {"adrlP","storeReg","alurA", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} }, + { mnem="stb *p++" , opcode=0xC1, {"adrlP","storeReg","alurB", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} }, + { mnem="stc *p++" , opcode=0xC2, {"adrlP","storeReg","alurC", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} }, + { mnem="sta *q++" , opcode=0xC3, {"adrlQ","storeReg","alurA", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} }, + { mnem="stb *q++" , opcode=0xC4, {"adrlQ","storeReg","alurB", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} }, + { mnem="stc *q++" , opcode=0xC5, {"adrlQ","storeReg","alurC", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} }, { category = "16-bit Load/Store", catlet="W" }, - { mnem="ldp imm16" , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} }, - { mnem="ldq imm16" , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} }, - { mnem="lds imm16" , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} }, - { mnem="ldv imm16" , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} }, - { mnem="ldp *s+imm8", opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, - { mnem="ldq *s+imm8", opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, - { mnem="stp *s+imm8", opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} }, - { mnem="stq *s+imm8", opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} }, - { mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveP","instrSub3"}, {"adrlP","loadRegT","instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69 - { mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT","instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B - { mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurPH","instrSub3"}, {"storeUT","adrInc","alurPL","instrSub4"}, {"instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"} }, -- 0x6D - { mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurQH","instrSub3"}, {"storeUT","adrInc","alurQL","instrSub4"}, {"instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"} }, -- 0x6F - { mnem="ldp *p" , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, - { mnem="ldq *p" , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} }, - { mnem="ldp *q" , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} }, - { mnem="ldq *q" , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, - { mnem="stp *q" , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} }, - { mnem="stq *p" , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} }, - { mnem="ldq *p++" , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} }, - { mnem="ldp *q++" , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} }, - { mnem="stp *q++" , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} }, - { mnem="stq *p++" , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} }, + { mnem="ldp imm16" , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} }, + { mnem="ldq imm16" , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} }, + { mnem="lds imm16" , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} }, + { mnem="ldv imm16" , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} }, + { mnem="ldp *s+imm8" , opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, + { mnem="ldq *s+imm8" , opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, + { mnem="stp *s+imm8" , opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} }, + { mnem="stq *s+imm8" , opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} }, + { mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69 + { mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B + { mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurPH", "instrSub3"}, {"storeUT","adrInc","alurPL", "instrSub4"}, { "instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0x6D + { mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurQH", "instrSub3"}, {"storeUT","adrInc","alurQL", "instrSub4"}, { "instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x6F + { mnem="ldp *p+imm16", opcode=0xEC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xED + { mnem="ldq *p+imm16", opcode=0xEE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xEF + { mnem="ldp *q+imm16", opcode=0xF8, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xF9 + { mnem="ldq *q+imm16", opcode=0xFA, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xFB + { mnem="stq *p+imm16", opcode=0x06, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTQ","alurQH", "instrSub3"}, {"storeUTQ","adrInc","alurQL","instrSub4"}, { "instrNext"}, desc="*P+imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x07 + { mnem="stp *q+imm16", opcode=0xFC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTP","alurPH", "instrSub3"}, {"storeUTP","adrInc","alurPL","instrSub4"}, { "instrNext"}, desc="*Q+imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0xFD + { mnem="ldp *p" , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, + { mnem="ldq *p" , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} }, + { mnem="ldp *q" , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} }, + { mnem="ldq *q" , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, + { mnem="stp *q" , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} }, + { mnem="stq *p" , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} }, + { mnem="ldq *p++" , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} }, + { mnem="ldp *q++" , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} }, + { mnem="stp *q++" , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} }, + { mnem="stq *p++" , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} }, - { category = "Moves", catlet="M" }, - { mnem="lda b" , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} }, - { mnem="lda c" , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} }, - { mnem="ldb a" , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} }, - { mnem="ldb c" , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} }, - { mnem="ldc a" , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} }, - { mnem="ldc b" , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} }, - { mnem="lda pl" , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} }, - { mnem="lda ph" , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} }, - { mnem="lda ql" , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} }, - { mnem="lda qh" , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} }, - { mnem="ldb pl" , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} }, - { mnem="ldc ph" , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} }, - { mnem="ldb ql" , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} }, - { mnem="ldc qh" , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} }, - { mnem="ldp q" , opcode=0x8A, {"adwlQ" , "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} }, - { mnem="ldp s" , opcode=0x8B, {"adwlS" , "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} }, - { mnem="ldp v" , opcode=0x8C, {"adwlV" , "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} }, - { mnem="ldp i" , opcode=0x8D, {"adwlI" , "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} }, - { mnem="ldp cb" , opcode=0x91, {"adwrCB", "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} }, - { mnem="ldq cb" , opcode=0xE0, {"adwrCB", "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} }, - { mnem="ldq p" , opcode=0x8E, {"adwlP" , "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} }, - { mnem="lds p" , opcode=0x8F, {"adwlP" , "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} }, - { mnem="ldv p" , opcode=0x90, {"adwlP" , "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} }, + { category = "Moves" , catlet="M" }, + { mnem="lda b" , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} }, + { mnem="lda c" , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} }, + { mnem="ldb a" , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} }, + { mnem="ldb c" , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} }, + { mnem="ldc a" , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} }, + { mnem="ldc b" , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} }, + { mnem="lda pl" , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} }, + { mnem="lda ph" , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} }, + { mnem="lda ql" , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} }, + { mnem="lda qh" , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} }, + { mnem="ldb pl" , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} }, + { mnem="ldc ph" , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} }, + { mnem="ldb ql" , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} }, + { mnem="ldc qh" , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} }, + { mnem="ldp q" , opcode=0x8A, {"adwlQ" , "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} }, + { mnem="ldp s" , opcode=0x8B, {"adwlS" , "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} }, + { mnem="ldp v" , opcode=0x8C, {"adwlV" , "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} }, + { mnem="ldp i" , opcode=0x8D, {"adwlI" , "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} }, + { mnem="ldp cb" , opcode=0x91, {"adwrCB", "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} }, + { mnem="ldq cb" , opcode=0xE0, {"adwrCB", "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} }, + { mnem="ldq p" , opcode=0x8E, {"adwlP" , "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} }, + { mnem="lds p" , opcode=0x8F, {"adwlP" , "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} }, + { mnem="ldv p" , opcode=0x90, {"adwlP" , "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} }, }, aliases = { - ["jpz imm8"] = {"jeq imm8"}, - ["jnz imm8"] = {"jne imm8"}, - ["jmp q" ] = {"ret" }, + ["jpz imm8" ] = {"jeq imm8"}, + ["jnz imm8" ] = {"jne imm8"}, + ["jmp q" ] = {"ret" }, }, }