diff --git a/BizHawk.Emulation/BizHawk.Emulation.csproj b/BizHawk.Emulation/BizHawk.Emulation.csproj
index 6951458d68..0196bb8211 100644
--- a/BizHawk.Emulation/BizHawk.Emulation.csproj
+++ b/BizHawk.Emulation/BizHawk.Emulation.csproj
@@ -199,6 +199,9 @@
+
+
+
diff --git a/BizHawk.Emulation/CPUs/MOS 6507/Disassembler.cs b/BizHawk.Emulation/CPUs/MOS 6507/Disassembler.cs
new file mode 100644
index 0000000000..f239ebb698
--- /dev/null
+++ b/BizHawk.Emulation/CPUs/MOS 6507/Disassembler.cs
@@ -0,0 +1,198 @@
+using System;
+
+// Do not modify this file directly! This is GENERATED code.
+// Please open the CpuCoreGenerator solution and make your modifications there.
+
+namespace BizHawk.Emulation.CPUs.M6507
+{
+ public partial class MOS6507
+ {
+ public string Disassemble(ushort pc, out int bytesToAdvance)
+ {
+ byte op = ReadMemory(pc);
+ switch (op)
+ {
+ case 0x00: bytesToAdvance = 1; return "BRK";
+ case 0x01: bytesToAdvance = 2; return string.Format("ORA (${0:X2},X)", ReadMemory(++pc));
+ case 0x04: bytesToAdvance = 2; return string.Format("NOP ${0:X2}", ReadMemory(++pc));
+ case 0x05: bytesToAdvance = 2; return string.Format("ORA ${0:X2}", ReadMemory(++pc));
+ case 0x06: bytesToAdvance = 2; return string.Format("ASL ${0:X2}", ReadMemory(++pc));
+ case 0x08: bytesToAdvance = 1; return "PHP";
+ case 0x09: bytesToAdvance = 2; return string.Format("ORA #${0:X2}", ReadMemory(++pc));
+ case 0x0A: bytesToAdvance = 1; return "ASL A";
+ case 0x0C: bytesToAdvance = 3; return string.Format("NOP (${0:X4})", ReadWord(++pc));
+ case 0x0D: bytesToAdvance = 3; return string.Format("ORA ${0:X4}", ReadWord(++pc));
+ case 0x0E: bytesToAdvance = 3; return string.Format("ASL ${0:X4}", ReadWord(++pc));
+ case 0x10: bytesToAdvance = 2; return string.Format("BPL ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0x11: bytesToAdvance = 2; return string.Format("ORA (${0:X2}),Y *", ReadMemory(++pc));
+ case 0x14: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
+ case 0x15: bytesToAdvance = 2; return string.Format("ORA ${0:X2},X", ReadMemory(++pc));
+ case 0x16: bytesToAdvance = 2; return string.Format("ASL ${0:X2},X", ReadMemory(++pc));
+ case 0x18: bytesToAdvance = 1; return "CLC";
+ case 0x19: bytesToAdvance = 3; return string.Format("ORA ${0:X4},Y *", ReadWord(++pc));
+ case 0x1A: bytesToAdvance = 1; return "NOP";
+ case 0x1C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
+ case 0x1D: bytesToAdvance = 3; return string.Format("ORA ${0:X4},X *", ReadWord(++pc));
+ case 0x1E: bytesToAdvance = 3; return string.Format("ASL ${0:X4},X", ReadWord(++pc));
+ case 0x20: bytesToAdvance = 3; return string.Format("JSR ${0:X4}", ReadWord(++pc));
+ case 0x21: bytesToAdvance = 2; return string.Format("AND (${0:X2},X)", ReadMemory(++pc));
+ case 0x24: bytesToAdvance = 2; return string.Format("BIT ${0:X2}", ReadMemory(++pc));
+ case 0x25: bytesToAdvance = 2; return string.Format("AND ${0:X2}", ReadMemory(++pc));
+ case 0x26: bytesToAdvance = 2; return string.Format("ROL ${0:X2}", ReadMemory(++pc));
+ case 0x28: bytesToAdvance = 1; return "PLP";
+ case 0x29: bytesToAdvance = 2; return string.Format("AND #${0:X2}", ReadMemory(++pc));
+ case 0x2A: bytesToAdvance = 1; return "ROL A";
+ case 0x2C: bytesToAdvance = 3; return string.Format("BIT ${0:X4}", ReadWord(++pc));
+ case 0x2D: bytesToAdvance = 3; return string.Format("AND ${0:X4}", ReadWord(++pc));
+ case 0x2E: bytesToAdvance = 3; return string.Format("ROL ${0:X4}", ReadWord(++pc));
+ case 0x30: bytesToAdvance = 2; return string.Format("BMI ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0x31: bytesToAdvance = 2; return string.Format("AND (${0:X2}),Y *", ReadMemory(++pc));
+ case 0x34: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
+ case 0x35: bytesToAdvance = 2; return string.Format("AND ${0:X2},X", ReadMemory(++pc));
+ case 0x36: bytesToAdvance = 2; return string.Format("ROL ${0:X2},X", ReadMemory(++pc));
+ case 0x38: bytesToAdvance = 1; return "SEC";
+ case 0x39: bytesToAdvance = 3; return string.Format("AND ${0:X4},Y *", ReadWord(++pc));
+ case 0x3A: bytesToAdvance = 1; return "NOP";
+ case 0x3C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
+ case 0x3D: bytesToAdvance = 3; return string.Format("AND ${0:X4},X *", ReadWord(++pc));
+ case 0x3E: bytesToAdvance = 3; return string.Format("ROL ${0:X4},X", ReadWord(++pc));
+ case 0x40: bytesToAdvance = 1; return "RTI";
+ case 0x41: bytesToAdvance = 2; return string.Format("EOR (${0:X2},X)", ReadMemory(++pc));
+ case 0x44: bytesToAdvance = 2; return string.Format("NOP ${0:X2}", ReadMemory(++pc));
+ case 0x45: bytesToAdvance = 2; return string.Format("EOR ${0:X2}", ReadMemory(++pc));
+ case 0x46: bytesToAdvance = 2; return string.Format("LSR ${0:X2}", ReadMemory(++pc));
+ case 0x48: bytesToAdvance = 1; return "PHA";
+ case 0x49: bytesToAdvance = 2; return string.Format("EOR #${0:X2}", ReadMemory(++pc));
+ case 0x4A: bytesToAdvance = 1; return "LSR A";
+ case 0x4C: bytesToAdvance = 3; return string.Format("JMP ${0:X4}", ReadWord(++pc));
+ case 0x4D: bytesToAdvance = 3; return string.Format("EOR ${0:X4}", ReadWord(++pc));
+ case 0x4E: bytesToAdvance = 3; return string.Format("LSR ${0:X4}", ReadWord(++pc));
+ case 0x50: bytesToAdvance = 2; return string.Format("BVC ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0x51: bytesToAdvance = 2; return string.Format("EOR (${0:X2}),Y *", ReadMemory(++pc));
+ case 0x54: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
+ case 0x55: bytesToAdvance = 2; return string.Format("EOR ${0:X2},X", ReadMemory(++pc));
+ case 0x56: bytesToAdvance = 2; return string.Format("LSR ${0:X2},X", ReadMemory(++pc));
+ case 0x58: bytesToAdvance = 1; return "CLI";
+ case 0x59: bytesToAdvance = 3; return string.Format("EOR ${0:X4},Y *", ReadWord(++pc));
+ case 0x5A: bytesToAdvance = 1; return "NOP";
+ case 0x5C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
+ case 0x5D: bytesToAdvance = 3; return string.Format("EOR ${0:X4},X *", ReadWord(++pc));
+ case 0x5E: bytesToAdvance = 3; return string.Format("LSR ${0:X4},X", ReadWord(++pc));
+ case 0x60: bytesToAdvance = 1; return "RTS";
+ case 0x61: bytesToAdvance = 2; return string.Format("ADC (${0:X2},X)", ReadMemory(++pc));
+ case 0x64: bytesToAdvance = 2; return string.Format("NOP ${0:X2}", ReadMemory(++pc));
+ case 0x65: bytesToAdvance = 2; return string.Format("ADC ${0:X2}", ReadMemory(++pc));
+ case 0x66: bytesToAdvance = 2; return string.Format("ROR ${0:X2}", ReadMemory(++pc));
+ case 0x68: bytesToAdvance = 1; return "PLA";
+ case 0x69: bytesToAdvance = 2; return string.Format("ADC #${0:X2}", ReadMemory(++pc));
+ case 0x6A: bytesToAdvance = 1; return "ROR A";
+ case 0x6C: bytesToAdvance = 3; return string.Format("JMP (${0:X4})", ReadWord(++pc));
+ case 0x6D: bytesToAdvance = 3; return string.Format("ADC ${0:X4}", ReadWord(++pc));
+ case 0x6E: bytesToAdvance = 3; return string.Format("ROR ${0:X4}", ReadWord(++pc));
+ case 0x70: bytesToAdvance = 2; return string.Format("BVS ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0x71: bytesToAdvance = 2; return string.Format("ADC (${0:X2}),Y *", ReadMemory(++pc));
+ case 0x74: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
+ case 0x75: bytesToAdvance = 2; return string.Format("ADC ${0:X2},X", ReadMemory(++pc));
+ case 0x76: bytesToAdvance = 2; return string.Format("ROR ${0:X2},X", ReadMemory(++pc));
+ case 0x78: bytesToAdvance = 1; return "SEI";
+ case 0x79: bytesToAdvance = 3; return string.Format("ADC ${0:X4},Y *", ReadWord(++pc));
+ case 0x7A: bytesToAdvance = 1; return "NOP";
+ case 0x7C: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
+ case 0x7D: bytesToAdvance = 3; return string.Format("ADC ${0:X4},X *", ReadWord(++pc));
+ case 0x7E: bytesToAdvance = 3; return string.Format("ROR ${0:X4},X", ReadWord(++pc));
+ case 0x80: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
+ case 0x81: bytesToAdvance = 2; return string.Format("STA (${0:X2},X)", ReadMemory(++pc));
+ case 0x82: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
+ case 0x84: bytesToAdvance = 2; return string.Format("STY ${0:X2}", ReadMemory(++pc));
+ case 0x85: bytesToAdvance = 2; return string.Format("STA ${0:X2}", ReadMemory(++pc));
+ case 0x86: bytesToAdvance = 2; return string.Format("STX ${0:X2}", ReadMemory(++pc));
+ case 0x88: bytesToAdvance = 1; return "DEY";
+ case 0x89: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
+ case 0x8A: bytesToAdvance = 1; return "TXA";
+ case 0x8C: bytesToAdvance = 3; return string.Format("STY ${0:X4}", ReadWord(++pc));
+ case 0x8D: bytesToAdvance = 3; return string.Format("STA ${0:X4}", ReadWord(++pc));
+ case 0x8E: bytesToAdvance = 3; return string.Format("STX ${0:X4}", ReadWord(++pc));
+ case 0x90: bytesToAdvance = 2; return string.Format("BCC ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0x91: bytesToAdvance = 2; return string.Format("STA (${0:X2}),Y", ReadMemory(++pc));
+ case 0x94: bytesToAdvance = 2; return string.Format("STY ${0:X2},X", ReadMemory(++pc));
+ case 0x95: bytesToAdvance = 2; return string.Format("STA ${0:X2},X", ReadMemory(++pc));
+ case 0x96: bytesToAdvance = 2; return string.Format("STX ${0:X2},Y", ReadMemory(++pc));
+ case 0x98: bytesToAdvance = 1; return "TYA";
+ case 0x99: bytesToAdvance = 3; return string.Format("STA ${0:X4},Y", ReadWord(++pc));
+ case 0x9A: bytesToAdvance = 1; return "TXS";
+ case 0x9D: bytesToAdvance = 3; return string.Format("STA ${0:X4},X", ReadWord(++pc));
+ case 0xA0: bytesToAdvance = 2; return string.Format("LDY #${0:X2}", ReadMemory(++pc));
+ case 0xA1: bytesToAdvance = 2; return string.Format("LDA (${0:X2},X)", ReadMemory(++pc));
+ case 0xA2: bytesToAdvance = 2; return string.Format("LDX #${0:X2}", ReadMemory(++pc));
+ case 0xA4: bytesToAdvance = 2; return string.Format("LDY ${0:X2}", ReadMemory(++pc));
+ case 0xA5: bytesToAdvance = 2; return string.Format("LDA ${0:X2}", ReadMemory(++pc));
+ case 0xA6: bytesToAdvance = 2; return string.Format("LDX ${0:X2}", ReadMemory(++pc));
+ case 0xA8: bytesToAdvance = 1; return "TAY";
+ case 0xA9: bytesToAdvance = 2; return string.Format("LDA #${0:X2}", ReadMemory(++pc));
+ case 0xAA: bytesToAdvance = 1; return "TAX";
+ case 0xAC: bytesToAdvance = 3; return string.Format("LDY ${0:X4}", ReadWord(++pc));
+ case 0xAD: bytesToAdvance = 3; return string.Format("LDA ${0:X4}", ReadWord(++pc));
+ case 0xAE: bytesToAdvance = 3; return string.Format("LDX ${0:X4}", ReadWord(++pc));
+ case 0xB0: bytesToAdvance = 2; return string.Format("BCS ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0xB1: bytesToAdvance = 2; return string.Format("LDA (${0:X2}),Y *", ReadMemory(++pc));
+ case 0xB4: bytesToAdvance = 2; return string.Format("LDY ${0:X2},X", ReadMemory(++pc));
+ case 0xB5: bytesToAdvance = 2; return string.Format("LDA ${0:X2},X", ReadMemory(++pc));
+ case 0xB6: bytesToAdvance = 2; return string.Format("LDX ${0:X2},Y", ReadMemory(++pc));
+ case 0xB8: bytesToAdvance = 1; return "CLV";
+ case 0xB9: bytesToAdvance = 3; return string.Format("LDA ${0:X4},Y *", ReadWord(++pc));
+ case 0xBA: bytesToAdvance = 1; return "TSX";
+ case 0xBC: bytesToAdvance = 3; return string.Format("LDY ${0:X4},X *", ReadWord(++pc));
+ case 0xBD: bytesToAdvance = 3; return string.Format("LDA ${0:X4},X *", ReadWord(++pc));
+ case 0xBE: bytesToAdvance = 3; return string.Format("LDX ${0:X4},Y *", ReadWord(++pc));
+ case 0xC0: bytesToAdvance = 2; return string.Format("CPY #${0:X2}", ReadMemory(++pc));
+ case 0xC1: bytesToAdvance = 2; return string.Format("CMP (${0:X2},X)", ReadMemory(++pc));
+ case 0xC2: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
+ case 0xC4: bytesToAdvance = 2; return string.Format("CPY ${0:X2}", ReadMemory(++pc));
+ case 0xC5: bytesToAdvance = 2; return string.Format("CMP ${0:X2}", ReadMemory(++pc));
+ case 0xC6: bytesToAdvance = 2; return string.Format("DEC ${0:X2}", ReadMemory(++pc));
+ case 0xC8: bytesToAdvance = 1; return "INY";
+ case 0xC9: bytesToAdvance = 2; return string.Format("CMP #${0:X2}", ReadMemory(++pc));
+ case 0xCA: bytesToAdvance = 1; return "DEX";
+ case 0xCC: bytesToAdvance = 3; return string.Format("CPY ${0:X4}", ReadWord(++pc));
+ case 0xCD: bytesToAdvance = 3; return string.Format("CMP ${0:X4}", ReadWord(++pc));
+ case 0xCE: bytesToAdvance = 3; return string.Format("DEC ${0:X4}", ReadWord(++pc));
+ case 0xD0: bytesToAdvance = 2; return string.Format("BNE ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0xD1: bytesToAdvance = 2; return string.Format("CMP (${0:X2}),Y *", ReadMemory(++pc));
+ case 0xD4: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
+ case 0xD5: bytesToAdvance = 2; return string.Format("CMP ${0:X2},X", ReadMemory(++pc));
+ case 0xD6: bytesToAdvance = 2; return string.Format("DEC ${0:X2},X", ReadMemory(++pc));
+ case 0xD8: bytesToAdvance = 1; return "CLD";
+ case 0xD9: bytesToAdvance = 3; return string.Format("CMP ${0:X4},Y *", ReadWord(++pc));
+ case 0xDA: bytesToAdvance = 1; return "NOP";
+ case 0xDC: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
+ case 0xDD: bytesToAdvance = 3; return string.Format("CMP ${0:X4},X *", ReadWord(++pc));
+ case 0xDE: bytesToAdvance = 3; return string.Format("DEC ${0:X4},X", ReadWord(++pc));
+ case 0xE0: bytesToAdvance = 2; return string.Format("CPX #${0:X2}", ReadMemory(++pc));
+ case 0xE1: bytesToAdvance = 2; return string.Format("SBC (${0:X2},X)", ReadMemory(++pc));
+ case 0xE2: bytesToAdvance = 2; return string.Format("NOP #${0:X2}", ReadMemory(++pc));
+ case 0xE4: bytesToAdvance = 2; return string.Format("CPX ${0:X2}", ReadMemory(++pc));
+ case 0xE5: bytesToAdvance = 2; return string.Format("SBC ${0:X2}", ReadMemory(++pc));
+ case 0xE6: bytesToAdvance = 2; return string.Format("INC ${0:X2}", ReadMemory(++pc));
+ case 0xE8: bytesToAdvance = 1; return "INX";
+ case 0xE9: bytesToAdvance = 2; return string.Format("SBC #${0:X2}", ReadMemory(++pc));
+ case 0xEA: bytesToAdvance = 1; return "NOP";
+ case 0xEC: bytesToAdvance = 3; return string.Format("CPX ${0:X4}", ReadWord(++pc));
+ case 0xED: bytesToAdvance = 3; return string.Format("SBC ${0:X4}", ReadWord(++pc));
+ case 0xEE: bytesToAdvance = 3; return string.Format("INC ${0:X4}", ReadWord(++pc));
+ case 0xF0: bytesToAdvance = 2; return string.Format("BEQ ${0:X4}", pc+2+(sbyte)ReadMemory(++pc));
+ case 0xF1: bytesToAdvance = 2; return string.Format("SBC (${0:X2}),Y *", ReadMemory(++pc));
+ case 0xF4: bytesToAdvance = 2; return string.Format("NOP ${0:X2},X", ReadMemory(++pc));
+ case 0xF5: bytesToAdvance = 2; return string.Format("SBC ${0:X2},X", ReadMemory(++pc));
+ case 0xF6: bytesToAdvance = 2; return string.Format("INC ${0:X2},X", ReadMemory(++pc));
+ case 0xF8: bytesToAdvance = 1; return "SED";
+ case 0xF9: bytesToAdvance = 3; return string.Format("SBC ${0:X4},Y *", ReadWord(++pc));
+ case 0xFA: bytesToAdvance = 1; return "NOP";
+ case 0xFC: bytesToAdvance = 2; return string.Format("NOP (${0:X2},X)", ReadMemory(++pc));
+ case 0xFD: bytesToAdvance = 3; return string.Format("SBC ${0:X4},X *", ReadWord(++pc));
+ case 0xFE: bytesToAdvance = 3; return string.Format("INC ${0:X4},X", ReadWord(++pc));
+ }
+ bytesToAdvance = 1;
+ return "???";
+ }
+ }
+}
diff --git a/BizHawk.Emulation/CPUs/MOS 6507/Execute.cs b/BizHawk.Emulation/CPUs/MOS 6507/Execute.cs
new file mode 100644
index 0000000000..512192e6e5
--- /dev/null
+++ b/BizHawk.Emulation/CPUs/MOS 6507/Execute.cs
@@ -0,0 +1,1254 @@
+using System;
+
+namespace BizHawk.Emulation.CPUs.M6507
+{
+ public partial class MOS6507
+ {
+ public void Execute(int cycles)
+ {
+ sbyte rel8;
+ byte value8, temp8;
+ ushort value16, temp16;
+ int temp;
+
+ PendingCycles += cycles;
+ while (PendingCycles > 0)
+ {
+ if (NMI)
+ {
+ TriggerException(ExceptionType.NMI);
+ NMI = false;
+ }
+ if (IRQ && !FlagI)
+ {
+ if (SEI_Pending)
+ FlagI = true;
+ TriggerException(ExceptionType.IRQ);
+ }
+ if (CLI_Pending)
+ {
+ FlagI = false;
+ CLI_Pending = false;
+ }
+ if (SEI_Pending)
+ {
+ FlagI = true;
+ SEI_Pending = false;
+ }
+ if(debug) Console.WriteLine(State());
+
+ ushort this_pc = PC;
+ byte opcode = ReadMemory(PC++);
+ switch (opcode)
+ {
+ case 0x00: // BRK
+ TriggerException(ExceptionType.BRK);
+ break;
+ case 0x01: // ORA (addr,X)
+ value8 = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x04: // NOP zp
+ PC += 1;
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x05: // ORA zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x06: // ASL zp
+ value16 = ReadMemory(PC++);
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 0x80) != 0;
+ value8 = (byte)(value8 << 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x08: // PHP
+ FlagB = true; //why would it do this?? how weird
+ WriteMemory((ushort)(S-- + 0x100), P);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x09: // ORA #nn
+ value8 = ReadMemory(PC++);
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x0A: // ASL A
+ FlagC = (A & 0x80) != 0;
+ A = (byte) (A << 1);
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x0C: // NOP (addr)
+ PC += 2;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x0D: // ORA addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x0E: // ASL addr
+ value16 = ReadWord(PC); PC += 2;
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 0x80) != 0;
+ value8 = (byte)(value8 << 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x10: // BPL +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagN == false) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x11: // ORA (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x14: // NOP zp,X
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x15: // ORA zp,X
+ value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x16: // ASL zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 0x80) != 0;
+ value8 = (byte)(value8 << 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x18: // CLC
+ FlagC = false;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x19: // ORA addr,Y*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x1A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x1C: // NOP (addr,X)
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x1D: // ORA addr,X*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ A |= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x1E: // ASL addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 0x80) != 0;
+ value8 = (byte)(value8 << 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 7; TotalExecutedCycles += 7;
+ break;
+ case 0x20: // JSR addr
+ temp16 = (ushort)(PC+1);
+ WriteMemory((ushort)(S-- + 0x100), (byte)(temp16 >> 8));
+ WriteMemory((ushort)(S-- + 0x100), (byte)temp16);
+ PC = ReadWord(PC);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x21: // AND (addr,X)
+ value8 = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x24: // BIT zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ FlagN = (value8 & 0x80) != 0;
+ FlagV = (value8 & 0x40) != 0;
+ FlagZ = (A & value8) == 0;
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x25: // AND zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x26: // ROL zp
+ value16 = ReadMemory(PC++);
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 << 1) | (P & 1));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 0x80) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x28: // PLP
+ //handle I flag differently. sort of a sloppy way to do the job, but it does finish it off.
+ value8 = ReadMemory((ushort)(++S + 0x100));
+ if ((value8 & 0x04) != 0 && !FlagI)
+ SEI_Pending = true;
+ if ((value8 & 0x04) == 0 && FlagI)
+ CLI_Pending = true;
+ value8 &= unchecked((byte)~0x04);
+ P &= 0x04;
+ P |= value8;
+FlagT = true;//this seems wrong
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x29: // AND #nn
+ value8 = ReadMemory(PC++);
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x2A: // ROL A
+ temp8 = A;
+ A = (byte)((A << 1) | (P & 1));
+ FlagC = (temp8 & 0x80) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x2C: // BIT addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ FlagN = (value8 & 0x80) != 0;
+ FlagV = (value8 & 0x40) != 0;
+ FlagZ = (A & value8) == 0;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x2D: // AND addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x2E: // ROL addr
+ value16 = ReadWord(PC); PC += 2;
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 << 1) | (P & 1));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 0x80) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x30: // BMI +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagN == true) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x31: // AND (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x34: // NOP zp,X
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x35: // AND zp,X
+ value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x36: // ROL zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 << 1) | (P & 1));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 0x80) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x38: // SEC
+ FlagC = true;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x39: // AND addr,Y*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x3A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x3C: // NOP (addr,X)
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x3D: // AND addr,X*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ A &= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x3E: // ROL addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 << 1) | (P & 1));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 0x80) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 7; TotalExecutedCycles += 7;
+ break;
+ case 0x40: // RTI
+ P = ReadMemory((ushort)(++S + 0x100));
+FlagT = true;// this seems wrong
+ PC = ReadMemory((ushort)(++S + 0x100));
+ PC |= (ushort)(ReadMemory((ushort)(++S + 0x100)) << 8);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x41: // EOR (addr,X)
+ value8 = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x44: // NOP zp
+ PC += 1;
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x45: // EOR zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x46: // LSR zp
+ value16 = ReadMemory(PC++);
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 1) != 0;
+ value8 = (byte)(value8 >> 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x48: // PHA
+ WriteMemory((ushort)(S-- + 0x100), A);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x49: // EOR #nn
+ value8 = ReadMemory(PC++);
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x4A: // LSR A
+ FlagC = (A & 1) != 0;
+ A = (byte) (A >> 1);
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x4C: // JMP addr
+ PC = ReadWord(PC);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x4D: // EOR addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x4E: // LSR addr
+ value16 = ReadWord(PC); PC += 2;
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 1) != 0;
+ value8 = (byte)(value8 >> 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x50: // BVC +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagV == false) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x51: // EOR (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x54: // NOP zp,X
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x55: // EOR zp,X
+ value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x56: // LSR zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 1) != 0;
+ value8 = (byte)(value8 >> 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x58: // CLI
+ //FlagI = false;
+ CLI_Pending = true;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x59: // EOR addr,Y*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x5A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x5C: // NOP (addr,X)
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x5D: // EOR addr,X*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ A ^= value8;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x5E: // LSR addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ value8 = ReadMemory(value16);
+ FlagC = (value8 & 1) != 0;
+ value8 = (byte)(value8 >> 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 7; TotalExecutedCycles += 7;
+ break;
+ case 0x60: // RTS
+ PC = ReadMemory((ushort)(++S + 0x100));
+ PC |= (ushort)(ReadMemory((ushort)(++S + 0x100)) << 8);
+ PC++;
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x61: // ADC (addr,X)
+ value8 = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x64: // NOP zp
+ PC += 1;
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x65: // ADC zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x66: // ROR zp
+ value16 = ReadMemory(PC++);
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 >> 1) | ((P & 1)<<7));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 1) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x68: // PLA
+ A = ReadMemory((ushort)(++S + 0x100));
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x69: // ADC #nn
+ value8 = ReadMemory(PC++);
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x6A: // ROR A
+ temp8 = A;
+ A = (byte)((A >> 1) | ((P & 1)<<7));
+ FlagC = (temp8 & 1) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x6C: // JMP (addr)
+ PC = ReadWordPageWrap(ReadWord(PC));
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x6D: // ADC addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x6E: // ROR addr
+ value16 = ReadWord(PC); PC += 2;
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 >> 1) | ((P & 1)<<7));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 1) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x70: // BVS +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagV == true) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x71: // ADC (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x74: // NOP zp,X
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x75: // ADC zp,X
+ value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x76: // ROR zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 >> 1) | ((P & 1)<<7));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 1) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x78: // SEI
+ //FlagI = true;
+ SEI_Pending = true;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x79: // ADC addr,Y*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x7A: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x7C: // NOP (addr,X)
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x7D: // ADC addr,X*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ temp = value8 + A + (FlagC ? 1 : 0);
+ FlagV = (~(A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp > 0xFF;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x7E: // ROR addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ value8 = temp8 = ReadMemory(value16);
+ value8 = (byte)((value8 >> 1) | ((P & 1)<<7));
+ WriteMemory(value16, value8);
+ FlagC = (temp8 & 1) != 0;
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 7; TotalExecutedCycles += 7;
+ break;
+ case 0x80: // NOP #nn
+ PC += 1;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x81: // STA (addr,X)
+ temp8 = (byte)(ReadMemory(PC++) + X);
+ value16 = ReadWordPageWrap(temp8);
+ WriteMemory(value16, A);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x82: // NOP #nn
+ PC += 1;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x84: // STY zp
+ value16 = ReadMemory(PC++);
+ WriteMemory(value16, Y);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x85: // STA zp
+ value16 = ReadMemory(PC++);
+ WriteMemory(value16, A);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x86: // STX zp
+ value16 = ReadMemory(PC++);
+ WriteMemory(value16, X);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0x88: // DEY
+ P = (byte)((P & 0x7D) | TableNZ[--Y]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x89: // NOP #nn
+ PC += 1;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x8A: // TXA
+ A = X;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x8C: // STY addr
+ value16 = ReadWord(PC); PC += 2;
+ WriteMemory(value16, Y);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x8D: // STA addr
+ value16 = ReadWord(PC); PC += 2;
+ WriteMemory(value16, A);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x8E: // STX addr
+ value16 = ReadWord(PC); PC += 2;
+ WriteMemory(value16, X);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x90: // BCC +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagC == false) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x91: // STA (addr),Y
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value16 = (ushort)(temp16+Y);
+ WriteMemory(value16, A);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0x94: // STY zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ WriteMemory(value16, Y);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x95: // STA zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ WriteMemory(value16, A);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x96: // STX zp,Y
+ value16 = (byte)(ReadMemory(PC++)+Y);
+ WriteMemory(value16, X);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0x98: // TYA
+ A = Y;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x99: // STA addr,Y
+ value16 = (ushort)(ReadWord(PC)+Y);
+ PC += 2;
+ WriteMemory(value16, A);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0x9A: // TXS
+ S = X;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0x9D: // STA addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ WriteMemory(value16, A);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0xA0: // LDY #nn
+ Y = ReadMemory(PC++);
+ P = (byte)((P & 0x7D) | TableNZ[Y]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xA1: // LDA (addr,X)
+ A = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0xA2: // LDX #nn
+ X = ReadMemory(PC++);
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xA4: // LDY zp
+ Y = ReadMemory(ReadMemory(PC++));
+ P = (byte)((P & 0x7D) | TableNZ[Y]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0xA5: // LDA zp
+ A = ReadMemory(ReadMemory(PC++));
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0xA6: // LDX zp
+ X = ReadMemory(ReadMemory(PC++));
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0xA8: // TAY
+ Y = A;
+ P = (byte)((P & 0x7D) | TableNZ[Y]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xA9: // LDA #nn
+ A = ReadMemory(PC++);
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xAA: // TAX
+ X = A;
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xAC: // LDY addr
+ Y = ReadMemory(ReadWord(PC)); PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[Y]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xAD: // LDA addr
+ A = ReadMemory(ReadWord(PC)); PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xAE: // LDX addr
+ X = ReadMemory(ReadWord(PC)); PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xB0: // BCS +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagC == true) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xB1: // LDA (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ A = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0xB4: // LDY zp,X
+ Y = ReadMemory((byte)(ReadMemory(PC++)+X));
+ P = (byte)((P & 0x7D) | TableNZ[Y]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xB5: // LDA zp,X
+ A = ReadMemory((byte)(ReadMemory(PC++)+X));
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xB6: // LDX zp,Y
+ X = ReadMemory((byte)(ReadMemory(PC++)+Y));
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xB8: // CLV
+ FlagV = false;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xB9: // LDA addr,Y*
+ temp16 = ReadWord(PC);
+ A = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xBA: // TSX
+ X = S;
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xBC: // LDY addr,X*
+ temp16 = ReadWord(PC);
+ Y = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[Y]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xBD: // LDA addr,X*
+ temp16 = ReadWord(PC);
+ A = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xBE: // LDX addr,Y*
+ temp16 = ReadWord(PC);
+ X = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ P = (byte)((P & 0x7D) | TableNZ[X]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xC0: // CPY #nn
+ value8 = ReadMemory(PC++);
+ value16 = (ushort) (Y - value8);
+ FlagC = (Y >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 2;
+ break;
+ case 0xC1: // CMP (addr,X)
+ value8 = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 6;
+ break;
+ case 0xC2: // NOP #nn
+ PC += 1;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xC4: // CPY zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ value16 = (ushort) (Y - value8);
+ FlagC = (Y >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 3;
+ break;
+ case 0xC5: // CMP zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 3;
+ break;
+ case 0xC6: // DEC zp
+ value16 = ReadMemory(PC++);
+ value8 = (byte)(ReadMemory(value16) - 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0xC8: // INY
+ P = (byte)((P & 0x7D) | TableNZ[++Y]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xC9: // CMP #nn
+ value8 = ReadMemory(PC++);
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 2;
+ break;
+ case 0xCA: // DEX
+ P = (byte)((P & 0x7D) | TableNZ[--X]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xCC: // CPY addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ value16 = (ushort) (Y - value8);
+ FlagC = (Y >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 4;
+ break;
+ case 0xCD: // CMP addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 4;
+ break;
+ case 0xCE: // DEC addr
+ value16 = ReadWord(PC); PC += 2;
+ value8 = (byte)(ReadMemory(value16) - 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0xD0: // BNE +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagZ == false) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xD1: // CMP (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 5;
+ break;
+ case 0xD4: // NOP zp,X
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xD5: // CMP zp,X
+ value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 4;
+ break;
+ case 0xD6: // DEC zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ value8 = (byte)(ReadMemory(value16) - 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0xD8: // CLD
+ FlagD = false;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xD9: // CMP addr,Y*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 4;
+ break;
+ case 0xDA: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xDC: // NOP (addr,X)
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xDD: // CMP addr,X*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ value16 = (ushort) (A - value8);
+ FlagC = (A >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 4;
+ break;
+ case 0xDE: // DEC addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ value8 = (byte)(ReadMemory(value16) - 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 7; TotalExecutedCycles += 7;
+ break;
+ case 0xE0: // CPX #nn
+ value8 = ReadMemory(PC++);
+ value16 = (ushort) (X - value8);
+ FlagC = (X >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 2;
+ break;
+ case 0xE1: // SBC (addr,X)
+ value8 = ReadMemory(ReadWordPageWrap((byte)(ReadMemory(PC++)+X)));
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0xE2: // NOP #nn
+ PC += 1;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xE4: // CPX zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ value16 = (ushort) (X - value8);
+ FlagC = (X >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 3;
+ break;
+ case 0xE5: // SBC zp
+ value8 = ReadMemory(ReadMemory(PC++));
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 3; TotalExecutedCycles += 3;
+ break;
+ case 0xE6: // INC zp
+ value16 = ReadMemory(PC++);
+ value8 = (byte)(ReadMemory(value16) + 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0xE8: // INX
+ P = (byte)((P & 0x7D) | TableNZ[++X]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xE9: // SBC #nn
+ value8 = ReadMemory(PC++);
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xEA: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xEC: // CPX addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ value16 = (ushort) (X - value8);
+ FlagC = (X >= value8);
+ P = (byte)((P & 0x7D) | TableNZ[(byte)value16]);
+ PendingCycles -= 4;
+ break;
+ case 0xED: // SBC addr
+ value8 = ReadMemory(ReadWord(PC)); PC += 2;
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xEE: // INC addr
+ value16 = ReadWord(PC); PC += 2;
+ value8 = (byte)(ReadMemory(value16) + 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0xF0: // BEQ +/-rel
+ rel8 = (sbyte)ReadMemory(PC++);
+ value16 = (ushort)(PC+rel8);
+ if (FlagZ == true) {
+ PendingCycles--; TotalExecutedCycles++;
+ if ((PC & 0xFF00) != (value16 & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC = value16;
+ }
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xF1: // SBC (addr),Y*
+ temp16 = ReadWordPageWrap(ReadMemory(PC++));
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16+Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 5; TotalExecutedCycles += 5;
+ break;
+ case 0xF4: // NOP zp,X
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xF5: // SBC zp,X
+ value8 = ReadMemory((byte)(ReadMemory(PC++)+X));
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xF6: // INC zp,X
+ value16 = (byte)(ReadMemory(PC++)+X);
+ value8 = (byte)(ReadMemory(value16) + 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 6; TotalExecutedCycles += 6;
+ break;
+ case 0xF8: // SED
+ FlagD = true;
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xF9: // SBC addr,Y*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+Y));
+ if ((temp16 & 0xFF00) != ((temp16 + Y) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xFA: // NOP
+ PendingCycles -= 2; TotalExecutedCycles += 2;
+ break;
+ case 0xFC: // NOP (addr,X)
+ PC += 1;
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xFD: // SBC addr,X*
+ temp16 = ReadWord(PC);
+ value8 = ReadMemory((ushort)(temp16+X));
+ if ((temp16 & 0xFF00) != ((temp16 + X) & 0xFF00))
+ { PendingCycles--; TotalExecutedCycles++; }
+ PC += 2;
+ temp = A - value8 - (FlagC?0:1);
+ FlagV = ((A ^ value8) & (A ^ temp) & 0x80) != 0;
+ FlagC = temp >= 0;
+ A = (byte)temp;
+ P = (byte)((P & 0x7D) | TableNZ[A]);
+ PendingCycles -= 4; TotalExecutedCycles += 4;
+ break;
+ case 0xFE: // INC addr,X
+ value16 = (ushort)(ReadWord(PC)+X);
+ PC += 2;
+ value8 = (byte)(ReadMemory(value16) + 1);
+ WriteMemory(value16, value8);
+ P = (byte)((P & 0x7D) | TableNZ[value8]);
+ PendingCycles -= 7; TotalExecutedCycles += 7;
+ break;
+ default:
+ if(throw_unhandled)
+ throw new Exception(String.Format("Unhandled opcode: {0:X2}", opcode));
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/BizHawk.Emulation/CPUs/MOS 6507/MOS6507.cs b/BizHawk.Emulation/CPUs/MOS 6507/MOS6507.cs
new file mode 100644
index 0000000000..ab0ef260d5
--- /dev/null
+++ b/BizHawk.Emulation/CPUs/MOS 6507/MOS6507.cs
@@ -0,0 +1,241 @@
+using System;
+using System.Globalization;
+using System.IO;
+
+namespace BizHawk.Emulation.CPUs.M6507
+{
+ public sealed partial class MOS6507
+ {
+ public MOS6507()
+ {
+ //InitTableNZ();
+ Reset();
+ }
+/*
+ private byte[] TableNZ;
+ private void InitTableNZ()
+ {
+ TableNZ = new byte[256];
+ for (int i = 0; i < 256; i++)
+ {
+ byte b = 0;
+ if (i == 0) b |= 0x02;
+ if (i > 127) b |= 0x80;
+ TableNZ[i] = b;
+ }
+ }*/
+
+ public bool debug;
+ public bool throw_unhandled;
+
+ public void Reset()
+ {
+ A = 0;
+ X = 0;
+ Y = 0;
+ P = 0;
+ S = 0;
+ PC = 0;
+ PendingCycles = 0;
+ TotalExecutedCycles = 0;
+ }
+
+ public string State()
+ {
+ int notused;
+ string a = string.Format("{0:X4} {1:X2} {2} ", PC, ReadMemory(PC), Disassemble(PC, out notused)).PadRight(30);
+ string b = string.Format("A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}", A, X, Y, P, S, TotalExecutedCycles);
+ string val = a + b + " ";
+ if (FlagN) val = val + "N";
+ if (FlagV) val = val + "V";
+ if (FlagT) val = val + "T";
+ if (FlagB) val = val + "B";
+ if (FlagD) val = val + "D";
+ if (FlagI) val = val + "I";
+ if (FlagZ) val = val + "Z";
+ if (FlagC) val = val + "C";
+ return val;
+ }
+
+ public const ushort NMIVector = 0xFFFA;
+ public const ushort ResetVector = 0xFFFC;
+ public const ushort BRKVector = 0xFFFE;
+ public const ushort IRQVector = 0xFFFE;
+
+ enum ExceptionType
+ {
+ BRK, NMI, IRQ
+ }
+
+ void TriggerException(ExceptionType type)
+ {
+ if (type == ExceptionType.BRK)
+ PC++;
+ WriteMemory((ushort)(S-- + 0x100), (byte)(PC >> 8));
+ WriteMemory((ushort)(S-- + 0x100), (byte)PC);
+ FlagB = type == ExceptionType.BRK;
+ WriteMemory((ushort)(S-- + 0x100), P);
+ FlagI = true;
+ switch (type)
+ {
+ case ExceptionType.NMI:
+ PC = ReadWord(NMIVector);
+ break;
+ case ExceptionType.IRQ:
+ PC = ReadWord(IRQVector);
+ break;
+ case ExceptionType.BRK:
+ PC = ReadWord(BRKVector);
+ break;
+ default: throw new Exception();
+ }
+ PendingCycles -= 7;
+ }
+
+ // ==== CPU State ====
+
+ public byte A;
+ public byte X;
+ public byte Y;
+ public byte P;
+ public ushort PC;
+ public byte S;
+
+ public bool IRQ;
+ public bool NMI;
+ public bool CLI_Pending;
+ public bool SEI_Pending;
+
+ public void SyncState(Serializer ser)
+ {
+ ser.BeginSection("MOS6502");
+ ser.Sync("A", ref A);
+ ser.Sync("X", ref X);
+ ser.Sync("Y", ref Y);
+ ser.Sync("P", ref P);
+ ser.Sync("PC", ref PC);
+ ser.Sync("S", ref S);
+ ser.Sync("NMI", ref NMI);
+ ser.Sync("IRQ", ref IRQ);
+ ser.Sync("CLI_Pending", ref CLI_Pending);
+ ser.Sync("SEI_Pending", ref SEI_Pending);
+ ser.Sync("TotalExecutedCycles", ref TotalExecutedCycles);
+ ser.Sync("PendingCycles", ref PendingCycles);
+ ser.EndSection();
+ }
+
+ public void SaveStateBinary(BinaryWriter writer) { SyncState(Serializer.CreateBinaryWriter(writer)); }
+ public void LoadStateBinary(BinaryReader reader) { SyncState(Serializer.CreateBinaryReader(reader)); }
+
+ // ==== End State ====
+
+ /// Carry Flag
+ private bool FlagC
+ {
+ get { return (P & 0x01) != 0; }
+ set { P = (byte)((P & ~0x01) | (value ? 0x01 : 0x00)); }
+ }
+
+ /// Zero Flag
+ private bool FlagZ
+ {
+ get { return (P & 0x02) != 0; }
+ set { P = (byte)((P & ~0x02) | (value ? 0x02 : 0x00)); }
+ }
+
+ /// Interrupt Disable Flag
+ public bool FlagI
+ {
+ get { return (P & 0x04) != 0; }
+ set { P = (byte)((P & ~0x04) | (value ? 0x04 : 0x00)); }
+ }
+
+ /// Decimal Mode Flag
+ private bool FlagD
+ {
+ get { return (P & 0x08) != 0; }
+ set { P = (byte)((P & ~0x08) | (value ? 0x08 : 0x00)); }
+ }
+
+ /// Break Flag
+ private bool FlagB
+ {
+ get { return (P & 0x10) != 0; }
+ set { P = (byte)((P & ~0x10) | (value ? 0x10 : 0x00)); }
+ }
+
+ /// T... Flag
+ private bool FlagT
+ {
+ get { return (P & 0x20) != 0; }
+ set { P = (byte)((P & ~0x20) | (value ? 0x20 : 0x00)); }
+ }
+
+ /// Overflow Flag
+ private bool FlagV
+ {
+ get { return (P & 0x40) != 0; }
+ set { P = (byte)((P & ~0x40) | (value ? 0x40 : 0x00)); }
+ }
+
+ /// Negative Flag
+ private bool FlagN
+ {
+ get { return (P & 0x80) != 0; }
+ set { P = (byte)((P & ~0x80) | (value ? 0x80 : 0x00)); }
+ }
+
+ public int TotalExecutedCycles;
+ public int PendingCycles;
+
+ public Func ReadMemory;
+ public Action WriteMemory;
+
+ public void UnregisterMemoryMapper()
+ {
+ ReadMemory = null;
+ WriteMemory = null;
+ }
+
+ public ushort ReadWord(ushort address)
+ {
+ byte l = ReadMemory(address);
+ byte h = ReadMemory(++address);
+ return (ushort)((h << 8) | l);
+ }
+
+ private void WriteWord(ushort address, ushort value)
+ {
+ byte l = (byte)(value & 0xFF);
+ byte h = (byte)(value >> 8);
+ WriteMemory(address, l);
+ WriteMemory(++address, h);
+ }
+
+ private ushort ReadWordPageWrap(ushort address)
+ {
+ ushort highAddress = (ushort)((address & 0xFF00) + ((address + 1) & 0xFF));
+ return (ushort)(ReadMemory(address) | (ReadMemory(highAddress) << 8));
+ }
+
+ private static readonly byte[] TableNZ =
+ {
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+ };
+ }
+}
\ No newline at end of file