X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fv6809.cpp;h=a6c07fcd40f0ad1899be1e3abc4387b97df9ebe1;hb=a7c3ff9deab4cefbc76ac52d38b67e7033c63cf6;hp=862f1a82dc19b9d38e259d770adb12bfb9c3e368;hpb=6e4a6b1f4aecb0ec7cab2c3dea9553f30f848a4c;p=thunder diff --git a/src/v6809.cpp b/src/v6809.cpp old mode 100644 new mode 100755 index 862f1a8..a6c07fc --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -1,246 +1,202 @@ // -// Virtual 6809 v1.3 +// Virtual 6809 v1.4.1 // -// by James Hammons -// (c) 1997, 2014 Underground Software +// by James L. Hammons +// (C) 1997, 2009, 2014 Underground Software // -// JLH = James Hammons +// JLH = James L. Hammons // // WHO WHEN WHAT // --- ---------- ----------------------------------------------------------- // JLH 06/15/2006 Added changelog ;-) // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code // JLH 11/11/2006 Removed all SignedX() references +// JLH 09/29/2009 Converted V6809 to macro implementation! +// JLH 04/17/2014 Misc. cleanups, fixes to missing instructions // -// Mebbe someday I'll get around to fixing the core to be more like V65C02... -// We have a start... ;-) -// +#define __DEBUG__ #include "v6809.h" -#define __DEBUG__ #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) +#define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4) //Not sure that this code is computing the carry correctly... Investigate! [Seems to be] -#define SET_C_ADD(a,b) (regs.cc = ((uint8_t)(b) > (uint8_t)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +//#define SET_C_ADD(a,b) (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0)) //#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) -#define SET_C_CMP(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +//#define SET_C_CMP(a,b) (flagC = ((uint8_t)(b) >= (uint8_t)(a) ? 1 : 0)) #define SET_ZN(r) SET_N(r); SET_Z(r) -#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +#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) +//#define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b) -//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. #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_t addr = EA_IMM; v = regs.RdMem(addr) -#define READ_ZP_WB(v) uint16_t addr = EA_ZP; v = regs.RdMem(addr) -#define READ_ZP_X_WB(v) uint16_t addr = EA_ZP_X; v = regs.RdMem(addr) -#define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2 -#define READ_ABS_X_WB(v) uint16_t addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2 -#define READ_ABS_Y_WB(v) uint16_t addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2 -#define READ_IND_ZP_X_WB(v) uint16_t addr = EA_IND_ZP_X; v = regs.RdMem(addr) -#define READ_IND_ZP_Y_WB(v) uint16_t addr = EA_IND_ZP_Y; v = regs.RdMem(addr) -#define READ_IND_ZP_WB(v) uint16_t addr = EA_IND_ZP; v = regs.RdMem(addr) +#define READ_DP_WB(v) uint16_t addr = EA_DP; v = regs.RdMem(addr) +#define READ_IDX_WB(v) uint16_t addr = EA_IDX; v = regs.RdMem(addr) +#define READ_ABS_WB(v) uint16_t 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_t addr; // Temporary variables common to all funcs... -static uint8_t tmp; +static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC; + +static const uint8_t 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 +}; + +static const uint8_t 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 +}; + +static const uint8_t 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_t FetchW(void); static uint16_t RdMemW(uint16_t addr); +static uint16_t FetchMemW(uint16_t addr); static void WrMemW(uint16_t addr, uint16_t w); static uint16_t ReadEXG(uint8_t); // Read TFR/EXG post byte static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data static uint16_t DecodeReg(uint8_t); // Decode register data static uint16_t DecodeIDX(uint8_t); // 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_t FetchW() +static inline uint16_t RdMemW(uint16_t addr) { - uint16_t w = RdMemW(regs.pc); - regs.pc += 2; - return w; + return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } + // -// Read word from memory function +// Fetch a word from memory function. Increments PC // -uint16_t RdMemW(uint16_t addr) +static inline uint16_t FetchMemW(uint16_t addr) { + regs.pc += 2; return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } + // // Write word to memory function // -void WrMemW(uint16_t addr, uint16_t w) +static inline void WrMemW(uint16_t addr, uint16_t w) { regs.WrMem(addr + 0, w >> 8); regs.WrMem(addr + 1, w & 0xFF); } + // // Function to read TFR/EXG post byte // -uint16_t ReadEXG(uint8_t code) +static uint16_t ReadEXG(uint8_t code) { uint16_t retval; @@ -271,6 +227,7 @@ uint16_t ReadEXG(uint8_t code) retval = regs.b; break; case 10: + PACK_FLAGS; retval = regs.cc; break; case 11: @@ -283,10 +240,11 @@ uint16_t ReadEXG(uint8_t code) return retval; } + // // Function to set TFR/EXG data // -void WriteEXG(uint8_t code, uint16_t data) +static void WriteEXG(uint8_t code, uint16_t data) { switch (code) { @@ -307,16 +265,17 @@ void WriteEXG(uint8_t code, uint16_t data) case 9: regs.b = data & 0xFF; break; case 10: - regs.cc = data & 0xFF; break; + regs.cc = data & 0xFF; UNPACK_FLAGS; break; case 11: regs.dp = data & 0xFF; break; } } + // // Function to decode register data // -uint16_t DecodeReg(uint8_t reg) +static uint16_t DecodeReg(uint8_t reg) { uint16_t retval; @@ -335,10 +294,11 @@ uint16_t DecodeReg(uint8_t reg) return retval; } + // // Function to decode IDX data // -uint16_t DecodeIDX(uint8_t code) +static uint16_t DecodeIDX(uint8_t code) { uint16_t addr, woff; uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F; @@ -390,7 +350,7 @@ uint16_t DecodeIDX(uint8_t code) addr = RdMemW(woff); break; case 9: - woff = DecodeReg(reg) + FetchW(); + woff = DecodeReg(reg) + FetchMemW(regs.pc); addr = RdMemW(woff); break; case 11: @@ -398,15 +358,17 @@ uint16_t DecodeIDX(uint8_t code) addr = RdMemW(woff); break; case 12: - woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); +// woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); + woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); + regs.pc++; 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; } @@ -455,10 +417,11 @@ uint16_t DecodeIDX(uint8_t code) case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; } case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; } case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)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_t)(int8_t)regs.RdMem(regs.pc++); break; } - case 13: { addr = regs.pc + FetchW(); break; } +// case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; } + case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); regs.pc++; break; } + case 13: { addr = regs.pc + FetchMemW(regs.pc); break; } } } } @@ -466,2589 +429,2875 @@ uint16_t DecodeIDX(uint8_t code) return addr; } + // -// 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! ;-) +// + +/* + +-----------------------------------------------------------------+ + | 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_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \ + flagC = (sum >> 8) & 0x01; \ + SET_H(m, acc, sum); \ + 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 # +{ + uint16_t m = READ_IMM; + OP_ADC_HANDLER(m, regs.a); +} + + +static void Op99(void) // ADCA DP +{ + uint16_t m = READ_DP; + OP_ADC_HANDLER(m, regs.a); +} + -static void Op00(void) // NEG DP +static void OpA9(void) // ADCA IDX { - addr = (regs.dp << 8) | regs.RdMem(regs.pc++); - tmp = 256 - regs.RdMem(addr); - regs.WrMem(addr, tmp); + uint16_t m = READ_IDX; + 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 - regs.clock += 6; +static void OpB9(void) // ADCA ABS +{ + uint16_t m = READ_ABS; + OP_ADC_HANDLER(m, regs.a); } -static void Op01(void) // NEG DP (Undocumented) + +static void OpC9(void) // ADCB # { - Op00(); + uint16_t m = READ_IMM; + OP_ADC_HANDLER(m, regs.b); } -static void Op03(void) // COM DP + +static void OpD9(void) // ADCB DP { - addr = (regs.dp << 8) | regs.RdMem(regs.pc++); - tmp = 0xFF ^ regs.RdMem(addr); - regs.WrMem(addr, tmp); + uint16_t m = READ_DP; + 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 - regs.clock += 6; +static void OpE9(void) // ADCB IDX +{ + uint16_t 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_t 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_t sum = (uint16_t)(acc) + (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_H(m, acc, sum); \ + SET_V(m, acc, sum); \ + (acc) = sum & 0xFF; \ + SET_ZN(acc) + +#define OP_ADD_HANDLER16(m, hireg, loreg) \ + uint32_t acc = (uint32_t)((hireg << 8) | loreg); \ + uint32_t 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_t 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_t)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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t m = READ_DP; + OP_ADD_HANDLER(m, regs.b); } -static void Op10(void) // Page 1 opcode + +static void OpE3(void) // ADDD IDX { - exec_op1[regs.RdMem(regs.pc++)](); + uint32_t m = READ_IDX16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op11(void) // Page 2 opcode + +static void OpEB(void) // ADDB IDX { - exec_op2[regs.RdMem(regs.pc++)](); + uint16_t m = READ_IDX; + OP_ADD_HANDLER(m, regs.b); } -static void Op12(void) // NOP + +static void OpF3(void) // ADDD ABS { - regs.clock += 2; + uint32_t m = READ_ABS16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op13(void) // SYNC + +static void OpFB(void) // ADDB ABS { - // Fix this so it does the right thing (software interrupt!) - regs.clock += 2; + uint16_t m = READ_ABS; + OP_ADD_HANDLER(m, regs.b); } -static void Op16(void) // LBRA + +/* + +-----------------------------------------------------------------+ + | 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 # { -// regs.pc += SignedW(FetchW()); - regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities + uint16_t m = READ_IMM; + OP_AND_HANDLER(m, regs.a); +} - regs.clock += 5; +static void Op94(void) // ANDA DP +{ + uint16_t m = READ_DP; + OP_AND_HANDLER(m, regs.a); } -static void Op17(void) // LBSR +static void OpA4(void) // ANDA IDX { - uint16_t word = FetchW(); - regs.WrMem(--regs.s, regs.pc & 0xFF); - regs.WrMem(--regs.s, regs.pc >> 8); -// regs.pc += SignedW(addr); - regs.pc += word; // No need to make signed, both are 16 bit + uint16_t m = READ_IDX; + OP_AND_HANDLER(m, regs.a); +} - regs.clock += 9; +static void OpB4(void) // ANDA ABS +{ + uint16_t m = READ_ABS; + OP_AND_HANDLER(m, regs.a); } -static void Op19(void) // DAA +static void OpC4(void) // ANDB # { -#if 0 - uint8_t result = regs.a; + uint16_t m = READ_IMM; + OP_AND_HANDLER(m, regs.b); +} - 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 - } +static void OpD4(void) // ANDB DP +{ + uint16_t m = READ_DP; + OP_AND_HANDLER(m, regs.b); +} - 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 - } +static void OpE4(void) // ANDB IDX +{ + uint16_t m = READ_IDX; + OP_AND_HANDLER(m, regs.b); +} - regs.a = result; +static void OpF4(void) // ANDB ABS +{ + uint16_t m = READ_ABS; + OP_AND_HANDLER(m, regs.b); +} - 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_t result = (uint16_t)regs.a; +/* + +-----------------------------------------------------------------+ + | 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 | +*/ - if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) - result += 0x06; +// ASL opcodes - if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) - result += 0x60; +#define OP_ASL_HANDLER(m) \ + uint16_t res = m << 1; \ + SET_V(m, m, res); \ + flagC = (res >> 8) & 0x01; \ + m = res & 0xFF; \ + SET_ZN(m) - regs.a = (uint8_t)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 Op08(void) // ASL DP +{ + uint8_t m; + READ_DP_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); } -static void Op1A(void) // ORCC # +static void Op48(void) // ASLA { - regs.cc |= regs.RdMem(regs.pc++); + OP_ASL_HANDLER(regs.a); +} - regs.clock += 3; +static void Op58(void) // ASLB +{ + OP_ASL_HANDLER(regs.b); } -static void Op1C(void) // ANDCC # +static void Op68(void) // ASL IDX { - regs.cc &= regs.RdMem(regs.pc++); + uint8_t m; + READ_IDX_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); +} - regs.clock += 3; +static void Op78(void) // ASL ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); } -static void Op1D(void) // SEX +/* + +-----------------------------------------------------------------+ + | 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_t res = (m & 0x80) | (m >> 1); \ + SET_ZN(res); \ + flagC = m & 0x01; \ + m = res + +static void Op07(void) // ASR DP { - (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00); + uint8_t m; + READ_DP_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} - ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void Op47(void) // ASRA +{ + OP_ASR_HANDLER(regs.a); +} - regs.clock += 2; +static void Op57(void) // ASRB +{ + OP_ASR_HANDLER(regs.b); } -static void Op1E(void) // EXG +static void Op67(void) // ASR IDX { - tmp = regs.RdMem(regs.pc++); - addr = ReadEXG(tmp >> 4); - WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF)); - WriteEXG(tmp & 0xF, addr); + uint8_t m; + READ_IDX_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} - regs.clock += 8; +static void Op77(void) // ASR ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); } -static void Op1F(void) // TFR +/* + +-----------------------------------------------------------------+ + | 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 { - tmp = regs.RdMem(regs.pc++); - WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); - regs.clock += 7; + uint16_t offset = READ_IMM16; + regs.pc += offset; } static void Op20(void) // BRA { -// regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always - regs.pc += (int16_t)(int8_t)regs.RdMem(regs.pc) + 1; // Branch always - - regs.clock += 3; + int16_t offset = (int16_t)(int8_t)READ_IMM; + regs.pc += offset; } static void Op21(void) // BRN { - regs.RdMem(regs.pc++); - - regs.clock += 3; + // This is basically a 2 byte NOP + int16_t offset = (int16_t)(int8_t)READ_IMM; } static void Op22(void) // BHI { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !C && !Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x05)) - regs.pc += word; - - regs.clock += 3; +#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 { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x05) - regs.pc += word; + // C || Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | flagC); +#else + if (flagZ || flagC) + regs.pc += offset; +#endif } -static void Op24(void) // BCC (BHS) +static void Op24(void) // BHS/CC { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !C + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x01)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagC ^ 0x01); +#else + if (!flagC) + regs.pc += offset; +#endif } -static void Op25(void) // BCS (BLO) +static void Op25(void) // BLO/CS { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x01) - regs.pc += word; + // C + int16_t offset = (int16_t)(int8_t)READ_IMM; +//if (disasm) +// WriteLog("[offset=%04X,flagC=%08X]", offset, flagC); - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagC; +#else + if (flagC) + regs.pc += offset; +#endif } static void Op26(void) // BNE { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x04)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ ^ 0x01); +#else + if (!flagZ) + regs.pc += offset; +#endif } static void Op27(void) // BEQ { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x04) - regs.pc += word; + // Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagZ; +#else + if (flagZ) + regs.pc += offset; +#endif } static void Op28(void) // BVC { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !V + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x02)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagV ^ 0x01); +#else + if (!flagV) + regs.pc += offset; +#endif } static void Op29(void) // BVS { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x02) - regs.pc += word; + // V + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagV; +#else + if (flagV) + regs.pc += offset; +#endif } static void Op2A(void) // BPL { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !N + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x08)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagN ^ 0x01); +#else + if (!flagN) + regs.pc += offset; +#endif } static void Op2B(void) // BMI { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x08) - regs.pc += word; + // N + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagN; +#else + if (flagN) + regs.pc += offset; +#endif } static void Op2C(void) // BGE { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // (N && V) || (!N && !V) + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; - - regs.clock += 3; +#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 { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) - regs.pc += word; + // (N && !V) || (!N && V) + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#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 { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // (N && V && !Z) || (!N && !V && !Z) + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) - regs.pc += word; - - regs.clock += 3; +#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 { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; + // Z || (N && !V) || (!N && V) + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#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 Op30(void) // LEAX +static void Op1021(void) // LBRN { - regs.x = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + // This is basically a 4 byte NOP + uint16_t offset = READ_IMM16; } -static void Op31(void) // LEAY + +static void Op1022(void) // LBHI { - regs.y = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + // !C && !Z + uint16_t 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 Op32(void) // LEAS + +static void Op1023(void) // LBLS { - regs.s = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + // C || Z + uint16_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t 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_t result = acc & (m); \ + SET_ZN(result); \ + CLR_V + +static void Op85(void) // BITA # +{ + uint8_t m = READ_IMM; + OP_BIT_HANDLER(m, regs.a); +} + +static void Op95(void) // BITA DP +{ + uint8_t m = READ_DP; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpA5(void) // BITA IDX +{ + uint8_t m = READ_IDX; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpB5(void) // BITA ABS +{ + uint8_t m = READ_ABS; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpC5(void) // BITB # +{ + uint8_t m = READ_IMM; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpD5(void) // BITB DP +{ + uint8_t m = READ_DP; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpE5(void) // BITB IDX +{ + uint8_t m = READ_IDX; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpF5(void) // BITB ABS +{ + uint8_t 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_t 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_t m; + READ_IDX_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7F(void) // CLR ABS +{ + uint8_t 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_t sum = (uint16_t)(acc) - (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + SET_ZN(sum) + +#define OP_CMP_HANDLER16(m, acc) \ + uint32_t sum = (uint32_t)(acc) - (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + SET_ZN16(sum) + +static void Op81(void) // CMPA # +{ + uint8_t m = READ_IMM; + OP_CMP_HANDLER(m, regs.a); +} + +static void Op8C(void) // CMPX # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void Op91(void) // CMPA DP +{ + uint8_t m = READ_DP; + OP_CMP_HANDLER(m, regs.a); +} + +static void Op9C(void) // CMPX DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpA1(void) // CMPA IDX +{ + uint8_t m = READ_IDX; + OP_CMP_HANDLER(m, regs.a); +} + +static void OpAC(void) // CMPX IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpB1(void) // CMPA ABS +{ + uint8_t m = READ_ABS; + OP_CMP_HANDLER(m, regs.a); +} + +static void OpBC(void) // CMPX ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpC1(void) // CMPB # +{ + uint8_t m = READ_IMM; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpD1(void) // CMPB DP +{ + uint8_t m = READ_DP; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpE1(void) // CMPB IDX +{ + uint8_t m = READ_IDX; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpF1(void) // CMPB ABS +{ + uint8_t m = READ_ABS; + OP_CMP_HANDLER(m, regs.b); +} + +static void Op1083(void) // CMPD # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op108C(void) // CMPY # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op1093(void) // CMPD DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op109C(void) // CMPY DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op10A3(void) // CMPD IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op10AC(void) // CMPY IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op10B3(void) // CMPD ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op10BC(void) // CMPY ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op1183(void) // CMPU # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op118C(void) // CMPS # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op1193(void) // CMPU DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op119C(void) // CMPS DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op11A3(void) // CMPU IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op11AC(void) // CMPS IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op11B3(void) // CMPU ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op11BC(void) // CMPS ABS +{ + uint16_t 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_t 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_t m; + READ_IDX_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +static void Op73(void) // COM ABS +{ + uint8_t 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 +{ +} + +/* +D3F8: A6 47 LDA (7),U CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA +D3FA: 8B 01 ADDA #$01 CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC +D3FC: 19 DAA CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD +*/ + +static void Op19() // DAA +{ + uint16_t result = (uint16_t)regs.a; + +// if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) + if ((regs.a & 0x0F) > 0x09 || flagH) + result += 0x06; + +// if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + result += 0x60; + + regs.a = (uint8_t)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_t 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_t m; + READ_IDX_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7A(void) // DEC ABS +{ + uint8_t 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_t m = READ_IMM; + OP_EOR_HANDLER(m, regs.a); +} + +static void Op98(void) // EORA DP +{ + uint8_t m = READ_DP; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpA8(void) // EORA IDX +{ + uint8_t m = READ_IDX; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpB8(void) // EORA ABS +{ + uint8_t m = READ_ABS; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpC8(void) // EORB # +{ + uint8_t m = READ_IMM; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpD8(void) // EORB DP +{ + uint8_t m = READ_DP; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpE8(void) // EORB IDX +{ + uint8_t m = READ_IDX; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpF8(void) // EORB ABS +{ + uint8_t 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_t 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_t m; + READ_IDX_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + + +static void Op7C(void) // INC ABS +{ + uint8_t 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 +{ + // This needs to be separate because of the EA_DP adding to regs.pc. + uint16_t m = EA_DP; + regs.pc = m; +} + + +static void Op17(void) // LBSR +{ + uint16_t word = FetchMemW(regs.pc); + PUSHS16(regs.pc); + regs.pc += word; } -static void Op33(void) // LEAU + + +static void Op39(void) // RTS { - regs.u = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + PULLS16(regs.pc); } -static void Op34(void) // PSHS + + +static void Op3B(void) // RTI { - tmp = regs.RdMem(regs.pc++); - if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); } - if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); } - if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); } - if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); } - if (tmp&0x08) regs.WrMem(--regs.s, regs.dp); - if (tmp&0x04) regs.WrMem(--regs.s, regs.b); - if (tmp&0x02) regs.WrMem(--regs.s, regs.a); - if (tmp&0x01) regs.WrMem(--regs.s, regs.cc); - regs.clock += 5; + 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 Op35(void) // PULS + + +static void Op6E(void) // JMP IDX { - tmp = regs.RdMem(regs.pc++); - if (tmp&0x01) regs.cc = regs.RdMem(regs.s++); - if (tmp&0x02) regs.a = regs.RdMem(regs.s++); - if (tmp&0x04) regs.b = regs.RdMem(regs.s++); - if (tmp&0x08) regs.dp = regs.RdMem(regs.s++); - if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.clock += 5; + regs.pc = EA_IDX; } -static void Op36(void) // PSHU + +static void Op7E(void) // JMP ABS { - tmp = regs.RdMem(regs.pc++); + regs.pc = EA_ABS; +} - if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); } - if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); } - if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); } - if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); } - if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp); - if (tmp & 0x04) regs.WrMem(--regs.u, regs.b); - if (tmp & 0x02) regs.WrMem(--regs.u, regs.a); - if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc); - regs.clock += 5; +static void Op8D(void) // BSR +{ + uint16_t word = (int16_t)(int8_t)READ_IMM; + PUSHS16(regs.pc); + regs.pc += word; } -static void Op37(void) // PULU + +static void Op9D(void) // JSR DP { - tmp = regs.RdMem(regs.pc++); - if (tmp&0x01) regs.cc = regs.RdMem(regs.u++); - if (tmp&0x02) regs.a = regs.RdMem(regs.u++); - if (tmp&0x04) regs.b = regs.RdMem(regs.u++); - if (tmp&0x08) regs.dp = regs.RdMem(regs.u++); - if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - regs.clock += 5; + uint16_t word = EA_DP; + PUSHS16(regs.pc); + regs.pc = word; } -static void Op39(void) // RTS + + +static void OpAD(void) // JSR IDX { - regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.clock += 5; + uint16_t word = EA_IDX; + PUSHS16(regs.pc); + regs.pc = word; } -static void Op3A(void) // ABX + + +static void OpBD(void) // JSR ABS { - regs.x += regs.b; - regs.clock += 3; + uint16_t word = EA_ABS; + PUSHS16(regs.pc); + regs.pc = word; } -static void Op3B(void) // RTI + + +/* + +-----------------------------------------------------------------+ + | 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 { - regs.cc = regs.RdMem(regs.s++); - if (regs.cc&0x80) // If E flag set, pull all regs - { - regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++); - regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.clock += 15; - } - else - { - regs.clock += 6; - } - regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); -} -static void Op3C(void) // CWAI -{ - regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80; - regs.clock += 1000000; // Force interrupt -} -static void Op3D(void) // MUL -{ - addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF; - (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry - regs.clock += 11; -} -static void Op3E(void) // RESET -{ -} -static void Op3F(void) // SWI -{ -} -static void Op40(void) // NEGA -{ - regs.a = 256 - regs.a; - (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry - (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (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 Op43(void) // COMA -{ - regs.a ^= 0xFF; - regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC - (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 Op44(void) // LSRA -{ - (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry - regs.a >>= 1; - (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 Op46(void) // RORA -{ - tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128; - (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry - (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 Op47(void) // ASRA -{ - (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry - regs.a >>= 1; // Do the shift - if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set - (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 Op48(void) // LSLA [Keep checking from here...] -{ - (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - regs.a <<= 1; - (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 Op49(void) // ROLA -{ - tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01); - (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - (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 Op4A(void) // DECA -{ - regs.a--; - (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust 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 Op4C(void) // INCA - { - regs.a++; - (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust 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 Op4D(void) // TSTA - { - 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 Op4F(void) // CLRA -{ - regs.a = 0; - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 2; -} -static void Op50(void) // NEGB - { - regs.b = 256 - regs.b; -// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry - (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry - regs.clock += 2; - } -static void Op53(void) // COMB - { - regs.b ^= 0xFF; - regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op54(void) // LSRB - { - (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry - regs.b >>= 1; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op56(void) // RORB - { - tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128; - (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op57(void) // ASRB - { - (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry - regs.b >>= 1; // Do the shift - if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op58(void) // LSLB - { - (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - regs.b <<= 1; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op59(void) // ROLB -{ - tmp = regs.b; - regs.b = (tmp<<1) + (regs.cc&0x01); - (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; -} -static void Op5A(void) // DECB - { - regs.b--; - (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op5C(void) // INCB - { - regs.b++; - (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op5D(void) // TSTB - { - regs.cc &= 0xFD; // Clear oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void Op5F(void) // CLRB - { - regs.b = 0; - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 2; - } -static void Op60(void) // NEG IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - tmp = regs.RdMem(addr); uint8_t res = 256 - tmp; - regs.WrMem(addr, res); -// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry - (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry - regs.clock += 6; - } -static void Op63(void) // COM IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - tmp = regs.RdMem(addr) ^ 0xFF; - 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 Op64(void) // LSR IDX - { - addr = DecodeIDX(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 Op66(void) // ROR IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - tmp = regs.RdMem(addr); uint8_t tmp2 = tmp; - tmp = (tmp >> 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 Op67(void) // ASR IDX - { - addr = DecodeIDX(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 Op68(void) // LSL IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - 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 Op69(void) // ROL IDX -{ - uint8_t tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - tmp = (tmp2<<1) + (regs.cc&0x01); - regs.WrMem(addr, tmp); - (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi 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 Op6A(void) // DEC IDX - { - uint8_t tmp; uint16_t addr; - addr = DecodeIDX(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 Op6C(void) // INC IDX - { - addr = DecodeIDX(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 Op6D(void) // TST IDX - { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - (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 Op6E(void) // JMP IDX -{ - regs.pc = DecodeIDX(regs.RdMem(regs.pc++)); - regs.clock += 3; -} -static void Op6F(void) // CLR IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 6; -} -static void Op70(void) // NEG ABS - { - addr = FetchW(); - tmp = regs.RdMem(addr); uint8_t res = 256 - tmp; - regs.WrMem(addr, res); - (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry - regs.clock += 7; - } -static void Op73(void) // COM ABS - { - addr = FetchW(); - tmp = regs.RdMem(addr) ^ 0xFF; - 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 += 7; - } -static void Op74(void) // LSR ABS - { - addr = FetchW(); - 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 += 7; - } -static void Op76(void) // ROR ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - tmp = regs.RdMem(addr); uint8_t tmp2 = tmp; - tmp = (tmp >> 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 += 7; - } -static void Op77(void) // ASR ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - 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 += 7; - } -static void Op78(void) // LSL ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - 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 += 7; - } -static void Op79(void) // ROL ABS -{ - uint8_t tmp2 = regs.RdMem(FetchW()); - tmp = (tmp2<<1) + (regs.cc&0x01); - regs.WrMem(addr, tmp); - (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi 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 += 7; -} -static void Op7A(void) // DEC ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - 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 += 7; - } -static void Op7C(void) // INC ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - 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 += 7; - } - -static void Op7D(void) // TST ABS -{ - uint8_t tmp = regs.RdMem(FetchW()); - - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - - regs.clock += 7; -} - -static void Op7E(void) // JMP ABS -{ - regs.pc = FetchW(); - regs.clock += 3; -} -static void Op7F(void) // CLR ABS - { - regs.WrMem(FetchW(), 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 7; - } -static void Op80(void) // SUBA # -{ - uint8_t tmp = regs.RdMem(regs.pc++); uint8_t as = regs.a; - regs.a -= tmp; - (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (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 Op81(void) // CMPA # -{ - tmp = regs.RdMem(regs.pc++); - uint8_t db = regs.a - tmp; - (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; -} -static void Op82(void) // SBCA # -{ - tmp = regs.RdMem(regs.pc++); uint8_t as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (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 Op83(void) // SUBD # -{ - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - dr -= addr; - (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 4; + // If bit 3 & 7 are not equal, $FF is the result (undocumented)... + + uint8_t m = READ_IMM; + uint8_t reg1 = m >> 4, reg2 = m & 0x0F; + uint16_t acc1 = ReadEXG(reg1); + uint16_t acc2 = ReadEXG(reg2); + + // If bit 3 & 7 are not equal, $FF is the result (undocumented)... + if (((m >> 4) ^ m) & 0x08) + acc1 = acc2 = 0xFF; + + WriteEXG(reg1, acc2); + WriteEXG(reg2, acc1); } -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++); - regs.cc &= 0xFD; // Clear 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 += 2; - } -static void Op86(void) // LDA # - { - regs.a = regs.RdMem(regs.pc++); - regs.cc &= 0xFD; // CLV - (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 Op88(void) // EORA # - { - regs.a ^= regs.RdMem(regs.pc++); - regs.cc &= 0xFD; // CLV - (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 Op89(void) // ADCA # -{ - tmp = regs.RdMem(regs.pc++); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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++); - regs.cc &= 0xFD; // CLV - (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 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 Op1F(void) // TFR +{ + uint8_t m = READ_IMM; + uint16_t acc = ReadEXG(m >> 4); + + // If bit 3 & 7 are not equal, $FF is the result (undocumented)... + if (((m >> 4) ^ m) & 0x08) + acc = 0xFF; + + WriteEXG(m & 0x0F, acc); } -static void Op8C(void) // CMPX # + +/* + +-----------------------------------------------------------------+ + | 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 # { - addr = FetchW(); - uint16_t dw = regs.x - addr; - (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; + uint8_t m = READ_IMM; + OP_LDA_HANDLER(m, regs.a); } -static void Op8D(void) // Bregs.s +static void Op8E(void) // LDX # { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - regs.WrMem(--regs.s, regs.pc & 0xFF); - regs.WrMem(--regs.s, regs.pc >> 8); - regs.pc += word; + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.x); +} - regs.clock += 7; -} - -static void Op8E(void) // LDX # - { - regs.x = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 3; - } -static void Op90(void) // SUBA DP - { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t as = regs.a; - regs.a -= tmp; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; - } -static void Op91(void) // CMPA DP - { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - uint8_t db = regs.a - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; - } -static void Op92(void) // SBCA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (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 += 4; +static void Op96(void) // LDA DP +{ + uint8_t m = READ_DP; + OP_LDA_HANDLER(m, regs.a); } -static void Op93(void) // SUBD DP + +static void Op9E(void) // LDX DP { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - dr -= adr2; - (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.x); } -static void Op94(void) // ANDA DP + +static void OpA6(void) // LDA IDX { - regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 4; + uint8_t m = READ_IDX; + OP_LDA_HANDLER(m, regs.a); } -static void Op95(void) // BITA DP - { - tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // Clear 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 += 4; - } -static void Op96(void) // LDA DP -{ - regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xF1; // CLN CLZ CLV - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag - regs.clock += 4; + +static void OpAE(void) // LDX IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.x); } -static void Op97(void) // STA DP - { - regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a); - regs.cc &= 0xFD; // CLV - (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 += 4; - } -static void Op98(void) // EORA DP - { - regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (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 += 4; - } -static void Op99(void) // ADCA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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 OpB6(void) // LDA ABS +{ + uint8_t m = READ_ABS; + OP_LDA_HANDLER(m, regs.a); } -static void Op9A(void) // ORA DP - { - regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (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 += 4; - } -static void Op9B(void) // ADDA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16_t)regs.a + (uint16_t)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 OpBE(void) // LDX ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.x); } -static void Op9C(void) // CMPX DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.x - adr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 6; - } -static void Op9D(void) // JSR DP - { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc = addr; // JSR to DP location... - regs.clock += 7; - } -static void Op9E(void) // LDX DP - { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; - } -static void Op9F(void) // STX DP - { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; - } -static void OpA0(void) // SUBA IDX - { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t as = regs.a; - regs.a -= tmp; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; - } -static void OpA1(void) // CMPA IDX - { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - uint8_t db = regs.a - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; - } -static void OpA2(void) // SBCA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (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 += 4; + +static void OpC6(void) // LDB # +{ + uint8_t m = READ_IMM; + OP_LDA_HANDLER(m, regs.b); } -static void OpA3(void) // SUBD IDX + +static void OpCC(void) // LDD # { - addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - dr -= adr2; - (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; -} -static void OpA4(void) // ANDA IDX - { - regs.a &= regs.RdMem(DecodeIDX(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 += 4; - } -static void OpA5(void) // BITA IDX - { - tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // Clear 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 += 4; - } -static void OpA6(void) // LDA IDX -{ - regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag - regs.clock += 4; + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16D(m); +} + +static void OpCE(void) // LDU # +{ + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpD6(void) // LDB DP +{ + uint8_t m = READ_DP; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpDC(void) // LDD DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16D(m); +} + +static void OpDE(void) // LDU DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpE6(void) // LDB IDX +{ + uint8_t m = READ_IDX; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpEC(void) // LDD IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16D(m); +} + +static void OpEE(void) // LDU IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpF6(void) // LDB ABS +{ + uint8_t m = READ_ABS; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpFC(void) // LDD ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16D(m); +} + +static void OpFE(void) // LDU ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void Op108E(void) // LDY # +{ + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op109E(void) // LDY DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10AE(void) // LDY IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10BE(void) // LDY ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10CE(void) // LDS # +{ + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10DE(void) // LDS DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10EE(void) // LDS IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10FE(void) // LDS ABS +{ + uint16_t 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_t 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_t m; + READ_IDX_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op74(void) // LSR ABS +{ + uint8_t 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_t 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_t 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_t 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_t m; + READ_IDX_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +static void Op70(void) // NEG ABS +{ + uint8_t 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_t m = READ_IMM; + OP_OR_HANDLER(m, regs.a); +} + +static void Op9A(void) // ORA DP +{ + uint8_t m = READ_DP; + OP_OR_HANDLER(m, regs.a); +} + +static void OpAA(void) // ORA IDX +{ + uint8_t m = READ_IDX; + OP_OR_HANDLER(m, regs.a); +} + +static void OpBA(void) // ORA ABS +{ + uint8_t m = READ_ABS; + OP_OR_HANDLER(m, regs.a); +} + +static void OpCA(void) // ORB # +{ + uint8_t m = READ_IMM; + OP_OR_HANDLER(m, regs.b); +} + +static void OpDA(void) // ORB DP +{ + uint8_t m = READ_DP; + OP_OR_HANDLER(m, regs.b); +} + +static void OpEA(void) // ORB IDX +{ + uint8_t m = READ_IDX; + OP_OR_HANDLER(m, regs.b); +} + +static void OpFA(void) // ORB ABS +{ + uint8_t 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_t 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); + } + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +static void Op35(void) // PULS +{ + uint8_t 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); + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +static void Op36(void) // PHSU +{ + uint8_t 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); + } + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +static void Op37(void) // PULU +{ + uint8_t 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); + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +/* + +-----------------------------------------------------------------+ + | 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_t 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_t m; + READ_DP_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); +} + +static void Op49(void) // ROLA +{ + OP_ROL_HANDLER(regs.a); } -static void OpA7(void) // STA IDX + +static void Op59(void) // ROLB { - regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag - regs.clock += 4; + OP_ROL_HANDLER(regs.b); } -static void OpA8(void) // EORA IDX - { - regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // CLV - (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 += 4; - } -static void OpA9(void) // ADCA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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 Op69(void) // ROL IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); } -static void OpAA(void) // ORA IDX + +static void Op79(void) // ROL ABS { - regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // CLV - (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 += 4; + uint8_t m; + READ_ABS_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); } -static void OpAB(void) // ADDA IDX + +/* + +-----------------------------------------------------------------+ + | 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_t res = (flagC << 7) | (m >> 1); \ + SET_ZN(res); \ + SET_V(m, m, res); \ + flagC = m & 0x01; \ + m = res + +static void Op06(void) // ROR DP { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16_t)regs.a + (uint16_t)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; + uint8_t m; + READ_DP_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void OpAC(void) // CMPX IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.x - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 6; -} -static void OpAD(void) // JSR IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc = addr; // Jregs.s directly to IDX ptr - regs.clock += 7; -} -static void OpAE(void) // LDX IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpAF(void) // STX IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 5; -} -static void OpB0(void) // SUBA ABS - { - tmp = regs.RdMem(FetchW()); uint8_t as = regs.a; - regs.a -= tmp; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 5; - } -static void OpB1(void) // CMPA ABS - { - tmp = regs.RdMem(FetchW()); - uint8_t db = regs.a - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 5; - } -static void OpB2(void) // SBCA ABS -{ - tmp = regs.RdMem(FetchW()); uint8_t as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (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 += 5; -} -static void OpB3(void) // SUBD ABS -{ - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - dr -= adr2; - (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 7; + +static void Op46(void) // RORA +{ + OP_ROR_HANDLER(regs.a); } -static void OpB4(void) // ANDA ABS + +static void Op56(void) // RORB { - regs.a &= regs.RdMem(FetchW()); - 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 += 5; + OP_ROR_HANDLER(regs.b); } -static void OpB5(void) // BITA ABS + +static void Op66(void) // ROR IDX { - tmp = regs.a & regs.RdMem(FetchW()); - regs.cc &= 0xFD; // Clear 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 += 5; + uint8_t m; + READ_IDX_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void OpB6(void) // LDA ABS + +static void Op76(void) // ROR ABS { - regs.a = regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (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 += 5; + uint8_t m; + READ_ABS_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void OpB7(void) // STA ABS + +/* + +-----------------------------------------------------------------+ + | 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_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + acc = (uint8_t)sum; \ + SET_ZN(acc) + +static void Op82(void) // SBCA # { - regs.WrMem(FetchW(), regs.a); - regs.cc &= 0xFD; // CLV - (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 += 5; + uint8_t m = READ_IMM; + OP_SBC_HANDLER(m, regs.a); } -static void OpB8(void) // EORA ABS + +static void Op92(void) // SBCA DP { - regs.a ^= regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (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 += 5; + uint8_t m = READ_DP; + OP_SBC_HANDLER(m, regs.a); } -static void OpB9(void) // ADCA ABS + +static void OpA2(void) // SBCA IDX { - tmp = regs.RdMem(FetchW()); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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; + uint8_t m = READ_IDX; + OP_SBC_HANDLER(m, regs.a); } -static void OpBA(void) // ORA ABS + +static void OpB2(void) // SBCA ABS { - regs.a |= regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (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 += 5; + uint8_t m = READ_ABS; + OP_SBC_HANDLER(m, regs.a); } -static void OpBB(void) // ADDA ABS + +static void OpC2(void) // SBCB # { - tmp = regs.RdMem(FetchW()); - addr = (uint16_t)regs.a + (uint16_t)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; + uint8_t m = READ_IMM; + OP_SBC_HANDLER(m, regs.b); } -static void OpBC(void) // CMPX ABS + +static void OpD2(void) // SBCB DP { - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.x - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 7; + uint8_t m = READ_DP; + OP_SBC_HANDLER(m, regs.b); } -static void OpBD(void) // JSR ABS + +static void OpE2(void) // SBCB IDX { - addr = FetchW(); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc = addr; // Go to absolute address (Not indir) - regs.clock += 8; + uint8_t m = READ_IDX; + OP_SBC_HANDLER(m, regs.b); } -static void OpBE(void) // LDX ABS +static void OpF2(void) // SBCB ABS { -// addr = FetchW(); -// regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.x = RdMemW(FetchW()); + uint8_t m = READ_ABS; + OP_SBC_HANDLER(m, regs.b); +} - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +/* + +-----------------------------------------------------------------+ + | 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- | +*/ - regs.clock += 6; -} +// STA opcodes -static void OpBF(void) // STX ABS -{ -// addr = FetchW(); -// regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); - WrMemW(FetchW(), regs.x); +#define OP_STA_HANDLER(m, acc) \ + regs.WrMem(m, acc); \ + CLR_V; \ + SET_ZN(acc) - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +#define OP_STA_HANDLER16(m, acc) \ + WrMemW(m, acc); \ + CLR_V; \ + SET_ZN16(acc) - regs.clock += 6; +static void Op97(void) // STA DP +{ + uint16_t addr = EA_DP; + OP_STA_HANDLER(addr, regs.a); } -static void OpC0(void) // SUBB # - { - tmp = regs.RdMem(regs.pc++); uint8_t bs = regs.b; - regs.b -= tmp; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 2; - } -static void OpC1(void) // CMPB # - { - tmp = regs.RdMem(regs.pc++); - uint8_t db = regs.b - tmp; - (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void OpC2(void) // SBCB # +static void Op9F(void) // STX DP { - tmp = regs.RdMem(regs.pc++); uint8_t bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.x); } -static void OpC3(void) // ADDD # + +static void OpA7(void) // STA IDX { - 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; + uint16_t addr = EA_IDX; + OP_STA_HANDLER(addr, regs.a); } -static void OpC4(void) // ANDB # - { - regs.b &= regs.RdMem(regs.pc++); - regs.cc &= 0xFD; // Clear oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 2; - } -static void OpC5(void) // BITB # -{ - tmp = regs.b & regs.RdMem(regs.pc++); - regs.cc &= 0xF1; // CLV CLZ CLN - if (tmp == 0) regs.cc |= 0x04; // Set Zero flag - if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag - regs.clock += 2; -} -static void OpC6(void) // LDB # -{ - regs.b = regs.RdMem(regs.pc++); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag - regs.clock += 2; -} -static void OpC8(void) // EORB # - { - regs.b ^= regs.RdMem(regs.pc++); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)tmp + (uint16_t)(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++); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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++); - regs.cc &= 0xFD; // CLV - ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 3; -} -static void OpCE(void) // LDU # -{ - regs.u = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 3; -} -static void OpD0(void) // SUBB DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t bs = regs.b; - regs.b -= tmp; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; -} -static void OpD1(void) // CMPB DP + +static void OpAF(void) // STX IDX { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - uint8_t db = regs.b - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.x); } -static void OpD2(void) // SBCB DP + +static void OpB7(void) // STA ABS { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; + uint16_t addr = EA_ABS; + OP_STA_HANDLER(addr, regs.a); } -static void OpD3(void) // ADDD DP + +static void OpBF(void) // STX ABS { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16_t 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++)); - regs.cc &= 0xFD; // Clear oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void OpD5(void) // BITB DP - { - tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // Clear 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 += 4; - } -static void OpD6(void) // LDB DP -{ - regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; -} -static void OpD7(void) // STB DP - { - regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void OpD8(void) // EORB DP - { - regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)tmp + (uint16_t)(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++)); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)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++); - regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpDD(void) // STD DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); - regs.cc &= 0xFD; // CLV - ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpDE(void) // LDU DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpDF(void) // STU DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpE0(void) // SUBB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t bs = regs.b; - regs.b -= tmp; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.x); } -static void OpE1(void) // CMPB IDX + +static void OpD7(void) // STB DP { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - uint8_t db = regs.b - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 4; + uint16_t addr = EA_DP; + OP_STA_HANDLER(addr, regs.b); } -static void OpE2(void) // SBCB IDX + +static void OpDD(void) // STD DP { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); } -static void OpE3(void) // ADDD IDX + +static void OpDF(void) // STU DP { - addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16_t 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++))); - regs.cc &= 0xFD; // Clear oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void OpE5(void) // BITB IDX - { - tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // Clear 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 += 4; - } -static void OpE6(void) // LDB IDX - { - regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void OpE7(void) // STB IDX -{ - regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 4; -} -static void OpE8(void) // EORB IDX - { - regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)tmp + (uint16_t)(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; + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.u); } -static void OpEA(void) // ORB IDX - { - regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)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++)); - regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 5; -} -static void OpED(void) // STD IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); - regs.cc &= 0xF1; // CLV CLZ CLZ - if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 5; -} -static void OpEE(void) // LDU IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 5; -} -static void OpEF(void) // STU IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 5; -} -static void OpF0(void) // SUBB ABS - { - tmp = regs.RdMem(FetchW()); uint8_t bs = regs.b; - regs.b -= tmp; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - } -static void OpF1(void) // CMPB ABS - { - tmp = regs.RdMem(FetchW()); - uint8_t db = regs.b - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.clock += 5; - } -static void OpF2(void) // SBCB ABS -{ - tmp = regs.RdMem(FetchW()); uint8_t bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((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_t 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()); - regs.cc &= 0xFD; // Clear oVerflow flag - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; - } -static void OpF5(void) // BITB ABS - { - tmp = regs.b & regs.RdMem(FetchW()); - regs.cc &= 0xFD; // Clear 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 += 5; - } -static void OpF6(void) // LDB ABS - { - regs.b = regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; - } -static void OpF7(void) // STB ABS - { - regs.WrMem(FetchW(), regs.b); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; - } -static void OpF8(void) // EORB ABS - { - regs.b ^= regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)tmp + (uint16_t)(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()); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (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_t)regs.b + (uint16_t)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(); - regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void OpFD(void) // STD ABS - { - addr = FetchW(); - regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); - regs.cc &= 0xFD; // CLV - ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void OpFE(void) // LDU ABS - { - addr = FetchW(); - regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void OpFF(void) // STU ABS - { - addr = FetchW(); - regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } - -// -// Page one opcodes' execute code -// -static void Op1021(void) // LBRN +static void OpE7(void) // STB IDX { - addr = FetchW(); - - regs.clock += 5; + uint16_t addr = EA_IDX; + OP_STA_HANDLER(addr, regs.b); } -static void Op1022(void) // LBHI +static void OpED(void) // STD IDX { - uint16_t word = FetchW(); - - if (!((regs.cc & 0x01) | (regs.cc & 0x04))) - regs.pc += word; - - regs.clock += 5; + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); } -static void Op1023(void) // LBLS +static void OpEF(void) // STU IDX { - uint16_t word = FetchW(); + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.u); +} - if ((regs.cc & 0x01) | (regs.cc & 0x04)) - regs.pc += word; +static void OpF7(void) // STB ABS +{ + uint16_t addr = EA_ABS; + OP_STA_HANDLER(addr, regs.b); +} - regs.clock += 5; +static void OpFD(void) // STD ABS +{ + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); } -static void Op1024(void) // LBCC (LBHS) +static void OpFF(void) // STU ABS { - uint16_t word = FetchW(); + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.u); +} - if (!(regs.cc & 0x01)) - regs.pc += word; +static void Op109F(void) // STY DP +{ + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.y); +} - regs.clock += 5; +static void Op10AF(void) // STY IDX +{ + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.y); } -static void Op1025(void) // LBCS (LBLO) +static void Op10BF(void) // STY ABS { - uint16_t word = FetchW(); + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.y); +} - if (regs.cc & 0x01) - regs.pc += word; +static void Op10DF(void) // STS DP +{ + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.s); +} - regs.clock += 5; +static void Op10EF(void) // STS IDX +{ + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.s); } -static void Op1026(void) // LBNE +static void Op10FF(void) // STS ABS { - uint16_t word = FetchW(); + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.s); +} - if (!(regs.cc & 0x04)) - regs.pc += word; +/* + +-----------------------------------------------------------------+ + | 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 | +*/ - regs.clock += 5; -} +// SUB opcodes -static void Op1027(void) // LBEQ -{ - uint16_t word = FetchW(); +#define OP_SUB_HANDLER(m, acc) \ + uint16_t sum = (uint16_t)acc - (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + acc = (uint8_t)sum; \ + SET_ZN(acc) - if (regs.cc & 0x04) - regs.pc += word; +#define OP_SUB_HANDLER16D(m) \ + uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \ + uint32_t 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) - regs.clock += 5; +static void Op80(void) // SUBA # +{ + uint8_t m = READ_IMM; + OP_SUB_HANDLER(m, regs.a); } -static void Op1028(void) // LBVC +static void Op83(void) // SUBD # { - uint16_t word = FetchW(); - - if (!(regs.cc & 0x02)) - regs.pc += word; - - regs.clock += 5; + uint16_t m = READ_IMM16; + OP_SUB_HANDLER16D(m); } -static void Op1029(void) // LBVS +static void Op90(void) // SUBA DP { - uint16_t word = FetchW(); + uint8_t m = READ_DP; + OP_SUB_HANDLER(m, regs.a); +} - if (regs.cc & 0x02) - regs.pc += word; +static void Op93(void) // SUBD DP +{ + uint16_t m = READ_DP16; + OP_SUB_HANDLER16D(m); +} - regs.clock += 5; +static void OpA0(void) // SUBA IDX +{ + uint8_t m = READ_IDX; + OP_SUB_HANDLER(m, regs.a); } -static void Op102A(void) // LBPL +static void OpA3(void) // SUBD IDX { - uint16_t word = FetchW(); + uint16_t m = READ_IDX16; + OP_SUB_HANDLER16D(m); +} - if (!(regs.cc & 0x08)) - regs.pc += word; +static void OpB0(void) // SUBA ABS +{ + uint8_t m = READ_ABS; + OP_SUB_HANDLER(m, regs.a); +} - regs.clock += 5; +static void OpB3(void) // SUBD ABS +{ + uint16_t m = READ_ABS16; + OP_SUB_HANDLER16D(m); } -static void Op102B(void) // LBMI +static void OpC0(void) // SUBB # { - uint16_t word = FetchW(); + uint8_t m = READ_IMM; + OP_SUB_HANDLER(m, regs.b); +} - if (regs.cc & 0x08) - regs.pc += word; +static void OpD0(void) // SUBB DP +{ + uint8_t m = READ_DP; + OP_SUB_HANDLER(m, regs.b); +} - regs.clock += 5; +static void OpE0(void) // SUBB IDX +{ + uint8_t m = READ_IDX; + OP_SUB_HANDLER(m, regs.b); } -static void Op102C(void) // LBGE +static void OpF0(void) // SUBB ABS { - uint16_t word = FetchW(); + uint8_t m = READ_ABS; + OP_SUB_HANDLER(m, regs.b); +} - if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; +/* + +-----------------------------------------------------------------+ + | 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- | +*/ - regs.clock += 5; -} +// TST opcodes -static void Op102D(void) // LBLT +#define OP_TST_HANDLER(m) \ + SET_ZN(m); \ + CLR_V + +static void Op0D(void) // TST DP { - uint16_t word = FetchW(); + uint8_t m = READ_DP; + OP_TST_HANDLER(m); +} - if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) - regs.pc += word; - regs.clock += 5; +static void Op4D(void) // TSTA +{ + OP_TST_HANDLER(regs.a); } -static void Op102E(void) // LBGT + +static void Op5D(void) // TSTB { - uint16_t word = FetchW(); + OP_TST_HANDLER(regs.b); +} - if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) - regs.pc += word; - regs.clock += 5; +static void Op6D(void) // TST IDX +{ + uint8_t m = READ_IDX; + OP_TST_HANDLER(m); } -static void Op102F(void) // LBLE + +static void Op7D(void) // TST ABS { - uint16_t word = FetchW(); - - if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; - - regs.clock += 5; -} - -static void Op103F(void) // SWI2 (Not yet implemented) -{ - regs.clock += 20; -} -static void Op1083(void) // CMPD # - { - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b; - uint16_t dw = dr - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((dr^addr^dw^((uint16_t)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op108C(void) // CMPY # - { - addr = FetchW(); - uint16_t dw = regs.y - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op108E(void) // LDY # - { - regs.y = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void Op1093(void) // CMPD DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b; - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = dr - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op109C(void) // CMPY DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.y - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } - -static void Op109E(void) // LDY DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } - -static void Op109F(void) // STY DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10A3(void) // CMPD IDX -{ - uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b; - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = dr - addr; - regs.cc &= 0xF0; // CLC CLV CLZ CLN - if (dr < addr) regs.cc |= 0x01; // Set Carry flag - if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow - if (dw == 0) regs.cc |= 0x04; // Set Zero flag - if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 7; -} -static void Op10AC(void) // CMPY IDX - { - uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.y - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op10AE(void) // LDY IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 6; -} -static void Op10AF(void) // STY IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10B3(void) // CMPD ABS - { - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b; - uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = dr - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; - } -static void Op10BC(void) // CMPY ABS - { - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.y - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; - } -static void Op10BE(void) // LDY ABS - { - addr = FetchW(); - regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 7; - } -static void Op10BF(void) // STY ABS - { - addr = FetchW(); - regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 7; - } -static void Op10CE(void) // LDS # - { - regs.s = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void Op10DE(void) // LDS DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10DF(void) // STS DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10EE(void) // LDS IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10EF(void) // STS IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10FE(void) // LDS ABS - { - addr = FetchW(); - regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 7; - } -static void Op10FF(void) // STS ABS -{ - addr = FetchW(); - regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 7; + uint8_t m = READ_ABS; + OP_TST_HANDLER(m); } + // -// Page two opcodes' execute code +// Undocumented Opcodes // - -static void Op113F(void) // SWI3 - { - regs.clock += 20; - } -static void Op1183(void) // CMPU # - { - addr = FetchW(); - uint16_t dw = regs.u - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op118C(void) // CMPS # - { - addr = FetchW(); - uint16_t dw = regs.s - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op1193(void) // CMPU DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.u - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op119C(void) // CMPS DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.s - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op11A3(void) // CMPU IDX - { - uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++)); - addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); - uint16_t dw = regs.u - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op11AC(void) // CMPS IDX - { - uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++)); - addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); - uint16_t dw = regs.s - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op11B3(void) // CMPU ABS - { - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.u - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; - } - -static void Op11BC(void) // CMPS ABS -{ - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.s - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; +static void Op01(void) +{ + Op00(); // NEG DP } + //temp, for testing... #ifdef __DEBUG__ static uint8_t backTrace[256]; static uint16_t btPC[256]; static int btPtr = 0;//*/ #endif -static void Op__(void) // Illegal opcode +static void Op__(void) // Illegal opcode { regs.clock++; // illegal = true; @@ -3063,6 +3312,98 @@ 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_t 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_t 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!) @@ -3075,6 +3416,7 @@ static void myMemcpy(void * dst, void * src, uint32_t size) d[i] = s[i]; } + // // Function to execute 6809 instructions // @@ -3087,28 +3429,25 @@ uint8_t backTrace[256]; V6809REGS btRegs[256]; bool tripped = false; #endif -#ifdef __DEBUG__ -//Here so this can be externally linked -bool disasm = false; -//bool disasm = true; -#endif void Execute6809(V6809REGS * context, uint32_t cycles) { - // If this is not in place, the clockOverrun calculations can cause the V6809 to get - // stuck in an infinite loop. - if (cycles == 0) // Nothing to do, so bail! + // If this is not in place, the clockOverrun calculations can cause the + // V6809 to get stuck in an infinite loop. + if (cycles == 0) return; myMemcpy(®s, context, sizeof(V6809REGS)); + // Explode flags register into individual uint8_ts + UNPACK_FLAGS; // Execute here... - // Since we can't guarantee that we'll execute the number of cycles passed in - // exactly, we have to keep track of how much we overran the number of cycles - // the last time we executed. Since we already executed those cycles, this time - // through we remove them from the cycles passed in in order to come out - // approximately even. Over the long run, this unevenness in execution times - // evens out. + // Since we can't guarantee that we'll execute the number of cycles passed + // in exactly, we have to keep track of how much we overran the number of + // cycles the last time we executed. Since we already executed those + // cycles, this time through we remove them from the cycles passed in in + // order to come out approximately even. Over the long run, this unevenness + // in execution times evens out. :-) uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun); while (regs.clock < endCycles) @@ -3138,8 +3477,16 @@ if (!tripped) } #endif #ifdef __DEBUG__ -//Decode6809(regs.pc); -if (disasm) Decode6809(regs); +if (disasm) +{ + Decode6809(regs); +// 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; @@ -3151,7 +3498,10 @@ 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_t opcode = regs.RdMem(regs.pc++); + exec_op0[opcode](); + regs.clock += page0Cycles[opcode]; // Handle any pending interrupts @@ -3164,7 +3514,7 @@ btPtr = (btPtr + 1) & 0xFF;//*/ #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; @@ -3175,22 +3525,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)... @@ -3201,18 +3548,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)... @@ -3224,56 +3571,49 @@ 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! -// Need to put IRQ handling in somewhere... It shouldn't be cleared here! // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } } #ifdef __DEBUG__ -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", - (regs.cc & FLAG_E ? "E" : "-"), (regs.cc & FLAG_F ? "F" : "-"), (regs.cc & FLAG_H ? "H" : "-"), - (regs.cc & FLAG_I ? "I" : "-"), (regs.cc & FLAG_N ? "N" : "-"), (regs.cc & FLAG_Z ? "Z" : "-"), - (regs.cc & FLAG_V ? "V" : "-"), (regs.cc & FLAG_C ? "C" : "-"), +if (disasm) WriteLog("CC=%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 } + // Keep track of how much we overran so we can adjust on the next run... regs.clockOverrun = (uint32_t)(regs.clock - endCycles); + regs.cc = PACK_FLAGS; // Mash flags back into the CC register myMemcpy(context, ®s, sizeof(V6809REGS)); - -#ifdef __DEBUG__ - if (disasm) - WriteLog("\n*** CONTEXT SWITCH ***\n\n"); -#endif } + // // Get the clock of the currently executing CPU // @@ -3282,6 +3622,7 @@ uint64_t GetCurrentV6809Clock(void) return regs.clock; } + // // Get the PC of the currently executing CPU // @@ -3290,12 +3631,14 @@ uint16_t GetCurrentV6809PC(void) return regs.pc; } + // Set a line of the currently executing CPU void SetLineOfCurrentV6809(uint32_t line) { regs.cpuFlags |= line; } + // Clear a line of the currently executing CPU void ClearLineOfCurrentV6809(uint32_t line) { @@ -3305,3 +3648,32 @@ if (disasm) #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