From 2597dd90454f6bd3063a9853f54b30807031cac5 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 2 May 2015 21:44:03 +0100 Subject: [PATCH] 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)