From 19aea5244bb82515b956016a91d361bf1e3dbc38 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Wed, 17 Jan 2018 22:17:08 +0000 Subject: [PATCH] The vector of instructions was good, but a switch is fastest and probably easiest to read/modify. (Running at 101Mz, 32M instructions per second) Signed-off-by: Adrian Conlon --- M6502/inc/mos6502.h | 12 - M6502/src/mos6502.cpp | 551 +++++++++++++++++++++--------------------- 2 files changed, 273 insertions(+), 290 deletions(-) diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index 22d170f..20d4c44 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -128,10 +128,6 @@ namespace EightBit { // Addressing modes, read - uint8_t AM_A() { - return A(); - } - uint8_t AM_Immediate() { return fetchByte(); } @@ -326,14 +322,6 @@ namespace EightBit { uint8_t s; // stack pointer uint8_t p; // processor status - typedef std::function delegate_t; - struct operation_t { - int timing = 0; - delegate_t method; - }; - - std::vector m_operations; - PinLevel m_soLine = Low; }; } \ No newline at end of file diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index a6444af..f6ba620 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -4,281 +4,6 @@ EightBit::MOS6502::MOS6502(Bus& bus) : Processor(bus) { - m_operations = { - /* 0 */ - /* 0 */ { 7, [this]() { BRK(); } }, - /* 1 */ { 6, [this]() { ORA(AM_IndexedIndirectX()); } }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 8, [this]() { SLO(AM_IndexedIndirectX()); } }, // *SLO - /* 4 */ { 3, [this]() { AM_ZeroPage(); } }, // *DOP - /* 5 */ { 3, [this]() { ORA(AM_ZeroPage()); } }, - /* 6 */ { 5, [this]() { setByte(ASL(AM_ZeroPage())); } }, - /* 7 */ { 5, [this]() { SLO(AM_ZeroPage()); } }, // *SLO - /* 8 */ { 3, [this]() { PHP(); } }, - /* 9 */ { 2, [this]() { ORA(AM_Immediate()); } }, - /* a */ { 2, [this]() { A() = ASL(A()); } }, - /* b */ { 0, []() { } }, - /* c */ { 4, [this]() { AM_Absolute(); } }, // *TOP - /* d */ { 4, [this]() { ORA(AM_Absolute()); } }, - /* e */ { 6, [this]() { setByte(ASL(AM_Absolute())); } }, - /* f */ { 6, [this]() { SLO(AM_Absolute()); } }, // *SLO - /* 1 */ - /* 0 */ { 2, [this]() { Branch(!(P() & NF)); } }, - /* 1 */ { 5, [this]() { ORA(AM_IndirectIndexedY()); } }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 7, [this]() { SLO(AM_IndirectIndexedY()); } }, // *SLO - /* 4 */ { 4, [this]() { AM_ZeroPageX(); } }, // *DOP - /* 5 */ { 4, [this]() { ORA(AM_ZeroPageX()); } }, - /* 6 */ { 6, [this]() { setByte(ASL(AM_ZeroPageX())); } }, - /* 7 */ { 6, [this]() { SLO(AM_ZeroPageX()); } }, // *SLO - /* 8 */ { 2, [this]() { clearFlag(P(), CF); } }, - /* 9 */ { 4, [this]() { ORA(AM_AbsoluteY()); } }, - /* a */ { 2, []() { } }, // *NOP - /* b */ { 6, [this]() { SLO(AM_AbsoluteY()); } }, // *SLO - /* c */ { 4, [this]() { AM_AbsoluteX(); } }, // *TOP - /* d */ { 4, [this]() { ORA(AM_AbsoluteX()); } }, - /* e */ { 7, [this]() { setByte(ASL(AM_AbsoluteX())); } }, - /* f */ { 6, [this]() { SLO(AM_AbsoluteX()); } }, // *SLO - /* 2 */ - /* 0 */ { 6, [this]() { JSR_abs(); } }, - /* 1 */ { 6, [this]() { ANDA(AM_IndexedIndirectX()); } }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 8, [this]() { RLA(AM_IndexedIndirectX()); } }, // *RLA - /* 4 */ { 3, [this]() { BIT(AM_ZeroPage()); } }, - /* 5 */ { 3, [this]() { ANDA(AM_ZeroPage()); } }, - /* 6 */ { 5, [this]() { setByte(ROL(AM_ZeroPage())); } }, - /* 7 */ { 5, [this]() { RLA(AM_ZeroPage()); } }, // *RLA - /* 8 */ { 4, [this]() { PLP(); } }, - /* 9 */ { 2, [this]() { ANDA(AM_Immediate()); } }, - /* a */ { 2, [this]() { A() = ROL(A()); } }, - /* b */ { 0, []() { } }, - /* c */ { 4, [this]() { BIT(AM_Absolute()); } }, - /* d */ { 4, [this]() { ANDA(AM_Absolute()); } }, - /* e */ { 6, [this]() { setByte(ROL(AM_Absolute())); } }, - /* f */ { 6, [this]() { RLA(AM_Absolute()); } }, // *RLA - /* 3 */ - /* 0 */ { 2, [this]() { Branch(!!(P() & NF)); } }, - /* 1 */ { 5, [this]() { ANDA(AM_IndirectIndexedY()); } }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 7, [this]() { RLA(AM_IndirectIndexedY()); } }, // *RLA - /* 4 */ { 4, [this]() { AM_ZeroPageX(); } }, // *DOP - /* 5 */ { 4, [this]() { ANDA(AM_ZeroPageX()); } }, - /* 6 */ { 6, [this]() { setByte(ROL(AM_ZeroPageX())); } }, - /* 7 */ { 6, [this]() { RLA(AM_ZeroPageX()); } }, // *RLA - /* 8 */ { 2, [this]() { setFlag(P(), CF); } }, - /* 9 */ { 4, [this]() { ANDA(AM_AbsoluteY()); } }, - /* a */ { 2, []() { } }, // *NOP - /* b */ { 6, [this]() { RLA(AM_AbsoluteY()); } }, // *RLA - /* c */ { 4, [this]() { AM_AbsoluteX(); } }, // *TOP - /* d */ { 4, [this]() { ANDA(AM_AbsoluteX()); } }, - /* e */ { 7, [this]() { setByte(ROL(AM_AbsoluteX())); } }, - /* f */ { 6, [this]() { RLA(AM_AbsoluteX()); } }, // *RLA - /* 4 */ - /* 0 */ { 6, [this]() { RTI(); } }, - /* 1 */ { 6, [this]() { EORA(AM_IndexedIndirectX()); } }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 8, [this]() { SRE(AM_IndexedIndirectX()); } }, // *SRE - /* 4 */ { 3, [this]() { AM_ZeroPage(); } }, // *DOP - /* 5 */ { 3, [this]() { EORA(AM_ZeroPage()); } }, - /* 6 */ { 5, [this]() { setByte(LSR(AM_ZeroPage())); } }, - /* 7 */ { 5, [this]() { SRE(AM_ZeroPage()); } }, // *SRE - /* 8 */ { 3, [this]() { push(A()); } }, - /* 9 */ { 2, [this]() { EORA(AM_Immediate()); } }, - /* a */ { 2, [this]() { A() = LSR(A()); } }, - /* b */ { 0, []() { } }, - /* c */ { 3, [this]() { JMP_abs(); } }, - /* d */ { 4, [this]() { EORA(AM_Absolute()); } }, - /* e */ { 6, [this]() { setByte(LSR(AM_Absolute())); } }, - /* f */ { 6, [this]() { SRE(AM_Absolute()); } }, // *SRE - /* 5 */ - /* 0 */ { 2, [this]() { Branch(!(P() & VF)); } }, // *SRE - /* 1 */ { 5, [this]() { EORA(AM_IndirectIndexedY()); } }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 7, [this]() { SRE(AM_IndirectIndexedY()); } }, // *SRE - /* 4 */ { 4, [this]() { AM_ZeroPage(); } }, // *DOP - /* 5 */ { 4, [this]() { EORA(AM_ZeroPageX()); } }, - /* 6 */ { 6, [this]() { setByte(LSR(AM_ZeroPageX())); } }, - /* 7 */ { 6, [this]() { SRE(AM_ZeroPageX()); } }, // *SRE - /* 8 */ { 2, [this]() { clearFlag(P(), IF); } }, - /* 9 */ { 4, [this]() { EORA(AM_AbsoluteY()); } }, - /* a */ { 2, []() { } }, // *NOP - /* b */ { 6, [this]() { SRE(AM_AbsoluteY()); } }, // *SRE - /* c */ { 4, [this]() { AM_AbsoluteX(); } }, // *TOP - /* d */ { 4, [this]() { EORA(AM_AbsoluteX()); } }, - /* e */ { 7, [this]() { setByte(LSR(AM_AbsoluteX())); } }, - /* f */ { 6, [this]() { SRE(AM_AbsoluteX()); } }, // *SRE - /* 6 */ - /* 0 */ { 6, [this]() { RTS(); } }, - /* 1 */ { 6, [this]() { A() = ADC(A(), AM_IndexedIndirectX());} }, - /* 2 */ { 0, []() { } }, - /* 3 */ { 8, [this]() { RRA(AM_IndexedIndirectX()); } }, // *RRA - /* 4 */ { 3, [this]() { AM_ZeroPage(); } }, // *DOP - /* 5 */ { 3, [this]() { A() = ADC(A(), AM_ZeroPage()); } }, - /* 6 */ { 5, [this]() { setByte(ROR(AM_ZeroPage())); } }, - /* 7 */ { 5, [this]() { RRA(AM_ZeroPage()); } }, // *RRA - /* 8 */ { 4, [this]() { adjustNZ(A() = pop()); } }, - /* 9 */ { 2, [this]() { A() = ADC(A(), AM_Immediate()); } }, // ADC # - /* a */ { 2, [this]() { A() = ROR(A()); } }, // ROR A - /* b */ { 0, []() { } }, - /* c */ { 5, [this]() { JMP_ind(); } }, // JMP ind - /* d */ { 4, [this]() { A() = ADC(A(), AM_Absolute()); } }, // ADC abs - /* e */ { 6, [this]() { setByte(ROR(AM_Absolute())); } }, // ROR abs - /* f */ { 6, [this]() { RRA(AM_Absolute()); } }, // *RRA - /* 7 */ - /* 0 */ { 2, [this]() { Branch(!!(P() & VF)); } }, - /* 1 */ { 5, [this]() { A() = ADC(A(), AM_IndirectIndexedY());} }, // ADC ind,Y - /* 2 */ { 0, []() { } }, - /* 3 */ { 7, [this]() { RRA(AM_IndirectIndexedY()); } }, // *RRA - /* 4 */ { 4, [this]() { AM_ZeroPageX(); } }, // *DOP - /* 5 */ { 4, [this]() { A() = ADC(A(), AM_ZeroPageX()); } }, - /* 6 */ { 6, [this]() { setByte(ROR(AM_ZeroPageX())); } }, - /* 7 */ { 6, [this]() { RRA(AM_ZeroPageX()); } }, // *RRA - /* 8 */ { 2, [this]() { setFlag(P(), IF); } }, - /* 9 */ { 4, [this]() { A() = ADC(A(), AM_AbsoluteY()); } }, // ADC abs,Y - /* a */ { 2, [this]() { } }, // *NOP - /* b */ { 6, [this]() { RRA(AM_AbsoluteY()); } }, // *RRA - /* c */ { 4, [this]() { AM_AbsoluteX(); } }, // *TOP - /* d */ { 4, [this]() { A() = ADC(A(), AM_AbsoluteX()); } }, // ADC abs,X - /* e */ { 7, [this]() { setByte(ROR(AM_AbsoluteX())); } }, // ROR abs,X - /* f */ { 6, [this]() { RRA(AM_AbsoluteX()); } }, // *RRA - /* 8 */ - /* 0 */ { 2, [this]() { AM_Immediate(); } }, // *DOP - /* 1 */ { 6, [this]() { AM_IndexedIndirectX(A()); } }, - /* 2 */ { 2, [this]() { AM_Immediate(); } }, // *DOP - /* 3 */ { 6, [this]() { AM_IndexedIndirectX(A() & X()); } }, // *SAX - /* 4 */ { 3, [this]() { AM_ZeroPage(Y()); } }, // STY zpg - /* 5 */ { 3, [this]() { AM_ZeroPage(A()); } }, - /* 6 */ { 3, [this]() { AM_ZeroPage(X()); } }, - /* 7 */ { 3, [this]() { AM_ZeroPage(A() & X()); } }, // *SAX - /* 8 */ { 2, [this]() { adjustNZ(--Y()); } }, - /* 9 */ { 2, [this]() { AM_Immediate(); } }, // *DOP - /* a */ { 2, [this]() { adjustNZ(A() = X()); } }, // TXA impl - /* b */ { 0, []() { } }, - /* c */ { 4, [this]() { AM_Absolute(Y()); } }, // STY abs - /* d */ { 4, [this]() { AM_Absolute(A()); } }, - /* e */ { 4, [this]() { AM_Absolute(X()); } }, // STX abs - /* f */ { 4, [this]() { AM_Absolute(A() & X()); } }, // *SAX - /* 9 */ - /* 0 */ { 2, [this]() { Branch(!(P() & CF)); } }, - /* 1 */ { 6, [this]() { AM_IndirectIndexedY(A()); } }, // STA ind,Y - /* 2 */ { 0, []() { } }, - /* 3 */ { 0, []() { } }, - /* 4 */ { 4, [this]() { AM_ZeroPageX(Y()); } }, // STY zpg,X - /* 5 */ { 4, [this]() { AM_ZeroPageX(A()); } }, - /* 6 */ { 4, [this]() { AM_ZeroPageY(X()); } }, - /* 7 */ { 4, [this]() { AM_ZeroPageY(A() & X()); } }, // *SAX - /* 8 */ { 2, [this]() { adjustNZ(A() = Y()); } }, - /* 9 */ { 5, [this]() { AM_AbsoluteY(A()); } }, // STA abs,Y - /* a */ { 2, [this]() { S() = X(); } }, - /* b */ { 0, []() { } }, - /* c */ { 0, []() { } }, - /* d */ { 5, [this]() { AM_AbsoluteX(A()); } }, // STA abs,X - /* e */ { 0, []() { } }, - /* f */ { 0, []() { } }, - /* A */ - /* 0 */ { 2, [this]() { adjustNZ(Y() = AM_Immediate()); } }, - /* 1 */ { 6, [this]() { adjustNZ(A() = AM_IndexedIndirectX());} }, - /* 2 */ { 2, [this]() { adjustNZ(X() = AM_Immediate()); } }, - /* 3 */ { 6, [this]() { LAX(AM_IndexedIndirectX()); } }, // *LAX - /* 4 */ { 3, [this]() { adjustNZ(Y() = AM_ZeroPage()); } }, // LDY zpg - /* 5 */ { 3, [this]() { adjustNZ(A() = AM_ZeroPage()); } }, - /* 6 */ { 3, [this]() { adjustNZ(X() = AM_ZeroPage()); } }, - /* 7 */ { 3, [this]() { LAX(AM_ZeroPage()); } }, // *LAX - /* 8 */ { 2, [this]() { adjustNZ(Y() = A()); } }, - /* 9 */ { 2, [this]() { adjustNZ(A() = AM_Immediate()); } }, - /* a */ { 2, [this]() { adjustNZ(X() = A()); } }, // TAX imp - /* b */ { 0, []() { } }, - /* c */ { 4, [this]() { adjustNZ(Y() = AM_Absolute()); } }, // LDY abs - /* d */ { 4, [this]() { adjustNZ(A() = AM_Absolute()); } }, // LDA abs - /* e */ { 4, [this]() { adjustNZ(X() = AM_Absolute()); } }, // LDX abs - /* f */ { 4, [this]() { LAX(AM_Absolute()); } }, // *LAX - /* B */ - /* 0 */ { 2, [this]() { Branch(!!(P() & CF)); } }, - /* 1 */ { 5, [this]() { adjustNZ(A() = AM_IndirectIndexedY());} }, // LDA ind,Y - /* 2 */ { 0, []() { } }, - /* 3 */ { 5, [this]() { LAX(AM_IndirectIndexedY()); } }, // *LAX - /* 4 */ { 4, [this]() { adjustNZ(Y() = AM_ZeroPageX()); } }, // LDY zpg,X - /* 5 */ { 4, [this]() { adjustNZ(A() = AM_ZeroPageX()); } }, - /* 6 */ { 4, [this]() { adjustNZ(X() = AM_ZeroPageY()); } }, - /* 7 */ { 4, [this]() { LAX(AM_ZeroPageY()); } }, // *LAX - /* 8 */ { 2, [this]() { clearFlag(P(), VF); } }, - /* 9 */ { 4, [this]() { adjustNZ(A() = AM_AbsoluteY()); } }, // LDA abs,Y - /* a */ { 2, [this]() { adjustNZ(X() = S()); } }, // TSX impl - /* b */ { 0, []() { } }, - /* c */ { 4, [this]() { adjustNZ(Y() = AM_AbsoluteX()); } }, // LDY abs,X - /* d */ { 4, [this]() { adjustNZ(A() = AM_AbsoluteX()); } }, // LDA abs,X - /* e */ { 4, [this]() { adjustNZ(X() = AM_AbsoluteY()); } }, // LDX abs,Y - /* f */ { 4, [this]() { LAX(AM_AbsoluteY()); } }, // *LAX - /* C */ - /* 0 */ { 2, [this]() { CMP(Y(), AM_Immediate()); } }, - /* 1 */ { 6, [this]() { CMP(A(), AM_IndexedIndirectX()); } }, - /* 2 */ { 2, [this]() { AM_Immediate(); } }, // *DOP - /* 3 */ { 8, [this]() { DCP(AM_IndexedIndirectX()); } }, // *DCP - /* 4 */ { 3, [this]() { CMP(Y(), AM_ZeroPage()); } }, // CPY zpg - /* 5 */ { 3, [this]() { CMP(A(), AM_ZeroPage()); } }, - /* 6 */ { 5, [this]() { setByte(DEC(AM_ZeroPage())); } }, - /* 7 */ { 5, [this]() { DCP(AM_ZeroPage()); } }, // *DCP - /* 8 */ { 2, [this]() { adjustNZ(++Y()); } }, - /* 9 */ { 2, [this]() { CMP(A(), AM_Immediate()); } }, // CMP # - /* a */ { 2, [this]() { adjustNZ(--X()); } }, - /* b */ { 0, []() { } }, - /* c */ { 4, [this]() { CMP(Y(), AM_Absolute()); } }, // CPY abs - /* d */ { 4, [this]() { CMP(A(), AM_Absolute()); } }, // CMP abs - /* e */ { 6, [this]() { setByte(DEC(AM_Absolute())); } }, // DEC abs - /* f */ { 6, [this]() { DCP(AM_Absolute()); } }, // *DCP - /* D */ - /* 0 */ { 2, [this]() { Branch(!(P() & ZF)); } }, - /* 1 */ { 5, [this]() { CMP(A(), AM_IndirectIndexedY()); } }, // CMP ind,Y - /* 2 */ { 0, []() { } }, - /* 3 */ { 7, [this]() { DCP(AM_IndirectIndexedY()); } }, // *DCP - /* 4 */ { 4, [this]() { AM_ZeroPageX(); } }, // *DOP - /* 5 */ { 4, [this]() { CMP(A(), AM_ZeroPageX()); } }, - /* 6 */ { 6, [this]() { setByte(DEC(AM_ZeroPageX())); } }, - /* 7 */ { 6, [this]() { DCP(AM_ZeroPageX()); } }, // *DCP - /* 8 */ { 2, [this]() { clearFlag(P(), DF); } }, - /* 9 */ { 4, [this]() { CMP(A(), AM_AbsoluteY()); } }, // CMP abs,Y - /* a */ { 2, [this]() { } }, // *NOP - /* b */ { 6, [this]() { DCP(AM_AbsoluteY()); } }, // *DCP - /* c */ { 4, [this]() { AM_AbsoluteX(); } }, // *TOP - /* d */ { 4, [this]() { CMP(A(), AM_AbsoluteX()); } }, // CMP abs,X - /* e */ { 7, [this]() { setByte(DEC(AM_AbsoluteX())); } }, - /* f */ { 6, [this]() { DCP(AM_AbsoluteX()); } }, // *DCP - /* E */ - /* 0 */ { 2, [this]() { CMP(X(), AM_Immediate()); } }, - /* 1 */ { 6, [this]() { A() = SBC(A(), AM_IndexedIndirectX());} }, - /* 2 */ { 2, [this]() { AM_Immediate(); } }, // *DOP - /* 3 */ { 8, [this]() { ISB(AM_IndexedIndirectX()); } }, // *ISB - /* 4 */ { 3, [this]() { CMP(X(), AM_ZeroPage()); } }, // CPX zpg - /* 5 */ { 3, [this]() { A() = SBC(A(), AM_ZeroPage()); } }, - /* 6 */ { 5, [this]() { setByte(INC(AM_ZeroPage())); } }, - /* 7 */ { 5, [this]() { ISB(AM_ZeroPage()); } }, // *ISB - /* 8 */ { 2, [this]() { adjustNZ(++X()); } }, - /* 9 */ { 2, [this]() { A() = SBC(A(), AM_Immediate()); } }, // SBC # - /* a */ { 2, [this]() { } }, // NOP - /* b */ { 2, [this]() { A() = SBC(A(), AM_Immediate()); } }, // *SBC - /* c */ { 4, [this]() { CMP(X(), AM_Absolute()); } }, // CPX abs - /* d */ { 4, [this]() { A() = SBC(A(), AM_Absolute()); } }, // SBC abs - /* e */ { 6, [this]() { setByte(INC(AM_Absolute())); } }, // INC abs - /* f */ { 6, [this]() { ISB(AM_Absolute()); } }, // *ISB - /* F */ - /* 0 */ { 2, [this]() { Branch(!!(P() & ZF)); } }, - /* 1 */ { 5, [this]() { A() = SBC(A(), AM_IndirectIndexedY());} }, // SBC ind,Y - /* 2 */ { 0, []() { } }, - /* 3 */ { 7, [this]() { ISB(AM_IndirectIndexedY()); } }, // *ISB - /* 4 */ { 4, [this]() { AM_ZeroPageX(); } }, // *DOP - /* 5 */ { 4, [this]() { A() = SBC(A(), AM_ZeroPageX()); } }, - /* 6 */ { 6, [this]() { setByte(INC(AM_ZeroPageX())); } }, - /* 7 */ { 6, [this]() { ISB(AM_ZeroPageX()); } }, // *ISB - /* 8 */ { 2, [this]() { setFlag(P(), DF); } }, - /* 9 */ { 4, [this]() { A() = SBC(A(), AM_AbsoluteY()); } }, // SBC abs,Y - /* a */ { 2, [this]() { } }, // *NOP - /* b */ { 6, [this]() { ISB(AM_AbsoluteY()); } }, // *ISB - /* c */ { 4, [this]() { AM_AbsoluteX(); } }, // *TOP - /* d */ { 4, [this]() { A() = SBC(A(), AM_AbsoluteX()); } }, // SBC abs,X - /* e */ { 7, [this]() { setByte(INC(AM_AbsoluteX())); } }, // INC abs,X - /* f */ { 6, [this]() { ISB(AM_AbsoluteX()); } } // *ISB - } ; - X() = Bit7; Y() = 0; A() = 0; @@ -339,10 +64,280 @@ void EightBit::MOS6502::interrupt(uint8_t vector) { int EightBit::MOS6502::execute(uint8_t cell) { - const operation_t& operation = m_operations[cell]; + switch (cell) { - addCycles(operation.timing); - (operation.method)(); + case 0x00: addCycles(7); BRK(); break; + case 0x01: addCycles(6); ORA(AM_IndexedIndirectX()); break; + case 0x02: addCycles(0); break; + case 0x03: addCycles(8); SLO(AM_IndexedIndirectX()); break; + case 0x04: addCycles(3); AM_ZeroPage(); break; + case 0x05: addCycles(3); ORA(AM_ZeroPage()); break; + case 0x06: addCycles(5); setByte(ASL(AM_ZeroPage())); break; + case 0x07: addCycles(5); SLO(AM_ZeroPage()); break; + case 0x08: addCycles(3); PHP(); break; + case 0x09: addCycles(2); ORA(AM_Immediate()); break; + case 0x0a: addCycles(2); A() = ASL(A()); break; + case 0x0b: addCycles(0); break; + case 0x0c: addCycles(4); AM_Absolute(); break; + case 0x0d: addCycles(4); ORA(AM_Absolute()); break; + case 0x0e: addCycles(6); setByte(ASL(AM_Absolute())); break; + case 0x0f: addCycles(6); SLO(AM_Absolute()); break; + + case 0x10: addCycles(2); Branch(!(P() & NF)); break; + case 0x11: addCycles(5); ORA(AM_IndirectIndexedY()); break; + case 0x12: addCycles(0); break; + case 0x13: addCycles(7); SLO(AM_IndirectIndexedY()); break; + case 0x14: addCycles(4); AM_ZeroPageX(); break; + case 0x15: addCycles(4); ORA(AM_ZeroPageX()); break; + case 0x16: addCycles(6); setByte(ASL(AM_ZeroPageX())); break; + case 0x17: addCycles(6); SLO(AM_ZeroPageX()); break; + case 0x18: addCycles(2); clearFlag(P(), CF); break; + case 0x19: addCycles(4); ORA(AM_AbsoluteY()); break; + case 0x1a: addCycles(2); break; + case 0x1b: addCycles(6); SLO(AM_AbsoluteY()); break; + case 0x1c: addCycles(4); AM_AbsoluteX(); break; + case 0x1d: addCycles(4); ORA(AM_AbsoluteX()); break; + case 0x1e: addCycles(7); setByte(ASL(AM_AbsoluteX())); break; + case 0x1f: addCycles(6); SLO(AM_AbsoluteX()); break; + + case 0x20: addCycles(6); JSR_abs(); break; + case 0x21: addCycles(6); ANDA(AM_IndexedIndirectX()); break; + case 0x22: addCycles(0); break; + case 0x23: addCycles(8); RLA(AM_IndexedIndirectX()); break; + case 0x24: addCycles(3); BIT(AM_ZeroPage()); break; + case 0x25: addCycles(3); ANDA(AM_ZeroPage()); break; + case 0x26: addCycles(5); setByte(ROL(AM_ZeroPage())); break; + case 0x27: addCycles(5); RLA(AM_ZeroPage()); break; + case 0x28: addCycles(4); PLP(); break; + case 0x29: addCycles(2); ANDA(AM_Immediate()); break; + case 0x2a: addCycles(2); A() = ROL(A()); break; + case 0x2b: addCycles(0); break; + case 0x2c: addCycles(4); BIT(AM_Absolute()); break; + case 0x2d: addCycles(4); ANDA(AM_Absolute()); break; + case 0x2e: addCycles(6); setByte(ROL(AM_Absolute())); break; + case 0x2f: addCycles(6); RLA(AM_Absolute()); break; + + case 0x30: addCycles(2); Branch(!!(P() & NF)); break; + case 0x31: addCycles(5); ANDA(AM_IndirectIndexedY()); break; + case 0x32: addCycles(0); break; + case 0x33: addCycles(7); RLA(AM_IndirectIndexedY()); break; + case 0x34: addCycles(4); AM_ZeroPageX(); break; + case 0x35: addCycles(4); ANDA(AM_ZeroPageX()); break; + case 0x36: addCycles(6); setByte(ROL(AM_ZeroPageX())); break; + case 0x37: addCycles(6); RLA(AM_ZeroPageX()); break; + case 0x38: addCycles(2); setFlag(P(), CF); break; + case 0x39: addCycles(4); ANDA(AM_AbsoluteY()); break; + case 0x3a: addCycles(2); break; + case 0x3b: addCycles(6); RLA(AM_AbsoluteY()); break; + case 0x3c: addCycles(4); AM_AbsoluteX(); break; + case 0x3d: addCycles(4); ANDA(AM_AbsoluteX()); break; + case 0x3e: addCycles(7); setByte(ROL(AM_AbsoluteX())); break; + case 0x3f: addCycles(6); RLA(AM_AbsoluteX()); break; + + case 0x40: addCycles(6); RTI(); break; + case 0x41: addCycles(6); EORA(AM_IndexedIndirectX()); break; + case 0x42: addCycles(0); break; + case 0x43: addCycles(8); SRE(AM_IndexedIndirectX()); break; + case 0x44: addCycles(3); AM_ZeroPage(); break; + case 0x45: addCycles(3); EORA(AM_ZeroPage()); break; + case 0x46: addCycles(5); setByte(LSR(AM_ZeroPage())); break; + case 0x47: addCycles(5); SRE(AM_ZeroPage()); break; + case 0x48: addCycles(3); push(A()); break; + case 0x49: addCycles(2); EORA(AM_Immediate()); break; + case 0x4a: addCycles(2); A() = LSR(A()); break; + case 0x4b: addCycles(0); break; + case 0x4c: addCycles(3); JMP_abs(); break; + case 0x4d: addCycles(4); EORA(AM_Absolute()); break; + case 0x4e: addCycles(6); setByte(LSR(AM_Absolute())); break; + case 0x4f: addCycles(6); SRE(AM_Absolute()); break; + + case 0x50: addCycles(2); Branch(!(P() & VF)); break; + case 0x51: addCycles(5); EORA(AM_IndirectIndexedY()); break; + case 0x52: addCycles(0); break; + case 0x53: addCycles(7); SRE(AM_IndirectIndexedY()); break; + case 0x54: addCycles(4); AM_ZeroPage(); break; + case 0x55: addCycles(4); EORA(AM_ZeroPageX()); break; + case 0x56: addCycles(6); setByte(LSR(AM_ZeroPageX())); break; + case 0x57: addCycles(6); SRE(AM_ZeroPageX()); break; + case 0x58: addCycles(2); clearFlag(P(), IF); break; + case 0x59: addCycles(4); EORA(AM_AbsoluteY()); break; + case 0x5a: addCycles(2); break; + case 0x5b: addCycles(6); SRE(AM_AbsoluteY()); break; + case 0x5c: addCycles(4); AM_AbsoluteX(); break; + case 0x5d: addCycles(4); EORA(AM_AbsoluteX()); break; + case 0x5e: addCycles(7); setByte(LSR(AM_AbsoluteX())); break; + case 0x5f: addCycles(6); SRE(AM_AbsoluteX()); break; + + case 0x60: addCycles(6); RTS(); break; + case 0x61: addCycles(6); A() = ADC(A(), AM_IndexedIndirectX()); break; + case 0x62: addCycles(0); break; + case 0x63: addCycles(8); RRA(AM_IndexedIndirectX()); break; + case 0x64: addCycles(3); AM_ZeroPage(); break; + case 0x65: addCycles(3); A() = ADC(A(), AM_ZeroPage()); break; + case 0x66: addCycles(5); setByte(ROR(AM_ZeroPage())); break; + case 0x67: addCycles(5); RRA(AM_ZeroPage()); break; + case 0x68: addCycles(4); adjustNZ(A() = pop()); break; + case 0x69: addCycles(2); A() = ADC(A(), AM_Immediate()); break; + case 0x6a: addCycles(2); A() = ROR(A()); break; + case 0x6b: addCycles(0); break; + case 0x6c: addCycles(5); JMP_ind(); break; + case 0x6d: addCycles(4); A() = ADC(A(), AM_Absolute()); break; + case 0x6e: addCycles(6); setByte(ROR(AM_Absolute())); break; + case 0x6f: addCycles(6); RRA(AM_Absolute()); break; + + case 0x70: addCycles(2); Branch(!!(P() & VF)); break; + case 0x71: addCycles(5); A() = ADC(A(), AM_IndirectIndexedY()); break; + case 0x72: addCycles(0); break; + case 0x73: addCycles(7); RRA(AM_IndirectIndexedY()); break; + case 0x74: addCycles(4); AM_ZeroPageX(); break; + case 0x75: addCycles(4); A() = ADC(A(), AM_ZeroPageX()); break; + case 0x76: addCycles(6); setByte(ROR(AM_ZeroPageX())); break; + case 0x77: addCycles(6); RRA(AM_ZeroPageX()); break; + case 0x78: addCycles(2); setFlag(P(), IF); break; + case 0x79: addCycles(4); A() = ADC(A(), AM_AbsoluteY()); break; + case 0x7a: addCycles(2); break; + case 0x7b: addCycles(6); RRA(AM_AbsoluteY()); break; + case 0x7c: addCycles(4); AM_AbsoluteX(); break; + case 0x7d: addCycles(4); A() = ADC(A(), AM_AbsoluteX()); break; + case 0x7e: addCycles(7); setByte(ROR(AM_AbsoluteX())); break; + case 0x7f: addCycles(6); RRA(AM_AbsoluteX()); break; + + case 0x80: addCycles(2); AM_Immediate(); break; + case 0x81: addCycles(6); AM_IndexedIndirectX(A()); break; + case 0x82: addCycles(2); AM_Immediate(); break; + case 0x83: addCycles(6); AM_IndexedIndirectX(A() & X()); break; + case 0x84: addCycles(3); AM_ZeroPage(Y()); break; + case 0x85: addCycles(3); AM_ZeroPage(A()); break; + case 0x86: addCycles(3); AM_ZeroPage(X()); break; + case 0x87: addCycles(3); AM_ZeroPage(A() & X()); break; + case 0x88: addCycles(2); adjustNZ(--Y()); break; + case 0x89: addCycles(2); AM_Immediate(); break; + case 0x8a: addCycles(2); adjustNZ(A() = X()); break; + case 0x8b: addCycles(0); break; + case 0x8c: addCycles(4); AM_Absolute(Y()); break; + case 0x8d: addCycles(4); AM_Absolute(A()); break; + case 0x8e: addCycles(4); AM_Absolute(X()); break; + case 0x8f: addCycles(4); AM_Absolute(A() & X()); break; + + case 0x90: addCycles(2); Branch(!(P() & CF)); break; + case 0x91: addCycles(6); AM_IndirectIndexedY(A()); break; + case 0x92: addCycles(0); break; + case 0x93: addCycles(0); break; + case 0x94: addCycles(4); AM_ZeroPageX(Y()); break; + case 0x95: addCycles(4); AM_ZeroPageX(A()); break; + case 0x96: addCycles(4); AM_ZeroPageY(X()); break; + case 0x97: addCycles(4); AM_ZeroPageY(A() & X()); break; + case 0x98: addCycles(2); adjustNZ(A() = Y()); break; + case 0x99: addCycles(5); AM_AbsoluteY(A()); break; + case 0x9a: addCycles(2); S() = X(); break; + case 0x9b: addCycles(0); break; + case 0x9c: addCycles(0); break; + case 0x9d: addCycles(5); AM_AbsoluteX(A()); break; + case 0x9e: addCycles(0); break; + case 0x9f: addCycles(0); break; + + case 0xa0: addCycles(2); adjustNZ(Y() = AM_Immediate()); break; + case 0xa1: addCycles(6); adjustNZ(A() = AM_IndexedIndirectX()); break; + case 0xa2: addCycles(2); adjustNZ(X() = AM_Immediate()); break; + case 0xa3: addCycles(6); LAX(AM_IndexedIndirectX()); break; + case 0xa4: addCycles(3); adjustNZ(Y() = AM_ZeroPage()); break; + case 0xa5: addCycles(3); adjustNZ(A() = AM_ZeroPage()); break; + case 0xa6: addCycles(3); adjustNZ(X() = AM_ZeroPage()); break; + case 0xa7: addCycles(3); LAX(AM_ZeroPage()); break; + case 0xa8: addCycles(2); adjustNZ(Y() = A()); break; + case 0xa9: addCycles(2); adjustNZ(A() = AM_Immediate()); break; + case 0xaa: addCycles(2); adjustNZ(X() = A()); break; + case 0xab: addCycles(0); break; + case 0xac: addCycles(4); adjustNZ(Y() = AM_Absolute()); break; + case 0xad: addCycles(4); adjustNZ(A() = AM_Absolute()); break; + case 0xae: addCycles(4); adjustNZ(X() = AM_Absolute()); break; + case 0xaf: addCycles(4); LAX(AM_Absolute()); break; + + case 0xb0: addCycles(2); Branch(!!(P() & CF)); break; + case 0xb1: addCycles(5); adjustNZ(A() = AM_IndirectIndexedY()); break; + case 0xb2: addCycles(0); break; + case 0xb3: addCycles(5); LAX(AM_IndirectIndexedY()); break; + case 0xb4: addCycles(4); adjustNZ(Y() = AM_ZeroPageX()); break; + case 0xb5: addCycles(4); adjustNZ(A() = AM_ZeroPageX()); break; + case 0xb6: addCycles(4); adjustNZ(X() = AM_ZeroPageY()); break; + case 0xb7: addCycles(4); LAX(AM_ZeroPageY()); break; + case 0xb8: addCycles(2); clearFlag(P(), VF); break; + case 0xb9: addCycles(4); adjustNZ(A() = AM_AbsoluteY()); break; + case 0xba: addCycles(2); adjustNZ(X() = S()); break; + case 0xbb: addCycles(0); break; + case 0xbc: addCycles(4); adjustNZ(Y() = AM_AbsoluteX()); break; + case 0xbd: addCycles(4); adjustNZ(A() = AM_AbsoluteX()); break; + case 0xbe: addCycles(4); adjustNZ(X() = AM_AbsoluteY()); break; + case 0xbf: addCycles(4); LAX(AM_AbsoluteY()); break; + + case 0xc0: addCycles(2); CMP(Y(), AM_Immediate()); break; + case 0xc1: addCycles(6); CMP(A(), AM_IndexedIndirectX()); break; + case 0xc2: addCycles(2); AM_Immediate(); break; + case 0xc3: addCycles(8); DCP(AM_IndexedIndirectX()); break; + case 0xc4: addCycles(3); CMP(Y(), AM_ZeroPage()); break; + case 0xc5: addCycles(3); CMP(A(), AM_ZeroPage()); break; + case 0xc6: addCycles(5); setByte(DEC(AM_ZeroPage())); break; + case 0xc7: addCycles(5); DCP(AM_ZeroPage()); break; + case 0xc8: addCycles(2); adjustNZ(++Y()); break; + case 0xc9: addCycles(2); CMP(A(), AM_Immediate()); break; + case 0xca: addCycles(2); adjustNZ(--X()); break; + case 0xcb: addCycles(0); break; + case 0xcc: addCycles(4); CMP(Y(), AM_Absolute()); break; + case 0xcd: addCycles(4); CMP(A(), AM_Absolute()); break; + case 0xce: addCycles(6); setByte(DEC(AM_Absolute())); break; + case 0xcf: addCycles(6); DCP(AM_Absolute()); break; + + case 0xd0: addCycles(2); Branch(!(P() & ZF)); break; + case 0xd1: addCycles(5); CMP(A(), AM_IndirectIndexedY()); break; + case 0xd2: addCycles(0); break; + case 0xd3: addCycles(7); DCP(AM_IndirectIndexedY()); break; + case 0xd4: addCycles(4); AM_ZeroPageX(); break; + case 0xd5: addCycles(4); CMP(A(), AM_ZeroPageX()); break; + case 0xd6: addCycles(6); setByte(DEC(AM_ZeroPageX())); break; + case 0xd7: addCycles(6); DCP(AM_ZeroPageX()); break; + case 0xd8: addCycles(2); clearFlag(P(), DF); break; + case 0xd9: addCycles(4); CMP(A(), AM_AbsoluteY()); break; + case 0xda: addCycles(2); break; + case 0xdb: addCycles(6); DCP(AM_AbsoluteY()); break; + case 0xdc: addCycles(4); AM_AbsoluteX(); break; + case 0xdd: addCycles(4); CMP(A(), AM_AbsoluteX()); break; + case 0xde: addCycles(7); setByte(DEC(AM_AbsoluteX())); break; + case 0xdf: addCycles(6); DCP(AM_AbsoluteX()); break; + + case 0xe0: addCycles(2); CMP(X(), AM_Immediate()); break; + case 0xe1: addCycles(6); A() = SBC(A(), AM_IndexedIndirectX()); break; + case 0xe2: addCycles(2); AM_Immediate(); break; + case 0xe3: addCycles(8); ISB(AM_IndexedIndirectX()); break; + case 0xe4: addCycles(3); CMP(X(), AM_ZeroPage()); break; + case 0xe5: addCycles(3); A() = SBC(A(), AM_ZeroPage()); break; + case 0xe6: addCycles(5); setByte(INC(AM_ZeroPage())); break; + case 0xe7: addCycles(5); ISB(AM_ZeroPage()); break; + case 0xe8: addCycles(2); adjustNZ(++X()); break; + case 0xe9: addCycles(2); A() = SBC(A(), AM_Immediate()); break; + case 0xea: addCycles(2); break; + case 0xeb: addCycles(2); A() = SBC(A(), AM_Immediate()); break; + case 0xec: addCycles(4); CMP(X(), AM_Absolute()); break; + case 0xed: addCycles(4); A() = SBC(A(), AM_Absolute()); break; + case 0xee: addCycles(6); setByte(INC(AM_Absolute())); break; + case 0xef: addCycles(6); ISB(AM_Absolute()); break; + + case 0xf0: addCycles(2); Branch(!!(P() & ZF)); break; + case 0xf1: addCycles(5); A() = SBC(A(), AM_IndirectIndexedY()); break; + case 0xf2: addCycles(0); break; + case 0xf3: addCycles(7); ISB(AM_IndirectIndexedY()); break; + case 0xf4: addCycles(4); AM_ZeroPageX(); break; + case 0xf5: addCycles(4); A() = SBC(A(), AM_ZeroPageX()); break; + case 0xf6: addCycles(6); setByte(INC(AM_ZeroPageX())); break; + case 0xf7: addCycles(6); ISB(AM_ZeroPageX()); break; + case 0xf8: addCycles(2); setFlag(P(), DF); break; + case 0xf9: addCycles(4); A() = SBC(A(), AM_AbsoluteY()); break; + case 0xfa: addCycles(2); break; + case 0xfb: addCycles(6); ISB(AM_AbsoluteY()); break; + case 0xfc: addCycles(4); AM_AbsoluteX(); break; + case 0xfd: addCycles(4); A() = SBC(A(), AM_AbsoluteX()); break; + case 0xfe: addCycles(7); setByte(INC(AM_AbsoluteX())); break; + case 0xff: addCycles(6); ISB(AM_AbsoluteX()); break; + } if (UNLIKELY(cycles() == 0)) throw std::logic_error("Unhandled opcode");