//------------------------------- ::Opcodes:: --------------------------------// // Listed in the order that they should be checked /*==== Oddballs ====*/ // Weird edge cases in the ISA // Need to be handled individually BRK 00 000 000 00 impl JSR 20 001 000 00 abs RTI 40 010 000 00 impl RTS 60 011 000 00 impl JMP 6c 011 011 00 ind // <-- the *only* indr instruction LDX be 101 111 10 abs,Y // grouped with abs,X STX 96 100 101 10 zpg,Y // grouped with zpg,X LDX b6 101 101 10 zpg,Y // grouped with zpg,X /*==== Conditional Branch Instructions ====*/ // all have the form xxy10000 // // i.e: (instr & 0x1F == 0x10) // // branch is taken if flag[xx] = y // // xx | flag // ------------- // 00 | negative (N) // 01 | overflow (V) // 10 | carry (C) // 11 | zero (Z) // // so, all branch instructions can // be consolidated into one handler: // /**/ bool branch(u8 instr, u16 addr) { /**/ u8 xx = instr >> 6; /**/ bool y = instr & 0b00100000; /**/ /**/ switch(xx) { /**/ case 0: return y == this->reg.p.n; /**/ case 1: return y == this->reg.p.v; /**/ case 2: return y == this->reg.p.c; /**/ case 3: return y == this->reg.p.z; /**/ } /**/ /**/ assert(false); /**/ return false; /**/ } BPL 10 000 10000 rel BMI 30 001 10000 rel BVC 50 010 10000 rel BVS 70 011 10000 rel BCC 90 100 10000 rel BCS b0 101 10000 rel BNE d0 110 10000 rel BEQ f0 111 10000 rel /*==== Regular Instructions ====*/ // cc = 00 // aaa | op // ----|---- // 000 | ... // 001 | BIT // 010 | JMP // 011 | ... // 100 | STY // 101 | LDY // 110 | CPY // 111 | CPX // bbb | addr mode // ----|----------- // 000 | # // 001 | zpg // 010 | impl // 011 | abs // 100 | rel // 101 | zpg,X // 110 | impl // 111 | abs,X // BPL 10 000 100 00 rel // BMI 30 001 100 00 rel // BVC 50 010 100 00 rel // BVS 70 011 100 00 rel // BCC 90 100 100 00 rel // BCS b0 101 100 00 rel // BNE d0 110 100 00 rel // BEQ f0 111 100 00 rel LDY a0 101 000 00 # CPY c0 110 000 00 # CPX e0 111 000 00 # BIT 24 001 001 00 zpg STY 84 100 001 00 zpg LDY a4 101 001 00 zpg CPY c4 110 001 00 zpg CPX e4 111 001 00 zpg PHP 08 000 010 00 impl PLP 28 001 010 00 impl PHA 48 010 010 00 impl PLA 68 011 010 00 impl DEY 88 100 010 00 impl TAY a8 101 010 00 impl INY c8 110 010 00 impl INX e8 111 010 00 impl BIT 2c 001 011 00 abs JMP 4c 010 011 00 abs // JMP 6c 011 011 00 ind STY 8c 100 011 00 abs LDY ac 101 011 00 abs CPY cc 110 011 00 abs CPX ec 111 011 00 abs STY 94 100 101 00 zpg,X LDY b4 101 101 00 zpg,X CLC 18 000 110 00 impl SEC 38 001 110 00 impl CLI 58 010 110 00 impl SEI 78 011 110 00 impl TYA 98 100 110 00 impl CLV b8 101 110 00 impl CLD d8 110 110 00 impl SED f8 111 110 00 impl LDY bc 101 111 00 abs,X // cc = 01 // aaa | op // ----|----- // 000 | ORA // 001 | AND // 010 | EOR // 011 | ADC // 100 | STA // 101 | LDA // 110 | CMP // 111 | SBC // bbb | addr mode // ----|----------- // 000 | X,ind // 001 | zpg // 010 | # // 011 | abs // 100 | ind,Y // 101 | zpg,X // 110 | abs,Y // 111 | abs,X ORA 01 000 000 01 X,ind AND 21 001 000 01 X,ind EOR 41 010 000 01 X,ind ADC 61 011 000 01 X,ind STA 81 100 000 01 X,ind LDA a1 101 000 01 X,ind CMP c1 110 000 01 X,ind SBC e1 111 000 01 X,ind ORA 05 000 001 01 zpg AND 25 001 001 01 zpg EOR 45 010 001 01 zpg ADC 65 011 001 01 zpg STA 85 100 001 01 zpg LDA a5 101 001 01 zpg CMP c5 110 001 01 zpg SBC e5 111 001 01 zpg ORA 09 000 010 01 # AND 29 001 010 01 # EOR 49 010 010 01 # ADC 69 011 010 01 # // STA # is missing LDA a9 101 010 01 # CMP c9 110 010 01 # SBC e9 111 010 01 # ORA 0d 000 011 01 abs AND 2d 001 011 01 abs EOR 4d 010 011 01 abs ADC 6d 011 011 01 abs STA 8d 100 011 01 abs LDA ad 101 011 01 abs CMP cd 110 011 01 abs SBC ed 111 011 01 abs ORA 11 000 100 01 ind,Y AND 31 001 100 01 ind,Y EOR 51 010 100 01 ind,Y ADC 71 011 100 01 ind,Y STA 91 100 100 01 ind,Y LDA b1 101 100 01 ind,Y CMP d1 110 100 01 ind,Y SBC f1 111 100 01 ind,Y ORA 15 000 101 01 zpg,X AND 35 001 101 01 zpg,X EOR 55 010 101 01 zpg,X ADC 75 011 101 01 zpg,X STA 95 100 101 01 zpg,X LDA b5 101 101 01 zpg,X CMP d5 110 101 01 zpg,X SBC f5 111 101 01 zpg,X ORA 19 000 110 01 abs,Y AND 39 001 110 01 abs,Y EOR 59 010 110 01 abs,Y ADC 79 011 110 01 abs,Y STA 99 100 110 01 abs,Y LDA b9 101 110 01 abs,Y CMP d9 110 110 01 abs,Y SBC f9 111 110 01 abs,Y ORA 1d 000 111 01 abs,X AND 3d 001 111 01 abs,X EOR 5d 010 111 01 abs,X ADC 7d 011 111 01 abs,X STA 9d 100 111 01 abs,X LDA bd 101 111 01 abs,X CMP dd 110 111 01 abs,X SBC fd 111 111 01 abs,X // cc = 10 // aaa | opcode // ----|----- // 000 | ASL // 001 | ROL // 010 | LSR // 011 | ROR // 100 | STX // 101 | LDX // 110 | DEC // 111 | INC // bbb | addr mode // ----|---------- // 000 | # // 001 | zpg // 010 | A // 011 | abs // 100 | // 101 | zpg,X // 110 | impl // 111 | abs,X LDX a2 101 000 10 # ASL 06 000 001 10 zpg ROL 26 001 001 10 zpg LSR 46 010 001 10 zpg ROR 66 011 001 10 zpg STX 86 100 001 10 zpg LDX a6 101 001 10 zpg DEC c6 110 001 10 zpg INC e6 111 001 10 zpg ASL 0a 000 010 10 A ROL 2a 001 010 10 A LSR 4a 010 010 10 A ROR 6a 011 010 10 A // TXA 8a 100 010 10 impl // TAX aa 101 010 10 impl // DEX ca 110 010 10 impl // NOP ea 111 010 10 impl ASL 0e 000 011 10 abs ROL 2e 001 011 10 abs LSR 4e 010 011 10 abs ROR 6e 011 011 10 abs STX 8e 100 011 10 abs LDX ae 101 011 10 abs DEC ce 110 011 10 abs INC ee 111 011 10 abs ASL 16 000 101 10 zpg,X ROL 36 001 101 10 zpg,X LSR 56 010 101 10 zpg,X ROR 76 011 101 10 zpg,X // STX 96 100 101 10 zpg,Y // LDX b6 101 101 10 zpg,Y DEC d6 110 101 10 zpg,X INC f6 111 101 10 zpg,X TXS 9a 100 110 10 impl TSX ba 101 110 10 impl ASL 1e 000 111 10 abs,X ROL 3e 001 111 10 abs,X LSR 5e 010 111 10 abs,X ROR 7e 011 111 10 abs,X // LDX be 101 111 10 abs,Y DEC de 110 111 10 abs,X INC fe 111 111 10 abs,X // cc = 11 // Doesn't exist!