From: Shamus Hammons Date: Sun, 27 Sep 2009 01:02:33 +0000 (+0000) Subject: Major refactoring of V6809 code--still not 100% at this point X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=stargem2;a=commitdiff_plain;h=05e3af22c4bd3c40744505a52bbdb24a13fab694 Major refactoring of V6809 code--still not 100% at this point --- diff --git a/src/stargem2.cpp b/src/stargem2.cpp index d1b7431..4f3e509 100755 --- a/src/stargem2.cpp +++ b/src/stargem2.cpp @@ -350,7 +350,7 @@ uint8 RdMem6809(uint16 addr) // More kludge... if ((addr == 0xC80C) && (gram[0xC80D] & 0x04)) // Read PORTA and DDR is set to Output { - ClearLine(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ + ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ //OK, this ALSO fucks up the execution of the demo... // Which means that the timing is still off. :-/ // mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Then clear the IRQ @@ -358,7 +358,7 @@ uint8 RdMem6809(uint16 addr) if ((addr == 0xC80E) && (gram[0xC80F] & 0x04)) // Read PORTB and DDR is set to Output { - ClearLine(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ + ClearLineOfCurrentV6809(V6809_ASSERT_LINE_IRQ); // Then clear the IRQ //OK, this ALSO fucks up the execution of the demo... // mainCPU.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Then clear the IRQ } @@ -471,6 +471,11 @@ static void FrameCallback(void) soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI; if (keys[SDLK_F6]) // Reset the 6808 (F6) soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; +//Temp, for testing... +extern bool disasm; +//disasm = true; + if (keys[SDLK_F9]) + disasm = true; if (paletteDirty) { diff --git a/src/v6809.cpp b/src/v6809.cpp index a8b24fa..a9855c6 100755 --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -17,30 +17,37 @@ // We have a start... ;-) // -//#define __DEBUG__ +#define __DEBUG__ #include "v6809.h" #ifdef __DEBUG__ #include "dis6809.h" // Temporary... #include "log.h" // Temporary... +bool disasm = false;//so we can extern this shit #endif +#define TEST_DONT_BRANCH_OPTIMIZATION + // Various macros -#define CLR_Z (regs.cc &= ~FLAG_Z) -#define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N)) -#define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C)) -#define CLR_V (regs.cc &= ~FLAG_V) -#define CLR_N (regs.cc &= ~FLAG_N) -#define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z)) -#define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N)) +#define CLR_Z (flagZ = 0) +#define CLR_ZN (flagZ = flagN = 0) +#define CLR_ZNC (flagZ = flagN = flagC = 0) +#define CLR_V (flagV = 0) +#define CLR_N (flagN = 0) +#define SET_Z(r) (flagZ = ((r) == 0 ? 1 : 0)) +#define SET_N(r) (flagN = ((r) & 0x80) >> 7) +#define SET_N16(r) (flagN = ((r) & 0x8000) >> 15) +#define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7) +#define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15) //Not sure that this code is computing the carry correctly... Investigate! [Seems to be] -#define SET_C_ADD(a,b) (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_C_ADD(a,b) (flagC = ((uint8)(b) > (uint8)(~(a)) ? 1 : 0)) //#define SET_C_SUB(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) -#define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_C_CMP(a,b) (flagC = ((uint8)(b) >= (uint8)(a) ? 1 : 0)) #define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZN16(r) SET_N16(r); SET_Z(r) #define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) //#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b) #define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b) @@ -48,191 +55,140 @@ //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! //Hmm, why not do like we did for READ_ABS*??? //Because the EA_* macros are usually used as an argument to a function call, that's why. +//Now, we CAN fix it using FetchMemW()!!! [DONE] #define EA_IMM regs.pc++ -#define EA_ZP regs.RdMem(regs.pc++) -#define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) & 0xFF -#define EA_ZP_Y (regs.RdMem(regs.pc++) + regs.y) & 0xFF -#define EA_ABS RdMemW(regs.pc) -#define EA_ABS_X RdMemW(regs.pc) + regs.x -#define EA_ABS_Y RdMemW(regs.pc) + regs.y -#define EA_IND_ZP_X RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF) -#define EA_IND_ZP_Y RdMemW(regs.RdMem(regs.pc++)) + regs.y -#define EA_IND_ZP RdMemW(regs.RdMem(regs.pc++)) +#define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++) +#define EA_IDX DecodeIDX(regs.RdMem(regs.pc++)) +#define EA_ABS FetchMemW(regs.pc) #define READ_IMM regs.RdMem(EA_IMM) -#define READ_ZP regs.RdMem(EA_ZP) -#define READ_ZP_X regs.RdMem(EA_ZP_X) -#define READ_ZP_Y regs.RdMem(EA_ZP_Y) -#define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2 -#define READ_ABS_X regs.RdMem(EA_ABS_X); regs.pc += 2 -#define READ_ABS_Y regs.RdMem(EA_ABS_Y); regs.pc += 2 -#define READ_IND_ZP_X regs.RdMem(EA_IND_ZP_X) -#define READ_IND_ZP_Y regs.RdMem(EA_IND_ZP_Y) -#define READ_IND_ZP regs.RdMem(EA_IND_ZP) +#define READ_IMM16 FetchMemW(regs.pc) +#define READ_DP regs.RdMem(EA_DP) +#define READ_DP16 RdMemW(EA_DP) +#define READ_IDX regs.RdMem(EA_IDX) +#define READ_IDX16 RdMemW(EA_IDX) +#define READ_ABS regs.RdMem(EA_ABS) +#define READ_ABS16 RdMemW(EA_ABS) #define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr) -#define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr) -#define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr) -#define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2 -#define READ_ABS_X_WB(v) uint16 addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2 -#define READ_ABS_Y_WB(v) uint16 addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2 -#define READ_IND_ZP_X_WB(v) uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr) -#define READ_IND_ZP_Y_WB(v) uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr) -#define READ_IND_ZP_WB(v) uint16 addr = EA_IND_ZP; v = regs.RdMem(addr) +#define READ_DP_WB(v) uint16 addr = EA_DP; v = regs.RdMem(addr) +#define READ_IDX_WB(v) uint16 addr = EA_IDX; v = regs.RdMem(addr) +#define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr) #define WRITE_BACK(d) regs.WrMem(addr, (d)) +#define PULLS(r) r = regs.RdMem(regs.s++) +#define PUSHS(r) regs.WrMem(--regs.s, (r)) +#define PULLS16(r) { r = RdMemW(regs.s); regs.s += 2; } +#define PUSHS16(r) { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); } +#define PULLU(r) r = regs.RdMem(regs.u++) +#define PUSHU(r) regs.WrMem(--regs.u, (r)) +#define PULLU16(r) { r = RdMemW(regs.u); regs.u += 2; } +#define PUSHU16(r) { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); } + +#define PACK_FLAGS ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC) +#define UNPACK_FLAGS flagE = (regs.cc & FLAG_E) >> 7; \ + flagF = (regs.cc & FLAG_F) >> 6; \ + flagH = (regs.cc & FLAG_H) >> 5; \ + flagI = (regs.cc & FLAG_I) >> 4; \ + flagN = (regs.cc & FLAG_N) >> 3; \ + flagZ = (regs.cc & FLAG_Z) >> 2; \ + flagV = (regs.cc & FLAG_V) >> 1; \ + flagC = (regs.cc & FLAG_C) + // Private global variables static V6809REGS regs; -//Let's see if we can nuke this shit. -static uint16 addr; // Temporary variables common to all funcs... -static uint8 tmp; +static uint8 flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC; + +uint8 page0Cycles[256] = { + 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x + 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x + 4, 4, 4, 4, 5, 5, 5, 5, 1, 5, 3, 6, 21, 11, 0, 19, // $3x + 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, // $4x + 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, // $5x + 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $6x + 7, 1, 1, 7, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 3, 7, // $7x + 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, // $8x + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $9x + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $Ax + 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, // $Bx + 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, // $Cx + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Dx + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Ex + 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx +}; + +uint8 page1Cycles[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x + 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, // $8x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $9x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $Ax + 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 7, 7, // $Bx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, // $Cx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Dx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Ex + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx +}; + +uint8 page2Cycles[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x + 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, // $8x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $9x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $Ax + 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, // $Bx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Cx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Dx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Ex + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx +}; // Private function prototypes -static uint16 FetchW(void); static uint16 RdMemW(uint16 addr); +static uint16 FetchMemW(uint16 addr); static void WrMemW(uint16 addr, uint16 w); static uint16 ReadEXG(uint8); // Read TFR/EXG post byte static void WriteEXG(uint8, uint16); // Set TFR/EXG data static uint16 DecodeReg(uint8); // Decode register data static uint16 DecodeIDX(uint8); // Decode IDX data -//static void (* exec_op1[256])(); -//static void (* exec_op2[256])(); -#if 1 - -// This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler -// isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't -// even *try* to see if they're there). - -#define FD(x) static void Op##x(); // FD -> "Forward Declaration" -#define FE(x) static void Op10##x(); -#define FF(x) static void Op11##x(); - -FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11) -FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23) -FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31) -FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40) -FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56) -FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69) -FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C) -FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B) -FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A) -FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8) -FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6) -FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4) -FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5) -FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3) -FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1) -FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF) -FD(__) FD(01) - -FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E) -FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3) -FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF) - -FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC) - -#undef FD -#undef FE -#undef FF - -#endif - -// We can move these down and do away with the forward declarations... !!! FIX !!! -// Actually, we can't because these are used in a couple of the opcode functions. -// Have to think about how to fix that... - -// -// Function arrays -// - -// Array of page zero opcode functions... -static void (* exec_op0[256])() = { - Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, - Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, - Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, - Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, - Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, - Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, - Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, - Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, - Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, - Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, - OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, - OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, - OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, - OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, - OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, - OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF -}; - -// Array of page one opcode functions... -static void (* exec_op1[256])() = { - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, - Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, - Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, - Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF -}; - -// Array of page two opcode functions... -static void (* exec_op2[256])() = { - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, - Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, - Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, - Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ -}; - - // -// Fetch a word out of 6809 memory (little endian format) -// This is a leftover from when fetches were separated from garden variety reads... +// Read word from memory function // -static uint16 FetchW() +static inline uint16 RdMemW(uint16 addr) { - uint16 w = RdMemW(regs.pc); - regs.pc += 2; - return w; + return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } // -// Read word from memory function +// Fetch a word from memory function. Increments PC // -uint16 RdMemW(uint16 addr) +static inline uint16 FetchMemW(uint16 addr) { + regs.pc += 2; return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } // // Write word to memory function // -void WrMemW(uint16 addr, uint16 w) +static inline void WrMemW(uint16 addr, uint16 w) { regs.WrMem(addr + 0, w >> 8); regs.WrMem(addr + 1, w & 0xFF); @@ -391,7 +347,7 @@ uint16 DecodeIDX(uint8 code) addr = RdMemW(woff); break; case 9: - woff = DecodeReg(reg) + FetchW(); + woff = DecodeReg(reg) + FetchMemW(regs.pc); addr = RdMemW(woff); break; case 11: @@ -403,11 +359,11 @@ uint16 DecodeIDX(uint8 code) addr = RdMemW(woff); break; case 13: - woff = regs.pc + FetchW(); + woff = regs.pc + FetchMemW(regs.pc); addr = RdMemW(woff); break; case 15: - woff = FetchW(); + woff = FetchMemW(regs.pc); addr = RdMemW(woff); break; } @@ -456,10 +412,10 @@ uint16 DecodeIDX(uint8 code) case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; } case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; } case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; } - case 9: { addr = DecodeReg(reg) + FetchW(); break; } + case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; } case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; } case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; } - case 13: { addr = regs.pc + FetchW(); break; } + case 13: { addr = regs.pc + FetchMemW(regs.pc); break; } } } } @@ -467,143 +423,2915 @@ uint16 DecodeIDX(uint8 code) return addr; } +#if 1 + // -// Page zero instructions... +// 6809 OPCODE IMPLEMENTATION +// +// NOTE: Lots of macros are used here to save a LOT of typing. Also +// helps speed the debugging process. :-) Because of this, combining +// certain lines may look like a good idea but would end in disaster. +// You have been warned! ;-) // -static void Op00(void) // NEG DP +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa | + | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa | + | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa | + | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa | + | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa | + | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa | + | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa | + | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa | +*/ + +// ADC opcodes + +#define OP_ADC_HANDLER(m, acc) \ + uint16 sum = (uint16)acc + (m) + (uint16)flagC; \ + flagC = (sum >> 8) & 0x01; \ + flagH = (sum >> 4) & 0x01; \ + SET_V(m, acc, sum); \ + acc = sum & 0xFF; \ + SET_ZN(acc) + +/* +Old flag handling code: + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative +*/ + +static void Op89(void) // ADCA # { - addr = (regs.dp << 8) | regs.RdMem(regs.pc++); - tmp = 256 - regs.RdMem(addr); - regs.WrMem(addr, tmp); + uint16 m = READ_IMM; + OP_ADC_HANDLER(m, regs.a); +} - (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry +static void Op99(void) // ADCA DP +{ + uint16 m = READ_DP; + OP_ADC_HANDLER(m, regs.a); +} - regs.clock += 6; +static void OpA9(void) // ADCA IDX +{ + uint16 m = READ_IDX; + OP_ADC_HANDLER(m, regs.a); } -static void Op01(void) // NEG DP (Undocumented) +static void OpB9(void) // ADCA ABS { - Op00(); + uint16 m = READ_ABS; + OP_ADC_HANDLER(m, regs.a); } -static void Op03(void) // COM DP +static void OpC9(void) // ADCB # { - addr = (regs.dp << 8) | regs.RdMem(regs.pc++); - tmp = 0xFF ^ regs.RdMem(addr); - regs.WrMem(addr, tmp); + uint16 m = READ_IMM; + OP_ADC_HANDLER(m, regs.b); +} - regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void OpD9(void) // ADCB DP +{ + uint16 m = READ_DP; + OP_ADC_HANDLER(m, regs.b); +} - regs.clock += 6; +static void OpE9(void) // ADCB IDX +{ + uint16 m = READ_IDX; + OP_ADC_HANDLER(m, regs.b); } -static void Op04(void) // LSR DP +static void OpF9(void) // ADCB ABS { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - tmp = regs.RdMem(addr); - (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry - tmp >>= 1; regs.WrMem(addr, tmp); - regs.cc &= 0xF7; // CLN - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 6; + uint16 m = READ_ABS; + OP_ADC_HANDLER(m, regs.b); } -static void Op06(void) // ROR DP + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- | + | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa | + | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa | + | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa | + | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa | + | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa | + | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa | + | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa | + | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa | + | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa | + | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa | + | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa | + | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa | +*/ + +// ADD opcodes + +#define OP_ADD_HANDLER(m, acc) \ + uint16 sum = (uint16)(acc) + (m); \ + flagC = (sum >> 8) & 0x01; \ + flagH = (sum >> 4) & 0x01; \ + SET_V(m, acc, sum); \ + (acc) = sum & 0xFF; \ + SET_ZN(acc) + +#define OP_ADD_HANDLER16(m, hireg, loreg) \ + uint32 acc = (uint32)((hireg << 8) | loreg); \ + uint32 sum = acc + (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + acc = sum & 0xFFFF; \ + hireg = (acc >> 8) & 0xFF; \ + loreg = acc & 0xFF; \ + SET_ZN16(acc) + +/* +Old flags: + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + + dr += addr; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 4; +*/ + +static void Op3A(void) // ABX { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr); - tmp = (tmp2>>1) + (regs.cc&0x01)*128; - regs.WrMem(addr, tmp); - (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + regs.x += (uint16)regs.b; } -static void Op07(void) // ASR DP + +static void Op8B(void) // ADDA # { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr); - (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry - tmp >>= 1; - if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set - regs.WrMem(addr, tmp); - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16 m = READ_IMM; + OP_ADD_HANDLER(m, regs.a); } -static void Op08(void) // LSL DP + +static void Op9B(void) // ADDA DP { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT - tmp = regs.RdMem(addr); - (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - tmp <<= 1; - regs.WrMem(addr, tmp); - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16 m = READ_DP; + OP_ADD_HANDLER(m, regs.a); } -static void Op09(void) // ROL DP + +static void OpAB(void) // ADDA IDX { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr); - tmp = (tmp2<<1) + (regs.cc&0x01); - regs.WrMem(addr, tmp); - (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16 m = READ_IDX; + OP_ADD_HANDLER(m, regs.a); } -static void Op0A(void) // DEC DP + +static void OpBB(void) // ADDA ABS { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - tmp = regs.RdMem(addr) - 1; - regs.WrMem(addr, tmp); - (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16 m = READ_ABS; + OP_ADD_HANDLER(m, regs.a); } -static void Op0C(void) // INC DP + +static void OpC3(void) // ADDD # { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - tmp = regs.RdMem(addr) + 1; - regs.WrMem(addr, tmp); - (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint32 m = READ_IMM16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op0D(void) // TST DP + +static void OpCB(void) // ADDB # { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16 m = READ_IMM; + OP_ADD_HANDLER(m, regs.b); } -static void Op0E(void) // JMP DP + +static void OpD3(void) // ADDD DP { - regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++); - regs.clock += 3; + uint32 m = READ_DP16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op0F(void) // CLR DP + +static void OpDB(void) // ADDB DP { - regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC - regs.clock += 6; + uint16 m = READ_DP; + OP_ADD_HANDLER(m, regs.b); +} + +static void OpE3(void) // ADDD IDX +{ + uint32 m = READ_IDX16; + OP_ADD_HANDLER16(m, regs.a, regs.b); +} + +static void OpEB(void) // ADDB IDX +{ + uint16 m = READ_IDX; + OP_ADD_HANDLER(m, regs.b); +} + +static void OpF3(void) // ADDD ABS +{ + uint32 m = READ_ABS16; + OP_ADD_HANDLER16(m, regs.a, regs.b); +} + +static void OpFB(void) // ADDB ABS +{ + uint16 m = READ_ABS; + OP_ADD_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- | + | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- | + | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- | + | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- | + | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- | + | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- | + | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- | + | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// AND opcodes + +#define OP_AND_HANDLER(m, acc) \ + acc &= m; \ + SET_ZN(acc); \ + CLR_V + +static void Op84(void) // ANDA # +{ + uint16 m = READ_IMM; + OP_AND_HANDLER(m, regs.a); } -static void Op10(void) // Page 1 opcode +static void Op94(void) // ANDA DP { - exec_op1[regs.RdMem(regs.pc++)](); + uint16 m = READ_DP; + OP_AND_HANDLER(m, regs.a); } -static void Op11(void) // Page 2 opcode +static void OpA4(void) // ANDA IDX +{ + uint16 m = READ_IDX; + OP_AND_HANDLER(m, regs.a); +} + +static void OpB4(void) // ANDA ABS +{ + uint16 m = READ_ABS; + OP_AND_HANDLER(m, regs.a); +} + +static void OpC4(void) // ANDB # +{ + uint16 m = READ_IMM; + OP_AND_HANDLER(m, regs.b); +} + +static void OpD4(void) // ANDB DP +{ + uint16 m = READ_DP; + OP_AND_HANDLER(m, regs.b); +} + +static void OpE4(void) // ANDB IDX +{ + uint16 m = READ_IDX; + OP_AND_HANDLER(m, regs.b); +} + +static void OpF4(void) // ANDB ABS +{ + uint16 m = READ_ABS; + OP_AND_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas | + | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas | + | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas | + | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas | + | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas | +*/ + +// ASL opcodes + +#define OP_ASL_HANDLER(m) \ + uint16 res = m << 1; \ + SET_V(m, m, res); \ + flagC = (res >> 8) & 0x01; \ + m = res & 0xFF; \ + SET_ZN(m) + +static void Op08(void) // ASL DP +{ + uint8 m; + READ_DP_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); +} + +static void Op48(void) // ASLA +{ + OP_ASL_HANDLER(regs.a); +} + +static void Op58(void) // ASLB +{ + OP_ASL_HANDLER(regs.b); +} + +static void Op68(void) // ASL IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); +} + +static void Op78(void) // ASL ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s | + | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s | + | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s | + | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s | + | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s | +*/ + +// ASR opcodes (arithmetic, so preserves the sign) + +#define OP_ASR_HANDLER(m) \ + uint8 res = (m & 0x80) | (m >> 1); \ + SET_ZN(res); \ + flagC = m & 0x01; \ + m = res + +static void Op07(void) // ASR DP +{ + uint8 m; + READ_DP_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op47(void) // ASRA +{ + OP_ASR_HANDLER(regs.a); +} + +static void Op57(void) // ASRB +{ + OP_ASR_HANDLER(regs.b); +} + +static void Op67(void) // ASR IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op77(void) // ASR ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- | + | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- | + | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- | + | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- | + | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- | + | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- | + | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- | + | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- | + | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- | + | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- | + | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- | + | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- | + | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- | + | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- | + | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- | + | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- | + | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- | + | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- | + | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- | + | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- | + | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- | + | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- | + | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- | + | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- | + | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- | + | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- | + | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- | + | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- | + | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- | + | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- | + | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- | + | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- | +*/ + +// Branch opcodes + +static void Op16(void) // LBRA +{ + uint16 offset = READ_IMM16; + regs.pc += offset; +} + +static void Op20(void) // BRA +{ + int16 offset = (int16)(int8)READ_IMM; + regs.pc += offset; +} + +static void Op21(void) // BRN +{ + // This is basically a 2 byte NOP + int16 offset = (int16)(int8)READ_IMM; +} + +static void Op22(void) // BHI +{ + // !C && !Z + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION +//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)... + regs.pc += offset * ((flagZ | flagC) ^ 0x01); +#else + if (!(flagZ || flagC)) + regs.pc += offset; +#endif +} + +static void Op23(void) // BLS +{ + // C || Z + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | flagC); +#else + if (flagZ || flagC) + regs.pc += offset; +#endif +} + +static void Op24(void) // BHS/CC +{ + // !C + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagC ^ 0x01); +#else + if (!flagC) + regs.pc += offset; +#endif +} + +static void Op25(void) // BLO/CS +{ + // C + int16 offset = (int16)(int8)READ_IMM; +//if (disasm) +// WriteLog("[offset=%04X,flagC=%08X]", offset, flagC); + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagC; +#else + if (flagC) + regs.pc += offset; +#endif +} + +static void Op26(void) // BNE +{ + // !Z + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ ^ 0x01); +#else + if (!flagZ) + regs.pc += offset; +#endif +} + +static void Op27(void) // BEQ +{ + // Z + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagZ; +#else + if (flagZ) + regs.pc += offset; +#endif +} + +static void Op28(void) // BVC +{ + // !V + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagV ^ 0x01); +#else + if (!flagV) + regs.pc += offset; +#endif +} + +static void Op29(void) // BVS +{ + // V + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagV; +#else + if (flagV) + regs.pc += offset; +#endif +} + +static void Op2A(void) // BPL +{ + // !N + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagN ^ 0x01); +#else + if (!flagN) + regs.pc += offset; +#endif +} + +static void Op2B(void) // BMI +{ + // N + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagN; +#else + if (flagN) + regs.pc += offset; +#endif +} + +static void Op2C(void) // BGE +{ + // (N && V) || (!N && !V) + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01))); +#else + if ((flagN && flagV) || (!flagN && !flagV)) + regs.pc += offset; +#endif +} + +static void Op2D(void) // BLT +{ + // (N && !V) || (!N && V) + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if ((flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif +} + +static void Op2E(void) // BGT +{ + // (N && V && !Z) || (!N && !V && !Z) + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01))); +#else + if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ)) + regs.pc += offset; +#endif +} + +static void Op2F(void) // BLE +{ + // Z || (N && !V) || (!N && V) + int16 offset = (int16)(int8)READ_IMM; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if (flagZ || (flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif +} + +static void Op1021(void) // LBRN +{ + // This is basically a 4 byte NOP + uint16 offset = READ_IMM16; +} + +static void Op1022(void) // LBHI +{ + // !C && !Z + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION +//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)... + regs.pc += offset * ((flagZ | flagC) ^ 0x01); +#else + if (!(flagZ || flagC)) + regs.pc += offset; +#endif +} + +static void Op1023(void) // LBLS +{ + // C || Z + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | flagC); +#else + if (flagZ || flagC) + regs.pc += offset; +#endif +} + +static void Op1024(void) // LBHS/CC +{ + // !C + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagC ^ 0x01); +#else + if (!flagC) + regs.pc += offset; +#endif +} + +static void Op1025(void) // LBLO/CS +{ + // C + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagC; +#else + if (flagC) + regs.pc += offset; +#endif +} + +static void Op1026(void) // LBNE +{ + // !Z + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ ^ 0x01); +#else + if (!flagZ) + regs.pc += offset; +#endif +} + +static void Op1027(void) // LBEQ +{ + // Z + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagZ; +#else + if (flagZ) + regs.pc += offset; +#endif +} + +static void Op1028(void) // LBVC +{ + // !V + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagV ^ 0x01); +#else + if (!flagV) + regs.pc += offset; +#endif +} + +static void Op1029(void) // LBVS +{ + // V + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagV; +#else + if (flagV) + regs.pc += offset; +#endif +} + +static void Op102A(void) // LBPL +{ + // !N + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagN ^ 0x01); +#else + if (!flagN) + regs.pc += offset; +#endif +} + +static void Op102B(void) // LBMI +{ + // N + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagN; +#else + if (flagN) + regs.pc += offset; +#endif +} + +static void Op102C(void) // LBGE +{ + // (N && V) || (!N && !V) + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01))); +#else + if ((flagN && flagV) || (!flagN && !flagV)) + regs.pc += offset; +#endif +} + +static void Op102D(void) // LBLT +{ + // (N && !V) || (!N && V) + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if ((flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif +} + +static void Op102E(void) // LBGT +{ + // (N && V && !Z) || (!N && !V && !Z) + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01))); +#else + if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ)) + regs.pc += offset; +#endif +} + +static void Op102F(void) // LBLE +{ + // Z || (N && !V) || (!N && V) + uint16 offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if (flagZ || (flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- | + | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- | + | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- | + | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- | + | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- | + | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- | + | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- | + | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// BIT opcodes + +#define OP_BIT_HANDLER(m, acc) \ + uint8 result = acc & (m); \ + SET_ZN(result); \ + CLR_V + +static void Op85(void) // BITA # +{ + uint8 m = READ_IMM; + OP_BIT_HANDLER(m, regs.a); +} + +static void Op95(void) // BITA DP +{ + uint8 m = READ_DP; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpA5(void) // BITA IDX +{ + uint8 m = READ_IDX; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpB5(void) // BITA ABS +{ + uint8 m = READ_ABS; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpC5(void) // BITB # +{ + uint8 m = READ_IMM; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpD5(void) // BITB DP +{ + uint8 m = READ_DP; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpE5(void) // BITB IDX +{ + uint8 m = READ_IDX; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpF5(void) // BITB ABS +{ + uint8 m = READ_ABS; + OP_BIT_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 | + | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 | + | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 | + | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 | + | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 | +*/ + +// CLR opcodes + +#define OP_CLR_HANDLER(m) \ + flagN = flagV = flagC = 0; \ + flagZ = 1; \ + m = 0 + +static void Op0F(void) // CLR DP +{ + uint8 m; + READ_DP_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op4F(void) // CLRA +{ + OP_CLR_HANDLER(regs.a); +} + +static void Op5F(void) // CLRB +{ + OP_CLR_HANDLER(regs.b); +} + +static void Op6F(void) // CLR IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7F(void) // CLR ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa | + | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa | + | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa | + | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa | + | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa | + | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa | + | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa | + | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa | + | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa | + | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa | + | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa | + | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa | + | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa | + | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa | + | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa | + | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa | + | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa | + | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa | + | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa | + | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa | + | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa | + | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa | + | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa | + | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa | + | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa | + | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa | + | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa | + | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa | +*/ + +// CMP opcodes + +#define OP_CMP_HANDLER(m, acc) \ + uint16 sum = (uint16)(acc) - (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + SET_ZN(sum) + +#define OP_CMP_HANDLER16(m, acc) \ + uint32 sum = (uint32)(acc) - (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + SET_ZN16(sum) + +static void Op81(void) // CMPA # +{ + uint8 m = READ_IMM; + OP_CMP_HANDLER(m, regs.a); +} + +static void Op8C(void) // CMPX # +{ + uint16 m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void Op91(void) // CMPA DP +{ + uint8 m = READ_DP; + OP_CMP_HANDLER(m, regs.a); +} + +static void Op9C(void) // CMPX DP +{ + uint16 m = READ_DP16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpA1(void) // CMPA IDX +{ + uint8 m = READ_IDX; + OP_CMP_HANDLER(m, regs.a); +} + +static void OpAC(void) // CMPX IDX +{ + uint16 m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpB1(void) // CMPA ABS +{ + uint8 m = READ_ABS; + OP_CMP_HANDLER(m, regs.a); +} + +static void OpBC(void) // CMPX ABS +{ + uint16 m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpC1(void) // CMPB # +{ + uint8 m = READ_IMM; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpD1(void) // CMPB DP +{ + uint8 m = READ_DP; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpE1(void) // CMPB IDX +{ + uint8 m = READ_IDX; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpF1(void) // CMPB ABS +{ + uint8 m = READ_ABS; + OP_CMP_HANDLER(m, regs.b); +} + +static void Op1083(void) // CMPD # +{ + uint16 m = READ_IMM16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op108C(void) // CMPY # +{ + uint16 m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op1093(void) // CMPD DP +{ + uint16 m = READ_DP16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op109C(void) // CMPY DP +{ + uint16 m = READ_DP16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op10A3(void) // CMPD IDX +{ + uint16 m = READ_IDX16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op10AC(void) // CMPY IDX +{ + uint16 m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op10B3(void) // CMPD ABS +{ + uint16 m = READ_ABS16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op10BC(void) // CMPY ABS +{ + uint16 m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op1183(void) // CMPU # +{ + uint16 m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op118C(void) // CMPS # +{ + uint16 m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op1193(void) // CMPU DP +{ + uint16 m = READ_DP16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op119C(void) // CMPS DP +{ + uint16 m = READ_DP16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op11A3(void) // CMPU IDX +{ + uint16 m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op11AC(void) // CMPS IDX +{ + uint16 m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op11B3(void) // CMPU ABS +{ + uint16 m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op11BC(void) // CMPS ABS +{ + uint16 m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.s); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 | + | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 | + | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 | + | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 | + | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 | +*/ + +// COM opcodes + +#define OP_COM_HANDLER(m) \ + m = ~m; \ + SET_ZN(m); \ + flagC = 1; \ + flagV = 0 + +static void Op03(void) // COM DP +{ + uint8 m; + READ_DP_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +static void Op43(void) // COMA +{ + OP_COM_HANDLER(regs.a); +} + +static void Op53(void) // COMB +{ + OP_COM_HANDLER(regs.b); +} + +static void Op63(void) // COM IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +static void Op73(void) // COM ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- | + | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd | + | 3E 0062 | RESET* | INHERENT | * | 1 | ***** | + | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- | + | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- | + | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- | +*/ + +static void Op13(void) // SYNC +{ +#warning "!!! SYNC not implemented !!!" +#if 0 + /* SYNC stops processing instructions until an interrupt request happens. */ + /* This doesn't require the corresponding interrupt to be enabled: if it */ + /* is disabled, execution continues with the next instruction. */ + m68_state->int_state |= M6809_SYNC; /* HJB 990227 */ + check_irq_lines(m68_state); + /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state), + * stop execution until the interrupt lines change. */ + if( m68_state->int_state & M6809_SYNC ) + if (m68_state->icount > 0) m68_state->icount = 0; +#endif +} + +static void Op3C(void) // CWAI +{ +#warning "!!! CWAI not implemented !!!" +#if 0 + UINT8 t; + IMMBYTE(t); + CC &= t; + /* + * CWAI stacks the entire machine state on the hardware stack, + * then waits for an interrupt; when the interrupt is taken + * later, the state is *not* saved again after CWAI. + */ + CC |= CC_E; /* HJB 990225: save entire state */ + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + m68_state->int_state |= M6809_CWAI; /* HJB 990228 */ + check_irq_lines(m68_state); /* HJB 990116 */ + if( m68_state->int_state & M6809_CWAI ) + if( m68_state->icount > 0 ) + m68_state->icount = 0; +#endif +} + +static void Op3E(void) // RESET +{ + regs.cpuFlags |= V6809_ASSERT_LINE_RESET; +} + +static void Op3F(void) // SWI +{ + flagE = 1; + regs.cc = PACK_FLAGS; // Mash flags into CC byte + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + flagF = flagI = 1; + regs.pc = RdMemW(0xFFFA); +} + +static void Op103F(void) // SWI2 +{ + flagE = 1; + regs.cc = PACK_FLAGS; // Mash flags into CC byte + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + regs.pc = RdMemW(0xFFF4); +} + +static void Op113F(void) // SWI3 +{ + flagE = 1; + regs.cc = PACK_FLAGS; // Mash flags into CC byte + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + regs.pc = RdMemW(0xFFF2); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 12 0018 | NOP | INHERENT | 2 | 1 | ----- | + | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a | + | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd | + | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd | + | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- | +*/ + +static void Op12() // NOP +{ +} + +static void Op19() // DAA +{ + uint16 result = (uint16)regs.a; + + if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) + result += 0x06; + + if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + result += 0x60; + + regs.a = (uint8)result; + SET_ZN(result); + CLR_V; + flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore +} + +static void Op1A() // ORCC +{ + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + regs.cc |= READ_IMM; + UNPACK_FLAGS; // & unmash 'em +} + +static void Op1C() // ANDCC +{ + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + regs.cc &= READ_IMM; + UNPACK_FLAGS; // & unmash 'em +} + +static void Op1D() // SEX +{ + regs.a = (regs.b & 0x80 ? 0xFF : 0x00); + SET_ZN16((regs.a << 8) | regs.b); + CLR_V; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- | + | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- | + | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- | + | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- | + | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- | +*/ + +// DEC opcodes (If we went from $80 -> $7F, sign overflowed.) + +#define OP_DEC_HANDLER(m) \ + m--; \ + SET_ZN(m); \ + flagV = (m == 0x7F ? 1 : 0) + +static void Op0A(void) // DEC DP +{ + uint8 m; + READ_DP_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op4A(void) // DECA +{ + OP_DEC_HANDLER(regs.a); +} + +static void Op5A(void) // DECB +{ + OP_DEC_HANDLER(regs.b); +} + +static void Op6A(void) // DEC IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7A(void) // DEC ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- | + | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- | + | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- | + | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- | + | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- | + | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- | + | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- | + | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// EOR opcodes + +#define OP_EOR_HANDLER(m, acc) \ + acc ^= (m); \ + SET_ZN(acc); \ + CLR_V + +static void Op88(void) // EORA # +{ + uint8 m = READ_IMM; + OP_EOR_HANDLER(m, regs.a); +} + +static void Op98(void) // EORA DP +{ + uint8 m = READ_DP; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpA8(void) // EORA IDX +{ + uint8 m = READ_IDX; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpB8(void) // EORA ABS +{ + uint8 m = READ_ABS; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpC8(void) // EORB # +{ + uint8 m = READ_IMM; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpD8(void) // EORB DP +{ + uint8 m = READ_DP; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpE8(void) // EORB IDX +{ + uint8 m = READ_IDX; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpF8(void) // EORB ABS +{ + uint8 m = READ_ABS; + OP_EOR_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- | + | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- | + | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- | + | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- | + | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- | +*/ + +// INC opcodes (If we went from $7F -> $80, sign overflowed.) + +#define OP_INC_HANDLER(m) \ + m++; \ + SET_ZN(m); \ + flagV = (m == 0x80 ? 1 : 0) + +static void Op0C(void) // INC DP +{ + uint8 m; + READ_DP_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op4C(void) // INCA +{ + OP_INC_HANDLER(regs.a); +} + +static void Op5C(void) // INCB +{ + OP_INC_HANDLER(regs.b); +} + +static void Op6C(void) // INC IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7C(void) // INC ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- | + | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- | + | 39 0057 | RTS | INHERENT | 5 | 1 | ----- | + | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- | + | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- | + | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- | + | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- | + | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- | + | AD 0173 | JSR | INDEXED | 7 | 2 | ----- | + | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- | +*/ + +static void Op0E(void) // JMP DP +{ + regs.pc = EA_DP; +} + +static void Op17(void) // LBSR +{ + uint16 word = FetchMemW(regs.pc); + PUSHS16(regs.pc); + regs.pc += word; +} + +static void Op39(void) // RTS +{ + PULLS16(regs.pc); +} + +static void Op3B(void) // RTI +{ + PULLS(regs.cc); + UNPACK_FLAGS; + + // If E flag set, pull all regs + if (flagE) + { + PULLS(regs.a); + PULLS(regs.b); + PULLS(regs.dp); + PULLS16(regs.x); + PULLS16(regs.y); + PULLS16(regs.u); + regs.clock += 9; + } + + PULLS16(regs.pc); +} + +static void Op6E(void) // JMP IDX +{ + regs.pc = EA_IDX; +} + +static void Op7E(void) // JMP ABS +{ + regs.pc = EA_ABS; +} + +static void Op8D(void) // BSR +{ + uint16 word = (int16)(int8)READ_IMM; + PUSHS16(regs.pc); + regs.pc += word; +} + +static void Op9D(void) // JSR DP +{ + uint16 word = EA_DP; + PUSHS16(regs.pc); + regs.pc = word; +} + +static void OpAD(void) // JSR IDX +{ + uint16 word = EA_IDX; + PUSHS16(regs.pc); + regs.pc = word; +} + +static void OpBD(void) // JSR ABS +{ + uint16 word = EA_ABS; + PUSHS16(regs.pc); + regs.pc = word; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc | + | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc | +*/ + +static void Op1E(void) // EXG +{ + uint8 m = READ_IMM; + uint8 reg1 = m >> 4, reg2 = m & 0x0F; + uint16 acc = ReadEXG(reg1); + WriteEXG(reg1, ReadEXG(reg2)); + WriteEXG(reg2, acc); +} + +static void Op1F(void) // TFR +{ + uint8 m = READ_IMM; + WriteEXG(m & 0x0F, ReadEXG(m >> 4)); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- | + | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- | + | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- | + | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- | + | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- | + | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- | + | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- | + | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- | + | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- | + | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- | + | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- | + | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- | + | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- | + | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- | + | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- | + | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- | + | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- | + | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- | + | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- | + | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- | + | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- | + | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- | + | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- | + | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- | + | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- | + | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- | + | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- | + | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- | +*/ + +// LDA opcodes + +#define OP_LDA_HANDLER(m, acc) \ + acc = m; \ + CLR_V; \ + SET_ZN(acc) + +#define OP_LDA_HANDLER16(m, acc) \ + acc = m; \ + CLR_V; \ + SET_ZN16(acc) + +#define OP_LDA_HANDLER16D(m) \ + regs.a = (m >> 8); \ + regs.b = m & 0xFF; \ + CLR_V; \ + SET_ZN16(m) + +static void Op86(void) // LDA # +{ + uint8 m = READ_IMM; + OP_LDA_HANDLER(m, regs.a); +} + +static void Op8E(void) // LDX # +{ + uint16 m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.x); +} + +static void Op96(void) // LDA DP +{ + uint8 m = READ_DP; + OP_LDA_HANDLER(m, regs.a); +} + +static void Op9E(void) // LDX DP +{ + uint16 m = READ_DP16; + OP_LDA_HANDLER16(m, regs.x); +} + +static void OpA6(void) // LDA IDX +{ + uint8 m = READ_IDX; + OP_LDA_HANDLER(m, regs.a); +} + +static void OpAE(void) // LDX IDX +{ + uint16 m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.x); +} + +static void OpB6(void) // LDA ABS +{ + uint8 m = READ_ABS; + OP_LDA_HANDLER(m, regs.a); +} + +static void OpBE(void) // LDX ABS +{ + uint16 m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.x); +} + +static void OpC6(void) // LDB # +{ + uint8 m = READ_IMM; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpCC(void) // LDD # +{ + uint16 m = READ_IMM16; + OP_LDA_HANDLER16D(m); +} + +static void OpCE(void) // LDU # +{ + uint16 m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpD6(void) // LDB DP +{ + uint8 m = READ_DP; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpDC(void) // LDD DP +{ + uint16 m = READ_DP16; + OP_LDA_HANDLER16D(m); +} + +static void OpDE(void) // LDU DP +{ + uint16 m = READ_DP16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpE6(void) // LDB IDX +{ + uint8 m = READ_IDX; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpEC(void) // LDD IDX +{ + uint16 m = READ_IDX16; + OP_LDA_HANDLER16D(m); +} + +static void OpEE(void) // LDU IDX +{ + uint16 m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpF6(void) // LDB ABS +{ + uint8 m = READ_ABS; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpFC(void) // LDD ABS +{ + uint16 m = READ_ABS16; + OP_LDA_HANDLER16D(m); +} + +static void OpFE(void) // LDU ABS +{ + uint16 m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void Op108E(void) // LDY # +{ + uint16 m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op109E(void) // LDY DP +{ + uint16 m = READ_DP16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10AE(void) // LDY IDX +{ + uint16 m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10BE(void) // LDY ABS +{ + uint16 m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10CE(void) // LDS # +{ + uint16 m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10DE(void) // LDS DP +{ + uint16 m = READ_DP16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10EE(void) // LDS IDX +{ + uint16 m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10FE(void) // LDS ABS +{ + uint16 m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.s); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- | + | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- | + | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- | + | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- | +*/ + +static void Op30(void) // LEAX +{ + regs.x = EA_IDX; + SET_Z(regs.x); +} + +static void Op31(void) // LEAY +{ + regs.y = EA_IDX; + SET_Z(regs.y); +} + +static void Op32(void) // LEAS +{ + regs.s = EA_IDX; +} + +static void Op33(void) // LEAU +{ + regs.u = EA_IDX; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s | + | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s | + | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s | + | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s | + | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s | +*/ + +// LSR opcodes + +#define OP_LSR_HANDLER(m) \ + flagC = m & 0x01; \ + m >>= 1; \ + SET_ZN(m) + +static void Op04(void) // LSR DP +{ + uint8 m; + READ_DP_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op44(void) // LSRA +{ + OP_LSR_HANDLER(regs.a); +} + +static void Op54(void) // LSRB +{ + OP_LSR_HANDLER(regs.b); +} + +static void Op64(void) // LSR IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op74(void) // LSR ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a | +*/ + +static void Op3D(void) // MUL +{ + uint16 prod = regs.a * regs.b; + regs.a = prod >> 8; + regs.b = prod & 0xFF; + SET_Z(prod); +// flagC = (prod & 0x0080 ? 1 : 0); + flagC = (prod >> 7) & 0x01; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa | + | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa | + | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa | + | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa | + | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa | +*/ + +// NEG opcodes + +#define OP_NEG_HANDLER(m) \ + uint8 res = -m; \ + SET_ZN(res); \ + SET_V(0, m, res); \ + flagC = (res >= 0x80 ? 1 : 0); \ + m = res + +/* + UINT16 r,t; + DIRBYTE(t); + r = -t; + CLR_NZVC; + SET_FLAGS8(0,t,r); + WM(EAD,r); +#define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);} +#define SET_C8(a) CC|=((a&0x100)>>8) +*/ +static void Op00(void) // NEG DP +{ + uint8 m; + READ_DP_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +static void Op40(void) // NEGA +{ + OP_NEG_HANDLER(regs.a); +} + +static void Op50(void) // NEGB +{ + OP_NEG_HANDLER(regs.b); +} + +static void Op60(void) // NEG IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +static void Op70(void) // NEG ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- | + | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- | + | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- | + | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- | + | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- | + | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- | + | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- | + | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// ORA opcodes + +#define OP_OR_HANDLER(m, acc) \ + acc |= (m); \ + SET_ZN(acc); \ + CLR_V + +static void Op8A(void) // ORA # +{ + uint8 m = READ_IMM; + OP_OR_HANDLER(m, regs.a); +} + +static void Op9A(void) // ORA DP +{ + uint8 m = READ_DP; + OP_OR_HANDLER(m, regs.a); +} + +static void OpAA(void) // ORA IDX +{ + uint8 m = READ_IDX; + OP_OR_HANDLER(m, regs.a); +} + +static void OpBA(void) // ORA ABS +{ + uint8 m = READ_ABS; + OP_OR_HANDLER(m, regs.a); +} + +static void OpCA(void) // ORB # +{ + uint8 m = READ_IMM; + OP_OR_HANDLER(m, regs.b); +} + +static void OpDA(void) // ORB DP +{ + uint8 m = READ_DP; + OP_OR_HANDLER(m, regs.b); +} + +static void OpEA(void) // ORB IDX +{ + uint8 m = READ_IDX; + OP_OR_HANDLER(m, regs.b); +} + +static void OpFA(void) // ORB ABS +{ + uint8 m = READ_ABS; + OP_OR_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- | + | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc | + | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- | + | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc | +*/ + +static void Op34(void) // PSHS +{ + uint8 m = READ_IMM; + + if (m & 0x80) + PUSHS16(regs.pc); + if (m & 0x40) + PUSHS16(regs.u); + if (m & 0x20) + PUSHS16(regs.y); + if (m & 0x10) + PUSHS16(regs.x); + if (m & 0x08) + PUSHS(regs.dp); + if (m & 0x04) + PUSHS(regs.b); + if (m & 0x02) + PUSHS(regs.a); + if (m & 0x01) + { + regs.cc = PACK_FLAGS; + PUSHS(regs.cc); + } +} + +static void Op35(void) // PULS +{ + uint8 m = READ_IMM; + + if (m & 0x01) + { + PULLS(regs.cc); + UNPACK_FLAGS; + } + if (m & 0x02) + PULLS(regs.a); + if (m & 0x04) + PULLS(regs.b); + if (m & 0x08) + PULLS(regs.dp); + if (m & 0x10) + PULLS16(regs.x); + if (m & 0x20) + PULLS16(regs.y); + if (m & 0x40) + PULLS16(regs.u); + if (m & 0x80) + PULLS16(regs.pc); +} + +static void Op36(void) // PHSU +{ + uint8 m = READ_IMM; + + if (m & 0x80) + PUSHU16(regs.pc); + if (m & 0x40) + PUSHU16(regs.s); + if (m & 0x20) + PUSHU16(regs.y); + if (m & 0x10) + PUSHU16(regs.x); + if (m & 0x08) + PUSHU(regs.dp); + if (m & 0x04) + PUSHU(regs.b); + if (m & 0x02) + PUSHU(regs.a); + if (m & 0x01) + { + regs.cc = PACK_FLAGS; + PUSHU(regs.cc); + } +} + +static void Op37(void) // PULU +{ + uint8 m = READ_IMM; + + if (m & 0x01) + { + PULLU(regs.cc); + UNPACK_FLAGS; + } + if (m & 0x02) + PULLU(regs.a); + if (m & 0x04) + PULLU(regs.b); + if (m & 0x08) + PULLU(regs.dp); + if (m & 0x10) + PULLU16(regs.x); + if (m & 0x20) + PULLU16(regs.y); + if (m & 0x40) + PULLU16(regs.s); + if (m & 0x80) + PULLU16(regs.pc); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas | + | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas | + | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas | + | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas | + | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas | +*/ + +// ROL opcodes + +#define OP_ROL_HANDLER(m) \ + uint8 res = (m << 1) | flagC; \ + SET_ZN(res); \ + SET_V(m, m, res); \ + flagC = (m >> 7) & 0x01; \ + m = res + +/* + UINT16 t,r; + DIRBYTE(t); + r = (CC & CC_C) | (t << 1); + CLR_NZVC; + SET_FLAGS8(t,t,r); + WM(EAD,r); +*/ +static void Op09(void) // ROL DP +{ + uint8 m; + READ_DP_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); +} + +static void Op49(void) // ROLA +{ + OP_ROL_HANDLER(regs.a); +} + +static void Op59(void) // ROLB +{ + OP_ROL_HANDLER(regs.b); +} + +static void Op69(void) // ROL IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); +} + +static void Op79(void) // ROL ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s | + | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s | + | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s | + | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s | + | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s | +*/ + +// ROR opcodes + +#define OP_ROR_HANDLER(m) \ + uint8 res = (flagC << 7) | (m >> 1); \ + SET_ZN(res); \ + SET_V(m, m, res); \ + flagC = m & 0x01; \ + m = res + +static void Op06(void) // ROR DP +{ + uint8 m; + READ_DP_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op46(void) // RORA +{ + OP_ROR_HANDLER(regs.a); +} + +static void Op56(void) // RORB +{ + OP_ROR_HANDLER(regs.b); +} + +static void Op66(void) // ROR IDX +{ + uint8 m; + READ_IDX_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op76(void) // ROR ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa | + | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa | + | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa | + | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa | + | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa | + | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa | + | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa | + | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa | +*/ + +// SBC opcodes + +#define OP_SBC_HANDLER(m, acc) \ + uint16 sum = (uint16)acc - (m) - (uint16)flagC; \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + acc = (uint8)sum; \ + SET_ZN(acc) + +static void Op82(void) // SBCA # +{ + uint8 m = READ_IMM; + OP_SBC_HANDLER(m, regs.a); +} + +static void Op92(void) // SBCA DP +{ + uint8 m = READ_DP; + OP_SBC_HANDLER(m, regs.a); +} + +static void OpA2(void) // SBCA IDX +{ + uint8 m = READ_IDX; + OP_SBC_HANDLER(m, regs.a); +} + +static void OpB2(void) // SBCA ABS +{ + uint8 m = READ_ABS; + OP_SBC_HANDLER(m, regs.a); +} + +static void OpC2(void) // SBCB # +{ + uint8 m = READ_IMM; + OP_SBC_HANDLER(m, regs.b); +} + +static void OpD2(void) // SBCB DP +{ + uint8 m = READ_DP; + OP_SBC_HANDLER(m, regs.b); +} + +static void OpE2(void) // SBCB IDX +{ + uint8 m = READ_IDX; + OP_SBC_HANDLER(m, regs.b); +} + +static void OpF2(void) // SBCB ABS +{ + uint8 m = READ_ABS; + OP_SBC_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- | + | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- | + | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- | + | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- | + | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- | + | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- | + | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- | + | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- | + | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- | + | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- | + | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- | + | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- | + | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- | + | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- | + | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- | + | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- | + | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- | + | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- | + | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- | + | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- | + | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- | +*/ + +// STA opcodes + +#define OP_STA_HANDLER(m, acc) \ + regs.WrMem(m, acc); \ + CLR_V; \ + SET_ZN(acc) + +#define OP_STA_HANDLER16(m, acc) \ + WrMemW(m, acc); \ + CLR_V; \ + SET_ZN16(acc) + +static void Op97(void) // STA DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER(addr, regs.a); +} + +static void Op9F(void) // STX DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER16(addr, regs.x); +} + +static void OpA7(void) // STA IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER(addr, regs.a); +} + +static void OpAF(void) // STX IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.x); +} + +static void OpB7(void) // STA ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER(addr, regs.a); +} + +static void OpBF(void) // STX ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.x); +} + +static void OpD7(void) // STB DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER(addr, regs.b); +} + +static void OpDD(void) // STD DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); +} + +static void OpDF(void) // STU DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER16(addr, regs.u); +} + +static void OpE7(void) // STB IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER(addr, regs.b); +} + +static void OpED(void) // STD IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); +} + +static void OpEF(void) // STU IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.u); +} + +static void OpF7(void) // STB ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER(addr, regs.b); +} + +static void OpFD(void) // STD ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); +} + +static void OpFF(void) // STU ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.u); +} + +static void Op109F(void) // STY DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER16(addr, regs.y); +} + +static void Op10AF(void) // STY IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.y); +} + +static void Op10BF(void) // STY ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.y); +} + +static void Op10DF(void) // STS DP +{ + uint16 addr = EA_DP; + OP_STA_HANDLER16(addr, regs.s); +} + +static void Op10EF(void) // STS IDX +{ + uint16 addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.s); +} + +static void Op10FF(void) // STS ABS +{ + uint16 addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.s); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa | + | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa | + | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa | + | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa | + | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa | + | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa | + | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa | + | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa | + | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa | + | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa | + | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa | + | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa | +*/ + +// SUB opcodes + +#define OP_SUB_HANDLER(m, acc) \ + uint16 sum = (uint16)acc - (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + acc = (uint8)sum; \ + SET_ZN(acc) + +#define OP_SUB_HANDLER16D(m) \ + uint32 acc = (uint32)((regs.a << 8) | regs.b); \ + uint32 sum = acc - (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + acc = sum & 0xFFFF; \ + regs.a = (acc >> 8) & 0xFF; \ + regs.b = acc & 0xFF; \ + SET_ZN16(acc) + +static void Op80(void) // SUBA # +{ + uint8 m = READ_IMM; + OP_SUB_HANDLER(m, regs.a); +} + +static void Op83(void) // SUBD # +{ + uint16 m = READ_IMM16; + OP_SUB_HANDLER16D(m); +} + +static void Op90(void) // SUBA DP +{ + uint8 m = READ_DP; + OP_SUB_HANDLER(m, regs.a); +} + +static void Op93(void) // SUBD DP +{ + uint16 m = READ_DP16; + OP_SUB_HANDLER16D(m); +} + +static void OpA0(void) // SUBA IDX +{ + uint8 m = READ_IDX; + OP_SUB_HANDLER(m, regs.a); +} + +static void OpA3(void) // SUBD IDX +{ + uint16 m = READ_IDX16; + OP_SUB_HANDLER16D(m); +} + +static void OpB0(void) // SUBA ABS +{ + uint8 m = READ_ABS; + OP_SUB_HANDLER(m, regs.a); +} + +static void OpB3(void) // SUBD ABS +{ + uint16 m = READ_ABS16; + OP_SUB_HANDLER16D(m); +} + +static void OpC0(void) // SUBB # +{ + uint8 m = READ_IMM; + OP_SUB_HANDLER(m, regs.b); +} + +static void OpD0(void) // SUBB DP +{ + uint8 m = READ_DP; + OP_SUB_HANDLER(m, regs.b); +} + +static void OpE0(void) // SUBB IDX +{ + uint8 m = READ_IDX; + OP_SUB_HANDLER(m, regs.b); +} + +static void OpF0(void) // SUBB ABS +{ + uint8 m = READ_ABS; + OP_SUB_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- | + | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- | + | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- | + | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- | + | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- | +*/ + +// TST opcodes + +#define OP_TST_HANDLER(m) \ + SET_ZN(m); \ + CLR_V + +static void Op0D(void) // TST DP +{ + uint8 m = READ_DP; + OP_TST_HANDLER(m); +} + +static void Op4D(void) // TSTA +{ + OP_TST_HANDLER(regs.a); +} + +static void Op5D(void) // TSTB +{ + OP_TST_HANDLER(regs.b); +} + +static void Op6D(void) // TST IDX +{ + uint8 m = READ_IDX; + OP_TST_HANDLER(m); +} + +static void Op7D(void) // TST ABS +{ + uint8 m = READ_ABS; + OP_TST_HANDLER(m); +} + +// Undocumented Opcodes + +static void Op01(void) +{ + Op00(); // NEG DP +} + +#else + +// +// Page zero instructions... +// + +static void Op00(void) // NEG DP +{ + addr = (regs.dp << 8) | regs.RdMem(regs.pc++); + tmp = 256 - regs.RdMem(addr); + regs.WrMem(addr, tmp); + + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + + regs.clock += 6; +} + +static void Op01(void) // NEG DP (Undocumented) +{ + Op00(); +} + +static void Op03(void) // COM DP +{ + addr = (regs.dp << 8) | regs.RdMem(regs.pc++); + tmp = 0xFF ^ regs.RdMem(addr); + regs.WrMem(addr, tmp); + + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void Op04(void) // LSR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 6; +} +static void Op06(void) // ROR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr); + tmp = (tmp2>>1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op07(void) // ASR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op08(void) // LSL DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op09(void) // ROL DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0A(void) // DEC DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0C(void) // INC DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0D(void) // TST DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0E(void) // JMP DP +{ + regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.clock += 3; +} +static void Op0F(void) // CLR DP { - exec_op2[regs.RdMem(regs.pc++)](); + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC + regs.clock += 6; } static void Op12(void) // NOP @@ -638,18 +3366,47 @@ static void Op17(void) // LBSR static void Op19(void) // DAA { - if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? - { - regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry - } - if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big? - { - regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry - } - regs.cc &= 0xF1; // CL NZV - if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 2; +#if 0 + uint8 result = regs.a; + + if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? + { +// regs.a += 0x06; + result += 0x06; + regs.cc |= 0x20; // Then adjust & set half carry + } + + if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big? + { +// regs.a += 0x60; + result += 0x60; + regs.cc |= 0x01; // Then adjust & set carry + } + + regs.a = result; + + regs.cc &= 0xF1; // CL NZV + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag +#else + uint16 result = (uint16)regs.a; + + if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) + result += 0x06; + + if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + result += 0x60; + + regs.a = (uint8)result; +// SET_ZN(result); +// CLR_V; // Not sure this is correct... + regs.cc &= 0xF1; // CL NZV + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag +// flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore + regs.cc |= (result & 0x100) > 8; +#endif + regs.clock += 2; } static void Op1A(void) // ORCC # @@ -933,11 +3690,6 @@ static void Op39(void) // RTS regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); regs.clock += 5; } -static void Op3A(void) // ABX -{ - regs.x += regs.b; - regs.clock += 3; -} static void Op3B(void) // RTI { regs.cc = regs.RdMem(regs.s++); @@ -1428,14 +4180,6 @@ static void Op83(void) // SUBD # regs.a = dr>>8; regs.b = dr&0xFF; regs.clock += 4; } -static void Op84(void) // ANDA # - { - regs.a &= regs.RdMem(regs.pc++); - regs.cc &= 0xFD; // Clear oVerflow flag - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } static void Op85(void) // BITA # { tmp = regs.a & regs.RdMem(regs.pc++); @@ -1460,18 +4204,6 @@ static void Op88(void) // EORA # (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 2; } -static void Op89(void) // ADCA # -{ - tmp = regs.RdMem(regs.pc++); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative - regs.clock += 2; -} static void Op8A(void) // ORA # { regs.a |= regs.RdMem(regs.pc++); @@ -1480,17 +4212,6 @@ static void Op8A(void) // ORA # (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 2; } -static void Op8B(void) // ADDA # -{ - tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp; - (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 2; -} static void Op8C(void) // CMPX # { addr = FetchW(); @@ -1562,6 +4283,14 @@ static void Op93(void) // SUBD DP regs.a = dr>>8; regs.b = dr&0xFF; regs.clock += 6; } +static void Op84(void) // ANDA # + { + regs.a &= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } static void Op94(void) // ANDA DP { regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); @@ -1602,18 +4331,6 @@ static void Op98(void) // EORA DP (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void Op99(void) // ADCA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative - regs.clock += 4; -} static void Op9A(void) // ORA DP { regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); @@ -1622,18 +4339,6 @@ static void Op9A(void) // ORA DP (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void Op9B(void) // ADDA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16)regs.a + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void Op9C(void) // CMPX DP { addr = (regs.dp<<8)|regs.RdMem(regs.pc++); @@ -1752,18 +4457,6 @@ static void OpA8(void) // EORA IDX (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpA9(void) // ADCA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void OpAA(void) // ORA IDX { regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); @@ -1772,18 +4465,6 @@ static void OpAA(void) // ORA IDX (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpAB(void) // ADDA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.a + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void OpAC(void) // CMPX IDX { addr = DecodeIDX(regs.RdMem(regs.pc++)); @@ -1902,18 +4583,6 @@ static void OpB8(void) // EORA ABS (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 5; } -static void OpB9(void) // ADCA ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 5; -} static void OpBA(void) // ORA ABS { regs.a |= regs.RdMem(FetchW()); @@ -1922,18 +4591,6 @@ static void OpBA(void) // ORA ABS (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 5; } -static void OpBB(void) // ADDA ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.a + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 5; -} static void OpBC(void) // CMPX ABS { addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); @@ -2008,18 +4665,6 @@ static void OpC2(void) // SBCB # (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 2; } -static void OpC3(void) // ADDD # -{ - addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - dr += addr; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 4; -} static void OpC4(void) // ANDB # { regs.b &= regs.RdMem(regs.pc++); @@ -2052,18 +4697,6 @@ static void OpC8(void) // EORB # (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 2; } -static void OpC9(void) // ADCB # -{ - tmp = regs.RdMem(regs.pc++); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 2; -} static void OpCA(void) // ORB # { regs.b |= regs.RdMem(regs.pc++); @@ -2072,17 +4705,6 @@ static void OpCA(void) // ORB # (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 2; } -static void OpCB(void) // ADDB # -{ - tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp; - (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 2; -} static void OpCC(void) // LDD # { regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++); @@ -2129,19 +4751,6 @@ static void OpD2(void) // SBCB DP (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpD3(void) // ADDD DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); - dr += adr2; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; -} static void OpD4(void) // ANDB DP { regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); @@ -2182,18 +4791,6 @@ static void OpD8(void) // EORB DP (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpD9(void) // ADCB DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void OpDA(void) // ORB DP { regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); @@ -2202,18 +4799,6 @@ static void OpDA(void) // ORB DP (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpDB(void) // ADDB DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16)regs.b + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void OpDC(void) // LDD DP { addr = (regs.dp<<8)|regs.RdMem(regs.pc++); @@ -2280,19 +4865,6 @@ static void OpE2(void) // SBCB IDX (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpE3(void) // ADDD IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); - dr += adr2; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; -} static void OpE4(void) // ANDB IDX { regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); @@ -2333,18 +4905,6 @@ static void OpE8(void) // EORB IDX (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpE9(void) // ADCB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void OpEA(void) // ORB IDX { regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); @@ -2353,18 +4913,6 @@ static void OpEA(void) // ORB IDX (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void OpEB(void) // ADDB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.b + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 4; -} static void OpEC(void) // LDD IDX { addr = DecodeIDX(regs.RdMem(regs.pc++)); @@ -2430,19 +4978,6 @@ static void OpF2(void) // SBCB ABS ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow regs.clock += 5; } -static void OpF3(void) // ADDD ABS -{ - addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); - dr += adr2; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 7; -} static void OpF4(void) // ANDB ABS { regs.b &= regs.RdMem(FetchW()); @@ -2483,18 +5018,6 @@ static void OpF8(void) // EORB ABS (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 5; } -static void OpF9(void) // ADCB ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 5; -} static void OpFA(void) // ORB ABS { regs.b |= regs.RdMem(FetchW()); @@ -2503,18 +5026,6 @@ static void OpFA(void) // ORB ABS (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 5; } -static void OpFB(void) // ADDB ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.b + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 5; -} static void OpFC(void) // LDD ABS { addr = FetchW(); @@ -3013,6 +5524,8 @@ static void Op11BC(void) // CMPS ABS (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl regs.clock += 8; } +#endif + //temp, for testing... #ifdef __DEBUG__ @@ -3035,6 +5548,95 @@ for(int i=0; i<256; i++) #endif } +// +// Function arrays +// + +// These are defined below, so we just use forward declarations here to prevent the compiler barfing... +static void Op10(void); +static void Op11(void); + +// Array of page zero opcode functions... + +static void (* exec_op0[256])() = { + Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, + Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, + Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, + Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, + Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, + Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, + Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, + Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, + Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, + Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, + OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, + OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, + OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, + OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, + OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, + OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF +}; + +// Array of page one opcode functions... +static void (* exec_op1[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, + Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, + Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, + Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF +}; + +// Array of page two opcode functions... +static void (* exec_op2[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, + Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, + Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, + Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ +}; + +// These are here to save typing a ton of forward declarations... + +// Page 1 opcode +static void Op10(void) +{ +// exec_op1[regs.RdMem(regs.pc++)](); + uint8 opcode = regs.RdMem(regs.pc++); + exec_op1[opcode](); + regs.clock += page1Cycles[opcode]; +} + +// Page 2 opcode +static void Op11(void) +{ +// exec_op2[regs.RdMem(regs.pc++)](); + uint8 opcode = regs.RdMem(regs.pc++); + exec_op2[opcode](); + regs.clock += page2Cycles[opcode]; +} + // // Internal "memcpy" (so we don't have to link with any external libraries!) @@ -3067,6 +5669,7 @@ void Execute6809(V6809REGS * context, uint32 cycles) return; myMemcpy(®s, context, sizeof(V6809REGS)); + UNPACK_FLAGS; // Explode flags register into individual uint8s // Execute here... @@ -3105,8 +5708,16 @@ if (!tripped) } #endif #ifdef __DEBUG__ -//Decode6809(regs.pc); -static bool disasm = false; +if (disasm) +{ + Decode6809(regs.pc); +// WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC); +} +#if 0 //we solved this... +if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1) + WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n"); +#endif +//static bool disasm = false; /*//if (regs.pc == 0x15BA) disasm = true; //if (regs.pc == 0xFE76) disasm = true; if (regs.x == 0xFED4) disasm = true; @@ -3118,18 +5729,23 @@ if (disasm) Decode6809(regs.pc); btPC[btPtr] = regs.pc; btPtr = (btPtr + 1) & 0xFF;//*/ #endif - exec_op0[regs.RdMem(regs.pc++)](); +// exec_op0[regs.RdMem(regs.pc++)](); + uint8 opcode = regs.RdMem(regs.pc++); + exec_op0[opcode](); + regs.clock += page0Cycles[opcode]; // Handle any pending interrupts - uint32 flags = context->cpuFlags; +// Hmm, this is bad and only works when flags are changed OUTSIDE of the running context... +// uint32 flags = context->cpuFlags; + uint32 flags = regs.cpuFlags; if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler *** { #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); #endif - regs.cc |= (FLAG_F | FLAG_I); // Set F, I + flagF = flagI = 1; // Set F, I regs.dp = 0; // Reset direct page register regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector context->cpuFlags &= ~V6809_ASSERT_LINE_RESET; @@ -3140,22 +5756,19 @@ if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); #endif - regs.cc |= FLAG_E; // Set the Entire flag - - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.u & 0xFF); - regs.WrMem(--regs.s, regs.u >> 8); - regs.WrMem(--regs.s, regs.y & 0xFF); - regs.WrMem(--regs.s, regs.y >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.dp); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - - regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags + flagE = 1; // Set Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + + PUSHS16(regs.pc); // Save all regs... + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + + flagI = flagF = 1; // Set IRQ/FIRQ suppress flags regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector regs.clock += 19; // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... @@ -3166,18 +5779,18 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n"); #endif - if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)? + if (!flagF) // Is the FIRQ masked (F == 1)? { #ifdef __DEBUG__ if (disasm) WriteLog(" FIRQ taken...\n"); #endif - regs.cc &= ~FLAG_E; // Clear the Entire flag + flagE = 0; // Clear Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.cc); + PUSHS16(regs.pc); + PUSHS(regs.cc); - regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags + flagI = flagF = 1; // Set IRQ/FIRQ suppress flags regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector regs.clock += 10; // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)... @@ -3189,27 +5802,24 @@ if (disasm) WriteLog(" FIRQ taken...\n"); #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: IRQ line asserted!\n"); #endif - if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)? + if (!flagI) // Is the IRQ masked (I == 1)? { #ifdef __DEBUG__ if (disasm) WriteLog(" IRQ taken...\n"); #endif - regs.cc |= FLAG_E; // Set the Entire flag - - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.u & 0xFF); - regs.WrMem(--regs.s, regs.u >> 8); - regs.WrMem(--regs.s, regs.y & 0xFF); - regs.WrMem(--regs.s, regs.y >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.dp); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - - regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags] + flagE = 1; // Set the Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + + flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags] regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector regs.clock += 19; // Apparently, not done here! @@ -3218,8 +5828,10 @@ if (disasm) WriteLog(" IRQ taken...\n"); } } #ifdef __DEBUG__ -if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", - regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ +if (disasm) WriteLog("\tCC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", + (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"), + (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"), + regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ #endif @@ -3228,6 +5840,7 @@ if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04 // Keep track of how much we overran so we can adjust on the next run... regs.clockOverrun = (uint32)(regs.clock - endCycles); + regs.cc = PACK_FLAGS; // Mash flags back into the CC register myMemcpy(context, ®s, sizeof(V6809REGS)); } @@ -3248,13 +5861,45 @@ uint16 GetCurrentV6809PC(void) } // Set a line of the currently executing CPU -void SetLine(uint32 line) +void SetLineOfCurrentV6809(uint32 line) { regs.cpuFlags |= line; } // Clear a line of the currently executing CPU -void ClearLine(uint32 line) +void ClearLineOfCurrentV6809(uint32 line) { +#ifdef __DEBUG__ +if (disasm) + WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER")); +#endif regs.cpuFlags &= ~line; } + +#if 0 +FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51 +E S=BFFF U=0000 PC=FEC0 +FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF + U=0000 PC=F51E +F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF + U=0000 PC=F520 +F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523 +F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526 +F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529 +F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B +F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D +F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531 +F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD +13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF +13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2 +13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5 +13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7 +13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9 +13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB +13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD +13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF +13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1 +13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3 +13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5 +13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000 +#endif diff --git a/src/v6809.h b/src/v6809.h index 9511654..39fc3f8 100755 --- a/src/v6809.h +++ b/src/v6809.h @@ -57,7 +57,7 @@ struct V6809REGS void Execute6809(V6809REGS *, uint32); // Function to execute 6809 instructions uint64 GetCurrentV6809Clock(void); // Get the clock of the currently executing CPU uint16 GetCurrentV6809PC(void); // Get the PC of the currently executing CPU -void SetLine(uint32 line); // Set a line of the currently executing CPU -void ClearLine(uint32 line); // Clear a line of the currently executing CPU +void SetLineOfCurrentV6809(uint32 line); // Set a line of the currently executing CPU +void ClearLineOfCurrentV6809(uint32 line); // Clear a line of the currently executing CPU #endif // __V6809_H__