From 9c7b8f50c661a3262c7e7d503d86bb4dca33420e Mon Sep 17 00:00:00 2001 From: tomcw Date: Mon, 4 May 2015 11:57:24 +0100 Subject: [PATCH] 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; }