From 151a7f3b334e8dcabceadb0a3c939c685afdcc7c Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 25 Apr 2015 21:15:17 +0100 Subject: [PATCH 01/11] Fixes for CPU emulation relating to page-crossing: bugs #264, #278; and opcode (abx,x): bug #271 --- source/CPU.cpp | 2 +- source/CPU/cpu6502.h | 135 ++++++++++++++--------------- source/CPU/cpu65C02.h | 75 ++++++++-------- source/CPU/cpu65d02.h | 149 ++++++++++++++++---------------- source/CPU/cpu_general.inl | 42 ++++++--- source/CPU/cpu_instructions.inl | 88 +++++++++---------- 6 files changed, 251 insertions(+), 240 deletions(-) diff --git a/source/CPU.cpp b/source/CPU.cpp index fadaecbb..fec4da4a 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -63,7 +63,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // What about these: // . 65C02: STZ?, TRB?, TSB? -// . Answer: TRB & TSB don't have affected adressing modes +// . Answer: TRB & TSB don't have affected addressing modes // . STZ probably doesn't add a cycle since otherwise it would be slower than STA which doesn't make sense. // // NB. 'Zero-page indexed' opcodes wrap back to zero-page. diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index eb140bac..98df871c 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -35,7 +35,6 @@ static DWORD Cpu6502 (DWORD uTotalCycles) WORD val; AF_TO_EF ULONG uExecutedCycles = 0; - BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA) WORD base; g_bDebugBreakpointHit = 0; @@ -67,27 +66,27 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x08: PHP CYC(3) break; case 0x09: IMM ORA CYC(2) break; case 0x0A: asl CYC(2) break; - case 0x0B: $ IMM ANC CYC(2) break; // invald - case 0x0C: $ abx NOP CYC(4) break; + case 0x0B: $ IMM ANC CYC(2) break; // invalid + case 0x0C: $ ABSX_SLOW NOP CYC(4) break; case 0x0D: ABS ORA CYC(4) break; case 0x0E: ABS ASLn CYC(6) break; case 0x0F: $ ABS ASO CYC(6) break; // invalid case 0x10: REL BPL CYC(2) break; - case 0x11: idy ORA CYC(5) break; + case 0x11: INDY_SLOW ORA CYC(5) break; case 0x12: $ HLT CYC(2) break; - case 0x13: $ idy ASO CYC(8) break; // invalid + case 0x13: $ INDY_FAST ASO CYC(8) break; // invalid case 0x14: $ zpx NOP CYC(4) break; case 0x15: zpx ORA CYC(4) break; case 0x16: zpx ASLn CYC(6) break; case 0x17: $ zpx ASO CYC(6) break; // invalid case 0x18: CLC CYC(2) break; - case 0x19: aby ORA CYC(4) break; + case 0x19: ABSY_SLOW ORA CYC(4) break; case 0x1A: $ NOP CYC(2) break; - case 0x1B: $ aby ASO CYC(7) break; // invalid - case 0x1C: $ abx NOP CYC(4) break; - case 0x1D: abx ORA CYC(4) break; - case 0x1E: abx ASLn CYC(6) break; - case 0x1F: $ abx ASO CYC(7) break; // invalid + case 0x1B: $ ABSY_FAST ASO CYC(7) break; // invalid + case 0x1C: $ ABSX_SLOW NOP CYC(4) break; + case 0x1D: ABSX_SLOW ORA CYC(4) break; + case 0x1E: ABSX_NMOS_RMW ASLn CYC(7) break; + case 0x1F: $ ABSX_FAST ASO CYC(7) break; // invalid case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; case 0x22: $ HLT CYC(2) break; @@ -105,21 +104,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x2E: ABS ROLn CYC(6) break; case 0x2F: $ ABS RLA CYC(6) break; case 0x30: REL BMI CYC(2) break; - case 0x31: idy AND CYC(5) break; + case 0x31: INDY_SLOW AND CYC(5) break; case 0x32: $ HLT CYC(2) break; - case 0x33: $ idy RLA CYC(8) break; // invalid + case 0x33: $ INDY_FAST RLA CYC(8) break; // invalid case 0x34: $ zpx NOP CYC(4) break; case 0x35: zpx AND CYC(4) break; case 0x36: zpx ROLn CYC(6) break; case 0x37: $ zpx RLA CYC(6) break; case 0x38: SEC CYC(2) break; - case 0x39: aby AND CYC(4) break; + case 0x39: ABSY_SLOW AND CYC(4) break; case 0x3A: $ NOP CYC(2) break; - case 0x3B: $ aby RLA CYC(7) break; // invalid - case 0x3C: $ abx NOP CYC(4) break; - case 0x3D: abx AND CYC(4) break; - case 0x3E: abx ROLn CYC(6) break; - case 0x3F: $ abx RLA CYC(7) break; // invalid + case 0x3B: $ ABSY_FAST RLA CYC(7) break; // invalid + case 0x3C: $ ABSX_SLOW NOP CYC(4) break; + case 0x3D: ABSX_SLOW AND CYC(4) break; + case 0x3E: ABSX_FAST ROLn CYC(6) break; + case 0x3F: $ ABSX_FAST RLA CYC(7) break; // invalid case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; case 0x42: $ HLT CYC(2) break; @@ -137,21 +136,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x4E: ABS LSRn CYC(6) break; case 0x4F: $ ABS LSE CYC(6) break; case 0x50: REL BVC CYC(2) break; - case 0x51: idy EOR CYC(5) break; + case 0x51: INDY_SLOW EOR CYC(5) break; case 0x52: $ HLT CYC(2) break; - case 0x53: $ idy LSE CYC(8) break; + case 0x53: $ INDY_FAST LSE CYC(8) break; case 0x54: $ zpx NOP CYC(4) break; case 0x55: zpx EOR CYC(4) break; case 0x56: zpx LSRn CYC(6) break; case 0x57: $ zpx LSE CYC(6) break; // invalid case 0x58: CLI CYC(2) break; - case 0x59: aby EOR CYC(4) break; + case 0x59: ABSY_SLOW EOR CYC(4) break; case 0x5A: $ NOP CYC(2) break; - case 0x5B: $ aby LSE CYC(7) break; // invalid - case 0x5C: $ abx NOP CYC(4) break; - case 0x5D: abx EOR CYC(4) break; - case 0x5E: abx LSRn CYC(6) break; - case 0x5F: $ abx LSE CYC(7) break; + case 0x5B: $ ABSY_FAST LSE CYC(7) break; // invalid + case 0x5C: $ ABSX_SLOW NOP CYC(4) break; + case 0x5D: ABSX_SLOW EOR CYC(4) break; + case 0x5E: ABSX_FAST LSRn CYC(6) break; + case 0x5F: $ ABSX_FAST LSE CYC(7) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADCn CYC(6) break; case 0x62: $ HLT CYC(2) break; @@ -164,26 +163,26 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x69: IMM ADCn CYC(2) break; case 0x6A: ror CYC(2) break; case 0x6B: $ IMM ARR CYC(2) break; // invalid - case 0x6C: IABSNMOS JMP CYC(6) break; + case 0x6C: IABSNMOS JMP CYC(5) break; // GH#264 case 0x6D: ABS ADCn CYC(4) break; case 0x6E: ABS RORn CYC(6) break; case 0x6F: $ ABS RRA CYC(6) break; // invalid case 0x70: REL BVS CYC(2) break; - case 0x71: idy ADCn CYC(5) break; + case 0x71: INDY_SLOW ADCn CYC(5) break; case 0x72: $ HLT CYC(2) break; - case 0x73: $ idy RRA CYC(8) break; // invalid + case 0x73: $ INDY_FAST RRA CYC(8) break; // invalid case 0x74: $ zpx NOP CYC(4) break; case 0x75: zpx ADCn CYC(4) break; case 0x76: zpx RORn CYC(6) break; case 0x77: $ zpx RRA CYC(6) break; // invalid case 0x78: SEI CYC(2) break; - case 0x79: aby ADCn CYC(4) break; + case 0x79: ABSY_SLOW ADCn CYC(4) break; case 0x7A: $ NOP CYC(2) break; - case 0x7B: $ aby RRA CYC(7) break; // invalid - case 0x7C: $ abx NOP CYC(4) break; - case 0x7D: abx ADCn CYC(4) break; - case 0x7E: abx RORn CYC(6) break; - case 0x7F: $ abx RRA CYC(7) break; // invalid + case 0x7B: $ ABSY_FAST RRA CYC(7) break; // invalid + case 0x7C: $ ABSX_SLOW NOP CYC(4) break; + case 0x7D: ABSX_SLOW ADCn CYC(4) break; + case 0x7E: ABSX_FAST RORn CYC(6) break; + case 0x7F: $ ABSX_FAST RRA CYC(7) break; // invalid case 0x80: $ IMM NOP CYC(2) break; case 0x81: idx STA CYC(6) break; case 0x82: $ IMM NOP CYC(2) break; @@ -201,21 +200,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: $ ABS AXS CYC(4) break; // invalid case 0x90: REL BCC CYC(2) break; - case 0x91: idy STA CYC(6) break; + case 0x91: INDY_FAST STA CYC(6) break; case 0x92: $ HLT CYC(2) break; - case 0x93: $ idy AXA CYC(6) break; // invalid + case 0x93: $ INDY_FAST AXA CYC(6) break; // invalid case 0x94: zpx STY CYC(4) break; case 0x95: zpx STA CYC(4) break; case 0x96: zpy STX CYC(4) break; case 0x97: $ zpy AXS CYC(4) break; // invalid case 0x98: TYA CYC(2) break; - case 0x99: aby STA CYC(5) break; + case 0x99: ABSY_FAST STA CYC(5) break; case 0x9A: TXS CYC(2) break; - case 0x9B: $ aby TAS CYC(5) break; // invalid - case 0x9C: $ abx SAY CYC(5) break; // invalid - case 0x9D: abx STA CYC(5) break; - case 0x9E: $ aby XAS CYC(5) break; - case 0x9F: $ aby AXA CYC(5) break; + case 0x9B: $ ABSY_FAST TAS CYC(5) break; // invalid + case 0x9C: $ ABSX_FAST SAY CYC(5) break; // invalid + case 0x9D: ABSX_FAST STA CYC(5) break; + case 0x9E: $ ABSY_FAST XAS CYC(5) break; + case 0x9F: $ ABSY_FAST AXA CYC(5) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; case 0xA2: IMM LDX CYC(2) break; @@ -233,21 +232,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: $ ABS LAX CYC(4) break; // invalid case 0xB0: REL BCS CYC(2) break; - case 0xB1: idy LDA CYC(5) break; + case 0xB1: INDY_SLOW LDA CYC(5) break; case 0xB2: $ HLT CYC(2) break; - case 0xB3: $ idy LAX CYC(5) break; + case 0xB3: $ INDY_SLOW LAX CYC(5) break; case 0xB4: zpx LDY CYC(4) break; case 0xB5: zpx LDA CYC(4) break; case 0xB6: zpy LDX CYC(4) break; case 0xB7: $ zpy LAX CYC(4) break; // invalid case 0xB8: CLV CYC(2) break; - case 0xB9: aby LDA CYC(4) break; + case 0xB9: ABSY_SLOW LDA CYC(4) break; case 0xBA: TSX CYC(2) break; - case 0xBB: $ aby LAS CYC(4) break; // invalid - case 0xBC: abx LDY CYC(4) break; - case 0xBD: abx LDA CYC(4) break; - case 0xBE: aby LDX CYC(4) break; - case 0xBF: $ aby LAX CYC(4) break; // invalid + case 0xBB: $ ABSY_SLOW LAS CYC(4) break; // invalid + case 0xBC: ABSX_SLOW LDY CYC(4) break; + case 0xBD: ABSX_SLOW LDA CYC(4) break; + case 0xBE: ABSY_SLOW LDX CYC(4) break; + case 0xBF: $ ABSY_SLOW LAX CYC(4) break; // invalid case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; case 0xC2: $ IMM NOP CYC(2) break; @@ -265,21 +264,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xCE: ABS DECn CYC(5) break; case 0xCF: $ ABS DCM CYC(6) break; // invalid case 0xD0: REL BNE CYC(2) break; - case 0xD1: idy CMP CYC(5) break; + case 0xD1: INDY_SLOW CMP CYC(5) break; case 0xD2: $ HLT CYC(2) break; - case 0xD3: $ idy DCM CYC(8) break; // invalid + case 0xD3: $ INDY_FAST DCM CYC(8) break; // invalid case 0xD4: $ zpx NOP CYC(4) break; case 0xD5: zpx CMP CYC(4) break; case 0xD6: zpx DECn CYC(6) break; case 0xD7: $ zpx DCM CYC(6) break; // invalid case 0xD8: CLD CYC(2) break; - case 0xD9: aby CMP CYC(4) break; + case 0xD9: ABSY_SLOW CMP CYC(4) break; case 0xDA: $ NOP CYC(2) break; - case 0xDB: $ aby DCM CYC(7) break; // invalid - case 0xDC: $ abx NOP CYC(4) break; - case 0xDD: abx CMP CYC(4) break; - case 0xDE: abx DECn CYC(6) break; - case 0xDF: $ abx DCM CYC(7) break; // invalid + case 0xDB: $ ABSY_FAST DCM CYC(7) break; // invalid + case 0xDC: $ ABSX_SLOW NOP CYC(4) break; + case 0xDD: ABSX_SLOW CMP CYC(4) break; + case 0xDE: ABSX_NMOS_RMW DECn CYC(7) break; + case 0xDF: $ ABSX_FAST DCM CYC(7) break; // invalid case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCn CYC(6) break; case 0xE2: $ IMM NOP CYC(2) break; @@ -297,21 +296,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xEE: ABS INCn CYC(6) break; case 0xEF: $ ABS INS CYC(6) break; // invalid case 0xF0: REL BEQ CYC(2) break; - case 0xF1: idy SBCn CYC(5) break; + case 0xF1: INDY_SLOW SBCn CYC(5) break; case 0xF2: $ HLT CYC(2) break; - case 0xF3: $ idy INS CYC(8) break; // invalid + case 0xF3: $ INDY_FAST INS CYC(8) break; // invalid case 0xF4: $ zpx NOP CYC(4) break; case 0xF5: zpx SBCn CYC(4) break; case 0xF6: zpx INCn CYC(6) break; case 0xF7: $ zpx INS CYC(6) break; // invalid case 0xF8: SED CYC(2) break; - case 0xF9: aby SBCn CYC(4) break; + case 0xF9: ABSY_SLOW SBCn CYC(4) break; case 0xFA: $ NOP CYC(2) break; - case 0xFB: $ aby INS CYC(7) break; - case 0xFC: $ abx NOP CYC(4) break; - case 0xFD: abx SBCn CYC(4) break; - case 0xFE: abx INCn CYC(6) break; - case 0xFF: $ abx INS CYC(7) break; + case 0xFB: $ ABSY_FAST INS CYC(7) break; + case 0xFC: $ ABSX_SLOW NOP CYC(4) break; + case 0xFD: ABSX_SLOW SBCn CYC(4) break; + case 0xFE: ABSX_NMOS_RMW INCn CYC(7) break; + case 0xFF: $ ABSX_FAST INS CYC(7) break; } } diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index 43223ef9..2dcd1ca6 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -38,7 +38,6 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) WORD val; AF_TO_EF ULONG uExecutedCycles = 0; - BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA) WORD base; g_bDebugBreakpointHit = 0; @@ -76,7 +75,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x0E: ABS ASLc CYC(6) break; case 0x0F: $ NOP CYC(2) break; case 0x10: REL BPL CYC(2) break; - case 0x11: idy ORA CYC(5) break; + case 0x11: INDY_SLOW ORA CYC(5) break; case 0x12: izp ORA CYC(5) break; case 0x13: $ NOP CYC(2) break; case 0x14: ZPG TRB CYC(5) break; @@ -84,12 +83,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x16: zpx ASLc CYC(6) break; case 0x17: $ NOP CYC(2) break; case 0x18: CLC CYC(2) break; - case 0x19: aby ORA CYC(4) break; + case 0x19: ABSY_SLOW ORA CYC(4) break; case 0x1A: INA CYC(2) break; case 0x1B: $ NOP CYC(2) break; case 0x1C: ABS TRB CYC(6) break; - case 0x1D: abx ORA CYC(4) break; - case 0x1E: abx ASLc CYC(6) break; + case 0x1D: ABSX_SLOW ORA CYC(4) break; + case 0x1E: ABSX_SLOW ASLc CYC(6) break; case 0x1F: $ NOP CYC(2) break; case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; @@ -108,7 +107,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x2E: ABS ROLc CYC(6) break; case 0x2F: $ NOP CYC(2) break; case 0x30: REL BMI CYC(2) break; - case 0x31: idy AND CYC(5) break; + case 0x31: INDY_SLOW AND CYC(5) break; case 0x32: izp AND CYC(5) break; case 0x33: $ NOP CYC(2) break; case 0x34: zpx BIT CYC(4) break; @@ -116,12 +115,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x36: zpx ROLc CYC(6) break; case 0x37: $ NOP CYC(2) break; case 0x38: SEC CYC(2) break; - case 0x39: aby AND CYC(4) break; + case 0x39: ABSY_SLOW AND CYC(4) break; case 0x3A: DEA CYC(2) break; case 0x3B: $ NOP CYC(2) break; - case 0x3C: abx BIT CYC(4) break; - case 0x3D: abx AND CYC(4) break; - case 0x3E: abx ROLc CYC(6) break; + case 0x3C: ABSX_SLOW BIT CYC(4) break; + case 0x3D: ABSX_SLOW AND CYC(4) break; + case 0x3E: ABSX_SLOW ROLc CYC(6) break; case 0x3F: $ NOP CYC(2) break; case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; @@ -140,7 +139,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x4E: ABS LSRc CYC(6) break; case 0x4F: $ NOP CYC(2) break; case 0x50: REL BVC CYC(2) break; - case 0x51: idy EOR CYC(5) break; + case 0x51: INDY_SLOW EOR CYC(5) break; case 0x52: izp EOR CYC(5) break; case 0x53: $ NOP CYC(2) break; case 0x54: $ zpx NOP CYC(4) break; @@ -148,12 +147,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x56: zpx LSRc CYC(6) break; case 0x57: $ NOP CYC(2) break; case 0x58: CLI CYC(2) break; - case 0x59: aby EOR CYC(4) break; + case 0x59: ABSY_SLOW EOR CYC(4) break; case 0x5A: PHY CYC(3) break; case 0x5B: $ NOP CYC(2) break; - case 0x5C: $ abx NOP CYC(8) break; - case 0x5D: abx EOR CYC(4) break; - case 0x5E: abx LSRc CYC(6) break; + case 0x5C: $ ABSX_SLOW NOP CYC(8) break; + case 0x5D: ABSX_SLOW EOR CYC(4) break; + case 0x5E: ABSX_SLOW LSRc CYC(6) break; case 0x5F: $ NOP CYC(2) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADCc CYC(6) break; @@ -172,7 +171,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x6E: ABS RORc CYC(6) break; case 0x6F: $ NOP CYC(2) break; case 0x70: REL BVS CYC(2) break; - case 0x71: idy ADCc CYC(5) break; + case 0x71: INDY_SLOW ADCc CYC(5) break; case 0x72: izp ADCc CYC(5) break; case 0x73: $ NOP CYC(2) break; case 0x74: zpx STZ CYC(4) break; @@ -180,12 +179,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x76: zpx RORc CYC(6) break; case 0x77: $ NOP CYC(2) break; case 0x78: SEI CYC(2) break; - case 0x79: aby ADCc CYC(4) break; + case 0x79: ABSY_SLOW ADCc CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: $ NOP CYC(2) break; case 0x7C: IABSX JMP CYC(6) break; // - case 0x7D: abx ADCc CYC(4) break; - case 0x7E: abx RORc CYC(6) break; + case 0x7D: ABSX_SLOW ADCc CYC(4) break; + case 0x7E: ABSX_SLOW RORc CYC(6) break; case 0x7F: $ NOP CYC(2) break; case 0x80: REL BRA CYC(2) break; case 0x81: idx STA CYC(6) break; @@ -204,7 +203,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: $ NOP CYC(2) break; case 0x90: REL BCC CYC(2) break; - case 0x91: idy STA CYC(6) break; + case 0x91: INDY_FAST STA CYC(6) break; case 0x92: izp STA CYC(5) break; case 0x93: $ NOP CYC(2) break; case 0x94: zpx STY CYC(4) break; @@ -212,12 +211,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x96: zpy STX CYC(4) break; case 0x97: $ NOP CYC(2) break; case 0x98: TYA CYC(2) break; - case 0x99: aby STA CYC(5) break; + case 0x99: ABSY_FAST STA CYC(5) break; case 0x9A: TXS CYC(2) break; case 0x9B: $ NOP CYC(2) break; case 0x9C: ABS STZ CYC(4) break; - case 0x9D: abx STA CYC(5) break; - case 0x9E: abx STZ CYC(5) break; + case 0x9D: ABSX_FAST STA CYC(5) break; + case 0x9E: ABSX_FAST STZ CYC(5) break; case 0x9F: $ NOP CYC(2) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; @@ -236,7 +235,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: $ NOP CYC(2) break; case 0xB0: REL BCS CYC(2) break; - case 0xB1: idy LDA CYC(5) break; + case 0xB1: INDY_SLOW LDA CYC(5) break; case 0xB2: izp LDA CYC(5) break; case 0xB3: $ NOP CYC(2) break; case 0xB4: zpx LDY CYC(4) break; @@ -244,12 +243,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xB6: zpy LDX CYC(4) break; case 0xB7: $ NOP CYC(2) break; case 0xB8: CLV CYC(2) break; - case 0xB9: aby LDA CYC(4) break; + case 0xB9: ABSY_SLOW LDA CYC(4) break; case 0xBA: TSX CYC(2) break; case 0xBB: $ NOP CYC(2) break; - case 0xBC: abx LDY CYC(4) break; - case 0xBD: abx LDA CYC(4) break; - case 0xBE: aby LDX CYC(4) break; + case 0xBC: ABSX_SLOW LDY CYC(4) break; + case 0xBD: ABSX_SLOW LDA CYC(4) break; + case 0xBE: ABSY_SLOW LDX CYC(4) break; case 0xBF: $ NOP CYC(2) break; case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; @@ -268,7 +267,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xCE: ABS DECc CYC(5) break; case 0xCF: $ NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; - case 0xD1: idy CMP CYC(5) break; + case 0xD1: INDY_SLOW CMP CYC(5) break; case 0xD2: izp CMP CYC(5) break; case 0xD3: $ NOP CYC(2) break; case 0xD4: $ zpx NOP CYC(4) break; @@ -276,12 +275,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xD6: zpx DECc CYC(6) break; case 0xD7: $ NOP CYC(2) break; case 0xD8: CLD CYC(2) break; - case 0xD9: aby CMP CYC(4) break; + case 0xD9: ABSY_SLOW CMP CYC(4) break; case 0xDA: PHX CYC(3) break; case 0xDB: $ NOP CYC(2) break; - case 0xDC: $ abx NOP CYC(4) break; - case 0xDD: abx CMP CYC(4) break; - case 0xDE: abx DECc CYC(6) break; + case 0xDC: $ ABSX_SLOW NOP CYC(4) break; + case 0xDD: ABSX_SLOW CMP CYC(4) break; + case 0xDE: ABSX_SLOW DECc CYC(6) break; case 0xDF: $ NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCc CYC(6) break; @@ -300,7 +299,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xEE: ABS INCc CYC(6) break; case 0xEF: $ NOP CYC(2) break; case 0xF0: REL BEQ CYC(2) break; - case 0xF1: idy SBCc CYC(5) break; + case 0xF1: INDY_SLOW SBCc CYC(5) break; case 0xF2: izp SBCc CYC(5) break; case 0xF3: $ NOP CYC(2) break; case 0xF4: $ zpx NOP CYC(4) break; @@ -308,12 +307,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xF6: zpx INCc CYC(6) break; case 0xF7: $ NOP CYC(2) break; case 0xF8: SED CYC(2) break; - case 0xF9: aby SBCc CYC(4) break; + case 0xF9: ABSY_SLOW SBCc CYC(4) break; case 0xFA: PLX CYC(4) break; case 0xFB: $ NOP CYC(2) break; - case 0xFC: $ abx NOP CYC(4) break; - case 0xFD: abx SBCc CYC(4) break; - case 0xFE: abx INCc CYC(6) break; + case 0xFC: $ ABSX_SLOW NOP CYC(4) break; + case 0xFD: ABSX_SLOW SBCc CYC(4) break; + case 0xFE: ABSX_SLOW INCc CYC(6) break; case 0xFF: $ NOP CYC(2) break; } #undef $ diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 80b800fa..286497bf 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -97,7 +97,6 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) WORD val; AF_TO_EF ULONG uExecutedCycles = 0; - BOOL bSlowerOnPagecross = 0; // Set if opcode writes to memory (eg. ASL, STA) WORD base; g_bDebugBreakpointHit = 0; @@ -147,7 +146,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x0E: ABS ASL_CMOS CYC(6) break; case 0x0F: INV NOP CYC(2) break; case 0x10: REL BPL CYC(2) break; - case 0x11: idy ORA CYC(5) break; + case 0x11: INDY_SLOW ORA CYC(5) break; case 0x12: izp ORA CYC(5) break; case 0x13: INV NOP CYC(2) break; case 0x14: ZPG TRB CYC(5) break; @@ -155,12 +154,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x16: zpx ASL_CMOS CYC(6) break; case 0x17: INV NOP CYC(2) break; case 0x18: CLC CYC(2) break; - case 0x19: aby ORA CYC(4) break; + case 0x19: ABSY_SLOW ORA CYC(4) break; case 0x1A: INA CYC(2) break; case 0x1B: INV NOP CYC(2) break; case 0x1C: ABS TRB CYC(6) break; - case 0x1D: abx ORA CYC(4) break; - case 0x1E: abx ASL_CMOS CYC(6) break; + case 0x1D: ABSX_SLOW ORA CYC(4) break; + case 0x1E: ABSX_SLOW ASL_CMOS CYC(6) break; case 0x1F: INV NOP CYC(2) break; case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; @@ -179,7 +178,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x2E: ABS ROL_CMOS CYC(6) break; case 0x2F: INV NOP CYC(2) break; case 0x30: REL BMI CYC(2) break; - case 0x31: idy AND CYC(5) break; + case 0x31: INDY_SLOW AND CYC(5) break; case 0x32: izp AND CYC(5) break; case 0x33: INV NOP CYC(2) break; case 0x34: zpx BIT CYC(4) break; @@ -187,12 +186,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x36: zpx ROL_CMOS CYC(6) break; case 0x37: INV NOP CYC(2) break; case 0x38: SEC CYC(2) break; - case 0x39: aby AND CYC(4) break; + case 0x39: ABSY_SLOW AND CYC(4) break; case 0x3A: DEA CYC(2) break; case 0x3B: INV NOP CYC(2) break; - case 0x3C: abx BIT CYC(4) break; - case 0x3D: abx AND CYC(4) break; - case 0x3E: abx ROL_CMOS CYC(6) break; + case 0x3C: ABSX_SLOW BIT CYC(4) break; + case 0x3D: ABSX_SLOW AND CYC(4) break; + case 0x3E: ABSX_SLOW ROL_CMOS CYC(6) break; case 0x3F: INV NOP CYC(2) break; case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; @@ -211,7 +210,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x4E: ABS LSR_CMOS CYC(6) break; case 0x4F: INV NOP CYC(2) break; case 0x50: REL BVC CYC(2) break; - case 0x51: idy EOR CYC(5) break; + case 0x51: INDY_SLOW EOR CYC(5) break; case 0x52: izp EOR CYC(5) break; case 0x53: INV NOP CYC(2) break; case 0x54: INV zpx NOP CYC(4) break; @@ -219,12 +218,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x56: zpx LSR_CMOS CYC(6) break; case 0x57: INV NOP CYC(2) break; case 0x58: CLI CYC(2) break; - case 0x59: aby EOR CYC(4) break; + case 0x59: ABSY_SLOW EOR CYC(4) break; case 0x5A: PHY CYC(3) break; case 0x5B: INV NOP CYC(2) break; - case 0x5C: INV abx NOP CYC(8) break; - case 0x5D: abx EOR CYC(4) break; - case 0x5E: abx LSR_CMOS CYC(6) break; + case 0x5C: INV ABSX_SLOW NOP CYC(8) break; + case 0x5D: ABSX_SLOW EOR CYC(4) break; + case 0x5E: ABSX_SLOW LSR_CMOS CYC(6) break; case 0x5F: INV NOP CYC(2) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADC_CMOS CYC(6) break; @@ -243,7 +242,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x6E: ABS ROR_CMOS CYC(6) break; case 0x6F: INV NOP CYC(2) break; case 0x70: REL BVS CYC(2) break; - case 0x71: idy ADC_CMOS CYC(5) break; + case 0x71: INDY_SLOW ADC_CMOS CYC(5) break; case 0x72: izp ADC_CMOS CYC(5) break; case 0x73: INV NOP CYC(2) break; case 0x74: zpx STZ CYC(4) break; @@ -251,12 +250,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x76: zpx ROR_CMOS CYC(6) break; case 0x77: INV NOP CYC(2) break; case 0x78: SEI CYC(2) break; - case 0x79: aby ADC_CMOS CYC(4) break; + case 0x79: ABSY_SLOW ADC_CMOS CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: INV NOP CYC(2) break; case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP - case 0x7D: abx ADC_CMOS CYC(4) break; - case 0x7E: abx ROR_CMOS CYC(6) break; + case 0x7D: ABSX_SLOW ADC_CMOS CYC(4) break; + case 0x7E: ABSX_SLOW ROR_CMOS CYC(6) break; case 0x7F: INV NOP CYC(2) break; case 0x80: REL BRA CYC(2) break; case 0x81: idx STA CYC(6) break; @@ -275,7 +274,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: INV NOP CYC(2) break; case 0x90: REL BCC CYC(2) break; - case 0x91: idy STA CYC(6) break; + case 0x91: INDY_FAST STA CYC(6) break; case 0x92: izp STA CYC(5) break; case 0x93: INV NOP CYC(2) break; case 0x94: zpx STY CYC(4) break; @@ -283,12 +282,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x96: zpy STX CYC(4) break; case 0x97: INV NOP CYC(2) break; case 0x98: TYA CYC(2) break; - case 0x99: aby STA CYC(5) break; + case 0x99: ABSY_FAST STA CYC(5) break; case 0x9A: TXS CYC(2) break; case 0x9B: INV NOP CYC(2) break; case 0x9C: ABS STZ CYC(4) break; - case 0x9D: abx STA CYC(5) break; - case 0x9E: abx STZ CYC(5) break; + case 0x9D: ABSX_FAST STA CYC(5) break; + case 0x9E: ABSX_FAST STZ CYC(5) break; case 0x9F: INV NOP CYC(2) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; @@ -307,7 +306,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: INV NOP CYC(2) break; case 0xB0: REL BCS CYC(2) break; - case 0xB1: idy LDA CYC(5) break; + case 0xB1: INDY_SLOW LDA CYC(5) break; case 0xB2: izp LDA CYC(5) break; case 0xB3: INV NOP CYC(2) break; case 0xB4: zpx LDY CYC(4) break; @@ -315,12 +314,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xB6: zpy LDX CYC(4) break; case 0xB7: INV NOP CYC(2) break; case 0xB8: CLV CYC(2) break; - case 0xB9: aby LDA CYC(4) break; + case 0xB9: ABSY_SLOW LDA CYC(4) break; case 0xBA: TSX CYC(2) break; case 0xBB: INV NOP CYC(2) break; - case 0xBC: abx LDY CYC(4) break; - case 0xBD: abx LDA CYC(4) break; - case 0xBE: aby LDX CYC(4) break; + case 0xBC: ABSX_SLOW LDY CYC(4) break; + case 0xBD: ABSX_SLOW LDA CYC(4) break; + case 0xBE: ABSY_SLOW LDX CYC(4) break; case 0xBF: INV NOP CYC(2) break; case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; @@ -339,7 +338,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xCE: ABS DEC_CMOS CYC(5) break; case 0xCF: INV NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; - case 0xD1: idy CMP CYC(5) break; + case 0xD1: INDY_SLOW CMP CYC(5) break; case 0xD2: izp CMP CYC(5) break; case 0xD3: INV NOP CYC(2) break; case 0xD4: INV zpx NOP CYC(4) break; @@ -347,12 +346,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xD6: zpx DEC_CMOS CYC(6) break; case 0xD7: INV NOP CYC(2) break; case 0xD8: CLD CYC(2) break; - case 0xD9: aby CMP CYC(4) break; + case 0xD9: ABSY_SLOW CMP CYC(4) break; case 0xDA: PHX CYC(3) break; case 0xDB: INV NOP CYC(2) break; - case 0xDC: INV abx NOP CYC(4) break; - case 0xDD: abx CMP CYC(4) break; - case 0xDE: abx DEC_CMOS CYC(6) break; + case 0xDC: INV ABSX_SLOW NOP CYC(4) break; + case 0xDD: ABSX_SLOW CMP CYC(4) break; + case 0xDE: ABSX_SLOW DEC_CMOS CYC(6) break; case 0xDF: INV NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBC_CMOS CYC(6) break; @@ -371,7 +370,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xEE: ABS INC_CMOS CYC(6) break; case 0xEF: INV NOP CYC(2) break; case 0xF0: REL BEQ CYC(2) break; - case 0xF1: idy SBC_CMOS CYC(5) break; + case 0xF1: INDY_SLOW SBC_CMOS CYC(5) break; case 0xF2: izp SBC_CMOS CYC(5) break; case 0xF3: INV NOP CYC(2) break; case 0xF4: INV zpx NOP CYC(4) break; @@ -379,12 +378,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xF6: zpx INC_CMOS CYC(6) break; case 0xF7: INV NOP CYC(2) break; case 0xF8: SED CYC(2) break; - case 0xF9: aby SBC_CMOS CYC(4) break; + case 0xF9: ABSY_SLOW SBC_CMOS CYC(4) break; case 0xFA: PLX CYC(4) break; case 0xFB: INV NOP CYC(2) break; - case 0xFC: INV abx NOP CYC(4) break; - case 0xFD: abx SBC_CMOS CYC(4) break; - case 0xFE: abx INC_CMOS CYC(6) break; + case 0xFC: INV ABSX_SLOW NOP CYC(4) break; + case 0xFD: ABSX_SLOW SBC_CMOS CYC(4) break; + case 0xFE: ABSX_SLOW INC_CMOS CYC(6) break; case 0xFF: INV NOP CYC(2) break; */ // Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode @@ -406,7 +405,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x0E: ABS ASLc CYC(6) break; case 0x0F: $ NOP CYC(2) break; case 0x10: REL BPL CYC(2) break; - case 0x11: idy ORA CYC(5) break; + case 0x11: INDY_SLOW ORA CYC(5) break; case 0x12: izp ORA CYC(5) break; case 0x13: $ NOP CYC(2) break; case 0x14: ZPG TRB CYC(5) break; @@ -414,12 +413,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x16: zpx ASLc CYC(6) break; case 0x17: $ NOP CYC(2) break; case 0x18: CLC CYC(2) break; - case 0x19: aby ORA CYC(4) break; + case 0x19: ABSY_SLOW ORA CYC(4) break; case 0x1A: INA CYC(2) break; case 0x1B: $ NOP CYC(2) break; case 0x1C: ABS TRB CYC(6) break; - case 0x1D: abx ORA CYC(4) break; - case 0x1E: abx ASLc CYC(6) break; + case 0x1D: ABSX_SLOW ORA CYC(4) break; + case 0x1E: ABSX_SLOW ASLc CYC(6) break; case 0x1F: $ NOP CYC(2) break; case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; @@ -438,7 +437,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x2E: ABS ROLc CYC(6) break; case 0x2F: $ NOP CYC(2) break; case 0x30: REL BMI CYC(2) break; - case 0x31: idy AND CYC(5) break; + case 0x31: INDY_SLOW AND CYC(5) break; case 0x32: izp AND CYC(5) break; case 0x33: $ NOP CYC(2) break; case 0x34: zpx BIT CYC(4) break; @@ -446,12 +445,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x36: zpx ROLc CYC(6) break; case 0x37: $ NOP CYC(2) break; case 0x38: SEC CYC(2) break; - case 0x39: aby AND CYC(4) break; + case 0x39: ABSY_SLOW AND CYC(4) break; case 0x3A: DEA CYC(2) break; case 0x3B: $ NOP CYC(2) break; - case 0x3C: abx BIT CYC(4) break; - case 0x3D: abx AND CYC(4) break; - case 0x3E: abx ROLc CYC(6) break; + case 0x3C: ABSX_SLOW BIT CYC(4) break; + case 0x3D: ABSX_SLOW AND CYC(4) break; + case 0x3E: ABSX_SLOW ROLc CYC(6) break; case 0x3F: $ NOP CYC(2) break; case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; @@ -470,7 +469,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x4E: ABS LSRc CYC(6) break; case 0x4F: $ NOP CYC(2) break; case 0x50: REL BVC CYC(2) break; - case 0x51: idy EOR CYC(5) break; + case 0x51: INDY_SLOW EOR CYC(5) break; case 0x52: izp EOR CYC(5) break; case 0x53: $ NOP CYC(2) break; case 0x54: $ zpx NOP CYC(4) break; @@ -478,12 +477,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x56: zpx LSRc CYC(6) break; case 0x57: $ NOP CYC(2) break; case 0x58: CLI CYC(2) break; - case 0x59: aby EOR CYC(4) break; + case 0x59: ABSY_SLOW EOR CYC(4) break; case 0x5A: PHY CYC(3) break; case 0x5B: $ NOP CYC(2) break; - case 0x5C: $ abx NOP CYC(8) break; - case 0x5D: abx EOR CYC(4) break; - case 0x5E: abx LSRc CYC(6) break; + case 0x5C: $ ABSX_SLOW NOP CYC(8) break; + case 0x5D: ABSX_SLOW EOR CYC(4) break; + case 0x5E: ABSX_SLOW LSRc CYC(6) break; case 0x5F: $ NOP CYC(2) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADCc CYC(6) break; @@ -502,7 +501,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x6E: ABS RORc CYC(6) break; case 0x6F: $ NOP CYC(2) break; case 0x70: REL BVS CYC(2) break; - case 0x71: idy ADCc CYC(5) break; + case 0x71: INDY_SLOW ADCc CYC(5) break; case 0x72: izp ADCc CYC(5) break; case 0x73: $ NOP CYC(2) break; case 0x74: zpx STZ CYC(4) break; @@ -510,12 +509,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x76: zpx RORc CYC(6) break; case 0x77: $ NOP CYC(2) break; case 0x78: SEI CYC(2) break; - case 0x79: aby ADCc CYC(4) break; + case 0x79: ABSY_SLOW ADCc CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: $ NOP CYC(2) break; case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP - case 0x7D: abx ADCc CYC(4) break; - case 0x7E: abx RORc CYC(6) break; + case 0x7D: ABSX_SLOW ADCc CYC(4) break; + case 0x7E: ABSX_SLOW RORc CYC(6) break; case 0x7F: $ NOP CYC(2) break; case 0x80: REL BRA CYC(2) break; case 0x81: idx STA CYC(6) break; @@ -534,7 +533,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: $ NOP CYC(2) break; case 0x90: REL BCC CYC(2) break; - case 0x91: idy STA CYC(6) break; + case 0x91: INDY_FAST STA CYC(6) break; case 0x92: izp STA CYC(5) break; case 0x93: $ NOP CYC(2) break; case 0x94: zpx STY CYC(4) break; @@ -542,12 +541,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x96: zpy STX CYC(4) break; case 0x97: $ NOP CYC(2) break; case 0x98: TYA CYC(2) break; - case 0x99: aby STA CYC(5) break; + case 0x99: ABSY_FAST STA CYC(5) break; case 0x9A: TXS CYC(2) break; case 0x9B: $ NOP CYC(2) break; case 0x9C: ABS STZ CYC(4) break; - case 0x9D: abx STA CYC(5) break; - case 0x9E: abx STZ CYC(5) break; + case 0x9D: ABSX_FAST STA CYC(5) break; + case 0x9E: ABSX_FAST STZ CYC(5) break; case 0x9F: $ NOP CYC(2) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; @@ -566,7 +565,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: $ NOP CYC(2) break; case 0xB0: REL BCS CYC(2) break; - case 0xB1: idy LDA CYC(5) break; + case 0xB1: INDY_SLOW LDA CYC(5) break; case 0xB2: izp LDA CYC(5) break; case 0xB3: $ NOP CYC(2) break; case 0xB4: zpx LDY CYC(4) break; @@ -574,12 +573,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xB6: zpy LDX CYC(4) break; case 0xB7: $ NOP CYC(2) break; case 0xB8: CLV CYC(2) break; - case 0xB9: aby LDA CYC(4) break; + case 0xB9: ABSY_SLOW LDA CYC(4) break; case 0xBA: TSX CYC(2) break; case 0xBB: $ NOP CYC(2) break; - case 0xBC: abx LDY CYC(4) break; - case 0xBD: abx LDA CYC(4) break; - case 0xBE: aby LDX CYC(4) break; + case 0xBC: ABSX_SLOW LDY CYC(4) break; + case 0xBD: ABSX_SLOW LDA CYC(4) break; + case 0xBE: ABSY_SLOW LDX CYC(4) break; case 0xBF: $ NOP CYC(2) break; case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; @@ -598,7 +597,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xCE: ABS DECc CYC(5) break; case 0xCF: $ NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; - case 0xD1: idy CMP CYC(5) break; + case 0xD1: INDY_SLOW CMP CYC(5) break; case 0xD2: izp CMP CYC(5) break; case 0xD3: $ NOP CYC(2) break; case 0xD4: $ zpx NOP CYC(4) break; @@ -606,12 +605,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xD6: zpx DECc CYC(6) break; case 0xD7: $ NOP CYC(2) break; case 0xD8: CLD CYC(2) break; - case 0xD9: aby CMP CYC(4) break; + case 0xD9: ABSY_SLOW CMP CYC(4) break; case 0xDA: PHX CYC(3) break; case 0xDB: $ NOP CYC(2) break; - case 0xDC: $ abx NOP CYC(4) break; - case 0xDD: abx CMP CYC(4) break; - case 0xDE: abx DECc CYC(6) break; + case 0xDC: $ ABSX_SLOW NOP CYC(4) break; + case 0xDD: ABSX_SLOW CMP CYC(4) break; + case 0xDE: ABSX_SLOW DECc CYC(6) break; case 0xDF: $ NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCc CYC(6) break; @@ -630,7 +629,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xEE: ABS INCc CYC(6) break; case 0xEF: $ NOP CYC(2) break; case 0xF0: REL BEQ CYC(2) break; - case 0xF1: idy SBCc CYC(5) break; + case 0xF1: INDY_SLOW SBCc CYC(5) break; case 0xF2: izp SBCc CYC(5) break; case 0xF3: $ NOP CYC(2) break; case 0xF4: $ zpx NOP CYC(4) break; @@ -638,12 +637,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xF6: zpx INCc CYC(6) break; case 0xF7: $ NOP CYC(2) break; case 0xF8: SED CYC(2) break; - case 0xF9: aby SBCc CYC(4) break; + case 0xF9: ABSY_SLOW SBCc CYC(4) break; case 0xFA: PLX CYC(4) break; case 0xFB: $ NOP CYC(2) break; - case 0xFC: $ abx NOP CYC(4) break; - case 0xFD: abx SBCc CYC(4) break; - case 0xFE: abx INCc CYC(6) break; + case 0xFC: $ ABSX_SLOW NOP CYC(4) break; + case 0xFD: ABSX_SLOW SBCc CYC(4) break; + case 0xFE: ABSX_SLOW INCc CYC(6) break; case 0xFF: $ NOP CYC(2) break; } #undef $ diff --git a/source/CPU/cpu_general.inl b/source/CPU/cpu_general.inl index 25f7086e..355d37ec 100644 --- a/source/CPU/cpu_general.inl +++ b/source/CPU/cpu_general.inl @@ -89,10 +89,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -#define CHECK_PAGE_CHANGE if (bSlowerOnPagecross) { \ - if ((base ^ addr) & 0xFF00) \ - uExtraCycles=1; \ - } +// TODO Optimization Note: uExtraCycles = ((base ^ addr) >> 8) & 1; +#define CHECK_PAGE_CHANGE if ((base ^ addr) & 0xFF00) \ + uExtraCycles=1; /**************************************************************************** * @@ -102,8 +101,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2; #define IABSX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2; -#define ABSX base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE; -#define ABSY base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; + +#define ABSX_SLOW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE; +#define ABSX_FAST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; + +#define ABSY_SLOW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; +#define ABSY_FAST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; + +// NMOS read-modify-write opcodes (asl/dec/inc abs,x) don't take an extra cycle if page-crossing (GH#271) +#define ABSX_NMOS_RMW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; + // TODO Optimization Note: uExtraCycles = ((base & 0xFF) + 1) >> 8; #define IABSCMOS base = *(LPWORD)(mem+regs.pc); \ addr = *(LPWORD)(mem+base); \ @@ -121,13 +128,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA addr = *(mem+0xFF)+(((WORD)*mem)<<8); \ else \ addr = *(LPWORD)(mem+base); -#define INDY if (*(mem+regs.pc) == 0xFF) \ + +#define INDY_SLOW if (*(mem+regs.pc) == 0xFF) /*SLOW: incurs an extra cycle for page-crossing*/ \ base = *(mem+0xFF)+(((WORD)*mem)<<8); \ else \ base = *(LPWORD)(mem+*(mem+regs.pc)); \ regs.pc++; \ addr = base+(WORD)regs.y; \ CHECK_PAGE_CHANGE; +#define INDY_FAST if (*(mem+regs.pc) == 0xFF) /*FAST: no extra cycle for page-crossing*/ \ + base = *(mem+0xFF)+(((WORD)*mem)<<8); \ + else \ + base = *(LPWORD)(mem+*(mem+regs.pc)); \ + regs.pc++; \ + addr = base+(WORD)regs.y; + #define IZPG base = *(mem+regs.pc++); \ if (base == 0xFF) \ addr = *(mem+0xFF)+(((WORD)*mem)<<8); \ @@ -143,12 +158,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF; // Tidy 3 char addressing modes to keep the opcode table visually aligned, clean, and readable. -#undef abx -#undef abx -#undef aby +//#undef abx +//#undef aby #undef asl #undef idx -#undef idy +//#undef idy #undef imm #undef izp #undef lsr @@ -158,11 +172,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #undef zpx #undef zpy -#define abx ABSX -#define aby ABSY +//#define abx ABSX // ABSX -> ABSX_SLOW or ABSX_FAST +//#define aby ABSY // ABSY -> ABSY_SLOW or ABSY_FAST #define asl ASLA // Arithmetic Shift Left #define idx INDX -#define idy INDY +//#define idy INDY // INDY -> INDY_SLOW or INDY_FAST #define imm IMM #define izp IZPG #define lsr LSRA // Logical Shift Right diff --git a/source/CPU/cpu_instructions.inl b/source/CPU/cpu_instructions.inl index 84e68bae..69a2d45b 100644 --- a/source/CPU/cpu_instructions.inl +++ b/source/CPU/cpu_instructions.inl @@ -177,7 +177,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // ========== -#define ADC_NMOS bSlowerOnPagecross = 1; \ +#define ADC_NMOS /*bSlowerOnPagecross = 1;*/ \ temp = READ; \ if (regs.ps & AF_DECIMAL) { \ val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \ @@ -203,7 +203,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA regs.a = val & 0xFF; \ SETNZ(regs.a); \ } -#define ADC_CMOS bSlowerOnPagecross = 1; \ +#define ADC_CMOS /*bSlowerOnPagecross = 1*/; \ temp = READ; \ flagv = !((regs.a ^ temp) & 0x80); \ if (regs.ps & AF_DECIMAL) { \ @@ -242,7 +242,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagn = 0; \ regs.a >>= 1; \ SETZ(regs.a) -#define AND bSlowerOnPagecross = 1; \ +#define AND /*bSlowerOnPagecross = 1;*/ \ regs.a &= READ; \ SETNZ(regs.a) #define ANC regs.a &= READ; \ @@ -274,12 +274,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagv = ((val & 0x40) ^ ((val & 0x20) << 1)); \ regs.a = (val & 0xFF); \ } -#define ASL_NMOS bSlowerOnPagecross = 0; \ +#define ASL_NMOS /*bSlowerOnPagecross = 0;*/ \ val = READ << 1; \ flagc = (val > 0xFF); \ SETNZ(val) \ WRITE(val) -#define ASL_CMOS bSlowerOnPagecross = 1; \ +#define ASL_CMOS /*bSlowerOnPagecross = 1*/; \ val = READ << 1; \ flagc = (val > 0xFF); \ SETNZ(val) \ @@ -288,21 +288,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagc = (val > 0xFF); \ SETNZ(val) \ regs.a = (BYTE)val; -#define ASO bSlowerOnPagecross = 0; \ +#define ASO /*bSlowerOnPagecross = 0;*/ \ val = READ << 1; \ flagc = (val > 0xFF); \ WRITE(val) \ regs.a |= val; \ SETNZ(regs.a) -#define AXA bSlowerOnPagecross = 0;/*FIXME: $93 case is still unclear*/ \ +#define AXA /*bSlowerOnPagecross = 0;*//*FIXME: $93 case is still unclear*/ \ val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \ WRITE(val) -#define AXS bSlowerOnPagecross = 0; \ +#define AXS /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.a & regs.x) #define BCC if (!flagc) BRANCH_TAKEN; #define BCS if ( flagc) BRANCH_TAKEN; #define BEQ if ( flagz) BRANCH_TAKEN; -#define BIT bSlowerOnPagecross = 1; \ +#define BIT /*bSlowerOnPagecross = 1;*/ \ val = READ; \ flagz = !(regs.a & val); \ flagn = val & 0x80; \ @@ -325,7 +325,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define CLD regs.ps &= ~AF_DECIMAL; #define CLI regs.ps &= ~AF_INTERRUPT; #define CLV flagv = 0; -#define CMP bSlowerOnPagecross = 1; \ +#define CMP /*bSlowerOnPagecross = 1;*/ \ val = READ; \ flagc = (regs.a >= val); \ val = regs.a-val; \ @@ -338,7 +338,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagc = (regs.y >= val); \ val = regs.y-val; \ SETNZ(val) -#define DCM bSlowerOnPagecross = 0; \ +#define DCM /*bSlowerOnPagecross = 0;*/ \ val = READ-1; \ WRITE(val) \ flagc = (regs.a >= val); \ @@ -346,11 +346,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(val) #define DEA --regs.a; \ SETNZ(regs.a) -#define DEC_NMOS bSlowerOnPagecross = 0; \ +#define DEC_NMOS /*bSlowerOnPagecross = 0;*/ \ val = READ-1; \ SETNZ(val) \ WRITE(val) -#define DEC_CMOS bSlowerOnPagecross = 1; \ +#define DEC_CMOS /*bSlowerOnPagecross = 1;*/ \ val = READ-1; \ SETNZ(val) \ WRITE(val) @@ -358,22 +358,22 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.x) #define DEY --regs.y; \ SETNZ(regs.y) -#define EOR bSlowerOnPagecross = 1; \ +#define EOR /*bSlowerOnPagecross = 1;*/ \ regs.a ^= READ; \ SETNZ(regs.a) #define HLT regs.bJammed = 1; \ --regs.pc; #define INA ++regs.a; \ SETNZ(regs.a) -#define INC_NMOS bSlowerOnPagecross = 0; \ +#define INC_NMOS /*bSlowerOnPagecross = 0;*/ \ val = READ+1; \ SETNZ(val) \ WRITE(val) -#define INC_CMOS bSlowerOnPagecross = 1; \ +#define INC_CMOS /*bSlowerOnPagecross = 1;*/ \ val = READ+1; \ SETNZ(val) \ WRITE(val) -#define INS bSlowerOnPagecross = 0; \ +#define INS /*bSlowerOnPagecross = 0;*/ \ val = READ+1; \ WRITE(val) \ temp = val; \ @@ -408,38 +408,38 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA PUSH(regs.pc >> 8) \ PUSH(regs.pc & 0xFF) \ regs.pc = addr; -#define LAS bSlowerOnPagecross = 1; \ +#define LAS /*bSlowerOnPagecross = 1*/; \ val = (BYTE)(READ & regs.sp); \ regs.a = regs.x = (BYTE) val; \ regs.sp = val | 0x100; \ SETNZ(val) -#define LAX bSlowerOnPagecross = 1; \ +#define LAX /*bSlowerOnPagecross = 1;*/ \ regs.a = regs.x = READ; \ SETNZ(regs.a) -#define LDA bSlowerOnPagecross = 1; \ +#define LDA /*bSlowerOnPagecross = 1;*/ \ regs.a = READ; \ SETNZ(regs.a) -#define LDX bSlowerOnPagecross = 1; \ +#define LDX /*bSlowerOnPagecross = 1;*/ \ regs.x = READ; \ SETNZ(regs.x) -#define LDY bSlowerOnPagecross = 1; \ +#define LDY /*bSlowerOnPagecross = 1;*/ \ regs.y = READ; \ SETNZ(regs.y) -#define LSE bSlowerOnPagecross = 0; \ +#define LSE /*bSlowerOnPagecross = 0;*/ \ val = READ; \ flagc = (val & 1); \ val >>= 1; \ WRITE(val) \ regs.a ^= val; \ SETNZ(regs.a) -#define LSR_NMOS bSlowerOnPagecross = 0; \ +#define LSR_NMOS /*bSlowerOnPagecross = 0;*/ \ val = READ; \ flagc = (val & 1); \ flagn = 0; \ val >>= 1; \ SETZ(val) \ WRITE(val) -#define LSR_CMOS bSlowerOnPagecross = 1; \ +#define LSR_CMOS /*bSlowerOnPagecross = 1;*/ \ val = READ; \ flagc = (val & 1); \ flagn = 0; \ @@ -450,12 +450,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagn = 0; \ regs.a >>= 1; \ SETZ(regs.a) -#define NOP bSlowerOnPagecross = 1; +#define NOP /*bSlowerOnPagecross = 1;*/ #define OAL regs.a |= 0xEE; \ regs.a &= READ; \ regs.x = regs.a; \ SETNZ(regs.a) -#define ORA bSlowerOnPagecross = 1; \ +#define ORA /*bSlowerOnPagecross = 1;*/ \ regs.a |= READ; \ SETNZ(regs.a) #define PHA PUSH(regs.a) @@ -471,18 +471,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.x) #define PLY regs.y = POP; \ SETNZ(regs.y) -#define RLA bSlowerOnPagecross = 0; \ +#define RLA /*bSlowerOnPagecross = 0;*/ \ val = (READ << 1) | flagc; \ flagc = (val > 0xFF); \ WRITE(val) \ regs.a &= val; \ SETNZ(regs.a) -#define ROL_NMOS bSlowerOnPagecross = 0; \ +#define ROL_NMOS /*bSlowerOnPagecross = 0;*/ \ val = (READ << 1) | flagc; \ flagc = (val > 0xFF); \ SETNZ(val) \ WRITE(val) -#define ROL_CMOS bSlowerOnPagecross = 1; \ +#define ROL_CMOS /*bSlowerOnPagecross = 1;*/ \ val = (READ << 1) | flagc; \ flagc = (val > 0xFF); \ SETNZ(val) \ @@ -491,13 +491,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagc = (val > 0xFF); \ regs.a = val & 0xFF; \ SETNZ(regs.a); -#define ROR_NMOS bSlowerOnPagecross = 0; \ +#define ROR_NMOS /*bSlowerOnPagecross = 0;*/ \ temp = READ; \ val = (temp >> 1) | (flagc ? 0x80 : 0); \ flagc = (temp & 1); \ SETNZ(val) \ WRITE(val) -#define ROR_CMOS bSlowerOnPagecross = 1; \ +#define ROR_CMOS /*bSlowerOnPagecross = 1;*/ \ temp = READ; \ val = (temp >> 1) | (flagc ? 0x80 : 0); \ flagc = (temp & 1); \ @@ -507,7 +507,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagc = (regs.a & 1); \ regs.a = val & 0xFF; \ SETNZ(regs.a) -#define RRA bSlowerOnPagecross = 0; \ +#define RRA /*bSlowerOnPagecross = 0;*/ \ temp = READ; \ val = (temp >> 1) | (flagc ? 0x80 : 0); \ flagc = (temp & 1); \ @@ -549,10 +549,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA flagc = (temp >= val); \ regs.x = temp-val; \ SETNZ(regs.x) -#define SAY bSlowerOnPagecross = 0; \ +#define SAY /*bSlowerOnPagecross = 0;*/ \ val = regs.y & (((base >> 8) + 1) & 0xFF); \ WRITE(val) -#define SBC_NMOS bSlowerOnPagecross = 1; \ +#define SBC_NMOS /*bSlowerOnPagecross = 1;*/ \ temp = READ; \ temp2 = regs.a - temp - !flagc; \ if (regs.ps & AF_DECIMAL) { \ @@ -576,7 +576,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA regs.a = val & 0xFF; \ SETNZ(regs.a); \ } -#define SBC_CMOS bSlowerOnPagecross = 1; \ +#define SBC_CMOS /*bSlowerOnPagecross = 1;*/ \ temp = READ; \ flagv = ((regs.a ^ temp) & 0x80); \ if (regs.ps & AF_DECIMAL) { \ @@ -622,15 +622,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define SEC flagc = 1; #define SED regs.ps |= AF_DECIMAL; #define SEI regs.ps |= AF_INTERRUPT; -#define STA bSlowerOnPagecross = 0; \ +#define STA /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.a) -#define STX bSlowerOnPagecross = 0; \ +#define STX /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.x) -#define STY bSlowerOnPagecross = 0; \ +#define STY /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.y) -#define STZ bSlowerOnPagecross = 0; \ +#define STZ /*bSlowerOnPagecross = 0;*/ \ WRITE(0) -#define TAS bSlowerOnPagecross = 0; \ +#define TAS /*bSlowerOnPagecross = 0;*/ \ val = regs.a & regs.x; \ regs.sp = 0x100 | val; \ val &= (((base >> 8) + 1) & 0xFF); \ @@ -639,12 +639,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.x) #define TAY regs.y = regs.a; \ SETNZ(regs.y) -#define TRB bSlowerOnPagecross = 0; \ +#define TRB /*bSlowerOnPagecross = 0;*/ \ val = READ; \ flagz = !(regs.a & val); \ val &= ~regs.a; \ WRITE(val) -#define TSB bSlowerOnPagecross = 0; \ +#define TSB /*bSlowerOnPagecross = 0;*/ \ val = READ; \ flagz = !(regs.a & val); \ val |= regs.a; \ @@ -659,7 +659,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define XAA regs.a = regs.x; \ regs.a &= READ; \ SETNZ(regs.a) -#define XAS bSlowerOnPagecross = 0; \ +#define XAS /*bSlowerOnPagecross = 0;*/ \ val = regs.x & (((base >> 8) + 1) & 0xFF); \ WRITE(val) From 2597dd90454f6bd3063a9853f54b30807031cac5 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 2 May 2015 21:44:03 +0100 Subject: [PATCH 02/11] Fixed undocumented AXA opcodes when page-crossing (#282) --- source/CPU/cpu6502.h | 4 ++-- source/CPU/cpu_general.inl | 11 +++++++++++ source/CPU/cpu_instructions.inl | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index 98df871c..54f70219 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -202,7 +202,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x90: REL BCC CYC(2) break; case 0x91: INDY_FAST STA CYC(6) break; case 0x92: $ HLT CYC(2) break; - case 0x93: $ INDY_FAST AXA CYC(6) break; // invalid + case 0x93: $ INDY_INV AXA CYC(6) break; // invalid case 0x94: zpx STY CYC(4) break; case 0x95: zpx STA CYC(4) break; case 0x96: zpy STX CYC(4) break; @@ -214,7 +214,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x9C: $ ABSX_FAST SAY CYC(5) break; // invalid case 0x9D: ABSX_FAST STA CYC(5) break; case 0x9E: $ ABSY_FAST XAS CYC(5) break; - case 0x9F: $ ABSY_FAST AXA CYC(5) break; + case 0x9F: $ ABSY_INV AXA CYC(5) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; case 0xA2: IMM LDX CYC(2) break; diff --git a/source/CPU/cpu_general.inl b/source/CPU/cpu_general.inl index 355d37ec..a26f4406 100644 --- a/source/CPU/cpu_general.inl +++ b/source/CPU/cpu_general.inl @@ -93,6 +93,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define CHECK_PAGE_CHANGE if ((base ^ addr) & 0xFF00) \ uExtraCycles=1; +#define CHECK_PAGE_CHANGE_INV if ((base ^ addr) & 0xFF00) \ + uExtraCycles=1; /* Reuse as flag to opcode to replace hi-addr! */ + /**************************************************************************** * * ADDRESSING MODE MACROS @@ -107,6 +110,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ABSY_SLOW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; #define ABSY_FAST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; +#define ABSY_INV base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE_INV; // NMOS read-modify-write opcodes (asl/dec/inc abs,x) don't take an extra cycle if page-crossing (GH#271) #define ABSX_NMOS_RMW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; @@ -142,6 +146,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA base = *(LPWORD)(mem+*(mem+regs.pc)); \ regs.pc++; \ addr = base+(WORD)regs.y; +#define INDY_INV if (*(mem+regs.pc) == 0xFF) /*FAST: no extra cycle for page-crossing*/ \ + base = *(mem+0xFF)+(((WORD)*mem)<<8); \ + else \ + base = *(LPWORD)(mem+*(mem+regs.pc)); \ + regs.pc++; \ + addr = base+(WORD)regs.y; \ + CHECK_PAGE_CHANGE_INV; #define IZPG base = *(mem+regs.pc++); \ if (base == 0xFF) \ diff --git a/source/CPU/cpu_instructions.inl b/source/CPU/cpu_instructions.inl index 69a2d45b..624ac82d 100644 --- a/source/CPU/cpu_instructions.inl +++ b/source/CPU/cpu_instructions.inl @@ -294,8 +294,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA WRITE(val) \ regs.a |= val; \ SETNZ(regs.a) -#define AXA /*bSlowerOnPagecross = 0;*//*FIXME: $93 case is still unclear*/ \ +#define AXA /*bSlowerOnPagecross = 0;*/ \ val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \ + if (uExtraCycles) {addr = (val<<8) | (addr&0xff); uExtraCycles = 0;} /* NB. Use 'uExtraCycles' to flag page-cross only */ \ WRITE(val) #define AXS /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.a & regs.x) From 48be79551b05cf173c203e8aa468717e4b3f6ff9 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 3 May 2015 19:04:30 +0100 Subject: [PATCH 03/11] Fixed other undocumented SAY,TAS,XAS (ie. like AXA) when page-crossing (#282) --- source/CPU/cpu6502.h | 4 ++-- source/CPU/cpu_general.inl | 18 +++++------------- source/CPU/cpu_instructions.inl | 6 ++++-- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index 54f70219..98df871c 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -202,7 +202,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x90: REL BCC CYC(2) break; case 0x91: INDY_FAST STA CYC(6) break; case 0x92: $ HLT CYC(2) break; - case 0x93: $ INDY_INV AXA CYC(6) break; // invalid + case 0x93: $ INDY_FAST AXA CYC(6) break; // invalid case 0x94: zpx STY CYC(4) break; case 0x95: zpx STA CYC(4) break; case 0x96: zpy STX CYC(4) break; @@ -214,7 +214,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x9C: $ ABSX_FAST SAY CYC(5) break; // invalid case 0x9D: ABSX_FAST STA CYC(5) break; case 0x9E: $ ABSY_FAST XAS CYC(5) break; - case 0x9F: $ ABSY_INV AXA CYC(5) break; + case 0x9F: $ ABSY_FAST AXA CYC(5) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; case 0xA2: IMM LDX CYC(2) break; diff --git a/source/CPU/cpu_general.inl b/source/CPU/cpu_general.inl index a26f4406..b6846045 100644 --- a/source/CPU/cpu_general.inl +++ b/source/CPU/cpu_general.inl @@ -93,9 +93,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define CHECK_PAGE_CHANGE if ((base ^ addr) & 0xFF00) \ uExtraCycles=1; -#define CHECK_PAGE_CHANGE_INV if ((base ^ addr) & 0xFF00) \ - uExtraCycles=1; /* Reuse as flag to opcode to replace hi-addr! */ - /**************************************************************************** * * ADDRESSING MODE MACROS @@ -110,12 +107,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ABSY_SLOW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; #define ABSY_FAST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; -#define ABSY_INV base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE_INV; // NMOS read-modify-write opcodes (asl/dec/inc abs,x) don't take an extra cycle if page-crossing (GH#271) #define ABSX_NMOS_RMW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; -// TODO Optimization Note: uExtraCycles = ((base & 0xFF) + 1) >> 8; +// TODO Optimization Note (just for IABSCMOS): uExtraCycles = ((base & 0xFF) + 1) >> 8; #define IABSCMOS base = *(LPWORD)(mem+regs.pc); \ addr = *(LPWORD)(mem+base); \ if ((base & 0xFF) == 0xFF) uExtraCycles=1; \ @@ -123,10 +119,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define IABSNMOS base = *(LPWORD)(mem+regs.pc); \ if ((base & 0xFF) == 0xFF) \ addr = *(mem+base)+((WORD)*(mem+(base&0xFF00))<<8);\ - else \ + else \ addr = *(LPWORD)(mem+base); \ regs.pc += 2; + #define IMM addr = regs.pc++; + #define INDX base = ((*(mem+regs.pc++))+regs.x) & 0xFF; \ if (base == 0xFF) \ addr = *(mem+0xFF)+(((WORD)*mem)<<8); \ @@ -146,19 +144,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA base = *(LPWORD)(mem+*(mem+regs.pc)); \ regs.pc++; \ addr = base+(WORD)regs.y; -#define INDY_INV if (*(mem+regs.pc) == 0xFF) /*FAST: no extra cycle for page-crossing*/ \ - base = *(mem+0xFF)+(((WORD)*mem)<<8); \ - else \ - base = *(LPWORD)(mem+*(mem+regs.pc)); \ - regs.pc++; \ - addr = base+(WORD)regs.y; \ - CHECK_PAGE_CHANGE_INV; #define IZPG base = *(mem+regs.pc++); \ if (base == 0xFF) \ addr = *(mem+0xFF)+(((WORD)*mem)<<8); \ else \ addr = *(LPWORD)(mem+base); + #define REL addr = (signed char)*(mem+regs.pc++); // TODO Optimization Note: diff --git a/source/CPU/cpu_instructions.inl b/source/CPU/cpu_instructions.inl index 624ac82d..89eb25f4 100644 --- a/source/CPU/cpu_instructions.inl +++ b/source/CPU/cpu_instructions.inl @@ -296,7 +296,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.a) #define AXA /*bSlowerOnPagecross = 0;*/ \ val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \ - if (uExtraCycles) {addr = (val<<8) | (addr&0xff); uExtraCycles = 0;} /* NB. Use 'uExtraCycles' to flag page-cross only */ \ + if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ WRITE(val) #define AXS /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.a & regs.x) @@ -552,6 +552,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.x) #define SAY /*bSlowerOnPagecross = 0;*/ \ val = regs.y & (((base >> 8) + 1) & 0xFF); \ + if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ WRITE(val) #define SBC_NMOS /*bSlowerOnPagecross = 1;*/ \ temp = READ; \ @@ -635,6 +636,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA val = regs.a & regs.x; \ regs.sp = 0x100 | val; \ val &= (((base >> 8) + 1) & 0xFF); \ + if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ WRITE(val) #define TAX regs.x = regs.a; \ SETNZ(regs.x) @@ -662,5 +664,5 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.a) #define XAS /*bSlowerOnPagecross = 0;*/ \ val = regs.x & (((base >> 8) + 1) & 0xFF); \ + if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ WRITE(val) - From 54f2425168fc5f2467c686ac2af9944eb46c3b7c Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 3 May 2015 21:44:24 +0100 Subject: [PATCH 04/11] Add unit test for #282 --- ApplewinExpress9.00.sln | 6 + test/TestCPU6502/TestCPU6502.cpp | 299 ++++++++++++++++++++++++++++ test/TestCPU6502/TestCPU6502.vcproj | 205 +++++++++++++++++++ test/TestCPU6502/stdafx.cpp | 8 + test/TestCPU6502/stdafx.h | 11 + 5 files changed, 529 insertions(+) create mode 100644 test/TestCPU6502/TestCPU6502.cpp create mode 100644 test/TestCPU6502/TestCPU6502.vcproj create mode 100644 test/TestCPU6502/stdafx.cpp create mode 100644 test/TestCPU6502/stdafx.h diff --git a/ApplewinExpress9.00.sln b/ApplewinExpress9.00.sln index 6fbec8fe..0b5bd62c 100644 --- a/ApplewinExpress9.00.sln +++ b/ApplewinExpress9.00.sln @@ -11,6 +11,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib-Express9. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zip_lib", "zip_lib\zip_lib.vcproj", "{709278B8-C583-4BD8-90DE-4E4F35A3BD8B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCPU6502", "test\TestCPU6502\TestCPU6502.vcproj", "{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -29,6 +31,10 @@ Global {709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Debug|Win32.Build.0 = Debug|Win32 {709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Release|Win32.ActiveCfg = Release|Win32 {709278B8-C583-4BD8-90DE-4E4F35A3BD8B}.Release|Win32.Build.0 = Release|Win32 + {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Debug|Win32.ActiveCfg = Debug|Win32 + {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Debug|Win32.Build.0 = Debug|Win32 + {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Release|Win32.ActiveCfg = Release|Win32 + {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp new file mode 100644 index 00000000..7ca2d2d9 --- /dev/null +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -0,0 +1,299 @@ +#include "stdafx.h" + +#include "../../source/Applewin.h" +#include "../../source/CPU.h" + +// From Applewin.cpp +eCPU g_ActiveCPU = CPU_6502; +enum AppMode_e g_nAppMode = MODE_RUNNING; + +// From Memory.cpp +LPBYTE memwrite[0x100]; // TODO: Init +LPBYTE mem = NULL; // TODO: Init +LPBYTE memdirty = NULL; // TODO: Init +iofunction IORead[256] = {0}; // TODO: Init +iofunction IOWrite[256] = {0}; // TODO: Init + +// From Debugger_Types.h + enum AddressingMode_e // ADDRESSING_MODES_e + { + AM_IMPLIED // Note: SetDebugBreakOnInvalid() assumes this order of first 4 entries + , AM_1 // Invalid 1 Byte + , AM_2 // Invalid 2 Bytes + , AM_3 // Invalid 3 Bytes + }; + +// From CPU.cpp +#define AF_SIGN 0x80 +#define AF_OVERFLOW 0x40 +#define AF_RESERVED 0x20 +#define AF_BREAK 0x10 +#define AF_DECIMAL 0x08 +#define AF_INTERRUPT 0x04 +#define AF_ZERO 0x02 +#define AF_CARRY 0x01 + +regsrec regs; + +static const int IRQ_CHECK_TIMEOUT = 128; +static signed int g_nIrqCheckTimeout = IRQ_CHECK_TIMEOUT; + +static __forceinline int Fetch(BYTE& iOpcode, ULONG uExecutedCycles) +{ + iOpcode = *(mem+regs.pc); + regs.pc++; + return 1; +} + +#define INV IsDebugBreakOnInvalid(AM_1); +inline int IsDebugBreakOnInvalid( int iOpcodeType ) +{ + return 0; +} + +static __forceinline void DoIrqProfiling(DWORD uCycles) +{ +} + +static __forceinline void CheckInterruptSources(ULONG uExecutedCycles) +{ +} + +static __forceinline void NMI(ULONG& uExecutedCycles, UINT& uExtraCycles, BOOL& flagc, BOOL& flagn, BOOL& flagv, BOOL& flagz) +{ +} + +static __forceinline void IRQ(ULONG& uExecutedCycles, UINT& uExtraCycles, BOOL& flagc, BOOL& flagn, BOOL& flagv, BOOL& flagz) +{ +} + +void RequestDebugger() +{ +} + +// From Debug.h +inline int IsDebugBreakpointHit() +{ + return 0; +} + +// From Debug.cpp +int g_bDebugBreakpointHit = 0; + +// From z80.cpp +DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles) +{ + return 0; +} + +#include "../../source/cpu/cpu_general.inl" +#include "../../source/cpu/cpu_instructions.inl" +#include "../../source/cpu/cpu6502.h" // MOS 6502 + +void init(void) +{ + //mem = new BYTE[64*1024]; + mem = (LPBYTE)VirtualAlloc(NULL,64*1024,MEM_COMMIT,PAGE_READWRITE); + + for (UINT i=0; i<256; i++) + memwrite[i] = mem+i*256; + + memdirty = new BYTE[256]; +} + +void reset(void) +{ + regs.a = 0; + regs.x = 0; + regs.y = 0; + regs.pc = 0x300; + regs.sp = 0x1FF; + regs.ps = 0; + regs.bJammed = 0; +} + +DWORD AXA_ZPY(BYTE a, BYTE x, BYTE y, WORD base) +{ + reset(); + mem[0xfe] = base&0xff; + mem[0xff] = base>>8; + regs.a = a; + regs.x = x; + regs.y = y; + mem[regs.pc+0] = 0x93; + mem[regs.pc+1] = 0xfe; + return Cpu6502(0); +} + +DWORD AXA_ABSY(BYTE a, BYTE x, BYTE y, WORD base) +{ + reset(); + regs.a = a; + regs.x = x; + regs.y = y; + mem[regs.pc+0] = 0x9f; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + return Cpu6502(0); +} + +DWORD SAY_ABSX(BYTE a, BYTE x, BYTE y, WORD base) +{ + reset(); + regs.a = a; + regs.x = x; + regs.y = y; + mem[regs.pc+0] = 0x9c; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + return Cpu6502(0); +} + +DWORD TAS_ABSY(BYTE a, BYTE x, BYTE y, WORD base) +{ + reset(); + regs.a = a; + regs.x = x; + regs.y = y; + mem[regs.pc+0] = 0x9b; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + return Cpu6502(0); +} + +DWORD XAS_ABSY(BYTE a, BYTE x, BYTE y, WORD base) +{ + reset(); + regs.a = a; + regs.x = x; + regs.y = y; + mem[regs.pc+0] = 0x9e; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + return Cpu6502(0); +} + +int test6502_GH282(void) +{ + // axa (zp),y + { + WORD base = 0x20ff, addr = 0x20ff; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0xff, y = 0; + DWORD cycles = AXA_ZPY(a, x, y, base); + if (cycles != 6) return 1; + if (mem[addr] != (a & x & ((base>>8)+1))) return 1; + } + + // axa (zp),y (page-cross) + { + WORD base = 0x20ff, addr = 0x2000; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0xff, y = 1; + DWORD cycles = AXA_ZPY(a, x, y, base); + if (cycles != 6) return 1; + if (mem[addr] != (a & x & ((base>>8)+1))) return 1; + } + + // + + // axa abs,y + { + WORD base = 0x20ff, addr = 0x20ff; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0xff, y = 0; + DWORD cycles = AXA_ABSY(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (a & x & ((base>>8)+1))) return 1; + } + + // axa abs,y (page-cross) + { + WORD base = 0x20ff, addr = 0x2000; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0xff, y = 1; + DWORD cycles = AXA_ABSY(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (a & x & ((base>>8)+1))) return 1; + } + + // + + // say abs,x + { + WORD base = 0x20ff, addr = 0x20ff; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0, y=0x20; + DWORD cycles = SAY_ABSX(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (y & ((base>>8)+1))) return 1; + } + + // say abs,x (page-cross) + { + WORD base = 0x20ff, addr = 0x2000; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 1, y=0x20; + DWORD cycles = SAY_ABSX(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (y & ((base>>8)+1))) return 1; + } + + // + + // tas abs,y + { + WORD base = 0x20ff, addr = 0x20ff; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0xff, y = 0; + DWORD cycles = TAS_ABSY(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (a & x & ((base>>8)+1))) return 1; + if (regs.sp != (0x100 | (a & x))) return 1; + } + + // tas abs,y (page-cross) + { + WORD base = 0x20ff, addr = 0x2000; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0xff, y = 1; + DWORD cycles = TAS_ABSY(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (a & x & ((base>>8)+1))) return 1; + if (regs.sp != (0x100 | (a & x))) return 1; + } + + // + + // xas abs,y + { + WORD base = 0x20ff, addr = 0x20ff; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0x20, y = 0; + DWORD cycles = XAS_ABSY(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (x & ((base>>8)+1))) return 1; + } + + // xas abs,y (page-cross) + { + WORD base = 0x20ff, addr = 0x2000; + mem[addr] = 0xcc; + BYTE a = 0xea, x = 0x20, y = 1; + DWORD cycles = XAS_ABSY(a, x, y, base); + if (cycles != 5) return 1; + if (mem[addr] != (x & ((base>>8)+1))) return 1; + } + + return 0; +} + +int _tmain(int argc, _TCHAR* argv[]) +{ + init(); + reset(); + + int res = test6502_GH282(); + + return res; +} diff --git a/test/TestCPU6502/TestCPU6502.vcproj b/test/TestCPU6502/TestCPU6502.vcproj new file mode 100644 index 00000000..f5582875 --- /dev/null +++ b/test/TestCPU6502/TestCPU6502.vcproj @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/TestCPU6502/stdafx.cpp b/test/TestCPU6502/stdafx.cpp new file mode 100644 index 00000000..eb380001 --- /dev/null +++ b/test/TestCPU6502/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// TestCPU6502.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test/TestCPU6502/stdafx.h b/test/TestCPU6502/stdafx.h new file mode 100644 index 00000000..ca800fd6 --- /dev/null +++ b/test/TestCPU6502/stdafx.h @@ -0,0 +1,11 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include +#include + +#include From 9c7b8f50c661a3262c7e7d503d86bb4dca33420e Mon Sep 17 00:00:00 2001 From: tomcw Date: Mon, 4 May 2015 11:57:24 +0100 Subject: [PATCH 05/11] Extend unit tests for #264 and #271. Refactor: renamed some macros. --- source/CPU/cpu6502.h | 142 ++++++++++++------------ source/CPU/cpu65C02.h | 86 +++++++------- source/CPU/cpu65d02.h | 160 +++++++++++++------------- source/CPU/cpu_general.inl | 34 +++--- source/CPU/cpu_instructions.inl | 34 ++---- test/TestCPU6502/TestCPU6502.cpp | 185 ++++++++++++++++++++++++++++++- 6 files changed, 399 insertions(+), 242 deletions(-) diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index 98df871c..afac92d3 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -67,26 +67,26 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x09: IMM ORA CYC(2) break; case 0x0A: asl CYC(2) break; case 0x0B: $ IMM ANC CYC(2) break; // invalid - case 0x0C: $ ABSX_SLOW NOP CYC(4) break; + case 0x0C: $ ABSX_OPT NOP CYC(4) break; case 0x0D: ABS ORA CYC(4) break; case 0x0E: ABS ASLn CYC(6) break; case 0x0F: $ ABS ASO CYC(6) break; // invalid case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_SLOW ORA CYC(5) break; + case 0x11: INDY_OPT ORA CYC(5) break; case 0x12: $ HLT CYC(2) break; - case 0x13: $ INDY_FAST ASO CYC(8) break; // invalid + case 0x13: $ INDY_CONST ASO CYC(8) break; // invalid case 0x14: $ zpx NOP CYC(4) break; case 0x15: zpx ORA CYC(4) break; case 0x16: zpx ASLn CYC(6) break; case 0x17: $ zpx ASO CYC(6) break; // invalid case 0x18: CLC CYC(2) break; - case 0x19: ABSY_SLOW ORA CYC(4) break; + case 0x19: ABSY_OPT ORA CYC(4) break; case 0x1A: $ NOP CYC(2) break; - case 0x1B: $ ABSY_FAST ASO CYC(7) break; // invalid - case 0x1C: $ ABSX_SLOW NOP CYC(4) break; - case 0x1D: ABSX_SLOW ORA CYC(4) break; - case 0x1E: ABSX_NMOS_RMW ASLn CYC(7) break; - case 0x1F: $ ABSX_FAST ASO CYC(7) break; // invalid + case 0x1B: $ ABSY_CONST ASO CYC(7) break; // invalid + case 0x1C: $ ABSX_OPT NOP CYC(4) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_CONST ASLn CYC(7) break; + case 0x1F: $ ABSX_CONST ASO CYC(7) break; // invalid case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; case 0x22: $ HLT CYC(2) break; @@ -104,21 +104,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x2E: ABS ROLn CYC(6) break; case 0x2F: $ ABS RLA CYC(6) break; case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_SLOW AND CYC(5) break; + case 0x31: INDY_OPT AND CYC(5) break; case 0x32: $ HLT CYC(2) break; - case 0x33: $ INDY_FAST RLA CYC(8) break; // invalid + case 0x33: $ INDY_CONST RLA CYC(8) break; // invalid case 0x34: $ zpx NOP CYC(4) break; case 0x35: zpx AND CYC(4) break; case 0x36: zpx ROLn CYC(6) break; case 0x37: $ zpx RLA CYC(6) break; case 0x38: SEC CYC(2) break; - case 0x39: ABSY_SLOW AND CYC(4) break; + case 0x39: ABSY_OPT AND CYC(4) break; case 0x3A: $ NOP CYC(2) break; - case 0x3B: $ ABSY_FAST RLA CYC(7) break; // invalid - case 0x3C: $ ABSX_SLOW NOP CYC(4) break; - case 0x3D: ABSX_SLOW AND CYC(4) break; - case 0x3E: ABSX_FAST ROLn CYC(6) break; - case 0x3F: $ ABSX_FAST RLA CYC(7) break; // invalid + case 0x3B: $ ABSY_CONST RLA CYC(7) break; // invalid + case 0x3C: $ ABSX_OPT NOP CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_CONST ROLn CYC(6) break; + case 0x3F: $ ABSX_CONST RLA CYC(7) break; // invalid case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; case 0x42: $ HLT CYC(2) break; @@ -136,21 +136,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x4E: ABS LSRn CYC(6) break; case 0x4F: $ ABS LSE CYC(6) break; case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_SLOW EOR CYC(5) break; + case 0x51: INDY_OPT EOR CYC(5) break; case 0x52: $ HLT CYC(2) break; - case 0x53: $ INDY_FAST LSE CYC(8) break; + case 0x53: $ INDY_CONST LSE CYC(8) break; case 0x54: $ zpx NOP CYC(4) break; case 0x55: zpx EOR CYC(4) break; case 0x56: zpx LSRn CYC(6) break; case 0x57: $ zpx LSE CYC(6) break; // invalid case 0x58: CLI CYC(2) break; - case 0x59: ABSY_SLOW EOR CYC(4) break; + case 0x59: ABSY_OPT EOR CYC(4) break; case 0x5A: $ NOP CYC(2) break; - case 0x5B: $ ABSY_FAST LSE CYC(7) break; // invalid - case 0x5C: $ ABSX_SLOW NOP CYC(4) break; - case 0x5D: ABSX_SLOW EOR CYC(4) break; - case 0x5E: ABSX_FAST LSRn CYC(6) break; - case 0x5F: $ ABSX_FAST LSE CYC(7) break; + case 0x5B: $ ABSY_CONST LSE CYC(7) break; // invalid + case 0x5C: $ ABSX_OPT NOP CYC(4) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_CONST LSRn CYC(6) break; + case 0x5F: $ ABSX_CONST LSE CYC(7) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADCn CYC(6) break; case 0x62: $ HLT CYC(2) break; @@ -168,21 +168,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x6E: ABS RORn CYC(6) break; case 0x6F: $ ABS RRA CYC(6) break; // invalid case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_SLOW ADCn CYC(5) break; + case 0x71: INDY_OPT ADCn CYC(5) break; case 0x72: $ HLT CYC(2) break; - case 0x73: $ INDY_FAST RRA CYC(8) break; // invalid + case 0x73: $ INDY_CONST RRA CYC(8) break; // invalid case 0x74: $ zpx NOP CYC(4) break; case 0x75: zpx ADCn CYC(4) break; case 0x76: zpx RORn CYC(6) break; case 0x77: $ zpx RRA CYC(6) break; // invalid case 0x78: SEI CYC(2) break; - case 0x79: ABSY_SLOW ADCn CYC(4) break; + case 0x79: ABSY_OPT ADCn CYC(4) break; case 0x7A: $ NOP CYC(2) break; - case 0x7B: $ ABSY_FAST RRA CYC(7) break; // invalid - case 0x7C: $ ABSX_SLOW NOP CYC(4) break; - case 0x7D: ABSX_SLOW ADCn CYC(4) break; - case 0x7E: ABSX_FAST RORn CYC(6) break; - case 0x7F: $ ABSX_FAST RRA CYC(7) break; // invalid + case 0x7B: $ ABSY_CONST RRA CYC(7) break; // invalid + case 0x7C: $ ABSX_OPT NOP CYC(4) break; + case 0x7D: ABSX_OPT ADCn CYC(4) break; + case 0x7E: ABSX_CONST RORn CYC(6) break; + case 0x7F: $ ABSX_CONST RRA CYC(7) break; // invalid case 0x80: $ IMM NOP CYC(2) break; case 0x81: idx STA CYC(6) break; case 0x82: $ IMM NOP CYC(2) break; @@ -200,21 +200,21 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: $ ABS AXS CYC(4) break; // invalid case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_FAST STA CYC(6) break; + case 0x91: INDY_CONST STA CYC(6) break; case 0x92: $ HLT CYC(2) break; - case 0x93: $ INDY_FAST AXA CYC(6) break; // invalid + case 0x93: $ INDY_CONST AXA CYC(6) break; // invalid case 0x94: zpx STY CYC(4) break; case 0x95: zpx STA CYC(4) break; case 0x96: zpy STX CYC(4) break; case 0x97: $ zpy AXS CYC(4) break; // invalid case 0x98: TYA CYC(2) break; - case 0x99: ABSY_FAST STA CYC(5) break; + case 0x99: ABSY_CONST STA CYC(5) break; case 0x9A: TXS CYC(2) break; - case 0x9B: $ ABSY_FAST TAS CYC(5) break; // invalid - case 0x9C: $ ABSX_FAST SAY CYC(5) break; // invalid - case 0x9D: ABSX_FAST STA CYC(5) break; - case 0x9E: $ ABSY_FAST XAS CYC(5) break; - case 0x9F: $ ABSY_FAST AXA CYC(5) break; + case 0x9B: $ ABSY_CONST TAS CYC(5) break; // invalid + case 0x9C: $ ABSX_CONST SAY CYC(5) break; // invalid + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: $ ABSY_CONST XAS CYC(5) break; + case 0x9F: $ ABSY_CONST AXA CYC(5) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; case 0xA2: IMM LDX CYC(2) break; @@ -232,28 +232,28 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: $ ABS LAX CYC(4) break; // invalid case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_SLOW LDA CYC(5) break; + case 0xB1: INDY_OPT LDA CYC(5) break; case 0xB2: $ HLT CYC(2) break; - case 0xB3: $ INDY_SLOW LAX CYC(5) break; + case 0xB3: $ INDY_OPT LAX CYC(5) break; case 0xB4: zpx LDY CYC(4) break; case 0xB5: zpx LDA CYC(4) break; case 0xB6: zpy LDX CYC(4) break; case 0xB7: $ zpy LAX CYC(4) break; // invalid case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_SLOW LDA CYC(4) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; case 0xBA: TSX CYC(2) break; - case 0xBB: $ ABSY_SLOW LAS CYC(4) break; // invalid - case 0xBC: ABSX_SLOW LDY CYC(4) break; - case 0xBD: ABSX_SLOW LDA CYC(4) break; - case 0xBE: ABSY_SLOW LDX CYC(4) break; - case 0xBF: $ ABSY_SLOW LAX CYC(4) break; // invalid + case 0xBB: $ ABSY_OPT LAS CYC(4) break; // invalid + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; + case 0xBF: $ ABSY_OPT LAX CYC(4) break; // invalid case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; case 0xC2: $ IMM NOP CYC(2) break; case 0xC3: $ idx DCM CYC(8) break; // invalid case 0xC4: ZPG CPY CYC(3) break; case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DECn CYC(5) break; + case 0xC6: ZPG DEC CYC(5) break; case 0xC7: $ ZPG DCM CYC(5) break; // invalid case 0xC8: INY CYC(2) break; case 0xC9: IMM CMP CYC(2) break; @@ -261,31 +261,31 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xCB: $ IMM SAX CYC(2) break; // invalid case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DECn CYC(5) break; + case 0xCE: ABS DEC CYC(5) break; case 0xCF: $ ABS DCM CYC(6) break; // invalid case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_SLOW CMP CYC(5) break; + case 0xD1: INDY_OPT CMP CYC(5) break; case 0xD2: $ HLT CYC(2) break; - case 0xD3: $ INDY_FAST DCM CYC(8) break; // invalid + case 0xD3: $ INDY_CONST DCM CYC(8) break; // invalid case 0xD4: $ zpx NOP CYC(4) break; case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DECn CYC(6) break; + case 0xD6: zpx DEC CYC(6) break; case 0xD7: $ zpx DCM CYC(6) break; // invalid case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_SLOW CMP CYC(4) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; case 0xDA: $ NOP CYC(2) break; - case 0xDB: $ ABSY_FAST DCM CYC(7) break; // invalid - case 0xDC: $ ABSX_SLOW NOP CYC(4) break; - case 0xDD: ABSX_SLOW CMP CYC(4) break; - case 0xDE: ABSX_NMOS_RMW DECn CYC(7) break; - case 0xDF: $ ABSX_FAST DCM CYC(7) break; // invalid + case 0xDB: $ ABSY_CONST DCM CYC(7) break; // invalid + case 0xDC: $ ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_CONST DEC CYC(7) break; + case 0xDF: $ ABSX_CONST DCM CYC(7) break; // invalid case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCn CYC(6) break; case 0xE2: $ IMM NOP CYC(2) break; case 0xE3: $ idx INS CYC(8) break; // invalid case 0xE4: ZPG CPX CYC(3) break; case 0xE5: ZPG SBCn CYC(3) break; - case 0xE6: ZPG INCn CYC(5) break; + case 0xE6: ZPG INC CYC(5) break; case 0xE7: $ ZPG INS CYC(5) break; // invalid case 0xE8: INX CYC(2) break; case 0xE9: IMM SBCn CYC(2) break; @@ -293,24 +293,24 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xEB: $ IMM SBCn CYC(2) break; case 0xEC: ABS CPX CYC(4) break; case 0xED: ABS SBCn CYC(4) break; - case 0xEE: ABS INCn CYC(6) break; + case 0xEE: ABS INC CYC(6) break; case 0xEF: $ ABS INS CYC(6) break; // invalid case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_SLOW SBCn CYC(5) break; + case 0xF1: INDY_OPT SBCn CYC(5) break; case 0xF2: $ HLT CYC(2) break; - case 0xF3: $ INDY_FAST INS CYC(8) break; // invalid + case 0xF3: $ INDY_CONST INS CYC(8) break; // invalid case 0xF4: $ zpx NOP CYC(4) break; case 0xF5: zpx SBCn CYC(4) break; - case 0xF6: zpx INCn CYC(6) break; + case 0xF6: zpx INC CYC(6) break; case 0xF7: $ zpx INS CYC(6) break; // invalid case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_SLOW SBCn CYC(4) break; + case 0xF9: ABSY_OPT SBCn CYC(4) break; case 0xFA: $ NOP CYC(2) break; - case 0xFB: $ ABSY_FAST INS CYC(7) break; - case 0xFC: $ ABSX_SLOW NOP CYC(4) break; - case 0xFD: ABSX_SLOW SBCn CYC(4) break; - case 0xFE: ABSX_NMOS_RMW INCn CYC(7) break; - case 0xFF: $ ABSX_FAST INS CYC(7) break; + case 0xFB: $ ABSY_CONST INS CYC(7) break; + case 0xFC: $ ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBCn CYC(4) break; + case 0xFE: ABSX_CONST INC CYC(7) break; + case 0xFF: $ ABSX_CONST INS CYC(7) break; } } diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index 2dcd1ca6..53245762 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -75,7 +75,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x0E: ABS ASLc CYC(6) break; case 0x0F: $ NOP CYC(2) break; case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_SLOW ORA CYC(5) break; + case 0x11: INDY_OPT ORA CYC(5) break; case 0x12: izp ORA CYC(5) break; case 0x13: $ NOP CYC(2) break; case 0x14: ZPG TRB CYC(5) break; @@ -83,12 +83,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x16: zpx ASLc CYC(6) break; case 0x17: $ NOP CYC(2) break; case 0x18: CLC CYC(2) break; - case 0x19: ABSY_SLOW ORA CYC(4) break; + case 0x19: ABSY_OPT ORA CYC(4) break; case 0x1A: INA CYC(2) break; case 0x1B: $ NOP CYC(2) break; case 0x1C: ABS TRB CYC(6) break; - case 0x1D: ABSX_SLOW ORA CYC(4) break; - case 0x1E: ABSX_SLOW ASLc CYC(6) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_OPT ASLc CYC(6) break; case 0x1F: $ NOP CYC(2) break; case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; @@ -107,7 +107,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x2E: ABS ROLc CYC(6) break; case 0x2F: $ NOP CYC(2) break; case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_SLOW AND CYC(5) break; + case 0x31: INDY_OPT AND CYC(5) break; case 0x32: izp AND CYC(5) break; case 0x33: $ NOP CYC(2) break; case 0x34: zpx BIT CYC(4) break; @@ -115,12 +115,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x36: zpx ROLc CYC(6) break; case 0x37: $ NOP CYC(2) break; case 0x38: SEC CYC(2) break; - case 0x39: ABSY_SLOW AND CYC(4) break; + case 0x39: ABSY_OPT AND CYC(4) break; case 0x3A: DEA CYC(2) break; case 0x3B: $ NOP CYC(2) break; - case 0x3C: ABSX_SLOW BIT CYC(4) break; - case 0x3D: ABSX_SLOW AND CYC(4) break; - case 0x3E: ABSX_SLOW ROLc CYC(6) break; + case 0x3C: ABSX_OPT BIT CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_OPT ROLc CYC(6) break; case 0x3F: $ NOP CYC(2) break; case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; @@ -139,7 +139,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x4E: ABS LSRc CYC(6) break; case 0x4F: $ NOP CYC(2) break; case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_SLOW EOR CYC(5) break; + case 0x51: INDY_OPT EOR CYC(5) break; case 0x52: izp EOR CYC(5) break; case 0x53: $ NOP CYC(2) break; case 0x54: $ zpx NOP CYC(4) break; @@ -147,12 +147,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x56: zpx LSRc CYC(6) break; case 0x57: $ NOP CYC(2) break; case 0x58: CLI CYC(2) break; - case 0x59: ABSY_SLOW EOR CYC(4) break; + case 0x59: ABSY_OPT EOR CYC(4) break; case 0x5A: PHY CYC(3) break; case 0x5B: $ NOP CYC(2) break; - case 0x5C: $ ABSX_SLOW NOP CYC(8) break; - case 0x5D: ABSX_SLOW EOR CYC(4) break; - case 0x5E: ABSX_SLOW LSRc CYC(6) break; + case 0x5C: $ ABSX_OPT NOP CYC(8) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_OPT LSRc CYC(6) break; case 0x5F: $ NOP CYC(2) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADCc CYC(6) break; @@ -171,7 +171,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x6E: ABS RORc CYC(6) break; case 0x6F: $ NOP CYC(2) break; case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_SLOW ADCc CYC(5) break; + case 0x71: INDY_OPT ADCc CYC(5) break; case 0x72: izp ADCc CYC(5) break; case 0x73: $ NOP CYC(2) break; case 0x74: zpx STZ CYC(4) break; @@ -179,12 +179,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x76: zpx RORc CYC(6) break; case 0x77: $ NOP CYC(2) break; case 0x78: SEI CYC(2) break; - case 0x79: ABSY_SLOW ADCc CYC(4) break; + case 0x79: ABSY_OPT ADCc CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: $ NOP CYC(2) break; case 0x7C: IABSX JMP CYC(6) break; // - case 0x7D: ABSX_SLOW ADCc CYC(4) break; - case 0x7E: ABSX_SLOW RORc CYC(6) break; + case 0x7D: ABSX_OPT ADCc CYC(4) break; + case 0x7E: ABSX_OPT RORc CYC(6) break; case 0x7F: $ NOP CYC(2) break; case 0x80: REL BRA CYC(2) break; case 0x81: idx STA CYC(6) break; @@ -203,7 +203,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: $ NOP CYC(2) break; case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_FAST STA CYC(6) break; + case 0x91: INDY_CONST STA CYC(6) break; case 0x92: izp STA CYC(5) break; case 0x93: $ NOP CYC(2) break; case 0x94: zpx STY CYC(4) break; @@ -211,12 +211,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x96: zpy STX CYC(4) break; case 0x97: $ NOP CYC(2) break; case 0x98: TYA CYC(2) break; - case 0x99: ABSY_FAST STA CYC(5) break; + case 0x99: ABSY_CONST STA CYC(5) break; case 0x9A: TXS CYC(2) break; case 0x9B: $ NOP CYC(2) break; case 0x9C: ABS STZ CYC(4) break; - case 0x9D: ABSX_FAST STA CYC(5) break; - case 0x9E: ABSX_FAST STZ CYC(5) break; + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: ABSX_CONST STZ CYC(5) break; case 0x9F: $ NOP CYC(2) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; @@ -235,7 +235,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: $ NOP CYC(2) break; case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_SLOW LDA CYC(5) break; + case 0xB1: INDY_OPT LDA CYC(5) break; case 0xB2: izp LDA CYC(5) break; case 0xB3: $ NOP CYC(2) break; case 0xB4: zpx LDY CYC(4) break; @@ -243,12 +243,12 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xB6: zpy LDX CYC(4) break; case 0xB7: $ NOP CYC(2) break; case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_SLOW LDA CYC(4) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; case 0xBA: TSX CYC(2) break; case 0xBB: $ NOP CYC(2) break; - case 0xBC: ABSX_SLOW LDY CYC(4) break; - case 0xBD: ABSX_SLOW LDA CYC(4) break; - case 0xBE: ABSY_SLOW LDX CYC(4) break; + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; case 0xBF: $ NOP CYC(2) break; case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; @@ -256,7 +256,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xC3: $ NOP CYC(2) break; case 0xC4: ZPG CPY CYC(3) break; case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DECc CYC(5) break; + case 0xC6: ZPG DEC CYC(5) break; case 0xC7: $ NOP CYC(2) break; case 0xC8: INY CYC(2) break; case 0xC9: IMM CMP CYC(2) break; @@ -264,23 +264,23 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xCB: $ NOP CYC(2) break; case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DECc CYC(5) break; + case 0xCE: ABS DEC CYC(5) break; case 0xCF: $ NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_SLOW CMP CYC(5) break; + case 0xD1: INDY_OPT CMP CYC(5) break; case 0xD2: izp CMP CYC(5) break; case 0xD3: $ NOP CYC(2) break; case 0xD4: $ zpx NOP CYC(4) break; case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DECc CYC(6) break; + case 0xD6: zpx DEC CYC(6) break; case 0xD7: $ NOP CYC(2) break; case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_SLOW CMP CYC(4) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; case 0xDA: PHX CYC(3) break; case 0xDB: $ NOP CYC(2) break; - case 0xDC: $ ABSX_SLOW NOP CYC(4) break; - case 0xDD: ABSX_SLOW CMP CYC(4) break; - case 0xDE: ABSX_SLOW DECc CYC(6) break; + case 0xDC: $ ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_CONST DEC CYC(7) break; case 0xDF: $ NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCc CYC(6) break; @@ -288,7 +288,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xE3: $ NOP CYC(2) break; case 0xE4: ZPG CPX CYC(3) break; case 0xE5: ZPG SBCc CYC(3) break; - case 0xE6: ZPG INCc CYC(5) break; + case 0xE6: ZPG INC CYC(5) break; case 0xE7: $ NOP CYC(2) break; case 0xE8: INX CYC(2) break; case 0xE9: IMM SBCc CYC(2) break; @@ -296,23 +296,23 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xEB: $ NOP CYC(2) break; case 0xEC: ABS CPX CYC(4) break; case 0xED: ABS SBCc CYC(4) break; - case 0xEE: ABS INCc CYC(6) break; + case 0xEE: ABS INC CYC(6) break; case 0xEF: $ NOP CYC(2) break; case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_SLOW SBCc CYC(5) break; + case 0xF1: INDY_OPT SBCc CYC(5) break; case 0xF2: izp SBCc CYC(5) break; case 0xF3: $ NOP CYC(2) break; case 0xF4: $ zpx NOP CYC(4) break; case 0xF5: zpx SBCc CYC(4) break; - case 0xF6: zpx INCc CYC(6) break; + case 0xF6: zpx INC CYC(6) break; case 0xF7: $ NOP CYC(2) break; case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_SLOW SBCc CYC(4) break; + case 0xF9: ABSY_OPT SBCc CYC(4) break; case 0xFA: PLX CYC(4) break; case 0xFB: $ NOP CYC(2) break; - case 0xFC: $ ABSX_SLOW NOP CYC(4) break; - case 0xFD: ABSX_SLOW SBCc CYC(4) break; - case 0xFE: ABSX_SLOW INCc CYC(6) break; + case 0xFC: $ ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBCc CYC(4) break; + case 0xFE: ABSX_CONST INC CYC(7) break; case 0xFF: $ NOP CYC(2) break; } #undef $ diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 286497bf..83de7293 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -146,7 +146,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x0E: ABS ASL_CMOS CYC(6) break; case 0x0F: INV NOP CYC(2) break; case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_SLOW ORA CYC(5) break; + case 0x11: INDY_OPT ORA CYC(5) break; case 0x12: izp ORA CYC(5) break; case 0x13: INV NOP CYC(2) break; case 0x14: ZPG TRB CYC(5) break; @@ -154,12 +154,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x16: zpx ASL_CMOS CYC(6) break; case 0x17: INV NOP CYC(2) break; case 0x18: CLC CYC(2) break; - case 0x19: ABSY_SLOW ORA CYC(4) break; + case 0x19: ABSY_OPT ORA CYC(4) break; case 0x1A: INA CYC(2) break; case 0x1B: INV NOP CYC(2) break; case 0x1C: ABS TRB CYC(6) break; - case 0x1D: ABSX_SLOW ORA CYC(4) break; - case 0x1E: ABSX_SLOW ASL_CMOS CYC(6) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_OPT ASL_CMOS CYC(6) break; case 0x1F: INV NOP CYC(2) break; case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; @@ -178,7 +178,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x2E: ABS ROL_CMOS CYC(6) break; case 0x2F: INV NOP CYC(2) break; case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_SLOW AND CYC(5) break; + case 0x31: INDY_OPT AND CYC(5) break; case 0x32: izp AND CYC(5) break; case 0x33: INV NOP CYC(2) break; case 0x34: zpx BIT CYC(4) break; @@ -186,12 +186,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x36: zpx ROL_CMOS CYC(6) break; case 0x37: INV NOP CYC(2) break; case 0x38: SEC CYC(2) break; - case 0x39: ABSY_SLOW AND CYC(4) break; + case 0x39: ABSY_OPT AND CYC(4) break; case 0x3A: DEA CYC(2) break; case 0x3B: INV NOP CYC(2) break; - case 0x3C: ABSX_SLOW BIT CYC(4) break; - case 0x3D: ABSX_SLOW AND CYC(4) break; - case 0x3E: ABSX_SLOW ROL_CMOS CYC(6) break; + case 0x3C: ABSX_OPT BIT CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_OPT ROL_CMOS CYC(6) break; case 0x3F: INV NOP CYC(2) break; case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; @@ -210,7 +210,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x4E: ABS LSR_CMOS CYC(6) break; case 0x4F: INV NOP CYC(2) break; case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_SLOW EOR CYC(5) break; + case 0x51: INDY_OPT EOR CYC(5) break; case 0x52: izp EOR CYC(5) break; case 0x53: INV NOP CYC(2) break; case 0x54: INV zpx NOP CYC(4) break; @@ -218,12 +218,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x56: zpx LSR_CMOS CYC(6) break; case 0x57: INV NOP CYC(2) break; case 0x58: CLI CYC(2) break; - case 0x59: ABSY_SLOW EOR CYC(4) break; + case 0x59: ABSY_OPT EOR CYC(4) break; case 0x5A: PHY CYC(3) break; case 0x5B: INV NOP CYC(2) break; - case 0x5C: INV ABSX_SLOW NOP CYC(8) break; - case 0x5D: ABSX_SLOW EOR CYC(4) break; - case 0x5E: ABSX_SLOW LSR_CMOS CYC(6) break; + case 0x5C: INV ABSX_OPT NOP CYC(8) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_OPT LSR_CMOS CYC(6) break; case 0x5F: INV NOP CYC(2) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADC_CMOS CYC(6) break; @@ -242,7 +242,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x6E: ABS ROR_CMOS CYC(6) break; case 0x6F: INV NOP CYC(2) break; case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_SLOW ADC_CMOS CYC(5) break; + case 0x71: INDY_OPT ADC_CMOS CYC(5) break; case 0x72: izp ADC_CMOS CYC(5) break; case 0x73: INV NOP CYC(2) break; case 0x74: zpx STZ CYC(4) break; @@ -250,12 +250,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x76: zpx ROR_CMOS CYC(6) break; case 0x77: INV NOP CYC(2) break; case 0x78: SEI CYC(2) break; - case 0x79: ABSY_SLOW ADC_CMOS CYC(4) break; + case 0x79: ABSY_OPT ADC_CMOS CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: INV NOP CYC(2) break; case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP - case 0x7D: ABSX_SLOW ADC_CMOS CYC(4) break; - case 0x7E: ABSX_SLOW ROR_CMOS CYC(6) break; + case 0x7D: ABSX_OPT ADC_CMOS CYC(4) break; + case 0x7E: ABSX_OPT ROR_CMOS CYC(6) break; case 0x7F: INV NOP CYC(2) break; case 0x80: REL BRA CYC(2) break; case 0x81: idx STA CYC(6) break; @@ -274,7 +274,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: INV NOP CYC(2) break; case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_FAST STA CYC(6) break; + case 0x91: INDY_CONST STA CYC(6) break; case 0x92: izp STA CYC(5) break; case 0x93: INV NOP CYC(2) break; case 0x94: zpx STY CYC(4) break; @@ -282,12 +282,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x96: zpy STX CYC(4) break; case 0x97: INV NOP CYC(2) break; case 0x98: TYA CYC(2) break; - case 0x99: ABSY_FAST STA CYC(5) break; + case 0x99: ABSY_CONST STA CYC(5) break; case 0x9A: TXS CYC(2) break; case 0x9B: INV NOP CYC(2) break; case 0x9C: ABS STZ CYC(4) break; - case 0x9D: ABSX_FAST STA CYC(5) break; - case 0x9E: ABSX_FAST STZ CYC(5) break; + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: ABSX_CONST STZ CYC(5) break; case 0x9F: INV NOP CYC(2) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; @@ -306,7 +306,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: INV NOP CYC(2) break; case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_SLOW LDA CYC(5) break; + case 0xB1: INDY_OPT LDA CYC(5) break; case 0xB2: izp LDA CYC(5) break; case 0xB3: INV NOP CYC(2) break; case 0xB4: zpx LDY CYC(4) break; @@ -314,12 +314,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xB6: zpy LDX CYC(4) break; case 0xB7: INV NOP CYC(2) break; case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_SLOW LDA CYC(4) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; case 0xBA: TSX CYC(2) break; case 0xBB: INV NOP CYC(2) break; - case 0xBC: ABSX_SLOW LDY CYC(4) break; - case 0xBD: ABSX_SLOW LDA CYC(4) break; - case 0xBE: ABSY_SLOW LDX CYC(4) break; + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; case 0xBF: INV NOP CYC(2) break; case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; @@ -338,7 +338,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xCE: ABS DEC_CMOS CYC(5) break; case 0xCF: INV NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_SLOW CMP CYC(5) break; + case 0xD1: INDY_OPT CMP CYC(5) break; case 0xD2: izp CMP CYC(5) break; case 0xD3: INV NOP CYC(2) break; case 0xD4: INV zpx NOP CYC(4) break; @@ -346,12 +346,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xD6: zpx DEC_CMOS CYC(6) break; case 0xD7: INV NOP CYC(2) break; case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_SLOW CMP CYC(4) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; case 0xDA: PHX CYC(3) break; case 0xDB: INV NOP CYC(2) break; - case 0xDC: INV ABSX_SLOW NOP CYC(4) break; - case 0xDD: ABSX_SLOW CMP CYC(4) break; - case 0xDE: ABSX_SLOW DEC_CMOS CYC(6) break; + case 0xDC: INV ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_OPT DEC_CMOS CYC(6) break; case 0xDF: INV NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBC_CMOS CYC(6) break; @@ -370,7 +370,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xEE: ABS INC_CMOS CYC(6) break; case 0xEF: INV NOP CYC(2) break; case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_SLOW SBC_CMOS CYC(5) break; + case 0xF1: INDY_OPT SBC_CMOS CYC(5) break; case 0xF2: izp SBC_CMOS CYC(5) break; case 0xF3: INV NOP CYC(2) break; case 0xF4: INV zpx NOP CYC(4) break; @@ -378,12 +378,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xF6: zpx INC_CMOS CYC(6) break; case 0xF7: INV NOP CYC(2) break; case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_SLOW SBC_CMOS CYC(4) break; + case 0xF9: ABSY_OPT SBC_CMOS CYC(4) break; case 0xFA: PLX CYC(4) break; case 0xFB: INV NOP CYC(2) break; - case 0xFC: INV ABSX_SLOW NOP CYC(4) break; - case 0xFD: ABSX_SLOW SBC_CMOS CYC(4) break; - case 0xFE: ABSX_SLOW INC_CMOS CYC(6) break; + case 0xFC: INV ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBC_CMOS CYC(4) break; + case 0xFE: ABSX_OPT INC_CMOS CYC(6) break; case 0xFF: INV NOP CYC(2) break; */ // Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode @@ -405,7 +405,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x0E: ABS ASLc CYC(6) break; case 0x0F: $ NOP CYC(2) break; case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_SLOW ORA CYC(5) break; + case 0x11: INDY_OPT ORA CYC(5) break; case 0x12: izp ORA CYC(5) break; case 0x13: $ NOP CYC(2) break; case 0x14: ZPG TRB CYC(5) break; @@ -413,12 +413,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x16: zpx ASLc CYC(6) break; case 0x17: $ NOP CYC(2) break; case 0x18: CLC CYC(2) break; - case 0x19: ABSY_SLOW ORA CYC(4) break; + case 0x19: ABSY_OPT ORA CYC(4) break; case 0x1A: INA CYC(2) break; case 0x1B: $ NOP CYC(2) break; case 0x1C: ABS TRB CYC(6) break; - case 0x1D: ABSX_SLOW ORA CYC(4) break; - case 0x1E: ABSX_SLOW ASLc CYC(6) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_OPT ASLc CYC(6) break; case 0x1F: $ NOP CYC(2) break; case 0x20: ABS JSR CYC(6) break; case 0x21: idx AND CYC(6) break; @@ -437,7 +437,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x2E: ABS ROLc CYC(6) break; case 0x2F: $ NOP CYC(2) break; case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_SLOW AND CYC(5) break; + case 0x31: INDY_OPT AND CYC(5) break; case 0x32: izp AND CYC(5) break; case 0x33: $ NOP CYC(2) break; case 0x34: zpx BIT CYC(4) break; @@ -445,12 +445,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x36: zpx ROLc CYC(6) break; case 0x37: $ NOP CYC(2) break; case 0x38: SEC CYC(2) break; - case 0x39: ABSY_SLOW AND CYC(4) break; + case 0x39: ABSY_OPT AND CYC(4) break; case 0x3A: DEA CYC(2) break; case 0x3B: $ NOP CYC(2) break; - case 0x3C: ABSX_SLOW BIT CYC(4) break; - case 0x3D: ABSX_SLOW AND CYC(4) break; - case 0x3E: ABSX_SLOW ROLc CYC(6) break; + case 0x3C: ABSX_OPT BIT CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_OPT ROLc CYC(6) break; case 0x3F: $ NOP CYC(2) break; case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; case 0x41: idx EOR CYC(6) break; @@ -469,7 +469,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x4E: ABS LSRc CYC(6) break; case 0x4F: $ NOP CYC(2) break; case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_SLOW EOR CYC(5) break; + case 0x51: INDY_OPT EOR CYC(5) break; case 0x52: izp EOR CYC(5) break; case 0x53: $ NOP CYC(2) break; case 0x54: $ zpx NOP CYC(4) break; @@ -477,12 +477,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x56: zpx LSRc CYC(6) break; case 0x57: $ NOP CYC(2) break; case 0x58: CLI CYC(2) break; - case 0x59: ABSY_SLOW EOR CYC(4) break; + case 0x59: ABSY_OPT EOR CYC(4) break; case 0x5A: PHY CYC(3) break; case 0x5B: $ NOP CYC(2) break; - case 0x5C: $ ABSX_SLOW NOP CYC(8) break; - case 0x5D: ABSX_SLOW EOR CYC(4) break; - case 0x5E: ABSX_SLOW LSRc CYC(6) break; + case 0x5C: $ ABSX_OPT NOP CYC(8) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_OPT LSRc CYC(6) break; case 0x5F: $ NOP CYC(2) break; case 0x60: RTS CYC(6) break; case 0x61: idx ADCc CYC(6) break; @@ -501,7 +501,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x6E: ABS RORc CYC(6) break; case 0x6F: $ NOP CYC(2) break; case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_SLOW ADCc CYC(5) break; + case 0x71: INDY_OPT ADCc CYC(5) break; case 0x72: izp ADCc CYC(5) break; case 0x73: $ NOP CYC(2) break; case 0x74: zpx STZ CYC(4) break; @@ -509,12 +509,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x76: zpx RORc CYC(6) break; case 0x77: $ NOP CYC(2) break; case 0x78: SEI CYC(2) break; - case 0x79: ABSY_SLOW ADCc CYC(4) break; + case 0x79: ABSY_OPT ADCc CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: $ NOP CYC(2) break; case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP - case 0x7D: ABSX_SLOW ADCc CYC(4) break; - case 0x7E: ABSX_SLOW RORc CYC(6) break; + case 0x7D: ABSX_OPT ADCc CYC(4) break; + case 0x7E: ABSX_OPT RORc CYC(6) break; case 0x7F: $ NOP CYC(2) break; case 0x80: REL BRA CYC(2) break; case 0x81: idx STA CYC(6) break; @@ -533,7 +533,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x8E: ABS STX CYC(4) break; case 0x8F: $ NOP CYC(2) break; case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_FAST STA CYC(6) break; + case 0x91: INDY_CONST STA CYC(6) break; case 0x92: izp STA CYC(5) break; case 0x93: $ NOP CYC(2) break; case 0x94: zpx STY CYC(4) break; @@ -541,12 +541,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x96: zpy STX CYC(4) break; case 0x97: $ NOP CYC(2) break; case 0x98: TYA CYC(2) break; - case 0x99: ABSY_FAST STA CYC(5) break; + case 0x99: ABSY_CONST STA CYC(5) break; case 0x9A: TXS CYC(2) break; case 0x9B: $ NOP CYC(2) break; case 0x9C: ABS STZ CYC(4) break; - case 0x9D: ABSX_FAST STA CYC(5) break; - case 0x9E: ABSX_FAST STZ CYC(5) break; + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: ABSX_CONST STZ CYC(5) break; case 0x9F: $ NOP CYC(2) break; case 0xA0: IMM LDY CYC(2) break; case 0xA1: idx LDA CYC(6) break; @@ -565,7 +565,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xAE: ABS LDX CYC(4) break; case 0xAF: $ NOP CYC(2) break; case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_SLOW LDA CYC(5) break; + case 0xB1: INDY_OPT LDA CYC(5) break; case 0xB2: izp LDA CYC(5) break; case 0xB3: $ NOP CYC(2) break; case 0xB4: zpx LDY CYC(4) break; @@ -573,12 +573,12 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xB6: zpy LDX CYC(4) break; case 0xB7: $ NOP CYC(2) break; case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_SLOW LDA CYC(4) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; case 0xBA: TSX CYC(2) break; case 0xBB: $ NOP CYC(2) break; - case 0xBC: ABSX_SLOW LDY CYC(4) break; - case 0xBD: ABSX_SLOW LDA CYC(4) break; - case 0xBE: ABSY_SLOW LDX CYC(4) break; + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; case 0xBF: $ NOP CYC(2) break; case 0xC0: IMM CPY CYC(2) break; case 0xC1: idx CMP CYC(6) break; @@ -586,7 +586,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xC3: $ NOP CYC(2) break; case 0xC4: ZPG CPY CYC(3) break; case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DECc CYC(5) break; + case 0xC6: ZPG DEC CYC(5) break; case 0xC7: $ NOP CYC(2) break; case 0xC8: INY CYC(2) break; case 0xC9: IMM CMP CYC(2) break; @@ -594,23 +594,23 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xCB: $ NOP CYC(2) break; case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DECc CYC(5) break; + case 0xCE: ABS DEC CYC(5) break; case 0xCF: $ NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_SLOW CMP CYC(5) break; + case 0xD1: INDY_OPT CMP CYC(5) break; case 0xD2: izp CMP CYC(5) break; case 0xD3: $ NOP CYC(2) break; case 0xD4: $ zpx NOP CYC(4) break; case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DECc CYC(6) break; + case 0xD6: zpx DEC CYC(6) break; case 0xD7: $ NOP CYC(2) break; case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_SLOW CMP CYC(4) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; case 0xDA: PHX CYC(3) break; case 0xDB: $ NOP CYC(2) break; - case 0xDC: $ ABSX_SLOW NOP CYC(4) break; - case 0xDD: ABSX_SLOW CMP CYC(4) break; - case 0xDE: ABSX_SLOW DECc CYC(6) break; + case 0xDC: $ ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_CONST DEC CYC(6) break; case 0xDF: $ NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCc CYC(6) break; @@ -618,7 +618,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xE3: $ NOP CYC(2) break; case 0xE4: ZPG CPX CYC(3) break; case 0xE5: ZPG SBCc CYC(3) break; - case 0xE6: ZPG INCc CYC(5) break; + case 0xE6: ZPG INC CYC(5) break; case 0xE7: $ NOP CYC(2) break; case 0xE8: INX CYC(2) break; case 0xE9: IMM SBCc CYC(2) break; @@ -626,23 +626,23 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xEB: $ NOP CYC(2) break; case 0xEC: ABS CPX CYC(4) break; case 0xED: ABS SBCc CYC(4) break; - case 0xEE: ABS INCc CYC(6) break; + case 0xEE: ABS INC CYC(6) break; case 0xEF: $ NOP CYC(2) break; case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_SLOW SBCc CYC(5) break; + case 0xF1: INDY_OPT SBCc CYC(5) break; case 0xF2: izp SBCc CYC(5) break; case 0xF3: $ NOP CYC(2) break; case 0xF4: $ zpx NOP CYC(4) break; case 0xF5: zpx SBCc CYC(4) break; - case 0xF6: zpx INCc CYC(6) break; + case 0xF6: zpx INC CYC(6) break; case 0xF7: $ NOP CYC(2) break; case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_SLOW SBCc CYC(4) break; + case 0xF9: ABSY_OPT SBCc CYC(4) break; case 0xFA: PLX CYC(4) break; case 0xFB: $ NOP CYC(2) break; - case 0xFC: $ ABSX_SLOW NOP CYC(4) break; - case 0xFD: ABSX_SLOW SBCc CYC(4) break; - case 0xFE: ABSX_SLOW INCc CYC(6) break; + case 0xFC: $ ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBCc CYC(4) break; + case 0xFE: ABSX_CONST INC CYC(6) break; case 0xFF: $ NOP CYC(2) break; } #undef $ diff --git a/source/CPU/cpu_general.inl b/source/CPU/cpu_general.inl index b6846045..af408c08 100644 --- a/source/CPU/cpu_general.inl +++ b/source/CPU/cpu_general.inl @@ -73,6 +73,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \ } +#define ON_PAGECROSS_REPLACE_HI_ADDR if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ + // // ExtraCycles: @@ -102,14 +104,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2; #define IABSX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2; -#define ABSX_SLOW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE; -#define ABSX_FAST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; +// Optimised for page-cross +#define ABSX_OPT base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE; +// Not optimised for page-cross +#define ABSX_CONST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; -#define ABSY_SLOW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; -#define ABSY_FAST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; - -// NMOS read-modify-write opcodes (asl/dec/inc abs,x) don't take an extra cycle if page-crossing (GH#271) -#define ABSX_NMOS_RMW base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; +// Optimised for page-cross +#define ABSY_OPT base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; +// Not optimised for page-cross +#define ABSY_CONST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; // TODO Optimization Note (just for IABSCMOS): uExtraCycles = ((base & 0xFF) + 1) >> 8; #define IABSCMOS base = *(LPWORD)(mem+regs.pc); \ @@ -131,14 +134,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA else \ addr = *(LPWORD)(mem+base); -#define INDY_SLOW if (*(mem+regs.pc) == 0xFF) /*SLOW: incurs an extra cycle for page-crossing*/ \ +// Optimised for page-cross +#define INDY_OPT if (*(mem+regs.pc) == 0xFF) /*incurs an extra cycle for page-crossing*/ \ base = *(mem+0xFF)+(((WORD)*mem)<<8); \ else \ base = *(LPWORD)(mem+*(mem+regs.pc)); \ regs.pc++; \ addr = base+(WORD)regs.y; \ CHECK_PAGE_CHANGE; -#define INDY_FAST if (*(mem+regs.pc) == 0xFF) /*FAST: no extra cycle for page-crossing*/ \ +// Not optimised for page-cross +#define INDY_CONST if (*(mem+regs.pc) == 0xFF) /*no extra cycle for page-crossing*/ \ base = *(mem+0xFF)+(((WORD)*mem)<<8); \ else \ base = *(LPWORD)(mem+*(mem+regs.pc)); \ @@ -156,16 +161,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // TODO Optimization Note: // . Opcodes that generate zero-page addresses can't be accessing $C000..$CFFF // so they could be paired with special READZP/WRITEZP macros (instead of READ/WRITE) -#define ZPG addr = *(mem+regs.pc++); +#define ZPG addr = *(mem+regs.pc++); #define ZPGX addr = ((*(mem+regs.pc++))+regs.x) & 0xFF; #define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF; // Tidy 3 char addressing modes to keep the opcode table visually aligned, clean, and readable. -//#undef abx -//#undef aby #undef asl #undef idx -//#undef idy #undef imm #undef izp #undef lsr @@ -175,11 +177,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #undef zpx #undef zpy -//#define abx ABSX // ABSX -> ABSX_SLOW or ABSX_FAST -//#define aby ABSY // ABSY -> ABSY_SLOW or ABSY_FAST #define asl ASLA // Arithmetic Shift Left #define idx INDX -//#define idy INDY // INDY -> INDY_SLOW or INDY_FAST #define imm IMM #define izp IZPG #define lsr LSRA // Logical Shift Right @@ -188,6 +187,3 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ror RORA // Rotate Right #define zpx ZPGX #define zpy ZPGY -// 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP -// 0x7C IABSX - diff --git a/source/CPU/cpu_instructions.inl b/source/CPU/cpu_instructions.inl index 89eb25f4..2fc4b2e1 100644 --- a/source/CPU/cpu_instructions.inl +++ b/source/CPU/cpu_instructions.inl @@ -68,15 +68,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #undef CPY #undef DCM #undef DEA -#undef DEC_NMOS -#undef DEC_CMOS +#undef DEC #undef DEX #undef DEY #undef EOR #undef HLT #undef INA -#undef INC_NMOS -#undef INC_CMOS +#undef INC #undef INS #undef INX #undef INY @@ -139,8 +137,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #undef ADCn #undef ASLn -#undef DECn -#undef INCn #undef LSRn #undef ROLn #undef RORn @@ -148,8 +144,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ADCn ADC_NMOS #define ASLn ASL_NMOS -#define DECn DEC_NMOS -#define INCn INC_NMOS #define LSRn LSR_NMOS #define ROLn ROL_NMOS #define RORn ROR_NMOS @@ -159,8 +153,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #undef ADCc #undef ASLc -#undef DECc -#undef INCc #undef LSRc #undef ROLc #undef RORc @@ -168,8 +160,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ADCc ADC_CMOS #define ASLc ASL_CMOS -#define DECc DEC_CMOS -#define INCc INC_CMOS #define LSRc LSR_CMOS #define ROLc ROL_CMOS #define RORc ROR_CMOS @@ -296,7 +286,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.a) #define AXA /*bSlowerOnPagecross = 0;*/ \ val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \ - if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ + ON_PAGECROSS_REPLACE_HI_ADDR \ WRITE(val) #define AXS /*bSlowerOnPagecross = 0;*/ \ WRITE(regs.a & regs.x) @@ -347,11 +337,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(val) #define DEA --regs.a; \ SETNZ(regs.a) -#define DEC_NMOS /*bSlowerOnPagecross = 0;*/ \ - val = READ-1; \ - SETNZ(val) \ - WRITE(val) -#define DEC_CMOS /*bSlowerOnPagecross = 1;*/ \ +#define DEC /*bSlowerOnPagecross = 0;*/ \ val = READ-1; \ SETNZ(val) \ WRITE(val) @@ -366,11 +352,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --regs.pc; #define INA ++regs.a; \ SETNZ(regs.a) -#define INC_NMOS /*bSlowerOnPagecross = 0;*/ \ - val = READ+1; \ - SETNZ(val) \ - WRITE(val) -#define INC_CMOS /*bSlowerOnPagecross = 1;*/ \ +#define INC /*bSlowerOnPagecross = 0;*/ \ val = READ+1; \ SETNZ(val) \ WRITE(val) @@ -552,7 +534,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.x) #define SAY /*bSlowerOnPagecross = 0;*/ \ val = regs.y & (((base >> 8) + 1) & 0xFF); \ - if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ + ON_PAGECROSS_REPLACE_HI_ADDR \ WRITE(val) #define SBC_NMOS /*bSlowerOnPagecross = 1;*/ \ temp = READ; \ @@ -636,7 +618,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA val = regs.a & regs.x; \ regs.sp = 0x100 | val; \ val &= (((base >> 8) + 1) & 0xFF); \ - if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ + ON_PAGECROSS_REPLACE_HI_ADDR \ WRITE(val) #define TAX regs.x = regs.a; \ SETNZ(regs.x) @@ -664,5 +646,5 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA SETNZ(regs.a) #define XAS /*bSlowerOnPagecross = 0;*/ \ val = regs.x & (((base >> 8) + 1) & 0xFF); \ - if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ \ + ON_PAGECROSS_REPLACE_HI_ADDR \ WRITE(val) diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp index 7ca2d2d9..211d8ac7 100644 --- a/test/TestCPU6502/TestCPU6502.cpp +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -86,9 +86,12 @@ DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles) return 0; } +//------------------------------------- + #include "../../source/cpu/cpu_general.inl" #include "../../source/cpu/cpu_instructions.inl" #include "../../source/cpu/cpu6502.h" // MOS 6502 +#include "../../source/cpu/cpu65C02.h" // WDC 65C02 void init(void) { @@ -112,6 +115,172 @@ void reset(void) regs.bJammed = 0; } +//------------------------------------- + +int test_GH264(void) +{ + reset(); + WORD abs = regs.pc+3; + WORD dst = abs+2; + mem[regs.pc+0] = 0x6c; // JMP (IND) + mem[regs.pc+1] = abs&0xff; + mem[regs.pc+2] = abs>>8; + mem[regs.pc+3] = dst&0xff; + mem[regs.pc+4] = dst>>8; + + DWORD cycles = Cpu6502(0); + if (cycles != 5) return 1; + if (regs.pc != dst) return 1; + + reset(); + cycles = Cpu65C02(0); + if (cycles != 6) return 1; + if (regs.pc != dst) return 1; + + return 0; +} + +//------------------------------------- + +void ASL_ABSX(BYTE x, WORD base, BYTE d) +{ + WORD addr = base+x; + mem[addr] = d; + + reset(); + regs.x = x; + mem[regs.pc+0] = 0x1e; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; +} + +void DEC_ABSX(BYTE x, WORD base, BYTE d) +{ + WORD addr = base+x; + mem[addr] = d; + + reset(); + regs.x = x; + mem[regs.pc+0] = 0xde; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; +} + +void INC_ABSX(BYTE x, WORD base, BYTE d) +{ + WORD addr = base+x; + mem[addr] = d; + + reset(); + regs.x = x; + mem[regs.pc+0] = 0xfe; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; +} + +int test_GH271(void) +{ + // asl abs,x + { + const WORD base = 0x20ff; + const BYTE d = 0x40; + + // no page-cross + { + const BYTE x = 0; + + ASL_ABSX(x, base, d); + if (Cpu6502(0) != 7) return 1; + if (mem[base+x] != ((d<<1)&0xff)) return 1; + + ASL_ABSX(x, base, d); + if (Cpu65C02(0) != 6) return 1; // Non-PX case is optimised on 65C02 + if (mem[base+x] != ((d<<1)&0xff)) return 1; + } + + // page-cross + { + const BYTE x = 1; + + ASL_ABSX(x, base, d); + if (Cpu6502(0) != 7) return 1; + if (mem[base+x] != ((d<<1)&0xff)) return 1; + + ASL_ABSX(x, base, d); + if (Cpu65C02(0) != 7) return 1; + if (mem[base+x] != ((d<<1)&0xff)) return 1; + } + } + + // dec abs,x + { + const WORD base = 0x20ff; + const BYTE d = 0x40; + + // no page-cross + { + const BYTE x = 0; + + DEC_ABSX(x, base, d); + if (Cpu6502(0) != 7) return 1; + if (mem[base+x] != ((d-1)&0xff)) return 1; + + DEC_ABSX(x, base, d); + if (Cpu65C02(0) != 7) return 1; // NB. Not optimised for 65C02 + if (mem[base+x] != ((d-1)&0xff)) return 1; + } + + // page-cross + { + const BYTE x = 1; + + DEC_ABSX(x, base, d); + if (Cpu6502(0) != 7) return 1; + if (mem[base+x] != ((d-1)&0xff)) return 1; + + DEC_ABSX(x, base, d); + if (Cpu65C02(0) != 7) return 1; + if (mem[base+x] != ((d-1)&0xff)) return 1; + } + } + + // inc abs,x + { + const WORD base = 0x20ff; + const BYTE d = 0x40; + + // no page-cross + { + const BYTE x = 0; + + INC_ABSX(x, base, d); + if (Cpu6502(0) != 7) return 1; + if (mem[base+x] != ((d+1)&0xff)) return 1; + + INC_ABSX(x, base, d); + if (Cpu65C02(0) != 7) return 1; // NB. Not optimised for 65C02 + if (mem[base+x] != ((d+1)&0xff)) return 1; + } + + // page-cross + { + const BYTE x = 1; + + INC_ABSX(x, base, d); + if (Cpu6502(0) != 7) return 1; + if (mem[base+x] != ((d+1)&0xff)) return 1; + + INC_ABSX(x, base, d); + if (Cpu65C02(0) != 7) return 1; + if (mem[base+x] != ((d+1)&0xff)) return 1; + } + } + + return 0; +} + +//------------------------------------- + DWORD AXA_ZPY(BYTE a, BYTE x, BYTE y, WORD base) { reset(); @@ -173,7 +342,7 @@ DWORD XAS_ABSY(BYTE a, BYTE x, BYTE y, WORD base) return Cpu6502(0); } -int test6502_GH282(void) +int test_GH282(void) { // axa (zp),y { @@ -288,12 +457,22 @@ int test6502_GH282(void) return 0; } +//------------------------------------- + int _tmain(int argc, _TCHAR* argv[]) { + int res = 1; init(); reset(); - int res = test6502_GH282(); + res = test_GH264(); + if (res) return res; - return res; + res = test_GH271(); + if (res) return res; + + res = test_GH282(); + if (res) return res; + + return 0; } From 38c98f0c313c48cbd69e57f03fe0743fe8c69d56 Mon Sep 17 00:00:00 2001 From: tomcw Date: Mon, 4 May 2015 12:04:37 +0100 Subject: [PATCH 06/11] Fix cpu65d02 for DEC/INC ABS,X timings --- source/CPU/cpu65d02.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 83de7293..2c30b26f 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -351,7 +351,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xDB: INV NOP CYC(2) break; case 0xDC: INV ABSX_OPT NOP CYC(4) break; case 0xDD: ABSX_OPT CMP CYC(4) break; - case 0xDE: ABSX_OPT DEC_CMOS CYC(6) break; + case 0xDE: ABSX_CONST DEC_CMOS CYC(7) break; case 0xDF: INV NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBC_CMOS CYC(6) break; @@ -383,7 +383,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xFB: INV NOP CYC(2) break; case 0xFC: INV ABSX_OPT NOP CYC(4) break; case 0xFD: ABSX_OPT SBC_CMOS CYC(4) break; - case 0xFE: ABSX_OPT INC_CMOS CYC(6) break; + case 0xFE: ABSX_CONST INC_CMOS CYC(7) break; case 0xFF: INV NOP CYC(2) break; */ // Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode @@ -610,7 +610,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xDB: $ NOP CYC(2) break; case 0xDC: $ ABSX_OPT NOP CYC(4) break; case 0xDD: ABSX_OPT CMP CYC(4) break; - case 0xDE: ABSX_CONST DEC CYC(6) break; + case 0xDE: ABSX_CONST DEC CYC(7) break; case 0xDF: $ NOP CYC(2) break; case 0xE0: IMM CPX CYC(2) break; case 0xE1: idx SBCc CYC(6) break; @@ -642,7 +642,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xFB: $ NOP CYC(2) break; case 0xFC: $ ABSX_OPT NOP CYC(4) break; case 0xFD: ABSX_OPT SBCc CYC(4) break; - case 0xFE: ABSX_CONST INC CYC(6) break; + case 0xFE: ABSX_CONST INC CYC(7) break; case 0xFF: $ NOP CYC(2) break; } #undef $ From cbb837bf6b7d75ab379a42daba414a9b6bbe208f Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 9 May 2015 19:20:31 +0100 Subject: [PATCH 07/11] Add timing tests for all opcodes: 6502, 65C02, page-cross and non-page-cross (#278). Also fix opcode timing for 0xCE: DEC abs (#288). --- source/CPU/cpu6502.h | 2 +- source/CPU/cpu65C02.h | 2 +- source/CPU/cpu65d02.h | 4 +- test/TestCPU6502/TestCPU6502.cpp | 601 ++++++++++++++++++++++++++++++- 4 files changed, 598 insertions(+), 11 deletions(-) diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index afac92d3..9d3d8454 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -261,7 +261,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) case 0xCB: $ IMM SAX CYC(2) break; // invalid case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(5) break; + case 0xCE: ABS DEC CYC(6) break; case 0xCF: $ ABS DCM CYC(6) break; // invalid case 0xD0: REL BNE CYC(2) break; case 0xD1: INDY_OPT CMP CYC(5) break; diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index 53245762..ecc00443 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -264,7 +264,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0xCB: $ NOP CYC(2) break; case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(5) break; + case 0xCE: ABS DEC CYC(6) break; case 0xCF: $ NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; case 0xD1: INDY_OPT CMP CYC(5) break; diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 2c30b26f..1db12bcc 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -335,7 +335,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xCB: INV NOP CYC(2) break; case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC_CMOS CYC(5) break; + case 0xCE: ABS DEC_CMOS CYC(6) break; case 0xCF: INV NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; case 0xD1: INDY_OPT CMP CYC(5) break; @@ -594,7 +594,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0xCB: $ NOP CYC(2) break; case 0xCC: ABS CPY CYC(4) break; case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(5) break; + case 0xCE: ABS DEC CYC(6) break; case 0xCF: $ NOP CYC(2) break; case 0xD0: REL BNE CYC(2) break; case 0xD1: INDY_OPT CMP CYC(5) break; diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp index 211d8ac7..e5fe5bb9 100644 --- a/test/TestCPU6502/TestCPU6502.cpp +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -95,7 +95,6 @@ DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles) void init(void) { - //mem = new BYTE[64*1024]; mem = (LPBYTE)VirtualAlloc(NULL,64*1024,MEM_COMMIT,PAGE_READWRITE); for (UINT i=0; i<256; i++) @@ -117,9 +116,11 @@ void reset(void) //------------------------------------- -int test_GH264(void) +int GH264_test(void) { + // No page-cross reset(); + regs.pc = 0x300; WORD abs = regs.pc+3; WORD dst = abs+2; mem[regs.pc+0] = 0x6c; // JMP (IND) @@ -137,6 +138,28 @@ int test_GH264(void) if (cycles != 6) return 1; if (regs.pc != dst) return 1; + // Page-cross + reset(); + regs.pc = 0x3fc; // 3FC: JMP (abs) + abs = regs.pc+3; // 3FF: lo(dst), hi(dst) + dst = abs+2; + mem[regs.pc+0] = 0x6c; // JMP (IND) + mem[regs.pc+1] = abs&0xff; + mem[regs.pc+2] = abs>>8; + mem[regs.pc+3] = dst&0xff; + mem[regs.pc+4] = mem[regs.pc & ~0xff] = dst>>8; // Allow for bug in 6502 + + cycles = Cpu6502(0); + if (cycles != 5) return 1; + if (regs.pc != dst) return 1; + + reset(); + regs.pc = 0x3fc; + mem[regs.pc & ~0xff] = 0; // Test that 65C02 fixes the bug in the 6502 + cycles = Cpu65C02(0); + if (cycles != 7) return 1; // todo: is this 6 or 7? + if (regs.pc != dst) return 1; + return 0; } @@ -178,7 +201,7 @@ void INC_ABSX(BYTE x, WORD base, BYTE d) mem[regs.pc+2] = base>>8; } -int test_GH271(void) +int GH271_test(void) { // asl abs,x { @@ -281,6 +304,567 @@ int test_GH271(void) //------------------------------------- +enum {CYC_6502=0, CYC_6502_PX, CYC_65C02, CYC_65C02_PX}; + +const BYTE g_OpcodeTimings[256][4] = +{ +// 6502 (no page-cross), 6502 (page-cross), 65C02 (no page-cross), 65C02 (page-cross) + {7,7,7,7}, // 00 + {6,6,6,6}, // 01 + {2,2,2,2}, // 02 + {8,8,2,2}, // 03 + {3,3,5,5}, // 04 + {3,3,3,3}, // 05 + {5,5,5,5}, // 06 + {5,5,2,2}, // 07 + {3,3,3,3}, // 08 + {2,2,2,2}, // 09 + {2,2,2,2}, // 0A + {2,2,2,2}, // 0B + {4,5,6,6}, // 0C + {4,4,4,4}, // 0D + {6,6,6,6}, // 0E + {6,6,2,2}, // 0F + {3,3,3,3}, // 10 + {5,6,5,6}, // 11 + {2,2,5,5}, // 12 + {8,8,2,2}, // 13 + {4,4,5,5}, // 14 + {4,4,4,4}, // 15 + {6,6,6,6}, // 16 + {6,6,2,2}, // 17 + {2,2,2,2}, // 18 + {4,5,4,5}, // 19 + {2,2,2,2}, // 1A + {7,7,2,2}, // 1B + {4,5,6,6}, // 1C + {4,5,4,5}, // 1D + {7,7,6,7}, // 1E + {7,7,2,2}, // 1F + {6,6,6,6}, // 20 + {6,6,6,6}, // 21 + {2,2,2,2}, // 22 + {8,8,2,2}, // 23 + {3,3,3,3}, // 24 + {3,3,3,3}, // 25 + {5,5,5,5}, // 26 + {5,5,2,2}, // 27 + {4,4,4,4}, // 28 + {2,2,2,2}, // 29 + {2,2,2,2}, // 2A + {2,2,2,2}, // 2B + {4,4,4,4}, // 2C + {2,2,2,2}, // 2D + {6,6,6,6}, // 2E + {6,6,2,2}, // 2F + {2,2,2,2}, // 30 + {5,6,5,6}, // 31 + {2,2,5,5}, // 32 + {8,8,2,2}, // 33 + {4,4,4,4}, // 34 + {4,4,4,4}, // 35 + {6,6,6,6}, // 36 + {6,6,2,2}, // 37 + {2,2,2,2}, // 38 + {4,5,4,5}, // 39 + {2,2,2,2}, // 3A + {7,7,2,2}, // 3B + {4,5,4,5}, // 3C + {4,5,4,5}, // 3D + {6,6,6,7}, // 3E + {7,7,2,2}, // 3F + {6,6,6,6}, // 40 + {6,6,6,6}, // 41 + {2,2,2,2}, // 42 + {8,8,2,2}, // 43 + {3,3,3,3}, // 44 + {3,3,3,3}, // 45 + {5,5,5,5}, // 46 + {5,5,2,2}, // 47 + {3,3,3,3}, // 48 + {2,2,2,2}, // 49 + {2,2,2,2}, // 4A + {2,2,2,2}, // 4B + {3,3,3,3}, // 4C + {4,4,4,4}, // 4D + {6,6,6,6}, // 4E + {6,6,2,2}, // 4F + {3,3,3,3}, // 50 + {5,6,5,6}, // 51 + {2,2,5,5}, // 52 + {8,8,2,2}, // 53 + {4,4,4,4}, // 54 + {4,4,4,4}, // 55 + {6,6,6,6}, // 56 + {6,6,2,2}, // 57 + {2,2,2,2}, // 58 + {4,5,4,5}, // 59 + {2,2,3,3}, // 5A + {7,7,2,2}, // 5B + {4,5,8,9}, // 5C + {4,5,4,5}, // 5D + {6,6,6,7}, // 5E + {7,7,2,2}, // 5F + {6,6,6,6}, // 60 + {6,6,6,6}, // 61 + {2,2,2,2}, // 62 + {8,8,2,2}, // 63 + {3,3,3,3}, // 64 + {3,3,3,3}, // 65 + {5,5,5,5}, // 66 + {5,5,2,2}, // 67 + {4,4,4,4}, // 68 + {2,2,2,2}, // 69 + {2,2,2,2}, // 6A + {2,2,2,2}, // 6B + {5,5,7,7}, // 6C + {4,4,4,4}, // 6D + {6,6,6,6}, // 6E + {6,6,2,2}, // 6F + {2,2,2,2}, // 70 + {5,6,5,6}, // 71 + {2,2,5,5}, // 72 + {8,8,2,2}, // 73 + {4,4,4,4}, // 74 + {4,4,4,4}, // 75 + {6,6,6,6}, // 76 + {6,6,2,2}, // 77 + {2,2,2,2}, // 78 + {4,5,4,5}, // 79 + {2,2,4,4}, // 7A + {7,7,2,2}, // 7B + {4,5,6,6}, // 7C + {4,5,4,5}, // 7D + {6,6,6,7}, // 7E + {7,7,2,2}, // 7F + {2,2,3,3}, // 80 + {6,6,6,6}, // 81 + {2,2,2,2}, // 82 + {6,6,2,2}, // 83 + {3,3,3,3}, // 84 + {3,3,3,3}, // 85 + {3,3,3,3}, // 86 + {3,3,2,2}, // 87 + {2,2,2,2}, // 88 + {2,2,2,2}, // 89 + {2,2,2,2}, // 8A + {2,2,2,2}, // 8B + {4,4,4,4}, // 8C + {4,4,4,4}, // 8D + {4,4,4,4}, // 8E + {4,4,2,2}, // 8F + {3,3,3,3}, // 90 + {6,6,6,6}, // 91 + {2,2,5,5}, // 92 + {6,6,2,2}, // 93 + {4,4,4,4}, // 94 + {4,4,4,4}, // 95 + {4,4,4,4}, // 96 + {4,4,2,2}, // 97 + {2,2,2,2}, // 98 + {5,5,5,5}, // 99 + {2,2,2,2}, // 9A + {5,5,2,2}, // 9B + {5,5,4,4}, // 9C + {5,5,5,5}, // 9D + {5,5,5,5}, // 9E + {5,5,2,2}, // 9F + {2,2,2,2}, // A0 + {6,6,6,6}, // A1 + {2,2,2,2}, // A2 + {6,6,2,2}, // A3 + {3,3,3,3}, // A4 + {3,3,3,3}, // A5 + {3,3,3,3}, // A6 + {3,3,2,2}, // A7 + {2,2,2,2}, // A8 + {2,2,2,2}, // A9 + {2,2,2,2}, // AA + {2,2,2,2}, // AB + {4,4,4,4}, // AC + {4,4,4,4}, // AD + {4,4,4,4}, // AE + {4,4,2,2}, // AF + {2,2,2,2}, // B0 + {5,6,5,6}, // B1 + {2,2,5,5}, // B2 + {5,6,2,2}, // B3 + {4,4,4,4}, // B4 + {4,4,4,4}, // B5 + {4,4,4,4}, // B6 + {4,4,2,2}, // B7 + {2,2,2,2}, // B8 + {4,5,4,5}, // B9 + {2,2,2,2}, // BA + {4,5,2,2}, // BB + {4,5,4,5}, // BC + {4,5,4,5}, // BD + {4,5,4,5}, // BE + {4,5,2,2}, // BF + {2,2,2,2}, // C0 + {6,6,6,6}, // C1 + {2,2,2,2}, // C2 + {8,8,2,2}, // C3 + {3,3,3,3}, // C4 + {3,3,3,3}, // C5 + {5,5,5,5}, // C6 + {5,5,2,2}, // C7 + {2,2,2,2}, // C8 + {2,2,2,2}, // C9 + {2,2,2,2}, // CA + {2,2,2,2}, // CB + {4,4,4,4}, // CC + {4,4,4,4}, // CD + {6,6,6,6}, // CE + {6,6,2,2}, // CF + {3,3,3,3}, // D0 + {5,6,5,6}, // D1 + {2,2,5,5}, // D2 + {8,8,2,2}, // D3 + {4,4,4,4}, // D4 + {4,4,4,4}, // D5 + {6,6,6,6}, // D6 + {6,6,2,2}, // D7 + {2,2,2,2}, // D8 + {4,5,4,5}, // D9 + {2,2,3,3}, // DA + {7,7,2,2}, // DB + {4,5,4,5}, // DC + {4,5,4,5}, // DD + {7,7,7,7}, // DE + {7,7,2,2}, // DF + {2,2,2,2}, // E0 + {6,6,6,6}, // E1 + {2,2,2,2}, // E2 + {8,8,2,2}, // E3 + {3,3,3,3}, // E4 + {3,3,3,3}, // E5 + {5,5,5,5}, // E6 + {5,5,2,2}, // E7 + {2,2,2,2}, // E8 + {2,2,2,2}, // E9 + {2,2,2,2}, // EA + {2,2,2,2}, // EB + {4,4,4,4}, // EC + {4,4,4,4}, // ED + {6,6,6,6}, // EE + {6,6,2,2}, // EF + {2,2,2,2}, // F0 + {5,6,5,6}, // F1 + {2,2,5,5}, // F2 + {8,8,2,2}, // F3 + {4,4,4,4}, // F4 + {4,4,4,4}, // F5 + {6,6,6,6}, // F6 + {6,6,2,2}, // F7 + {2,2,2,2}, // F8 + {4,5,4,5}, // F9 + {2,2,4,4}, // FA + {7,7,2,2}, // FB + {4,5,4,5}, // FC + {4,5,4,5}, // FD + {7,7,7,7}, // FE + {7,7,2,2}, // FF +}; + +int GH278_Bcc_Sub(BYTE op, BYTE ps_not_taken, BYTE ps_taken, WORD pc) +{ + mem[pc+0] = op; + mem[pc+1] = 0x01; + const WORD dst_not_taken = pc+2; + const WORD dst_taken = pc+2 + mem[pc+1]; + + const int pagecross = (((pc+2) ^ dst_taken) >> 8) & 1; + + // 6502 + + reset(); + regs.pc = pc; + regs.ps = ps_not_taken; + if (Cpu6502(0) != 2) return 1; + if (regs.pc != dst_not_taken) return 1; + + reset(); + regs.pc = pc; + regs.ps = ps_taken; + if (Cpu6502(0) != 3+pagecross) return 1; + if (regs.pc != dst_taken) return 1; + + // 65C02 + + reset(); + regs.pc = pc; + regs.ps = ps_not_taken; + if (Cpu65C02(0) != 2) return 1; + if (regs.pc != dst_not_taken) return 1; + + reset(); + regs.pc = pc; + regs.ps = ps_taken; + if (Cpu65C02(0) != 3+pagecross) return 1; + if (regs.pc != dst_taken) return 1; + + return 0; +} + +int GH278_Bcc(BYTE op, BYTE ps_not_taken, BYTE ps_taken) +{ + if (GH278_Bcc_Sub(op, ps_not_taken, ps_taken, 0x300)) return 1; // no page cross + if (GH278_Bcc_Sub(op, ps_not_taken, ps_taken, 0x3FD)) return 1; // page cross + + return 0; +} + +int GH278_BRA(void) +{ + // No page-cross + { + WORD pc = 0x300; + mem[pc+0] = 0x80; // BRA + mem[pc+1] = 0x01; + const WORD dst_taken = pc+2 + mem[pc+1]; + + reset(); + regs.pc = pc; + if (Cpu65C02(0) != 3) return 1; + if (regs.pc != dst_taken) return 1; + } + + // Page-cross + { + WORD pc = 0x3FD; + mem[pc+0] = 0x80; // BRA + mem[pc+1] = 0x01; + const WORD dst_taken = pc+2 + mem[pc+1]; + + reset(); + regs.pc = pc; + if (Cpu65C02(0) != 4) return 1; + if (regs.pc != dst_taken) return 1; + } + + return 0; +} + +int GH278_JMP_INDX(void) +{ + // No page-cross + reset(); + regs.pc = 0x300; + WORD abs = regs.pc+3; + WORD dst = abs+2; + mem[regs.pc+0] = 0x7c; // JMP (IND,X) + mem[regs.pc+1] = abs&0xff; + mem[regs.pc+2] = abs>>8; + mem[regs.pc+3] = dst&0xff; + mem[regs.pc+4] = dst>>8; + + DWORD cycles = Cpu65C02(0); + if (cycles != 6) return 1; + if (regs.pc != dst) return 1; + + // Page-cross (case 1) + reset(); + regs.pc = 0x3fc; + abs = regs.pc+3; + dst = abs+2; + mem[regs.pc+0] = 0x7c; // JMP (IND,X) + mem[regs.pc+1] = abs&0xff; + mem[regs.pc+2] = abs>>8; + mem[regs.pc+3] = dst&0xff; + mem[regs.pc+4] = dst>>8; + + cycles = Cpu65C02(0); + if (cycles != 6) return 1; // todo: is this 6 or 7? + if (regs.pc != dst) return 1; + + // Page-cross (case 2) + reset(); + regs.x = 1; + regs.pc = 0x3fa; + abs = regs.pc+3; + dst = abs+2 + regs.x; + mem[regs.pc+0] = 0x7c; // JMP (IND,X) + mem[regs.pc+1] = abs&0xff; + mem[regs.pc+2] = abs>>8; + mem[regs.pc+3] = 0xcc; // unused + mem[regs.pc+4] = dst&0xff; + mem[regs.pc+5] = dst>>8; + + cycles = Cpu65C02(0); + if (cycles != 6) return 1; // todo: is this 6 or 7? + if (regs.pc != dst) return 1; + + return 0; +} + +int GH278_ADC_SBC(UINT op) +{ + const WORD base = 0x20ff; + reset(); + mem[regs.pc+0] = op; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + mem[0xff] = 0xff; mem[0x00] = 0x00; // For: OPCODE (zp),Y + + // No page-cross + reset(); + regs.ps = AF_DECIMAL; + DWORD cycles = Cpu6502(0); + if (g_OpcodeTimings[op][CYC_6502] != cycles) return 1; + + reset(); + regs.ps = AF_DECIMAL; + cycles = Cpu65C02(0); + if (g_OpcodeTimings[op][CYC_65C02]+1 != cycles) return 1; // CMOS is +1 cycles in decimal mode + + // Page-cross + reset(); + regs.ps = AF_DECIMAL; + regs.x = 1; + regs.y = 1; + cycles = Cpu6502(0); + if (g_OpcodeTimings[op][CYC_6502_PX] != cycles) return 1; + + reset(); + regs.ps = AF_DECIMAL; + regs.x = 1; + regs.y = 1; + cycles = Cpu65C02(0); + if (g_OpcodeTimings[op][CYC_65C02_PX]+1 != cycles) return 1; // CMOS is +1 cycles in decimal mode + + return 0; +} + +int GH278_ADC(void) +{ + const BYTE adc[] = {0x61,0x65,0x69,0x6D,0x71,0x72,0x75,0x79,0x7D}; + + for (UINT i = 0; i>8; + DWORD cycles = Cpu6502(0); + if (g_OpcodeTimings[op][variant] != cycles) return 1; + } + + variant++; + + // Page-cross + for (UINT op=0; op<256; op++) + { + reset(); + regs.x = 1; + regs.y = 1; + WORD base = 0x20ff; + mem[regs.pc+0] = op; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + mem[0xff] = 0xff; mem[0x00] = 0x00; // For: OPCODE (zp),Y + DWORD cycles = Cpu6502(0); + if (g_OpcodeTimings[op][variant] != cycles) return 1; + } + + variant++; + + // + // 65C02 + // + + // No page-cross + for (UINT op=0; op<256; op++) + { + reset(); + WORD base = 0x20ff; + mem[regs.pc+0] = op; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + DWORD cycles = Cpu65C02(0); + if (g_OpcodeTimings[op][variant] != cycles) return 1; + } + + variant++; + + // Page-cross + for (UINT op=0; op<256; op++) + { + reset(); + regs.x = 1; + regs.y = 1; + WORD base = 0x20ff; + mem[regs.pc+0] = op; + mem[regs.pc+1] = base&0xff; + mem[regs.pc+2] = base>>8; + mem[0xff] = 0xff; mem[0x00] = 0x00; // For: OPCODE (zp),Y + DWORD cycles = Cpu65C02(0); + if (g_OpcodeTimings[op][variant] != cycles) return 1; + } + + // + // Bcc + // + + if (GH278_Bcc(0x10, AF_SIGN, 0)) return 1; // BPL + if (GH278_Bcc(0x30, 0, AF_SIGN)) return 1; // BMI + if (GH278_Bcc(0x50, AF_OVERFLOW, 0)) return 1; // BVC + if (GH278_Bcc(0x70, 0, AF_OVERFLOW)) return 1; // BVS + if (GH278_Bcc(0x90, AF_CARRY, 0)) return 1; // BCC + if (GH278_Bcc(0xB0, 0, AF_CARRY)) return 1; // BCS + if (GH278_Bcc(0xD0, AF_ZERO, 0)) return 1; // BNE + if (GH278_Bcc(0xF0, 0, AF_ZERO)) return 1; // BEQ + if (GH278_BRA()) return 1; // BRA + + // + // JMP (IND) and JMP (IND,X) + // . NB. GH264_test() tests JMP (IND) + // + + if (GH278_JMP_INDX()) return 1; + + // + // ADC/SBC CMOS decimal mode is +1 cycles + // + + if (GH278_ADC()) return 1; + if (GH278_SBC()) return 1; + + return 0; +} + +//------------------------------------- + DWORD AXA_ZPY(BYTE a, BYTE x, BYTE y, WORD base) { reset(); @@ -342,7 +926,7 @@ DWORD XAS_ABSY(BYTE a, BYTE x, BYTE y, WORD base) return Cpu6502(0); } -int test_GH282(void) +int GH282_test(void) { // axa (zp),y { @@ -465,13 +1049,16 @@ int _tmain(int argc, _TCHAR* argv[]) init(); reset(); - res = test_GH264(); + res = GH264_test(); if (res) return res; - res = test_GH271(); + res = GH271_test(); if (res) return res; - res = test_GH282(); + res = GH278_test(); + if (res) return res; + + res = GH282_test(); if (res) return res; return 0; From df5635dc111752194a60df4f760a80f6a591dce8 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 9 May 2015 20:57:25 +0100 Subject: [PATCH 08/11] Align opcodes in 6502 and 65C02 switch statements --- source/CPU/cpu6502.h | 523 +++++++++++++++++++------------------ source/CPU/cpu65C02.h | 514 ++++++++++++++++++------------------ source/CPU/cpu65d02.h | 2 +- source/CPU/cpu_general.inl | 4 +- 4 files changed, 522 insertions(+), 521 deletions(-) diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index 9d3d8454..e7039c07 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -49,269 +49,270 @@ static DWORD Cpu6502 (DWORD uTotalCycles) } else { - if (!Fetch(iOpcode, uExecutedCycles)) - break; + if (!Fetch(iOpcode, uExecutedCycles)) + break; #define $ INV // INV = Invalid -> Debugger Break - switch (iOpcode) - { - case 0x00: BRK CYC(7) break; - case 0x01: idx ORA CYC(6) break; - case 0x02: $ HLT CYC(2) break; - case 0x03: $ idx ASO CYC(8) break; - case 0x04: $ ZPG NOP CYC(3) break; - case 0x05: ZPG ORA CYC(3) break; - case 0x06: ZPG ASLn CYC(5) break; - case 0x07: $ ZPG ASO CYC(5) break; // invalid - case 0x08: PHP CYC(3) break; - case 0x09: IMM ORA CYC(2) break; - case 0x0A: asl CYC(2) break; - case 0x0B: $ IMM ANC CYC(2) break; // invalid - case 0x0C: $ ABSX_OPT NOP CYC(4) break; - case 0x0D: ABS ORA CYC(4) break; - case 0x0E: ABS ASLn CYC(6) break; - case 0x0F: $ ABS ASO CYC(6) break; // invalid - case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_OPT ORA CYC(5) break; - case 0x12: $ HLT CYC(2) break; - case 0x13: $ INDY_CONST ASO CYC(8) break; // invalid - case 0x14: $ zpx NOP CYC(4) break; - case 0x15: zpx ORA CYC(4) break; - case 0x16: zpx ASLn CYC(6) break; - case 0x17: $ zpx ASO CYC(6) break; // invalid - case 0x18: CLC CYC(2) break; - case 0x19: ABSY_OPT ORA CYC(4) break; - case 0x1A: $ NOP CYC(2) break; - case 0x1B: $ ABSY_CONST ASO CYC(7) break; // invalid - case 0x1C: $ ABSX_OPT NOP CYC(4) break; - case 0x1D: ABSX_OPT ORA CYC(4) break; - case 0x1E: ABSX_CONST ASLn CYC(7) break; - case 0x1F: $ ABSX_CONST ASO CYC(7) break; // invalid - case 0x20: ABS JSR CYC(6) break; - case 0x21: idx AND CYC(6) break; - case 0x22: $ HLT CYC(2) break; - case 0x23: $ idx RLA CYC(8) break; - case 0x24: ZPG BIT CYC(3) break; - case 0x25: ZPG AND CYC(3) break; - case 0x26: ZPG ROLn CYC(5) break; - case 0x27: $ ZPG RLA CYC(5) break; - case 0x28: PLP CYC(4) break; - case 0x29: IMM AND CYC(2) break; - case 0x2A: rol CYC(2) break; - case 0x2B: $ IMM ANC CYC(2) break; // invalid - case 0x2C: ABS BIT CYC(4) break; - case 0x2D: ABS AND CYC(2) break; - case 0x2E: ABS ROLn CYC(6) break; - case 0x2F: $ ABS RLA CYC(6) break; - case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_OPT AND CYC(5) break; - case 0x32: $ HLT CYC(2) break; - case 0x33: $ INDY_CONST RLA CYC(8) break; // invalid - case 0x34: $ zpx NOP CYC(4) break; - case 0x35: zpx AND CYC(4) break; - case 0x36: zpx ROLn CYC(6) break; - case 0x37: $ zpx RLA CYC(6) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY_OPT AND CYC(4) break; - case 0x3A: $ NOP CYC(2) break; - case 0x3B: $ ABSY_CONST RLA CYC(7) break; // invalid - case 0x3C: $ ABSX_OPT NOP CYC(4) break; - case 0x3D: ABSX_OPT AND CYC(4) break; - case 0x3E: ABSX_CONST ROLn CYC(6) break; - case 0x3F: $ ABSX_CONST RLA CYC(7) break; // invalid - case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; - case 0x41: idx EOR CYC(6) break; - case 0x42: $ HLT CYC(2) break; - case 0x43: $ idx LSE CYC(8) break; // invalid - case 0x44: $ ZPG NOP CYC(3) break; - case 0x45: ZPG EOR CYC(3) break; - case 0x46: ZPG LSRn CYC(5) break; - case 0x47: $ ZPG LSE CYC(5) break; // invalid - case 0x48: PHA CYC(3) break; - case 0x49: IMM EOR CYC(2) break; - case 0x4A: lsr CYC(2) break; - case 0x4B: $ IMM ALR CYC(2) break; // invalid - case 0x4C: ABS JMP CYC(3) break; - case 0x4D: ABS EOR CYC(4) break; - case 0x4E: ABS LSRn CYC(6) break; - case 0x4F: $ ABS LSE CYC(6) break; - case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_OPT EOR CYC(5) break; - case 0x52: $ HLT CYC(2) break; - case 0x53: $ INDY_CONST LSE CYC(8) break; - case 0x54: $ zpx NOP CYC(4) break; - case 0x55: zpx EOR CYC(4) break; - case 0x56: zpx LSRn CYC(6) break; - case 0x57: $ zpx LSE CYC(6) break; // invalid - case 0x58: CLI CYC(2) break; - case 0x59: ABSY_OPT EOR CYC(4) break; - case 0x5A: $ NOP CYC(2) break; - case 0x5B: $ ABSY_CONST LSE CYC(7) break; // invalid - case 0x5C: $ ABSX_OPT NOP CYC(4) break; - case 0x5D: ABSX_OPT EOR CYC(4) break; - case 0x5E: ABSX_CONST LSRn CYC(6) break; - case 0x5F: $ ABSX_CONST LSE CYC(7) break; - case 0x60: RTS CYC(6) break; - case 0x61: idx ADCn CYC(6) break; - case 0x62: $ HLT CYC(2) break; - case 0x63: $ idx RRA CYC(8) break; // invalid - case 0x64: $ ZPG NOP CYC(3) break; - case 0x65: ZPG ADCn CYC(3) break; - case 0x66: ZPG RORn CYC(5) break; - case 0x67: $ ZPG RRA CYC(5) break; - case 0x68: PLA CYC(4) break; - case 0x69: IMM ADCn CYC(2) break; - case 0x6A: ror CYC(2) break; - case 0x6B: $ IMM ARR CYC(2) break; // invalid - case 0x6C: IABSNMOS JMP CYC(5) break; // GH#264 - case 0x6D: ABS ADCn CYC(4) break; - case 0x6E: ABS RORn CYC(6) break; - case 0x6F: $ ABS RRA CYC(6) break; // invalid - case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_OPT ADCn CYC(5) break; - case 0x72: $ HLT CYC(2) break; - case 0x73: $ INDY_CONST RRA CYC(8) break; // invalid - case 0x74: $ zpx NOP CYC(4) break; - case 0x75: zpx ADCn CYC(4) break; - case 0x76: zpx RORn CYC(6) break; - case 0x77: $ zpx RRA CYC(6) break; // invalid - case 0x78: SEI CYC(2) break; - case 0x79: ABSY_OPT ADCn CYC(4) break; - case 0x7A: $ NOP CYC(2) break; - case 0x7B: $ ABSY_CONST RRA CYC(7) break; // invalid - case 0x7C: $ ABSX_OPT NOP CYC(4) break; - case 0x7D: ABSX_OPT ADCn CYC(4) break; - case 0x7E: ABSX_CONST RORn CYC(6) break; - case 0x7F: $ ABSX_CONST RRA CYC(7) break; // invalid - case 0x80: $ IMM NOP CYC(2) break; - case 0x81: idx STA CYC(6) break; - case 0x82: $ IMM NOP CYC(2) break; - case 0x83: $ idx AXS CYC(6) break; // invalid - case 0x84: ZPG STY CYC(3) break; - case 0x85: ZPG STA CYC(3) break; - case 0x86: ZPG STX CYC(3) break; - case 0x87: $ ZPG AXS CYC(3) break; // invalid - case 0x88: DEY CYC(2) break; - case 0x89: $ IMM NOP CYC(2) break; - case 0x8A: TXA CYC(2) break; - case 0x8B: $ IMM XAA CYC(2) break; // invalid - case 0x8C: ABS STY CYC(4) break; - case 0x8D: ABS STA CYC(4) break; - case 0x8E: ABS STX CYC(4) break; - case 0x8F: $ ABS AXS CYC(4) break; // invalid - case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_CONST STA CYC(6) break; - case 0x92: $ HLT CYC(2) break; - case 0x93: $ INDY_CONST AXA CYC(6) break; // invalid - case 0x94: zpx STY CYC(4) break; - case 0x95: zpx STA CYC(4) break; - case 0x96: zpy STX CYC(4) break; - case 0x97: $ zpy AXS CYC(4) break; // invalid - case 0x98: TYA CYC(2) break; - case 0x99: ABSY_CONST STA CYC(5) break; - case 0x9A: TXS CYC(2) break; - case 0x9B: $ ABSY_CONST TAS CYC(5) break; // invalid - case 0x9C: $ ABSX_CONST SAY CYC(5) break; // invalid - case 0x9D: ABSX_CONST STA CYC(5) break; - case 0x9E: $ ABSY_CONST XAS CYC(5) break; - case 0x9F: $ ABSY_CONST AXA CYC(5) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: idx LDA CYC(6) break; - case 0xA2: IMM LDX CYC(2) break; - case 0xA3: $ idx LAX CYC(6) break; // invalid - case 0xA4: ZPG LDY CYC(3) break; - case 0xA5: ZPG LDA CYC(3) break; - case 0xA6: ZPG LDX CYC(3) break; - case 0xA7: $ ZPG LAX CYC(3) break; // invalid - case 0xA8: TAY CYC(2) break; - case 0xA9: IMM LDA CYC(2) break; - case 0xAA: TAX CYC(2) break; - case 0xAB: $ IMM OAL CYC(2) break; // invalid - case 0xAC: ABS LDY CYC(4) break; - case 0xAD: ABS LDA CYC(4) break; - case 0xAE: ABS LDX CYC(4) break; - case 0xAF: $ ABS LAX CYC(4) break; // invalid - case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_OPT LDA CYC(5) break; - case 0xB2: $ HLT CYC(2) break; - case 0xB3: $ INDY_OPT LAX CYC(5) break; - case 0xB4: zpx LDY CYC(4) break; - case 0xB5: zpx LDA CYC(4) break; - case 0xB6: zpy LDX CYC(4) break; - case 0xB7: $ zpy LAX CYC(4) break; // invalid - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_OPT LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: $ ABSY_OPT LAS CYC(4) break; // invalid - case 0xBC: ABSX_OPT LDY CYC(4) break; - case 0xBD: ABSX_OPT LDA CYC(4) break; - case 0xBE: ABSY_OPT LDX CYC(4) break; - case 0xBF: $ ABSY_OPT LAX CYC(4) break; // invalid - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: idx CMP CYC(6) break; - case 0xC2: $ IMM NOP CYC(2) break; - case 0xC3: $ idx DCM CYC(8) break; // invalid - case 0xC4: ZPG CPY CYC(3) break; - case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DEC CYC(5) break; - case 0xC7: $ ZPG DCM CYC(5) break; // invalid - case 0xC8: INY CYC(2) break; - case 0xC9: IMM CMP CYC(2) break; - case 0xCA: DEX CYC(2) break; - case 0xCB: $ IMM SAX CYC(2) break; // invalid - case 0xCC: ABS CPY CYC(4) break; - case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(6) break; - case 0xCF: $ ABS DCM CYC(6) break; // invalid - case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_OPT CMP CYC(5) break; - case 0xD2: $ HLT CYC(2) break; - case 0xD3: $ INDY_CONST DCM CYC(8) break; // invalid - case 0xD4: $ zpx NOP CYC(4) break; - case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DEC CYC(6) break; - case 0xD7: $ zpx DCM CYC(6) break; // invalid - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_OPT CMP CYC(4) break; - case 0xDA: $ NOP CYC(2) break; - case 0xDB: $ ABSY_CONST DCM CYC(7) break; // invalid - case 0xDC: $ ABSX_OPT NOP CYC(4) break; - case 0xDD: ABSX_OPT CMP CYC(4) break; - case 0xDE: ABSX_CONST DEC CYC(7) break; - case 0xDF: $ ABSX_CONST DCM CYC(7) break; // invalid - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: idx SBCn CYC(6) break; - case 0xE2: $ IMM NOP CYC(2) break; - case 0xE3: $ idx INS CYC(8) break; // invalid - case 0xE4: ZPG CPX CYC(3) break; - case 0xE5: ZPG SBCn CYC(3) break; - case 0xE6: ZPG INC CYC(5) break; - case 0xE7: $ ZPG INS CYC(5) break; // invalid - case 0xE8: INX CYC(2) break; - case 0xE9: IMM SBCn CYC(2) break; - case 0xEA: NOP CYC(2) break; - case 0xEB: $ IMM SBCn CYC(2) break; - case 0xEC: ABS CPX CYC(4) break; - case 0xED: ABS SBCn CYC(4) break; - case 0xEE: ABS INC CYC(6) break; - case 0xEF: $ ABS INS CYC(6) break; // invalid - case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_OPT SBCn CYC(5) break; - case 0xF2: $ HLT CYC(2) break; - case 0xF3: $ INDY_CONST INS CYC(8) break; // invalid - case 0xF4: $ zpx NOP CYC(4) break; - case 0xF5: zpx SBCn CYC(4) break; - case 0xF6: zpx INC CYC(6) break; - case 0xF7: $ zpx INS CYC(6) break; // invalid - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_OPT SBCn CYC(4) break; - case 0xFA: $ NOP CYC(2) break; - case 0xFB: $ ABSY_CONST INS CYC(7) break; - case 0xFC: $ ABSX_OPT NOP CYC(4) break; - case 0xFD: ABSX_OPT SBCn CYC(4) break; - case 0xFE: ABSX_CONST INC CYC(7) break; - case 0xFF: $ ABSX_CONST INS CYC(7) break; - } + switch (iOpcode) + { + case 0x00: BRK CYC(7) break; + case 0x01: idx ORA CYC(6) break; + case 0x02: $ HLT CYC(2) break; + case 0x03: $ idx ASO CYC(8) break; + case 0x04: $ ZPG NOP CYC(3) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASLn CYC(5) break; + case 0x07: $ ZPG ASO CYC(5) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: asl CYC(2) break; + case 0x0B: $ IMM ANC CYC(2) break; + case 0x0C: $ ABSX_OPT NOP CYC(4) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASLn CYC(6) break; + case 0x0F: $ ABS ASO CYC(6) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY_OPT ORA CYC(5) break; + case 0x12: $ HLT CYC(2) break; + case 0x13: $ INDY_CONST ASO CYC(8) break; + case 0x14: $ zpx NOP CYC(4) break; + case 0x15: zpx ORA CYC(4) break; + case 0x16: zpx ASLn CYC(6) break; + case 0x17: $ zpx ASO CYC(6) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY_OPT ORA CYC(4) break; + case 0x1A: $ NOP CYC(2) break; + case 0x1B: $ ABSY_CONST ASO CYC(7) break; + case 0x1C: $ ABSX_OPT NOP CYC(4) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_CONST ASLn CYC(7) break; + case 0x1F: $ ABSX_CONST ASO CYC(7) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: idx AND CYC(6) break; + case 0x22: $ HLT CYC(2) break; + case 0x23: $ idx RLA CYC(8) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROLn CYC(5) break; + case 0x27: $ ZPG RLA CYC(5) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: rol CYC(2) break; + case 0x2B: $ IMM ANC CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROLn CYC(6) break; + case 0x2F: $ ABS RLA CYC(6) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY_OPT AND CYC(5) break; + case 0x32: $ HLT CYC(2) break; + case 0x33: $ INDY_CONST RLA CYC(8) break; + case 0x34: $ zpx NOP CYC(4) break; + case 0x35: zpx AND CYC(4) break; + case 0x36: zpx ROLn CYC(6) break; + case 0x37: $ zpx RLA CYC(6) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY_OPT AND CYC(4) break; + case 0x3A: $ NOP CYC(2) break; + case 0x3B: $ ABSY_CONST RLA CYC(7) break; + case 0x3C: $ ABSX_OPT NOP CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_CONST ROLn CYC(6) break; + case 0x3F: $ ABSX_CONST RLA CYC(7) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: idx EOR CYC(6) break; + case 0x42: $ HLT CYC(2) break; + case 0x43: $ idx LSE CYC(8) break; + case 0x44: $ ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSRn CYC(5) break; + case 0x47: $ ZPG LSE CYC(5) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: lsr CYC(2) break; + case 0x4B: $ IMM ALR CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSRn CYC(6) break; + case 0x4F: $ ABS LSE CYC(6) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY_OPT EOR CYC(5) break; + case 0x52: $ HLT CYC(2) break; + case 0x53: $ INDY_CONST LSE CYC(8) break; + case 0x54: $ zpx NOP CYC(4) break; + case 0x55: zpx EOR CYC(4) break; + case 0x56: zpx LSRn CYC(6) break; + case 0x57: $ zpx LSE CYC(6) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY_OPT EOR CYC(4) break; + case 0x5A: $ NOP CYC(2) break; + case 0x5B: $ ABSY_CONST LSE CYC(7) break; + case 0x5C: $ ABSX_OPT NOP CYC(4) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_CONST LSRn CYC(6) break; + case 0x5F: $ ABSX_CONST LSE CYC(7) break; + case 0x60: RTS CYC(6) break; + case 0x61: idx ADCn CYC(6) break; + case 0x62: $ HLT CYC(2) break; + case 0x63: $ idx RRA CYC(8) break; + case 0x64: $ ZPG NOP CYC(3) break; + case 0x65: ZPG ADCn CYC(3) break; + case 0x66: ZPG RORn CYC(5) break; + case 0x67: $ ZPG RRA CYC(5) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADCn CYC(2) break; + case 0x6A: ror CYC(2) break; + case 0x6B: $ IMM ARR CYC(2) break; + case 0x6C: IABS_NMOS JMP CYC(5) break; // GH#264 + case 0x6D: ABS ADCn CYC(4) break; + case 0x6E: ABS RORn CYC(6) break; + case 0x6F: $ ABS RRA CYC(6) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY_OPT ADCn CYC(5) break; + case 0x72: $ HLT CYC(2) break; + case 0x73: $ INDY_CONST RRA CYC(8) break; + case 0x74: $ zpx NOP CYC(4) break; + case 0x75: zpx ADCn CYC(4) break; + case 0x76: zpx RORn CYC(6) break; + case 0x77: $ zpx RRA CYC(6) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY_OPT ADCn CYC(4) break; + case 0x7A: $ NOP CYC(2) break; + case 0x7B: $ ABSY_CONST RRA CYC(7) break; + case 0x7C: $ ABSX_OPT NOP CYC(4) break; + case 0x7D: ABSX_OPT ADCn CYC(4) break; + case 0x7E: ABSX_CONST RORn CYC(6) break; + case 0x7F: $ ABSX_CONST RRA CYC(7) break; + case 0x80: $ IMM NOP CYC(2) break; + case 0x81: idx STA CYC(6) break; + case 0x82: $ IMM NOP CYC(2) break; + case 0x83: $ idx AXS CYC(6) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: $ ZPG AXS CYC(3) break; + case 0x88: DEY CYC(2) break; + case 0x89: $ IMM NOP CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: $ IMM XAA CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: $ ABS AXS CYC(4) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY_CONST STA CYC(6) break; + case 0x92: $ HLT CYC(2) break; + case 0x93: $ INDY_CONST AXA CYC(6) break; + case 0x94: zpx STY CYC(4) break; + case 0x95: zpx STA CYC(4) break; + case 0x96: zpy STX CYC(4) break; + case 0x97: $ zpy AXS CYC(4) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY_CONST STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: $ ABSY_CONST TAS CYC(5) break; + case 0x9C: $ ABSX_CONST SAY CYC(5) break; + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: $ ABSY_CONST XAS CYC(5) break; + case 0x9F: $ ABSY_CONST AXA CYC(5) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: idx LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: $ idx LAX CYC(6) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: $ ZPG LAX CYC(3) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: $ IMM OAL CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: $ ABS LAX CYC(4) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY_OPT LDA CYC(5) break; + case 0xB2: $ HLT CYC(2) break; + case 0xB3: $ INDY_OPT LAX CYC(5) break; + case 0xB4: zpx LDY CYC(4) break; + case 0xB5: zpx LDA CYC(4) break; + case 0xB6: zpy LDX CYC(4) break; + case 0xB7: $ zpy LAX CYC(4) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: $ ABSY_OPT LAS CYC(4) break; + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; + case 0xBF: $ ABSY_OPT LAX CYC(4) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: idx CMP CYC(6) break; + case 0xC2: $ IMM NOP CYC(2) break; + case 0xC3: $ idx DCM CYC(8) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC CYC(5) break; + case 0xC7: $ ZPG DCM CYC(5) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: $ IMM SAX CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC CYC(6) break; + case 0xCF: $ ABS DCM CYC(6) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY_OPT CMP CYC(5) break; + case 0xD2: $ HLT CYC(2) break; + case 0xD3: $ INDY_CONST DCM CYC(8) break; + case 0xD4: $ zpx NOP CYC(4) break; + case 0xD5: zpx CMP CYC(4) break; + case 0xD6: zpx DEC CYC(6) break; + case 0xD7: $ zpx DCM CYC(6) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; + case 0xDA: $ NOP CYC(2) break; + case 0xDB: $ ABSY_CONST DCM CYC(7) break; + case 0xDC: $ ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_CONST DEC CYC(7) break; + case 0xDF: $ ABSX_CONST DCM CYC(7) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: idx SBCn CYC(6) break; + case 0xE2: $ IMM NOP CYC(2) break; + case 0xE3: $ idx INS CYC(8) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBCn CYC(3) break; + case 0xE6: ZPG INC CYC(5) break; + case 0xE7: $ ZPG INS CYC(5) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBCn CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: $ IMM SBCn CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBCn CYC(4) break; + case 0xEE: ABS INC CYC(6) break; + case 0xEF: $ ABS INS CYC(6) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY_OPT SBCn CYC(5) break; + case 0xF2: $ HLT CYC(2) break; + case 0xF3: $ INDY_CONST INS CYC(8) break; + case 0xF4: $ zpx NOP CYC(4) break; + case 0xF5: zpx SBCn CYC(4) break; + case 0xF6: zpx INC CYC(6) break; + case 0xF7: $ zpx INS CYC(6) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY_OPT SBCn CYC(4) break; + case 0xFA: $ NOP CYC(2) break; + case 0xFB: $ ABSY_CONST INS CYC(7) break; + case 0xFC: $ ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBCn CYC(4) break; + case 0xFE: ABSX_CONST INC CYC(7) break; + case 0xFF: $ ABSX_CONST INS CYC(7) break; + } +#undef $ } CheckInterruptSources(uExecutedCycles); diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index ecc00443..60d7139a 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -55,265 +55,265 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) if (!Fetch(iOpcode, uExecutedCycles)) break; +#define $ INV // INV = Invalid -> Debugger Break switch (iOpcode) { -#define $ INV // INV = Invalid -> Debugger Break - case 0x00: BRK CYC(7) break; - case 0x01: idx ORA CYC(6) break; - case 0x02: $ IMM NOP CYC(2) break; - case 0x03: $ NOP CYC(2) break; - case 0x04: ZPG TSB CYC(5) break; - case 0x05: ZPG ORA CYC(3) break; - case 0x06: ZPG ASLc CYC(5) break; - case 0x07: $ NOP CYC(2) break; - case 0x08: PHP CYC(3) break; - case 0x09: IMM ORA CYC(2) break; - case 0x0A: asl CYC(2) break; - case 0x0B: $ NOP CYC(2) break; - case 0x0C: ABS TSB CYC(6) break; - case 0x0D: ABS ORA CYC(4) break; - case 0x0E: ABS ASLc CYC(6) break; - case 0x0F: $ NOP CYC(2) break; - case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_OPT ORA CYC(5) break; - case 0x12: izp ORA CYC(5) break; - case 0x13: $ NOP CYC(2) break; - case 0x14: ZPG TRB CYC(5) break; - case 0x15: zpx ORA CYC(4) break; - case 0x16: zpx ASLc CYC(6) break; - case 0x17: $ NOP CYC(2) break; - case 0x18: CLC CYC(2) break; - case 0x19: ABSY_OPT ORA CYC(4) break; - case 0x1A: INA CYC(2) break; - case 0x1B: $ NOP CYC(2) break; - case 0x1C: ABS TRB CYC(6) break; - case 0x1D: ABSX_OPT ORA CYC(4) break; - case 0x1E: ABSX_OPT ASLc CYC(6) break; - case 0x1F: $ NOP CYC(2) break; - case 0x20: ABS JSR CYC(6) break; - case 0x21: idx AND CYC(6) break; - case 0x22: $ IMM NOP CYC(2) break; - case 0x23: $ NOP CYC(2) break; - case 0x24: ZPG BIT CYC(3) break; - case 0x25: ZPG AND CYC(3) break; - case 0x26: ZPG ROLc CYC(5) break; - case 0x27: $ NOP CYC(2) break; - case 0x28: PLP CYC(4) break; - case 0x29: IMM AND CYC(2) break; - case 0x2A: rol CYC(2) break; - case 0x2B: $ NOP CYC(2) break; - case 0x2C: ABS BIT CYC(4) break; - case 0x2D: ABS AND CYC(2) break; - case 0x2E: ABS ROLc CYC(6) break; - case 0x2F: $ NOP CYC(2) break; - case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_OPT AND CYC(5) break; - case 0x32: izp AND CYC(5) break; - case 0x33: $ NOP CYC(2) break; - case 0x34: zpx BIT CYC(4) break; - case 0x35: zpx AND CYC(4) break; - case 0x36: zpx ROLc CYC(6) break; - case 0x37: $ NOP CYC(2) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY_OPT AND CYC(4) break; - case 0x3A: DEA CYC(2) break; - case 0x3B: $ NOP CYC(2) break; - case 0x3C: ABSX_OPT BIT CYC(4) break; - case 0x3D: ABSX_OPT AND CYC(4) break; - case 0x3E: ABSX_OPT ROLc CYC(6) break; - case 0x3F: $ NOP CYC(2) break; - case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; - case 0x41: idx EOR CYC(6) break; - case 0x42: $ IMM NOP CYC(2) break; - case 0x43: $ NOP CYC(2) break; - case 0x44: $ ZPG NOP CYC(3) break; - case 0x45: ZPG EOR CYC(3) break; - case 0x46: ZPG LSRc CYC(5) break; - case 0x47: $ NOP CYC(2) break; - case 0x48: PHA CYC(3) break; - case 0x49: IMM EOR CYC(2) break; - case 0x4A: lsr CYC(2) break; - case 0x4B: $ NOP CYC(2) break; - case 0x4C: ABS JMP CYC(3) break; - case 0x4D: ABS EOR CYC(4) break; - case 0x4E: ABS LSRc CYC(6) break; - case 0x4F: $ NOP CYC(2) break; - case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_OPT EOR CYC(5) break; - case 0x52: izp EOR CYC(5) break; - case 0x53: $ NOP CYC(2) break; - case 0x54: $ zpx NOP CYC(4) break; - case 0x55: zpx EOR CYC(4) break; - case 0x56: zpx LSRc CYC(6) break; - case 0x57: $ NOP CYC(2) break; - case 0x58: CLI CYC(2) break; - case 0x59: ABSY_OPT EOR CYC(4) break; - case 0x5A: PHY CYC(3) break; - case 0x5B: $ NOP CYC(2) break; - case 0x5C: $ ABSX_OPT NOP CYC(8) break; - case 0x5D: ABSX_OPT EOR CYC(4) break; - case 0x5E: ABSX_OPT LSRc CYC(6) break; - case 0x5F: $ NOP CYC(2) break; - case 0x60: RTS CYC(6) break; - case 0x61: idx ADCc CYC(6) break; - case 0x62: $ IMM NOP CYC(2) break; - case 0x63: $ NOP CYC(2) break; - case 0x64: ZPG STZ CYC(3) break; - case 0x65: ZPG ADCc CYC(3) break; - case 0x66: ZPG RORc CYC(5) break; - case 0x67: $ NOP CYC(2) break; - case 0x68: PLA CYC(4) break; - case 0x69: IMM ADCc CYC(2) break; - case 0x6A: ror CYC(2) break; - case 0x6B: $ NOP CYC(2) break; - case 0x6C: IABSCMOS JMP CYC(6) break; - case 0x6D: ABS ADCc CYC(4) break; - case 0x6E: ABS RORc CYC(6) break; - case 0x6F: $ NOP CYC(2) break; - case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_OPT ADCc CYC(5) break; - case 0x72: izp ADCc CYC(5) break; - case 0x73: $ NOP CYC(2) break; - case 0x74: zpx STZ CYC(4) break; - case 0x75: zpx ADCc CYC(4) break; - case 0x76: zpx RORc CYC(6) break; - case 0x77: $ NOP CYC(2) break; - case 0x78: SEI CYC(2) break; - case 0x79: ABSY_OPT ADCc CYC(4) break; - case 0x7A: PLY CYC(4) break; - case 0x7B: $ NOP CYC(2) break; - case 0x7C: IABSX JMP CYC(6) break; // - case 0x7D: ABSX_OPT ADCc CYC(4) break; - case 0x7E: ABSX_OPT RORc CYC(6) break; - case 0x7F: $ NOP CYC(2) break; - case 0x80: REL BRA CYC(2) break; - case 0x81: idx STA CYC(6) break; - case 0x82: $ IMM NOP CYC(2) break; - case 0x83: $ NOP CYC(2) break; - case 0x84: ZPG STY CYC(3) break; - case 0x85: ZPG STA CYC(3) break; - case 0x86: ZPG STX CYC(3) break; - case 0x87: $ NOP CYC(2) break; - case 0x88: DEY CYC(2) break; - case 0x89: IMM BITI CYC(2) break; - case 0x8A: TXA CYC(2) break; - case 0x8B: $ NOP CYC(2) break; - case 0x8C: ABS STY CYC(4) break; - case 0x8D: ABS STA CYC(4) break; - case 0x8E: ABS STX CYC(4) break; - case 0x8F: $ NOP CYC(2) break; - case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_CONST STA CYC(6) break; - case 0x92: izp STA CYC(5) break; - case 0x93: $ NOP CYC(2) break; - case 0x94: zpx STY CYC(4) break; - case 0x95: zpx STA CYC(4) break; - case 0x96: zpy STX CYC(4) break; - case 0x97: $ NOP CYC(2) break; - case 0x98: TYA CYC(2) break; - case 0x99: ABSY_CONST STA CYC(5) break; - case 0x9A: TXS CYC(2) break; - case 0x9B: $ NOP CYC(2) break; - case 0x9C: ABS STZ CYC(4) break; - case 0x9D: ABSX_CONST STA CYC(5) break; - case 0x9E: ABSX_CONST STZ CYC(5) break; - case 0x9F: $ NOP CYC(2) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: idx LDA CYC(6) break; - case 0xA2: IMM LDX CYC(2) break; - case 0xA3: $ NOP CYC(2) break; - case 0xA4: ZPG LDY CYC(3) break; - case 0xA5: ZPG LDA CYC(3) break; - case 0xA6: ZPG LDX CYC(3) break; - case 0xA7: $ NOP CYC(2) break; - case 0xA8: TAY CYC(2) break; - case 0xA9: IMM LDA CYC(2) break; - case 0xAA: TAX CYC(2) break; - case 0xAB: $ NOP CYC(2) break; - case 0xAC: ABS LDY CYC(4) break; - case 0xAD: ABS LDA CYC(4) break; - case 0xAE: ABS LDX CYC(4) break; - case 0xAF: $ NOP CYC(2) break; - case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_OPT LDA CYC(5) break; - case 0xB2: izp LDA CYC(5) break; - case 0xB3: $ NOP CYC(2) break; - case 0xB4: zpx LDY CYC(4) break; - case 0xB5: zpx LDA CYC(4) break; - case 0xB6: zpy LDX CYC(4) break; - case 0xB7: $ NOP CYC(2) break; - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_OPT LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: $ NOP CYC(2) break; - case 0xBC: ABSX_OPT LDY CYC(4) break; - case 0xBD: ABSX_OPT LDA CYC(4) break; - case 0xBE: ABSY_OPT LDX CYC(4) break; - case 0xBF: $ NOP CYC(2) break; - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: idx CMP CYC(6) break; - case 0xC2: $ IMM NOP CYC(2) break; - case 0xC3: $ NOP CYC(2) break; - case 0xC4: ZPG CPY CYC(3) break; - case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DEC CYC(5) break; - case 0xC7: $ NOP CYC(2) break; - case 0xC8: INY CYC(2) break; - case 0xC9: IMM CMP CYC(2) break; - case 0xCA: DEX CYC(2) break; - case 0xCB: $ NOP CYC(2) break; - case 0xCC: ABS CPY CYC(4) break; - case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(6) break; - case 0xCF: $ NOP CYC(2) break; - case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_OPT CMP CYC(5) break; - case 0xD2: izp CMP CYC(5) break; - case 0xD3: $ NOP CYC(2) break; - case 0xD4: $ zpx NOP CYC(4) break; - case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DEC CYC(6) break; - case 0xD7: $ NOP CYC(2) break; - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_OPT CMP CYC(4) break; - case 0xDA: PHX CYC(3) break; - case 0xDB: $ NOP CYC(2) break; - case 0xDC: $ ABSX_OPT NOP CYC(4) break; - case 0xDD: ABSX_OPT CMP CYC(4) break; - case 0xDE: ABSX_CONST DEC CYC(7) break; - case 0xDF: $ NOP CYC(2) break; - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: idx SBCc CYC(6) break; - case 0xE2: $ IMM NOP CYC(2) break; - case 0xE3: $ NOP CYC(2) break; - case 0xE4: ZPG CPX CYC(3) break; - case 0xE5: ZPG SBCc CYC(3) break; - case 0xE6: ZPG INC CYC(5) break; - case 0xE7: $ NOP CYC(2) break; - case 0xE8: INX CYC(2) break; - case 0xE9: IMM SBCc CYC(2) break; - case 0xEA: NOP CYC(2) break; - case 0xEB: $ NOP CYC(2) break; - case 0xEC: ABS CPX CYC(4) break; - case 0xED: ABS SBCc CYC(4) break; - case 0xEE: ABS INC CYC(6) break; - case 0xEF: $ NOP CYC(2) break; - case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_OPT SBCc CYC(5) break; - case 0xF2: izp SBCc CYC(5) break; - case 0xF3: $ NOP CYC(2) break; - case 0xF4: $ zpx NOP CYC(4) break; - case 0xF5: zpx SBCc CYC(4) break; - case 0xF6: zpx INC CYC(6) break; - case 0xF7: $ NOP CYC(2) break; - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_OPT SBCc CYC(4) break; - case 0xFA: PLX CYC(4) break; - case 0xFB: $ NOP CYC(2) break; - case 0xFC: $ ABSX_OPT NOP CYC(4) break; - case 0xFD: ABSX_OPT SBCc CYC(4) break; - case 0xFE: ABSX_CONST INC CYC(7) break; - case 0xFF: $ NOP CYC(2) break; + case 0x00: BRK CYC(7) break; + case 0x01: idx ORA CYC(6) break; + case 0x02: $ IMM NOP CYC(2) break; + case 0x03: $ NOP CYC(2) break; + case 0x04: ZPG TSB CYC(5) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASLc CYC(5) break; + case 0x07: $ NOP CYC(2) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: asl CYC(2) break; + case 0x0B: $ NOP CYC(2) break; + case 0x0C: ABS TSB CYC(6) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASLc CYC(6) break; + case 0x0F: $ NOP CYC(2) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY_OPT ORA CYC(5) break; + case 0x12: izp ORA CYC(5) break; + case 0x13: $ NOP CYC(2) break; + case 0x14: ZPG TRB CYC(5) break; + case 0x15: zpx ORA CYC(4) break; + case 0x16: zpx ASLc CYC(6) break; + case 0x17: $ NOP CYC(2) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY_OPT ORA CYC(4) break; + case 0x1A: INA CYC(2) break; + case 0x1B: $ NOP CYC(2) break; + case 0x1C: ABS TRB CYC(6) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_OPT ASLc CYC(6) break; + case 0x1F: $ NOP CYC(2) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: idx AND CYC(6) break; + case 0x22: $ IMM NOP CYC(2) break; + case 0x23: $ NOP CYC(2) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROLc CYC(5) break; + case 0x27: $ NOP CYC(2) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: rol CYC(2) break; + case 0x2B: $ NOP CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROLc CYC(6) break; + case 0x2F: $ NOP CYC(2) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY_OPT AND CYC(5) break; + case 0x32: izp AND CYC(5) break; + case 0x33: $ NOP CYC(2) break; + case 0x34: zpx BIT CYC(4) break; + case 0x35: zpx AND CYC(4) break; + case 0x36: zpx ROLc CYC(6) break; + case 0x37: $ NOP CYC(2) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY_OPT AND CYC(4) break; + case 0x3A: DEA CYC(2) break; + case 0x3B: $ NOP CYC(2) break; + case 0x3C: ABSX_OPT BIT CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_OPT ROLc CYC(6) break; + case 0x3F: $ NOP CYC(2) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: idx EOR CYC(6) break; + case 0x42: $ IMM NOP CYC(2) break; + case 0x43: $ NOP CYC(2) break; + case 0x44: $ ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSRc CYC(5) break; + case 0x47: $ NOP CYC(2) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: lsr CYC(2) break; + case 0x4B: $ NOP CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSRc CYC(6) break; + case 0x4F: $ NOP CYC(2) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY_OPT EOR CYC(5) break; + case 0x52: izp EOR CYC(5) break; + case 0x53: $ NOP CYC(2) break; + case 0x54: $ zpx NOP CYC(4) break; + case 0x55: zpx EOR CYC(4) break; + case 0x56: zpx LSRc CYC(6) break; + case 0x57: $ NOP CYC(2) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY_OPT EOR CYC(4) break; + case 0x5A: PHY CYC(3) break; + case 0x5B: $ NOP CYC(2) break; + case 0x5C: $ ABSX_OPT NOP CYC(8) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_OPT LSRc CYC(6) break; + case 0x5F: $ NOP CYC(2) break; + case 0x60: RTS CYC(6) break; + case 0x61: idx ADCc CYC(6) break; + case 0x62: $ IMM NOP CYC(2) break; + case 0x63: $ NOP CYC(2) break; + case 0x64: ZPG STZ CYC(3) break; + case 0x65: ZPG ADCc CYC(3) break; + case 0x66: ZPG RORc CYC(5) break; + case 0x67: $ NOP CYC(2) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADCc CYC(2) break; + case 0x6A: ror CYC(2) break; + case 0x6B: $ NOP CYC(2) break; + case 0x6C: IABS_CMOS JMP CYC(6) break; + case 0x6D: ABS ADCc CYC(4) break; + case 0x6E: ABS RORc CYC(6) break; + case 0x6F: $ NOP CYC(2) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY_OPT ADCc CYC(5) break; + case 0x72: izp ADCc CYC(5) break; + case 0x73: $ NOP CYC(2) break; + case 0x74: zpx STZ CYC(4) break; + case 0x75: zpx ADCc CYC(4) break; + case 0x76: zpx RORc CYC(6) break; + case 0x77: $ NOP CYC(2) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY_OPT ADCc CYC(4) break; + case 0x7A: PLY CYC(4) break; + case 0x7B: $ NOP CYC(2) break; + case 0x7C: IABSX JMP CYC(6) break; // + case 0x7D: ABSX_OPT ADCc CYC(4) break; + case 0x7E: ABSX_OPT RORc CYC(6) break; + case 0x7F: $ NOP CYC(2) break; + case 0x80: REL BRA CYC(2) break; + case 0x81: idx STA CYC(6) break; + case 0x82: $ IMM NOP CYC(2) break; + case 0x83: $ NOP CYC(2) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: $ NOP CYC(2) break; + case 0x88: DEY CYC(2) break; + case 0x89: IMM BITI CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: $ NOP CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: $ NOP CYC(2) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY_CONST STA CYC(6) break; + case 0x92: izp STA CYC(5) break; + case 0x93: $ NOP CYC(2) break; + case 0x94: zpx STY CYC(4) break; + case 0x95: zpx STA CYC(4) break; + case 0x96: zpy STX CYC(4) break; + case 0x97: $ NOP CYC(2) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY_CONST STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: $ NOP CYC(2) break; + case 0x9C: ABS STZ CYC(4) break; + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: ABSX_CONST STZ CYC(5) break; + case 0x9F: $ NOP CYC(2) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: idx LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: $ NOP CYC(2) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: $ NOP CYC(2) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: $ NOP CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: $ NOP CYC(2) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY_OPT LDA CYC(5) break; + case 0xB2: izp LDA CYC(5) break; + case 0xB3: $ NOP CYC(2) break; + case 0xB4: zpx LDY CYC(4) break; + case 0xB5: zpx LDA CYC(4) break; + case 0xB6: zpy LDX CYC(4) break; + case 0xB7: $ NOP CYC(2) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: $ NOP CYC(2) break; + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; + case 0xBF: $ NOP CYC(2) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: idx CMP CYC(6) break; + case 0xC2: $ IMM NOP CYC(2) break; + case 0xC3: $ NOP CYC(2) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC CYC(5) break; + case 0xC7: $ NOP CYC(2) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: $ NOP CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC CYC(6) break; + case 0xCF: $ NOP CYC(2) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY_OPT CMP CYC(5) break; + case 0xD2: izp CMP CYC(5) break; + case 0xD3: $ NOP CYC(2) break; + case 0xD4: $ zpx NOP CYC(4) break; + case 0xD5: zpx CMP CYC(4) break; + case 0xD6: zpx DEC CYC(6) break; + case 0xD7: $ NOP CYC(2) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; + case 0xDA: PHX CYC(3) break; + case 0xDB: $ NOP CYC(2) break; + case 0xDC: $ ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_CONST DEC CYC(7) break; + case 0xDF: $ NOP CYC(2) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: idx SBCc CYC(6) break; + case 0xE2: $ IMM NOP CYC(2) break; + case 0xE3: $ NOP CYC(2) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBCc CYC(3) break; + case 0xE6: ZPG INC CYC(5) break; + case 0xE7: $ NOP CYC(2) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBCc CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: $ NOP CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBCc CYC(4) break; + case 0xEE: ABS INC CYC(6) break; + case 0xEF: $ NOP CYC(2) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY_OPT SBCc CYC(5) break; + case 0xF2: izp SBCc CYC(5) break; + case 0xF3: $ NOP CYC(2) break; + case 0xF4: $ zpx NOP CYC(4) break; + case 0xF5: zpx SBCc CYC(4) break; + case 0xF6: zpx INC CYC(6) break; + case 0xF7: $ NOP CYC(2) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY_OPT SBCc CYC(4) break; + case 0xFA: PLX CYC(4) break; + case 0xFB: $ NOP CYC(2) break; + case 0xFC: $ ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBCc CYC(4) break; + case 0xFE: ABSX_CONST INC CYC(7) break; + case 0xFF: $ NOP CYC(2) break; } #undef $ } diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 1db12bcc..21e0ee82 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -496,7 +496,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) case 0x69: IMM ADCc CYC(2) break; case 0x6A: ror CYC(2) break; case 0x6B: $ NOP CYC(2) break; - case 0x6C: IABSCMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP + case 0x6C: IABS_CMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP case 0x6D: ABS ADCc CYC(4) break; case 0x6E: ABS RORc CYC(6) break; case 0x6F: $ NOP CYC(2) break; diff --git a/source/CPU/cpu_general.inl b/source/CPU/cpu_general.inl index af408c08..4d565efb 100644 --- a/source/CPU/cpu_general.inl +++ b/source/CPU/cpu_general.inl @@ -115,11 +115,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ABSY_CONST base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; // TODO Optimization Note (just for IABSCMOS): uExtraCycles = ((base & 0xFF) + 1) >> 8; -#define IABSCMOS base = *(LPWORD)(mem+regs.pc); \ +#define IABS_CMOS base = *(LPWORD)(mem+regs.pc); \ addr = *(LPWORD)(mem+base); \ if ((base & 0xFF) == 0xFF) uExtraCycles=1; \ regs.pc += 2; -#define IABSNMOS base = *(LPWORD)(mem+regs.pc); \ +#define IABS_NMOS base = *(LPWORD)(mem+regs.pc); \ if ((base & 0xFF) == 0xFF) \ addr = *(mem+base)+((WORD)*(mem+(base&0xFF00))<<8);\ else \ From a52942f1cd567e327c6c0b4cd5cbd08191c2f6cf Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 9 May 2015 21:22:01 +0100 Subject: [PATCH 09/11] Make AppleWin project dependent on TestCPU6502 & and run the test as a pre-build event before AppleWin gets built. --- ApplewinExpress9.00.sln | 3 ++- ApplewinExpress9.00.vcproj | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ApplewinExpress9.00.sln b/ApplewinExpress9.00.sln index 0b5bd62c..93c42b2b 100644 --- a/ApplewinExpress9.00.sln +++ b/ApplewinExpress9.00.sln @@ -1,9 +1,10 @@  Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 +# Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Applewin", "ApplewinExpress9.00.vcproj", "{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}" ProjectSection(ProjectDependencies) = postProject {7935B998-C713-42AE-8F6D-9FF9080A1B1B} = {7935B998-C713-42AE-8F6D-9FF9080A1B1B} + {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2} = {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2} {709278B8-C583-4BD8-90DE-4E4F35A3BD8B} = {709278B8-C583-4BD8-90DE-4E4F35A3BD8B} EndProjectSection EndProject diff --git a/ApplewinExpress9.00.vcproj b/ApplewinExpress9.00.vcproj index 8c235c50..2142ec9e 100644 --- a/ApplewinExpress9.00.vcproj +++ b/ApplewinExpress9.00.vcproj @@ -26,6 +26,8 @@ > Date: Sat, 9 May 2015 15:45:12 -0700 Subject: [PATCH 10/11] Remove extraneous // on 0x7C --- source/CPU/cpu65C02.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index 60d7139a..0a547dca 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -182,7 +182,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) case 0x79: ABSY_OPT ADCc CYC(4) break; case 0x7A: PLY CYC(4) break; case 0x7B: $ NOP CYC(2) break; - case 0x7C: IABSX JMP CYC(6) break; // + case 0x7C: IABSX JMP CYC(6) break; case 0x7D: ABSX_OPT ADCc CYC(4) break; case 0x7E: ABSX_OPT RORc CYC(6) break; case 0x7F: $ NOP CYC(2) break; From ac8aecfb1b5328d1543601ba9946363498ac6afb Mon Sep 17 00:00:00 2001 From: Michaelangel007 Date: Sat, 9 May 2015 15:45:55 -0700 Subject: [PATCH 11/11] Sync up debug 6502 to 65C02 --- source/CPU/cpu65d02.h | 777 ++++++++++++++---------------------------- 1 file changed, 258 insertions(+), 519 deletions(-) diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 21e0ee82..6945677c 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -125,525 +125,264 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) { // TODO Optimization Note: ?? Move CYC(#) to array ?? -// Version 1 opcode: INV AM Instruction // Form1: INV=DebugBreak AM=AddressingMode -// INV Instruction // Form2: -//! ! ! ! ! ! // Tab-Stops -/* - case 0x00: BRK CYC(7) break; - case 0x01: idx ORA CYC(6) break; - case 0x02: INV IMM NOP CYC(2) break; - case 0x03: INV NOP CYC(2) break; - case 0x04: ZPG TSB CYC(5) break; - case 0x05: ZPG ORA CYC(3) break; - case 0x06: ZPG ASL_CMOS CYC(5) break; - case 0x07: INV NOP CYC(2) break; - case 0x08: PHP CYC(3) break; - case 0x09: IMM ORA CYC(2) break; - case 0x0A: asl CYC(2) break; - case 0x0B: INV NOP CYC(2) break; - case 0x0C: ABS TSB CYC(6) break; - case 0x0D: ABS ORA CYC(4) break; - case 0x0E: ABS ASL_CMOS CYC(6) break; - case 0x0F: INV NOP CYC(2) break; - case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_OPT ORA CYC(5) break; - case 0x12: izp ORA CYC(5) break; - case 0x13: INV NOP CYC(2) break; - case 0x14: ZPG TRB CYC(5) break; - case 0x15: zpx ORA CYC(4) break; - case 0x16: zpx ASL_CMOS CYC(6) break; - case 0x17: INV NOP CYC(2) break; - case 0x18: CLC CYC(2) break; - case 0x19: ABSY_OPT ORA CYC(4) break; - case 0x1A: INA CYC(2) break; - case 0x1B: INV NOP CYC(2) break; - case 0x1C: ABS TRB CYC(6) break; - case 0x1D: ABSX_OPT ORA CYC(4) break; - case 0x1E: ABSX_OPT ASL_CMOS CYC(6) break; - case 0x1F: INV NOP CYC(2) break; - case 0x20: ABS JSR CYC(6) break; - case 0x21: idx AND CYC(6) break; - case 0x22: INV IMM NOP CYC(2) break; - case 0x23: INV NOP CYC(2) break; - case 0x24: ZPG BIT CYC(3) break; - case 0x25: ZPG AND CYC(3) break; - case 0x26: ZPG ROL_CMOS CYC(5) break; - case 0x27: INV NOP CYC(2) break; - case 0x28: PLP CYC(4) break; - case 0x29: IMM AND CYC(2) break; - case 0x2A: rol CYC(2) break; - case 0x2B: INV NOP CYC(2) break; - case 0x2C: ABS BIT CYC(4) break; - case 0x2D: ABS AND CYC(2) break; - case 0x2E: ABS ROL_CMOS CYC(6) break; - case 0x2F: INV NOP CYC(2) break; - case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_OPT AND CYC(5) break; - case 0x32: izp AND CYC(5) break; - case 0x33: INV NOP CYC(2) break; - case 0x34: zpx BIT CYC(4) break; - case 0x35: zpx AND CYC(4) break; - case 0x36: zpx ROL_CMOS CYC(6) break; - case 0x37: INV NOP CYC(2) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY_OPT AND CYC(4) break; - case 0x3A: DEA CYC(2) break; - case 0x3B: INV NOP CYC(2) break; - case 0x3C: ABSX_OPT BIT CYC(4) break; - case 0x3D: ABSX_OPT AND CYC(4) break; - case 0x3E: ABSX_OPT ROL_CMOS CYC(6) break; - case 0x3F: INV NOP CYC(2) break; - case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; - case 0x41: idx EOR CYC(6) break; - case 0x42: INV IMM NOP CYC(2) break; - case 0x43: INV NOP CYC(2) break; - case 0x44: INV ZPG NOP CYC(3) break; - case 0x45: ZPG EOR CYC(3) break; - case 0x46: ZPG LSR_CMOS CYC(5) break; - case 0x47: INV NOP CYC(2) break; - case 0x48: PHA CYC(3) break; - case 0x49: IMM EOR CYC(2) break; - case 0x4A: lsr CYC(2) break; - case 0x4B: INV NOP CYC(2) break; - case 0x4C: ABS JMP CYC(3) break; - case 0x4D: ABS EOR CYC(4) break; - case 0x4E: ABS LSR_CMOS CYC(6) break; - case 0x4F: INV NOP CYC(2) break; - case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_OPT EOR CYC(5) break; - case 0x52: izp EOR CYC(5) break; - case 0x53: INV NOP CYC(2) break; - case 0x54: INV zpx NOP CYC(4) break; - case 0x55: zpx EOR CYC(4) break; - case 0x56: zpx LSR_CMOS CYC(6) break; - case 0x57: INV NOP CYC(2) break; - case 0x58: CLI CYC(2) break; - case 0x59: ABSY_OPT EOR CYC(4) break; - case 0x5A: PHY CYC(3) break; - case 0x5B: INV NOP CYC(2) break; - case 0x5C: INV ABSX_OPT NOP CYC(8) break; - case 0x5D: ABSX_OPT EOR CYC(4) break; - case 0x5E: ABSX_OPT LSR_CMOS CYC(6) break; - case 0x5F: INV NOP CYC(2) break; - case 0x60: RTS CYC(6) break; - case 0x61: idx ADC_CMOS CYC(6) break; - case 0x62: INV IMM NOP CYC(2) break; - case 0x63: INV NOP CYC(2) break; - case 0x64: ZPG STZ CYC(3) break; - case 0x65: ZPG ADC_CMOS CYC(3) break; - case 0x66: ZPG ROR_CMOS CYC(5) break; - case 0x67: INV NOP CYC(2) break; - case 0x68: PLA CYC(4) break; - case 0x69: IMM ADC_CMOS CYC(2) break; - case 0x6A: ror CYC(2) break; - case 0x6B: INV NOP CYC(2) break; - case 0x6C: IABSCMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP - case 0x6D: ABS ADC_CMOS CYC(4) break; - case 0x6E: ABS ROR_CMOS CYC(6) break; - case 0x6F: INV NOP CYC(2) break; - case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_OPT ADC_CMOS CYC(5) break; - case 0x72: izp ADC_CMOS CYC(5) break; - case 0x73: INV NOP CYC(2) break; - case 0x74: zpx STZ CYC(4) break; - case 0x75: zpx ADC_CMOS CYC(4) break; - case 0x76: zpx ROR_CMOS CYC(6) break; - case 0x77: INV NOP CYC(2) break; - case 0x78: SEI CYC(2) break; - case 0x79: ABSY_OPT ADC_CMOS CYC(4) break; - case 0x7A: PLY CYC(4) break; - case 0x7B: INV NOP CYC(2) break; - case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP - case 0x7D: ABSX_OPT ADC_CMOS CYC(4) break; - case 0x7E: ABSX_OPT ROR_CMOS CYC(6) break; - case 0x7F: INV NOP CYC(2) break; - case 0x80: REL BRA CYC(2) break; - case 0x81: idx STA CYC(6) break; - case 0x82: INV IMM NOP CYC(2) break; - case 0x83: INV NOP CYC(2) break; - case 0x84: ZPG STY CYC(3) break; - case 0x85: ZPG STA CYC(3) break; - case 0x86: ZPG STX CYC(3) break; - case 0x87: INV NOP CYC(2) break; - case 0x88: DEY CYC(2) break; - case 0x89: IMM BITI CYC(2) break; - case 0x8A: TXA CYC(2) break; - case 0x8B: INV NOP CYC(2) break; - case 0x8C: ABS STY CYC(4) break; - case 0x8D: ABS STA CYC(4) break; - case 0x8E: ABS STX CYC(4) break; - case 0x8F: INV NOP CYC(2) break; - case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_CONST STA CYC(6) break; - case 0x92: izp STA CYC(5) break; - case 0x93: INV NOP CYC(2) break; - case 0x94: zpx STY CYC(4) break; - case 0x95: zpx STA CYC(4) break; - case 0x96: zpy STX CYC(4) break; - case 0x97: INV NOP CYC(2) break; - case 0x98: TYA CYC(2) break; - case 0x99: ABSY_CONST STA CYC(5) break; - case 0x9A: TXS CYC(2) break; - case 0x9B: INV NOP CYC(2) break; - case 0x9C: ABS STZ CYC(4) break; - case 0x9D: ABSX_CONST STA CYC(5) break; - case 0x9E: ABSX_CONST STZ CYC(5) break; - case 0x9F: INV NOP CYC(2) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: idx LDA CYC(6) break; - case 0xA2: IMM LDX CYC(2) break; - case 0xA3: INV NOP CYC(2) break; - case 0xA4: ZPG LDY CYC(3) break; - case 0xA5: ZPG LDA CYC(3) break; - case 0xA6: ZPG LDX CYC(3) break; - case 0xA7: INV NOP CYC(2) break; - case 0xA8: TAY CYC(2) break; - case 0xA9: IMM LDA CYC(2) break; - case 0xAA: TAX CYC(2) break; - case 0xAB: INV NOP CYC(2) break; - case 0xAC: ABS LDY CYC(4) break; - case 0xAD: ABS LDA CYC(4) break; - case 0xAE: ABS LDX CYC(4) break; - case 0xAF: INV NOP CYC(2) break; - case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_OPT LDA CYC(5) break; - case 0xB2: izp LDA CYC(5) break; - case 0xB3: INV NOP CYC(2) break; - case 0xB4: zpx LDY CYC(4) break; - case 0xB5: zpx LDA CYC(4) break; - case 0xB6: zpy LDX CYC(4) break; - case 0xB7: INV NOP CYC(2) break; - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_OPT LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: INV NOP CYC(2) break; - case 0xBC: ABSX_OPT LDY CYC(4) break; - case 0xBD: ABSX_OPT LDA CYC(4) break; - case 0xBE: ABSY_OPT LDX CYC(4) break; - case 0xBF: INV NOP CYC(2) break; - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: idx CMP CYC(6) break; - case 0xC2: INV IMM NOP CYC(2) break; - case 0xC3: INV NOP CYC(2) break; - case 0xC4: ZPG CPY CYC(3) break; - case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DEC_CMOS CYC(5) break; - case 0xC7: INV NOP CYC(2) break; - case 0xC8: INY CYC(2) break; - case 0xC9: IMM CMP CYC(2) break; - case 0xCA: DEX CYC(2) break; - case 0xCB: INV NOP CYC(2) break; - case 0xCC: ABS CPY CYC(4) break; - case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC_CMOS CYC(6) break; - case 0xCF: INV NOP CYC(2) break; - case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_OPT CMP CYC(5) break; - case 0xD2: izp CMP CYC(5) break; - case 0xD3: INV NOP CYC(2) break; - case 0xD4: INV zpx NOP CYC(4) break; - case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DEC_CMOS CYC(6) break; - case 0xD7: INV NOP CYC(2) break; - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_OPT CMP CYC(4) break; - case 0xDA: PHX CYC(3) break; - case 0xDB: INV NOP CYC(2) break; - case 0xDC: INV ABSX_OPT NOP CYC(4) break; - case 0xDD: ABSX_OPT CMP CYC(4) break; - case 0xDE: ABSX_CONST DEC_CMOS CYC(7) break; - case 0xDF: INV NOP CYC(2) break; - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: idx SBC_CMOS CYC(6) break; - case 0xE2: INV IMM NOP CYC(2) break; - case 0xE3: INV NOP CYC(2) break; - case 0xE4: ZPG CPX CYC(3) break; - case 0xE5: ZPG SBC_CMOS CYC(3) break; - case 0xE6: ZPG INC_CMOS CYC(5) break; - case 0xE7: INV NOP CYC(2) break; - case 0xE8: INX CYC(2) break; - case 0xE9: IMM SBC_CMOS CYC(2) break; - case 0xEA: NOP CYC(2) break; - case 0xEB: INV NOP CYC(2) break; - case 0xEC: ABS CPX CYC(4) break; - case 0xED: ABS SBC_CMOS CYC(4) break; - case 0xEE: ABS INC_CMOS CYC(6) break; - case 0xEF: INV NOP CYC(2) break; - case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_OPT SBC_CMOS CYC(5) break; - case 0xF2: izp SBC_CMOS CYC(5) break; - case 0xF3: INV NOP CYC(2) break; - case 0xF4: INV zpx NOP CYC(4) break; - case 0xF5: zpx SBC_CMOS CYC(4) break; - case 0xF6: zpx INC_CMOS CYC(6) break; - case 0xF7: INV NOP CYC(2) break; - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_OPT SBC_CMOS CYC(4) break; - case 0xFA: PLX CYC(4) break; - case 0xFB: INV NOP CYC(2) break; - case 0xFC: INV ABSX_OPT NOP CYC(4) break; - case 0xFD: ABSX_OPT SBC_CMOS CYC(4) break; - case 0xFE: ABSX_CONST INC_CMOS CYC(7) break; - case 0xFF: INV NOP CYC(2) break; -*/ -// Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode -//! ! ! ! ! ! // Tab-Stops - case 0x00: BRK CYC(7) break; - case 0x01: idx ORA CYC(6) break; - case 0x02: $ IMM NOP CYC(2) break; - case 0x03: $ NOP CYC(2) break; - case 0x04: ZPG TSB CYC(5) break; - case 0x05: ZPG ORA CYC(3) break; - case 0x06: ZPG ASLc CYC(5) break; - case 0x07: $ NOP CYC(2) break; - case 0x08: PHP CYC(3) break; - case 0x09: IMM ORA CYC(2) break; - case 0x0A: asl CYC(2) break; - case 0x0B: $ NOP CYC(2) break; - case 0x0C: ABS TSB CYC(6) break; - case 0x0D: ABS ORA CYC(4) break; - case 0x0E: ABS ASLc CYC(6) break; - case 0x0F: $ NOP CYC(2) break; - case 0x10: REL BPL CYC(2) break; - case 0x11: INDY_OPT ORA CYC(5) break; - case 0x12: izp ORA CYC(5) break; - case 0x13: $ NOP CYC(2) break; - case 0x14: ZPG TRB CYC(5) break; - case 0x15: zpx ORA CYC(4) break; - case 0x16: zpx ASLc CYC(6) break; - case 0x17: $ NOP CYC(2) break; - case 0x18: CLC CYC(2) break; - case 0x19: ABSY_OPT ORA CYC(4) break; - case 0x1A: INA CYC(2) break; - case 0x1B: $ NOP CYC(2) break; - case 0x1C: ABS TRB CYC(6) break; - case 0x1D: ABSX_OPT ORA CYC(4) break; - case 0x1E: ABSX_OPT ASLc CYC(6) break; - case 0x1F: $ NOP CYC(2) break; - case 0x20: ABS JSR CYC(6) break; - case 0x21: idx AND CYC(6) break; - case 0x22: $ IMM NOP CYC(2) break; - case 0x23: $ NOP CYC(2) break; - case 0x24: ZPG BIT CYC(3) break; - case 0x25: ZPG AND CYC(3) break; - case 0x26: ZPG ROLc CYC(5) break; - case 0x27: $ NOP CYC(2) break; - case 0x28: PLP CYC(4) break; - case 0x29: IMM AND CYC(2) break; - case 0x2A: rol CYC(2) break; - case 0x2B: $ NOP CYC(2) break; - case 0x2C: ABS BIT CYC(4) break; - case 0x2D: ABS AND CYC(2) break; - case 0x2E: ABS ROLc CYC(6) break; - case 0x2F: $ NOP CYC(2) break; - case 0x30: REL BMI CYC(2) break; - case 0x31: INDY_OPT AND CYC(5) break; - case 0x32: izp AND CYC(5) break; - case 0x33: $ NOP CYC(2) break; - case 0x34: zpx BIT CYC(4) break; - case 0x35: zpx AND CYC(4) break; - case 0x36: zpx ROLc CYC(6) break; - case 0x37: $ NOP CYC(2) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY_OPT AND CYC(4) break; - case 0x3A: DEA CYC(2) break; - case 0x3B: $ NOP CYC(2) break; - case 0x3C: ABSX_OPT BIT CYC(4) break; - case 0x3D: ABSX_OPT AND CYC(4) break; - case 0x3E: ABSX_OPT ROLc CYC(6) break; - case 0x3F: $ NOP CYC(2) break; - case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; - case 0x41: idx EOR CYC(6) break; - case 0x42: $ IMM NOP CYC(2) break; - case 0x43: $ NOP CYC(2) break; - case 0x44: $ ZPG NOP CYC(3) break; - case 0x45: ZPG EOR CYC(3) break; - case 0x46: ZPG LSRc CYC(5) break; - case 0x47: $ NOP CYC(2) break; - case 0x48: PHA CYC(3) break; - case 0x49: IMM EOR CYC(2) break; - case 0x4A: lsr CYC(2) break; - case 0x4B: $ NOP CYC(2) break; - case 0x4C: ABS JMP CYC(3) break; - case 0x4D: ABS EOR CYC(4) break; - case 0x4E: ABS LSRc CYC(6) break; - case 0x4F: $ NOP CYC(2) break; - case 0x50: REL BVC CYC(2) break; - case 0x51: INDY_OPT EOR CYC(5) break; - case 0x52: izp EOR CYC(5) break; - case 0x53: $ NOP CYC(2) break; - case 0x54: $ zpx NOP CYC(4) break; - case 0x55: zpx EOR CYC(4) break; - case 0x56: zpx LSRc CYC(6) break; - case 0x57: $ NOP CYC(2) break; - case 0x58: CLI CYC(2) break; - case 0x59: ABSY_OPT EOR CYC(4) break; - case 0x5A: PHY CYC(3) break; - case 0x5B: $ NOP CYC(2) break; - case 0x5C: $ ABSX_OPT NOP CYC(8) break; - case 0x5D: ABSX_OPT EOR CYC(4) break; - case 0x5E: ABSX_OPT LSRc CYC(6) break; - case 0x5F: $ NOP CYC(2) break; - case 0x60: RTS CYC(6) break; - case 0x61: idx ADCc CYC(6) break; - case 0x62: $ IMM NOP CYC(2) break; - case 0x63: $ NOP CYC(2) break; - case 0x64: ZPG STZ CYC(3) break; - case 0x65: ZPG ADCc CYC(3) break; - case 0x66: ZPG RORc CYC(5) break; - case 0x67: $ NOP CYC(2) break; - case 0x68: PLA CYC(4) break; - case 0x69: IMM ADCc CYC(2) break; - case 0x6A: ror CYC(2) break; - case 0x6B: $ NOP CYC(2) break; - case 0x6C: IABS_CMOS JMP CYC(6) break; // 0x6C // 65c02 IABSCMOS JMP // 6502 IABSNMOS JMP - case 0x6D: ABS ADCc CYC(4) break; - case 0x6E: ABS RORc CYC(6) break; - case 0x6F: $ NOP CYC(2) break; - case 0x70: REL BVS CYC(2) break; - case 0x71: INDY_OPT ADCc CYC(5) break; - case 0x72: izp ADCc CYC(5) break; - case 0x73: $ NOP CYC(2) break; - case 0x74: zpx STZ CYC(4) break; - case 0x75: zpx ADCc CYC(4) break; - case 0x76: zpx RORc CYC(6) break; - case 0x77: $ NOP CYC(2) break; - case 0x78: SEI CYC(2) break; - case 0x79: ABSY_OPT ADCc CYC(4) break; - case 0x7A: PLY CYC(4) break; - case 0x7B: $ NOP CYC(2) break; - case 0x7C: IABSX JMP CYC(6) break; // 0x7C // 65c02 IABSX JMP // 6502 ABSX NOP - case 0x7D: ABSX_OPT ADCc CYC(4) break; - case 0x7E: ABSX_OPT RORc CYC(6) break; - case 0x7F: $ NOP CYC(2) break; - case 0x80: REL BRA CYC(2) break; - case 0x81: idx STA CYC(6) break; - case 0x82: $ IMM NOP CYC(2) break; - case 0x83: $ NOP CYC(2) break; - case 0x84: ZPG STY CYC(3) break; - case 0x85: ZPG STA CYC(3) break; - case 0x86: ZPG STX CYC(3) break; - case 0x87: $ NOP CYC(2) break; - case 0x88: DEY CYC(2) break; - case 0x89: IMM BITI CYC(2) break; - case 0x8A: TXA CYC(2) break; - case 0x8B: $ NOP CYC(2) break; - case 0x8C: ABS STY CYC(4) break; - case 0x8D: ABS STA CYC(4) break; - case 0x8E: ABS STX CYC(4) break; - case 0x8F: $ NOP CYC(2) break; - case 0x90: REL BCC CYC(2) break; - case 0x91: INDY_CONST STA CYC(6) break; - case 0x92: izp STA CYC(5) break; - case 0x93: $ NOP CYC(2) break; - case 0x94: zpx STY CYC(4) break; - case 0x95: zpx STA CYC(4) break; - case 0x96: zpy STX CYC(4) break; - case 0x97: $ NOP CYC(2) break; - case 0x98: TYA CYC(2) break; - case 0x99: ABSY_CONST STA CYC(5) break; - case 0x9A: TXS CYC(2) break; - case 0x9B: $ NOP CYC(2) break; - case 0x9C: ABS STZ CYC(4) break; - case 0x9D: ABSX_CONST STA CYC(5) break; - case 0x9E: ABSX_CONST STZ CYC(5) break; - case 0x9F: $ NOP CYC(2) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: idx LDA CYC(6) break; - case 0xA2: IMM LDX CYC(2) break; - case 0xA3: $ NOP CYC(2) break; - case 0xA4: ZPG LDY CYC(3) break; - case 0xA5: ZPG LDA CYC(3) break; - case 0xA6: ZPG LDX CYC(3) break; - case 0xA7: $ NOP CYC(2) break; - case 0xA8: TAY CYC(2) break; - case 0xA9: IMM LDA CYC(2) break; - case 0xAA: TAX CYC(2) break; - case 0xAB: $ NOP CYC(2) break; - case 0xAC: ABS LDY CYC(4) break; - case 0xAD: ABS LDA CYC(4) break; - case 0xAE: ABS LDX CYC(4) break; - case 0xAF: $ NOP CYC(2) break; - case 0xB0: REL BCS CYC(2) break; - case 0xB1: INDY_OPT LDA CYC(5) break; - case 0xB2: izp LDA CYC(5) break; - case 0xB3: $ NOP CYC(2) break; - case 0xB4: zpx LDY CYC(4) break; - case 0xB5: zpx LDA CYC(4) break; - case 0xB6: zpy LDX CYC(4) break; - case 0xB7: $ NOP CYC(2) break; - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY_OPT LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: $ NOP CYC(2) break; - case 0xBC: ABSX_OPT LDY CYC(4) break; - case 0xBD: ABSX_OPT LDA CYC(4) break; - case 0xBE: ABSY_OPT LDX CYC(4) break; - case 0xBF: $ NOP CYC(2) break; - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: idx CMP CYC(6) break; - case 0xC2: $ IMM NOP CYC(2) break; - case 0xC3: $ NOP CYC(2) break; - case 0xC4: ZPG CPY CYC(3) break; - case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DEC CYC(5) break; - case 0xC7: $ NOP CYC(2) break; - case 0xC8: INY CYC(2) break; - case 0xC9: IMM CMP CYC(2) break; - case 0xCA: DEX CYC(2) break; - case 0xCB: $ NOP CYC(2) break; - case 0xCC: ABS CPY CYC(4) break; - case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(6) break; - case 0xCF: $ NOP CYC(2) break; - case 0xD0: REL BNE CYC(2) break; - case 0xD1: INDY_OPT CMP CYC(5) break; - case 0xD2: izp CMP CYC(5) break; - case 0xD3: $ NOP CYC(2) break; - case 0xD4: $ zpx NOP CYC(4) break; - case 0xD5: zpx CMP CYC(4) break; - case 0xD6: zpx DEC CYC(6) break; - case 0xD7: $ NOP CYC(2) break; - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY_OPT CMP CYC(4) break; - case 0xDA: PHX CYC(3) break; - case 0xDB: $ NOP CYC(2) break; - case 0xDC: $ ABSX_OPT NOP CYC(4) break; - case 0xDD: ABSX_OPT CMP CYC(4) break; - case 0xDE: ABSX_CONST DEC CYC(7) break; - case 0xDF: $ NOP CYC(2) break; - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: idx SBCc CYC(6) break; - case 0xE2: $ IMM NOP CYC(2) break; - case 0xE3: $ NOP CYC(2) break; - case 0xE4: ZPG CPX CYC(3) break; - case 0xE5: ZPG SBCc CYC(3) break; - case 0xE6: ZPG INC CYC(5) break; - case 0xE7: $ NOP CYC(2) break; - case 0xE8: INX CYC(2) break; - case 0xE9: IMM SBCc CYC(2) break; - case 0xEA: NOP CYC(2) break; - case 0xEB: $ NOP CYC(2) break; - case 0xEC: ABS CPX CYC(4) break; - case 0xED: ABS SBCc CYC(4) break; - case 0xEE: ABS INC CYC(6) break; - case 0xEF: $ NOP CYC(2) break; - case 0xF0: REL BEQ CYC(2) break; - case 0xF1: INDY_OPT SBCc CYC(5) break; - case 0xF2: izp SBCc CYC(5) break; - case 0xF3: $ NOP CYC(2) break; - case 0xF4: $ zpx NOP CYC(4) break; - case 0xF5: zpx SBCc CYC(4) break; - case 0xF6: zpx INC CYC(6) break; - case 0xF7: $ NOP CYC(2) break; - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY_OPT SBCc CYC(4) break; - case 0xFA: PLX CYC(4) break; - case 0xFB: $ NOP CYC(2) break; - case 0xFC: $ ABSX_OPT NOP CYC(4) break; - case 0xFD: ABSX_OPT SBCc CYC(4) break; - case 0xFE: ABSX_CONST INC CYC(7) break; - case 0xFF: $ NOP CYC(2) break; +// Version 2 opcode: $ AM Instruction // $=DebugBreak AM=AddressingMode +//! ! ! ! ! ! // Tab-Stops + case 0x00: BRK CYC(7) break; + case 0x01: idx ORA CYC(6) break; + case 0x02: $ IMM NOP CYC(2) break; + case 0x03: $ NOP CYC(2) break; + case 0x04: ZPG TSB CYC(5) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASLc CYC(5) break; + case 0x07: $ NOP CYC(2) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: asl CYC(2) break; + case 0x0B: $ NOP CYC(2) break; + case 0x0C: ABS TSB CYC(6) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASLc CYC(6) break; + case 0x0F: $ NOP CYC(2) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY_OPT ORA CYC(5) break; + case 0x12: izp ORA CYC(5) break; + case 0x13: $ NOP CYC(2) break; + case 0x14: ZPG TRB CYC(5) break; + case 0x15: zpx ORA CYC(4) break; + case 0x16: zpx ASLc CYC(6) break; + case 0x17: $ NOP CYC(2) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY_OPT ORA CYC(4) break; + case 0x1A: INA CYC(2) break; + case 0x1B: $ NOP CYC(2) break; + case 0x1C: ABS TRB CYC(6) break; + case 0x1D: ABSX_OPT ORA CYC(4) break; + case 0x1E: ABSX_OPT ASLc CYC(6) break; + case 0x1F: $ NOP CYC(2) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: idx AND CYC(6) break; + case 0x22: $ IMM NOP CYC(2) break; + case 0x23: $ NOP CYC(2) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROLc CYC(5) break; + case 0x27: $ NOP CYC(2) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: rol CYC(2) break; + case 0x2B: $ NOP CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROLc CYC(6) break; + case 0x2F: $ NOP CYC(2) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY_OPT AND CYC(5) break; + case 0x32: izp AND CYC(5) break; + case 0x33: $ NOP CYC(2) break; + case 0x34: zpx BIT CYC(4) break; + case 0x35: zpx AND CYC(4) break; + case 0x36: zpx ROLc CYC(6) break; + case 0x37: $ NOP CYC(2) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY_OPT AND CYC(4) break; + case 0x3A: DEA CYC(2) break; + case 0x3B: $ NOP CYC(2) break; + case 0x3C: ABSX_OPT BIT CYC(4) break; + case 0x3D: ABSX_OPT AND CYC(4) break; + case 0x3E: ABSX_OPT ROLc CYC(6) break; + case 0x3F: $ NOP CYC(2) break; + case 0x40: RTI CYC(6) DoIrqProfiling(uExecutedCycles); break; + case 0x41: idx EOR CYC(6) break; + case 0x42: $ IMM NOP CYC(2) break; + case 0x43: $ NOP CYC(2) break; + case 0x44: $ ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSRc CYC(5) break; + case 0x47: $ NOP CYC(2) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: lsr CYC(2) break; + case 0x4B: $ NOP CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSRc CYC(6) break; + case 0x4F: $ NOP CYC(2) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY_OPT EOR CYC(5) break; + case 0x52: izp EOR CYC(5) break; + case 0x53: $ NOP CYC(2) break; + case 0x54: $ zpx NOP CYC(4) break; + case 0x55: zpx EOR CYC(4) break; + case 0x56: zpx LSRc CYC(6) break; + case 0x57: $ NOP CYC(2) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY_OPT EOR CYC(4) break; + case 0x5A: PHY CYC(3) break; + case 0x5B: $ NOP CYC(2) break; + case 0x5C: $ ABSX_OPT NOP CYC(8) break; + case 0x5D: ABSX_OPT EOR CYC(4) break; + case 0x5E: ABSX_OPT LSRc CYC(6) break; + case 0x5F: $ NOP CYC(2) break; + case 0x60: RTS CYC(6) break; + case 0x61: idx ADCc CYC(6) break; + case 0x62: $ IMM NOP CYC(2) break; + case 0x63: $ NOP CYC(2) break; + case 0x64: ZPG STZ CYC(3) break; + case 0x65: ZPG ADCc CYC(3) break; + case 0x66: ZPG RORc CYC(5) break; + case 0x67: $ NOP CYC(2) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADCc CYC(2) break; + case 0x6A: ror CYC(2) break; + case 0x6B: $ NOP CYC(2) break; + case 0x6C: IABS_CMOS JMP CYC(6) break; + case 0x6D: ABS ADCc CYC(4) break; + case 0x6E: ABS RORc CYC(6) break; + case 0x6F: $ NOP CYC(2) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY_OPT ADCc CYC(5) break; + case 0x72: izp ADCc CYC(5) break; + case 0x73: $ NOP CYC(2) break; + case 0x74: zpx STZ CYC(4) break; + case 0x75: zpx ADCc CYC(4) break; + case 0x76: zpx RORc CYC(6) break; + case 0x77: $ NOP CYC(2) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY_OPT ADCc CYC(4) break; + case 0x7A: PLY CYC(4) break; + case 0x7B: $ NOP CYC(2) break; + case 0x7C: IABSX JMP CYC(6) break; + case 0x7D: ABSX_OPT ADCc CYC(4) break; + case 0x7E: ABSX_OPT RORc CYC(6) break; + case 0x7F: $ NOP CYC(2) break; + case 0x80: REL BRA CYC(2) break; + case 0x81: idx STA CYC(6) break; + case 0x82: $ IMM NOP CYC(2) break; + case 0x83: $ NOP CYC(2) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: $ NOP CYC(2) break; + case 0x88: DEY CYC(2) break; + case 0x89: IMM BITI CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: $ NOP CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: $ NOP CYC(2) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY_CONST STA CYC(6) break; + case 0x92: izp STA CYC(5) break; + case 0x93: $ NOP CYC(2) break; + case 0x94: zpx STY CYC(4) break; + case 0x95: zpx STA CYC(4) break; + case 0x96: zpy STX CYC(4) break; + case 0x97: $ NOP CYC(2) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY_CONST STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: $ NOP CYC(2) break; + case 0x9C: ABS STZ CYC(4) break; + case 0x9D: ABSX_CONST STA CYC(5) break; + case 0x9E: ABSX_CONST STZ CYC(5) break; + case 0x9F: $ NOP CYC(2) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: idx LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: $ NOP CYC(2) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: $ NOP CYC(2) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: $ NOP CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: $ NOP CYC(2) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY_OPT LDA CYC(5) break; + case 0xB2: izp LDA CYC(5) break; + case 0xB3: $ NOP CYC(2) break; + case 0xB4: zpx LDY CYC(4) break; + case 0xB5: zpx LDA CYC(4) break; + case 0xB6: zpy LDX CYC(4) break; + case 0xB7: $ NOP CYC(2) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY_OPT LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: $ NOP CYC(2) break; + case 0xBC: ABSX_OPT LDY CYC(4) break; + case 0xBD: ABSX_OPT LDA CYC(4) break; + case 0xBE: ABSY_OPT LDX CYC(4) break; + case 0xBF: $ NOP CYC(2) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: idx CMP CYC(6) break; + case 0xC2: $ IMM NOP CYC(2) break; + case 0xC3: $ NOP CYC(2) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC CYC(5) break; + case 0xC7: $ NOP CYC(2) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: $ NOP CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC CYC(6) break; + case 0xCF: $ NOP CYC(2) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY_OPT CMP CYC(5) break; + case 0xD2: izp CMP CYC(5) break; + case 0xD3: $ NOP CYC(2) break; + case 0xD4: $ zpx NOP CYC(4) break; + case 0xD5: zpx CMP CYC(4) break; + case 0xD6: zpx DEC CYC(6) break; + case 0xD7: $ NOP CYC(2) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY_OPT CMP CYC(4) break; + case 0xDA: PHX CYC(3) break; + case 0xDB: $ NOP CYC(2) break; + case 0xDC: $ ABSX_OPT NOP CYC(4) break; + case 0xDD: ABSX_OPT CMP CYC(4) break; + case 0xDE: ABSX_CONST DEC CYC(7) break; + case 0xDF: $ NOP CYC(2) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: idx SBCc CYC(6) break; + case 0xE2: $ IMM NOP CYC(2) break; + case 0xE3: $ NOP CYC(2) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBCc CYC(3) break; + case 0xE6: ZPG INC CYC(5) break; + case 0xE7: $ NOP CYC(2) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBCc CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: $ NOP CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBCc CYC(4) break; + case 0xEE: ABS INC CYC(6) break; + case 0xEF: $ NOP CYC(2) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY_OPT SBCc CYC(5) break; + case 0xF2: izp SBCc CYC(5) break; + case 0xF3: $ NOP CYC(2) break; + case 0xF4: $ zpx NOP CYC(4) break; + case 0xF5: zpx SBCc CYC(4) break; + case 0xF6: zpx INC CYC(6) break; + case 0xF7: $ NOP CYC(2) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY_OPT SBCc CYC(4) break; + case 0xFA: PLX CYC(4) break; + case 0xFB: $ NOP CYC(2) break; + case 0xFC: $ ABSX_OPT NOP CYC(4) break; + case 0xFD: ABSX_OPT SBCc CYC(4) break; + case 0xFE: ABSX_CONST INC CYC(7) break; + case 0xFF: $ NOP CYC(2) break; } #undef $