diff --git a/include/mos6502.enums.h b/include/mos6502.enums.h index 07f9c06..f2c6212 100644 --- a/include/mos6502.enums.h +++ b/include/mos6502.enums.h @@ -47,6 +47,8 @@ enum addr_mode { ABS, // absolute ABX, // absolute x-index ABY, // absolute y-index + BY2, // Consume 2 bytes (for NP2) + BY3, // Consume 3 bytes (for NP3) IMM, // immediate IMP, // implied IND, // indirect @@ -102,6 +104,8 @@ enum instruction { LDY, // LoaD Y LSR, // Logical Shift Right NOP, // NO oPeration + NP2, // No oPeration (2 bytes consumed) + NP3, // No oPeration (3 bytes consumed) ORA, // OR with Accumulator PHA, // PusH Accumulator PHP, // PusH Predicate register diff --git a/include/mos6502.h b/include/mos6502.h index c4a79c8..bf6a66e 100644 --- a/include/mos6502.h +++ b/include/mos6502.h @@ -211,6 +211,8 @@ DECL_INST(ldx); DECL_INST(ldy); DECL_INST(lsr); DECL_INST(nop); +DECL_INST(np2); +DECL_INST(np3); DECL_INST(ora); DECL_INST(pha); DECL_INST(php); diff --git a/src/mos6502.addr.c b/src/mos6502.addr.c index 54a9572..88f308b 100644 --- a/src/mos6502.addr.c +++ b/src/mos6502.addr.c @@ -19,22 +19,22 @@ */ static int addr_modes[] = { // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F - IMP, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 0x - REL, IDY, ZPG, NOA, ZPG, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, ABS, ABX, ABX, NOA, // 1x - ABS, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 2x - REL, IDY, ZPG, NOA, ZPX, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, ABX, ABX, ABX, NOA, // 3x - IMP, IDX, NOA, NOA, NOA, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 4x - REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, NOA, ABX, ABX, NOA, // 5x - IMP, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, IND, ABS, ABS, NOA, // 6x - REL, IDY, ZPG, NOA, ZPX, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, ABX, ABX, ABX, NOA, // 7x - REL, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // 8x - REL, IDY, ZPG, NOA, ZPX, ZPX, ZPY, NOA, IMP, ABY, IMP, NOA, ABS, ABX, ABX, NOA, // 9x - IMM, IDX, IMM, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // Ax - REL, IDY, ZPG, NOA, ZPX, ZPX, ZPY, NOA, IMP, ABY, IMP, NOA, ABX, ABX, ABY, NOA, // Bx - IMM, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // Cx - REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, NOA, ABX, ABX, NOA, // Dx - IMM, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // Ex - REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, NOA, ABX, ABX, NOA, // Fx + IMP, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, ABS, ABS, ABS, IMP, // 0x + REL, IDY, ZPG, IMP, ZPG, ZPX, ZPX, IMP, IMP, ABY, ACC, IMP, ABS, ABX, ABX, IMP, // 1x + ABS, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, ABS, ABS, ABS, IMP, // 2x + REL, IDY, ZPG, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABY, ACC, IMP, ABX, ABX, ABX, IMP, // 3x + IMP, IDX, BY2, IMP, BY2, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, ABS, ABS, ABS, IMP, // 4x + REL, IDY, ZPG, IMP, BY2, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, BY3, ABX, ABX, IMP, // 5x + IMP, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, IND, ABS, ABS, IMP, // 6x + REL, IDY, ZPG, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, ABX, ABX, ABX, IMP, // 7x + REL, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // 8x + REL, IDY, ZPG, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABY, IMP, IMP, ABS, ABX, ABX, IMP, // 9x + IMM, IDX, IMM, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // Ax + REL, IDY, ZPG, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABY, IMP, IMP, ABX, ABX, ABY, IMP, // Bx + IMM, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // Cx + REL, IDY, ZPG, IMP, BY2, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, BY3, ABX, ABX, IMP, // Dx + IMM, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // Ex + REL, IDY, ZPG, IMP, BY2, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, BY3, ABX, ABX, IMP, // Fx }; /* diff --git a/src/mos6502.c b/src/mos6502.c index 6e0f123..3a05b41 100644 --- a/src/mos6502.c +++ b/src/mos6502.c @@ -27,22 +27,22 @@ */ static int instructions[] = { // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F - BRK, ORA, BAD, BAD, TSB, ORA, ASL, BAD, PHP, ORA, ASL, BAD, TSB, ORA, ASL, BAD, // 0x - BPL, ORA, ORA, BAD, TRB, ORA, ASL, BAD, CLC, ORA, INC, BAD, TRB, ORA, ASL, BAD, // 1x - JSR, AND, BAD, BAD, BIT, AND, ROL, BAD, PLP, AND, ROL, BAD, BIT, AND, ROL, BAD, // 2x - BMI, AND, AND, BAD, BIT, AND, ROL, BAD, SEC, AND, DEC, BAD, BIT, AND, ROL, BAD, // 3x - RTI, EOR, BAD, BAD, BAD, EOR, LSR, BAD, PHA, EOR, LSR, BAD, JMP, EOR, LSR, BAD, // 4x - BVC, EOR, EOR, BAD, BAD, EOR, LSR, BAD, CLI, EOR, PHY, BAD, BAD, EOR, LSR, BAD, // 5x - RTS, ADC, BAD, BAD, STZ, ADC, ROR, BAD, PLA, ADC, ROR, BAD, JMP, ADC, ROR, BAD, // 6x - BVS, ADC, ADC, BAD, STZ, ADC, ROR, BAD, SEI, ADC, PLY, BAD, JMP, ADC, ROR, BAD, // 7x - BRA, STA, BAD, BAD, STY, STA, STX, BAD, DEY, BIM, TXA, BAD, STY, STA, STX, BAD, // 8x - BCC, STA, STA, BAD, STY, STA, STX, BAD, TYA, STA, TXS, BAD, STZ, STA, STZ, BAD, // 9x - LDY, LDA, LDX, BAD, LDY, LDA, LDX, BAD, TAY, LDA, TAX, BAD, LDY, LDA, LDX, BAD, // Ax - BCS, LDA, LDA, BAD, LDY, LDA, LDX, BAD, CLV, LDA, TSX, BAD, LDY, LDA, LDX, BAD, // Bx - CPY, CMP, BAD, BAD, CPY, CMP, DEC, BAD, INY, CMP, DEX, BAD, CPY, CMP, DEC, BAD, // Cx - BNE, CMP, CMP, BAD, BAD, CMP, DEC, BAD, CLD, CMP, PHX, BAD, BAD, CMP, DEC, BAD, // Dx - CPX, SBC, BAD, BAD, CPX, SBC, INC, BAD, INX, SBC, NOP, BAD, CPX, SBC, INC, BAD, // Ex - BEQ, SBC, SBC, BAD, BAD, SBC, INC, BAD, SED, SBC, PLX, BAD, BAD, SBC, INC, BAD, // Fx + BRK, ORA, NP2, NOP, TSB, ORA, ASL, NOP, PHP, ORA, ASL, NOP, TSB, ORA, ASL, NOP, // 0x + BPL, ORA, ORA, NOP, TRB, ORA, ASL, NOP, CLC, ORA, INC, NOP, TRB, ORA, ASL, NOP, // 1x + JSR, AND, NP2, NOP, BIT, AND, ROL, NOP, PLP, AND, ROL, NOP, BIT, AND, ROL, NOP, // 2x + BMI, AND, AND, NOP, BIT, AND, ROL, NOP, SEC, AND, DEC, NOP, BIT, AND, ROL, NOP, // 3x + RTI, EOR, NP2, NOP, NP2, EOR, LSR, NOP, PHA, EOR, LSR, NOP, JMP, EOR, LSR, NOP, // 4x + BVC, EOR, EOR, NOP, NP2, EOR, LSR, NOP, CLI, EOR, PHY, NOP, NP3, EOR, LSR, NOP, // 5x + RTS, ADC, NP2, NOP, STZ, ADC, ROR, NOP, PLA, ADC, ROR, NOP, JMP, ADC, ROR, NOP, // 6x + BVS, ADC, ADC, NOP, STZ, ADC, ROR, NOP, SEI, ADC, PLY, NOP, JMP, ADC, ROR, NOP, // 7x + BRA, STA, NP2, NOP, STY, STA, STX, NOP, DEY, BIM, TXA, NOP, STY, STA, STX, NOP, // 8x + BCC, STA, STA, NOP, STY, STA, STX, NOP, TYA, STA, TXS, NOP, STZ, STA, STZ, NOP, // 9x + LDY, LDA, LDX, NOP, LDY, LDA, LDX, NOP, TAY, LDA, TAX, NOP, LDY, LDA, LDX, NOP, // Ax + BCS, LDA, LDA, NOP, LDY, LDA, LDX, NOP, CLV, LDA, TSX, NOP, LDY, LDA, LDX, NOP, // Bx + CPY, CMP, NP2, NOP, CPY, CMP, DEC, NOP, INY, CMP, DEX, NOP, CPY, CMP, DEC, NOP, // Cx + BNE, CMP, CMP, NOP, NP2, CMP, DEC, NOP, CLD, CMP, PHX, NOP, NP3, CMP, DEC, NOP, // Dx + CPX, SBC, NP2, NOP, CPX, SBC, INC, NOP, INX, SBC, NOP, NOP, CPX, SBC, INC, NOP, // Ex + BEQ, SBC, SBC, NOP, NP2, SBC, INC, NOP, SED, SBC, PLX, NOP, NP3, SBC, INC, NOP, // Fx }; /* @@ -94,6 +94,8 @@ static mos6502_instruction_handler instruction_handlers[] = { INST_HANDLER(ldy), INST_HANDLER(lsr), INST_HANDLER(nop), + INST_HANDLER(np2), + INST_HANDLER(np3), INST_HANDLER(ora), INST_HANDLER(pha), INST_HANDLER(php), @@ -132,22 +134,22 @@ static mos6502_instruction_handler instruction_handlers[] = { */ static int cycles[] = { // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F - 7, 6, 0, 0, 5, 3, 5, 0, 3, 2, 2, 0, 6, 4, 6, 0, // 0x - 2, 5, 5, 0, 5, 4, 6, 0, 2, 4, 2, 0, 6, 4, 6, 0, // 1x - 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0, // 2x - 2, 5, 5, 0, 4, 4, 6, 0, 2, 4, 2, 0, 4, 4, 6, 0, // 3x - 6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0, // 4x - 2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 3, 0, 0, 4, 6, 0, // 5x - 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0, // 6x - 2, 5, 5, 0, 4, 4, 6, 0, 2, 4, 4, 0, 6, 4, 6, 0, // 7x - 3, 6, 0, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0, // 8x - 2, 6, 5, 0, 4, 4, 4, 0, 2, 5, 2, 0, 4, 5, 5, 0, // 9x - 2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0, // Ax - 2, 5, 5, 0, 4, 4, 4, 0, 2, 4, 2, 0, 4, 4, 4, 0, // Bx - 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 3, 0, // Cx - 2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 3, 0, 0, 4, 7, 0, // Dx - 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0, // Ex - 2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 4, 0, 0, 4, 7, 0, // Fx + 7, 6, 2, 1, 5, 3, 5, 1, 3, 2, 2, 1, 6, 4, 6, 1, // 0x + 2, 5, 5, 1, 5, 4, 6, 1, 2, 4, 2, 1, 6, 4, 6, 1, // 1x + 6, 6, 2, 1, 3, 3, 5, 1, 4, 2, 2, 1, 4, 4, 6, 1, // 2x + 2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 2, 1, 4, 4, 6, 1, // 3x + 6, 6, 2, 1, 3, 3, 5, 1, 3, 2, 2, 1, 3, 4, 6, 1, // 4x + 2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 3, 1, 8, 4, 6, 1, // 5x + 6, 6, 2, 1, 3, 3, 5, 1, 4, 2, 2, 1, 5, 4, 6, 1, // 6x + 2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 4, 1, 6, 4, 6, 1, // 7x + 3, 6, 2, 1, 3, 3, 3, 1, 2, 2, 2, 1, 4, 4, 4, 1, // 8x + 2, 6, 5, 1, 4, 4, 4, 1, 2, 5, 2, 1, 4, 5, 5, 1, // 9x + 2, 6, 2, 1, 3, 3, 3, 1, 2, 2, 2, 1, 4, 4, 4, 1, // Ax + 2, 5, 5, 1, 4, 4, 4, 1, 2, 4, 2, 1, 4, 4, 4, 1, // Bx + 2, 6, 2, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 3, 1, // Cx + 2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 3, 1, 4, 4, 7, 1, // Dx + 2, 6, 2, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 6, 1, // Ex + 2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 4, 1, 4, 4, 7, 1, // Fx }; /* @@ -462,6 +464,8 @@ mos6502_would_jump(int inst_code) inst_code == BVS || inst_code == JMP || inst_code == JSR || + inst_code == NP2 || // this is KIND of a hack, but it works! + inst_code == NP3 || // these jump ahead by 2 or 3 bytes (respectively) inst_code == RTS || inst_code == RTI; } diff --git a/src/mos6502.dis.c b/src/mos6502.dis.c index 0e6b637..8a28e86 100644 --- a/src/mos6502.dis.c +++ b/src/mos6502.dis.c @@ -78,6 +78,8 @@ static char *instruction_strings[] = { "LDY", "LSR", "NOP", + "NP2", + "NP3", "ORA", "PHA", "PHP", @@ -231,11 +233,17 @@ int mos6502_dis_expected_bytes(int addr_mode) { switch (addr_mode) { + // This is kind of not a real address mode? We use it to tell + // the code to skip three bytes for opcodes that use it. + case BY3: + return 3; + // These are 16-bit operands, because they work with absolute // addresses in memory. case ABS: case ABY: case ABX: + case BY2: // (also not a real address mode!) case IND: return 2; diff --git a/src/mos6502.exec.c b/src/mos6502.exec.c index aba595e..0890b70 100644 --- a/src/mos6502.exec.c +++ b/src/mos6502.exec.c @@ -68,6 +68,14 @@ DEFINE_INST(nop) // do nothing } +DEFINE_INST(np2) +{ +} + +DEFINE_INST(np3) +{ +} + /* * Here we return from an interrupt, which effectively resets the PC * register to the last value on the stack. diff --git a/tests/mos6502.c b/tests/mos6502.c index 2d13c80..060eafb 100644 --- a/tests/mos6502.c +++ b/tests/mos6502.c @@ -124,6 +124,8 @@ Test(mos6502, would_jump) case BVS: case JMP: case JSR: + case NP2: + case NP3: case RTS: case RTI: expect = true; diff --git a/tests/mos6502.exec.c b/tests/mos6502.exec.c index 72419f1..2c0402d 100644 --- a/tests/mos6502.exec.c +++ b/tests/mos6502.exec.c @@ -45,6 +45,13 @@ Test(mos6502_exec, jsr) cr_assert_eq(mos6502_pop_stack(cpu), 125); } +/* + * In addition to nop, we also have np2 and np3 which also do nothing. + * We're just passing on those. + * + * Test(mos6502_exec, np2) + * Test(mos6502_exec, np3) + */ Test(mos6502_exec, nop) { // currently this test does nothing -- we _should_ test to see if we