//
-// Virtual 6809 v1.3
+// Virtual 6809 v1.4.2
//
// by James Hammons
-// (c) 1997, 2014 Underground Software
+// (C) 1997, 2009, 2014, 2023 Underground Software
//
// JLH = James Hammons <jlhamm@acm.org>
//
// 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
-//
-
-// Mebbe someday I'll get around to fixing the core to be more like V65C02...
-// We have a start... ;-)
+// JLH 09/29/2009 Converted V6809 to macro implementation!
+// JLH 04/17/2014 Misc. cleanups, fixes to missing instructions
+// JLH 01/03/2023 Added missing clock cycles to indexed memory accesses
//
#include "v6809.h"
-#define __DEBUG__
-#ifdef __DEBUG__
-#include "dis6809.h" // Temporary...
-#include "log.h" // Temporary...
-#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))
-
-//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_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 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)
#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_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_ZN16(r) SET_N16(r); SET_Z(r)
-//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
+};
+
+// Cycle counts for PUL/PSHx instructions
+static uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
// 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;
retval = regs.b;
break;
case 10:
+ PACK_FLAGS;
retval = regs.cc;
break;
case 11:
//
// 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)
{
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;
//
// Function to decode IDX data
//
-uint16_t DecodeIDX(uint8_t code)
-{
+static uint16_t DecodeIDX(uint8_t code)
+{
+/*
+Cycle counts are now taken into account here...
+
+ 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+90 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+B0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+D0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+F0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
+
+80 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+A0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+C0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+E0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
+*/
uint16_t addr, woff;
+ int16_t offset;
uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
+ {
addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
+ regs.clock++;
+ }
else
{
if (idxind)
case 2: regs.u += 2; break;
case 3: regs.s += 2; break;
}
+ regs.clock += 6;
break;
case 3:
switch (reg)
}
woff = DecodeReg(reg);
addr = RdMemW(woff);
+ regs.clock += 6;
break;
case 4:
woff = DecodeReg(reg);
addr = RdMemW(woff);
+ regs.clock += 3;
break;
case 5:
woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 6:
woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 8:
woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 9:
- woff = DecodeReg(reg) + FetchW();
+ woff = DecodeReg(reg) + FetchMemW(regs.pc);
addr = RdMemW(woff);
+ regs.clock += 7;
break;
case 11:
woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
addr = RdMemW(woff);
+ regs.clock += 7;
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++);
+#if 1
+ // I believe this is the correct interpretation
+ offset = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+ woff = regs.pc + offset;
+#else
+ woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
+ regs.pc++;
+#endif
addr = RdMemW(woff);
+ regs.clock += 4;
break;
case 13:
- woff = regs.pc + FetchW();
+ woff = regs.pc + FetchMemW(regs.pc);
addr = RdMemW(woff);
+ regs.clock += 8;
break;
case 15:
- woff = FetchW();
+ woff = FetchMemW(regs.pc);
addr = RdMemW(woff);
+ regs.clock += 5;
break;
+ default:
+ addr = 0;
}
}
else
case 2: regs.u++; break;
case 3: regs.s++; break;
}
+ regs.clock += 2;
break;
case 1:
addr = DecodeReg(reg);
case 2: regs.u += 2; break;
case 3: regs.s += 2; break;
}
+ regs.clock += 3;
+ break;
+ case 2:
+ switch(reg)
+ {
+ case 0: regs.x--; break;
+ case 1: regs.y--; break;
+ case 2: regs.u--; break;
+ case 3: regs.s--; break;
+ }
+ addr = DecodeReg(reg);
+ regs.clock += 2;
+ break;
+ case 3:
+ switch(reg)
+ {
+ case 0: regs.x -= 2; break;
+ case 1: regs.y -= 2; break;
+ case 2: regs.u -= 2; break;
+ case 3: regs.s -= 2; break;
+ }
+ addr = DecodeReg(reg);
+ regs.clock += 3;
+ break;
+ case 4:
+ addr = DecodeReg(reg);
+ break;
+ case 5:
+ addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
+ regs.clock++;
+ break;
+ case 6:
+ addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
+ regs.clock++;
+ break;
+ case 8:
+ addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+ regs.clock++;
break;
- case 2: { switch(reg)
- {
- case 0: regs.x--; break;
- case 1: regs.y--; break;
- case 2: regs.u--; break;
- case 3: regs.s--; break;
- }
- addr = DecodeReg(reg); break; }
- case 3: { switch(reg)
- {
- case 0: regs.x--; regs.x--; break;
- case 1: regs.y--; regs.y--; break;
- case 2: regs.u--; regs.u--; break;
- case 3: regs.s--; regs.s--; break;
- }
- addr = DecodeReg(reg); break; }
- case 4: { addr = DecodeReg(reg); break; }
- 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 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 9:
+ addr = DecodeReg(reg) + FetchMemW(regs.pc);
+ regs.clock += 4;
+ break;
+ case 11:
+ addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);
+ regs.clock += 4;
+ break;
+ case 12:
+// addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
+#if 1
+ // I believe this is the correct interpretation of the above
+ offset = (int16_t)(int8_t)regs.RdMem(regs.pc++);
+ addr = regs.pc + offset;
+#else
+ addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
+ regs.pc++;
+#endif
+ regs.clock++;
+ break;
+ case 13:
+ addr = regs.pc + FetchMemW(regs.pc);
+ regs.clock += 5;
+ break;
+ default:
+ addr = 0;
}
}
}
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)
-static void Op00(void) // NEG DP
+static void Op89(void) // ADCA #
{
- addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
- tmp = 256 - regs.RdMem(addr);
- regs.WrMem(addr, tmp);
+ uint16_t m = READ_IMM;
+ OP_ADC_HANDLER(m, regs.a);
+}
- (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
- (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
- (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
+static void Op99(void) // ADCA DP
+{
+ uint16_t m = READ_DP;
+ OP_ADC_HANDLER(m, regs.a);
+}
- regs.clock += 6;
+static void OpA9(void) // ADCA IDX
+{
+ uint16_t m = READ_IDX;
+ OP_ADC_HANDLER(m, regs.a);
}
-static void Op01(void) // NEG DP (Undocumented)
+static void OpB9(void) // ADCA ABS
{
- Op00();
+ uint16_t m = READ_ABS;
+ OP_ADC_HANDLER(m, regs.a);
}
-static void Op03(void) // COM DP
+static void OpC9(void) // ADCB #
{
- addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
- tmp = 0xFF ^ regs.RdMem(addr);
- regs.WrMem(addr, tmp);
+ uint16_t m = READ_IMM;
+ OP_ADC_HANDLER(m, regs.b);
+}
- regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
- (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+static void OpD9(void) // ADCB DP
+{
+ uint16_t m = READ_DP;
+ OP_ADC_HANDLER(m, regs.b);
+}
- 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)
+
+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++);
-
- 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
+//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++);
+ // 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
+ 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++);
-
- if (!(regs.cc & 0x01))
- regs.pc += word;
+ // !C
+ int16_t offset = (int16_t)(int8_t)READ_IMM;
- 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++);
+ // 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;
+#else
+ if (flagC)
+ regs.pc += offset;
+#endif
}
static void Op26(void) // BNE
{
- 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 ^ 0x01);
+#else
+ if (!flagZ)
+ regs.pc += offset;
+#endif
}
static void Op27(void) // BEQ
{
- 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;
+#else
+ if (flagZ)
+ regs.pc += offset;
+#endif
}
static void Op28(void) // BVC
{
- 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 ^ 0x01);
+#else
+ if (!flagV)
+ regs.pc += offset;
+#endif
}
static void Op29(void) // BVS
{
- 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;
+#else
+ if (flagV)
+ regs.pc += offset;
+#endif
}
static void Op2A(void) // BPL
{
- 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 ^ 0x01);
+#else
+ if (!flagN)
+ regs.pc += offset;
+#endif
}
static void Op2B(void) // BMI
{
- 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;
+#else
+ if (flagN)
+ regs.pc += offset;
+#endif
}
static void Op2C(void) // BGE
{
- 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) | ((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++);
+ // (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 ^ 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++);
-
- if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
- regs.pc += word;
+ // (N && V && !Z) || (!N && !V && !Z)
+ int16_t offset = (int16_t)(int8_t)READ_IMM;
- 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++);
+ // Z || (N && !V) || (!N && V)
+ 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 * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
+#else
+ if (flagZ || (flagN && !flagV) || (!flagN && flagV))
+ regs.pc += offset;
+#endif
}
-static void Op30(void) // LEAX
-{
- regs.x = DecodeIDX(regs.RdMem(regs.pc++));
- (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- regs.clock += 4;
-}
-static void Op31(void) // LEAY
-{
- regs.y = DecodeIDX(regs.RdMem(regs.pc++));
- (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- regs.clock += 4;
-}
-static void Op32(void) // LEAS
-{
- regs.s = DecodeIDX(regs.RdMem(regs.pc++));
- (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- regs.clock += 4;
-}
-static void Op33(void) // LEAU
+static void Op1021(void) // LBRN
{
- regs.u = DecodeIDX(regs.RdMem(regs.pc++));
- (regs.u == 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 Op34(void) // PSHS
+
+static void Op1022(void) // LBHI
{
- 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;
+ // !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 Op35(void) // PULS
+
+static void Op1023(void) // LBLS
{
- 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;
+ // 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 Op36(void) // PSHU
+static void Op1024(void) // LBHS/CC
{
- tmp = regs.RdMem(regs.pc++);
+ // !C
+ uint16_t offset = READ_IMM16;
- 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);
+#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_LINE_RESET;
+}
+
+static void Op3F(void) // SWI
+{
+ flagE = 1;
+ regs.cc = PACK_FLAGS; // Mash flags into CC byte
+ PUSHS16(regs.pc);
+ PUSHS16(regs.u);
+ PUSHS16(regs.y);
+ PUSHS16(regs.x);
+ PUSHS(regs.dp);
+ PUSHS(regs.b);
+ PUSHS(regs.a);
+ PUSHS(regs.cc);
+ flagF = flagI = 1;
+ regs.pc = RdMemW(0xFFFA);
+}
+
+static void Op103F(void) // SWI2
+{
+ flagE = 1;
+ regs.cc = PACK_FLAGS; // Mash flags into CC byte
+ PUSHS16(regs.pc);
+ PUSHS16(regs.u);
+ PUSHS16(regs.y);
+ PUSHS16(regs.x);
+ PUSHS(regs.dp);
+ PUSHS(regs.b);
+ PUSHS(regs.a);
+ PUSHS(regs.cc);
+ regs.pc = RdMemW(0xFFF4);
+}
+
+static void Op113F(void) // SWI3
+{
+ flagE = 1;
+ regs.cc = PACK_FLAGS; // Mash flags into CC byte
+ PUSHS16(regs.pc);
+ PUSHS16(regs.u);
+ PUSHS16(regs.y);
+ PUSHS16(regs.x);
+ PUSHS(regs.dp);
+ PUSHS(regs.b);
+ PUSHS(regs.a);
+ PUSHS(regs.cc);
+ regs.pc = RdMemW(0xFFF2);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
+ | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
+ | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
+ | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
+ | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
+*/
+
+static void Op12() // NOP
+{
+}
+
+static void Op19() // DAA
+{
+ uint16_t result = (uint16_t)regs.a;
+
+ if ((regs.a & 0x0F) > 0x09 || flagH)
+ result += 0x06;
+
+ 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 Op39(void) // RTS
+{
+ PULLS16(regs.pc);
+}
+
+static void Op3B(void) // RTI
+{
+ PULLS(regs.cc);
+ UNPACK_FLAGS;
+
+ // If E flag set, pull all regs
+ if (flagE)
+ {
+ PULLS(regs.a);
+ PULLS(regs.b);
+ PULLS(regs.dp);
+ PULLS16(regs.x);
+ PULLS16(regs.y);
+ PULLS16(regs.u);
+ regs.clock += 9;
+ }
+
+ PULLS16(regs.pc);
+}
+
+static void Op6E(void) // JMP IDX
+{
+ regs.pc = EA_IDX;
+}
+
+static void Op7E(void) // JMP ABS
+{
+ regs.pc = EA_ABS;
+}
+
+static void Op8D(void) // BSR
+{
+ uint16_t word = (int16_t)(int8_t)READ_IMM;
+ PUSHS16(regs.pc);
+ regs.pc += word;
+}
+
+static void Op9D(void) // JSR DP
+{
+ uint16_t word = EA_DP;
+ PUSHS16(regs.pc);
+ regs.pc = word;
+}
+
+static void OpAD(void) // JSR IDX
+{
+ uint16_t word = EA_IDX;
+ PUSHS16(regs.pc);
+ regs.pc = word;
+}
+
+static void OpBD(void) // JSR ABS
+{
+ uint16_t word = EA_ABS;
+ PUSHS16(regs.pc);
+ regs.pc = word;
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
+ | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
+*/
+
+static void Op1E(void) // EXG
+{
+ // 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 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);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
+ | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
+ | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
+ | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
+ | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
+ | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
+ | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
+ | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
+ | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
+ | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
+ | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
+ | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
+ | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
+ | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
+ | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
+ | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
+ | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
+ | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
+ | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
+ | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
+ | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
+ | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
+ | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
+ | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
+ | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
+ | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
+ | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
+ | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
+*/
+
+// LDA opcodes
+
+#define OP_LDA_HANDLER(m, acc) \
+ acc = m; \
+ CLR_V; \
+ SET_ZN(acc)
+
+#define OP_LDA_HANDLER16(m, acc) \
+ acc = m; \
+ CLR_V; \
+ SET_ZN16(acc)
+
+#define OP_LDA_HANDLER16D(m) \
+ regs.a = (m >> 8); \
+ regs.b = m & 0xFF; \
+ CLR_V; \
+ SET_ZN16(m)
+
+static void Op86(void) // LDA #
+{
+ uint8_t m = READ_IMM;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void Op8E(void) // LDX #
+{
+ uint16_t m = READ_IMM16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void Op96(void) // LDA DP
+{
+ uint8_t m = READ_DP;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void Op9E(void) // LDX DP
+{
+ uint16_t m = READ_DP16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void OpA6(void) // LDA IDX
+{
+ uint8_t m = READ_IDX;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void OpAE(void) // LDX IDX
+{
+ uint16_t m = READ_IDX16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void OpB6(void) // LDA ABS
+{
+ uint8_t m = READ_ABS;
+ OP_LDA_HANDLER(m, regs.a);
+}
+
+static void OpBE(void) // LDX ABS
+{
+ uint16_t m = READ_ABS16;
+ OP_LDA_HANDLER16(m, regs.x);
+}
+
+static void OpC6(void) // LDB #
+{
+ uint8_t m = READ_IMM;
+ OP_LDA_HANDLER(m, regs.b);
+}
+
+static void OpCC(void) // LDD #
+{
+ 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
+
+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);
+}
- regs.clock += 5;
+static void OpCA(void) // ORB #
+{
+ uint8_t m = READ_IMM;
+ OP_OR_HANDLER(m, regs.b);
}
-static void Op37(void) // PULU
+static void OpDA(void) // ORB 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;
+ uint8_t m = READ_DP;
+ OP_OR_HANDLER(m, regs.b);
}
-static void Op39(void) // RTS
+
+static void OpEA(void) // ORB IDX
{
- regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
- regs.clock += 5;
+ uint8_t m = READ_IDX;
+ OP_OR_HANDLER(m, regs.b);
}
-static void Op3A(void) // ABX
+
+static void OpFA(void) // ORB ABS
{
- regs.x += regs.b;
- regs.clock += 3;
+ uint8_t m = READ_ABS;
+ OP_OR_HANDLER(m, regs.b);
}
-static void Op3B(void) // RTI
+
+/*
+ +-----------------------------------------------------------------+
+ | 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
{
- 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;
-}
-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 Op8C(void) // CMPX #
-{
- 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;
-}
-
-static void Op8D(void) // Bregs.s
-{
- 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;
+ uint8_t m = READ_IMM;
- 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 Op93(void) // SUBD 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;
-}
-static void Op94(void) // ANDA DP
-{
- 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;
-}
-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 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 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 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 OpA3(void) // SUBD IDX
-{
- 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;
-}
-static void OpA7(void) // STA IDX
-{
- 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;
-}
-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 OpAA(void) // ORA 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 OpAB(void) // ADDA IDX
-{
- 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;
-}
-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 OpB4(void) // ANDA ABS
-{
- 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;
-}
-static void OpB5(void) // BITA ABS
-{
- 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;
-}
-static void OpB6(void) // LDA 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;
-}
-static void OpB7(void) // STA ABS
-{
- 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;
-}
-static void OpB8(void) // EORA 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;
-}
-static void OpB9(void) // ADCA ABS
-{
- 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;
-}
-static void OpBA(void) // ORA 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;
-}
-static void OpBB(void) // ADDA ABS
-{
- 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;
-}
-static void OpBC(void) // CMPX ABS
-{
- 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;
-}
-static void OpBD(void) // JSR ABS
-{
- 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;
-}
-
-static void OpBE(void) // LDX ABS
-{
-// addr = FetchW();
-// regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
- regs.x = RdMemW(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 += 6;
-}
-
-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);
-
- 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 += 6;
-}
-
-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 #
-{
- 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;
-}
-static void OpC3(void) // ADDD #
-{
- addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
- dr += addr;
- (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
- dr &= 0xFFFF;
- (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
- ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
- regs.a = dr>>8; regs.b = dr&0xFF;
- regs.clock += 4;
-}
-static void OpC4(void) // ANDB #
- {
- regs.b &= regs.RdMem(regs.pc++);
- 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
-{
- 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;
-}
-static void OpD2(void) // SBCB DP
-{
- 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;
-}
-static void OpD3(void) // ADDD DP
-{
- addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
- uint16_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;
-}
-static void OpE1(void) // CMPB IDX
-{
- 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;
-}
-static void OpE2(void) // SBCB IDX
-{
- 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;
-}
-static void OpE3(void) // ADDD IDX
-{
- 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;
-}
-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;
- }
+ 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);
+ }
-//
-// Page one opcodes' execute code
-//
+ // Count bits in each nybble to come up with correct cycle counts...
+ regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
+}
-static void Op1021(void) // LBRN
+static void Op35(void) // PULS
{
- addr = FetchW();
+ 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...
+ 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);
+ }
- regs.clock += 5;
+ // Count bits in each nybble to come up with correct cycle counts...
+ regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
}
-static void Op1022(void) // LBHI
+static void Op37(void) // PULU
{
- uint16_t word = FetchW();
+ uint8_t m = READ_IMM;
- if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
- regs.pc += word;
+ 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);
- regs.clock += 5;
+ // Count bits in each nybble to come up with correct cycle counts...
+ regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
}
-static void Op1023(void) // LBLS
+/*
+ +-----------------------------------------------------------------+
+ | 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
+
+static void Op09(void) // ROL DP
{
- uint16_t word = FetchW();
+ uint8_t m;
+ READ_DP_WB(m);
+ OP_ROL_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+static void Op49(void) // ROLA
+{
+ OP_ROL_HANDLER(regs.a);
+}
- if ((regs.cc & 0x01) | (regs.cc & 0x04))
- regs.pc += word;
+static void Op59(void) // ROLB
+{
+ OP_ROL_HANDLER(regs.b);
+}
- regs.clock += 5;
+static void Op69(void) // ROL IDX
+{
+ uint8_t m;
+ READ_IDX_WB(m);
+ OP_ROL_HANDLER(m);
+ WRITE_BACK(m);
}
-static void Op1024(void) // LBCC (LBHS)
+static void Op79(void) // ROL ABS
{
- uint16_t word = FetchW();
+ uint8_t m;
+ READ_ABS_WB(m);
+ OP_ROL_HANDLER(m);
+ WRITE_BACK(m);
+}
- if (!(regs.cc & 0x01))
- regs.pc += word;
+/*
+ +-----------------------------------------------------------------+
+ | 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 |
+*/
- regs.clock += 5;
+// 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
+{
+ uint8_t m;
+ READ_DP_WB(m);
+ OP_ROR_HANDLER(m);
+ WRITE_BACK(m);
}
-static void Op1025(void) // LBCS (LBLO)
+static void Op46(void) // RORA
{
- uint16_t word = FetchW();
+ OP_ROR_HANDLER(regs.a);
+}
- if (regs.cc & 0x01)
- regs.pc += word;
+static void Op56(void) // RORB
+{
+ OP_ROR_HANDLER(regs.b);
+}
- regs.clock += 5;
+static void Op66(void) // ROR IDX
+{
+ uint8_t m;
+ READ_IDX_WB(m);
+ OP_ROR_HANDLER(m);
+ WRITE_BACK(m);
}
-static void Op1026(void) // LBNE
+static void Op76(void) // ROR ABS
{
- uint16_t word = FetchW();
+ uint8_t m;
+ READ_ABS_WB(m);
+ OP_ROR_HANDLER(m);
+ WRITE_BACK(m);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
+ | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
+ | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
+ | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
+ | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
+ | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
+ | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
+ | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
+*/
- if (!(regs.cc & 0x04))
- regs.pc += word;
+// SBC opcodes
- regs.clock += 5;
+#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 #
+{
+ uint8_t m = READ_IMM;
+ OP_SBC_HANDLER(m, regs.a);
}
-static void Op1027(void) // LBEQ
+static void Op92(void) // SBCA DP
{
- uint16_t word = FetchW();
+ uint8_t m = READ_DP;
+ OP_SBC_HANDLER(m, regs.a);
+}
- if (regs.cc & 0x04)
- regs.pc += word;
+static void OpA2(void) // SBCA IDX
+{
+ uint8_t m = READ_IDX;
+ OP_SBC_HANDLER(m, regs.a);
+}
- regs.clock += 5;
+static void OpB2(void) // SBCA ABS
+{
+ uint8_t m = READ_ABS;
+ OP_SBC_HANDLER(m, regs.a);
}
-static void Op1028(void) // LBVC
+static void OpC2(void) // SBCB #
{
- uint16_t word = FetchW();
+ uint8_t m = READ_IMM;
+ OP_SBC_HANDLER(m, regs.b);
+}
- if (!(regs.cc & 0x02))
- regs.pc += word;
+static void OpD2(void) // SBCB DP
+{
+ uint8_t m = READ_DP;
+ OP_SBC_HANDLER(m, regs.b);
+}
- regs.clock += 5;
+static void OpE2(void) // SBCB IDX
+{
+ uint8_t m = READ_IDX;
+ OP_SBC_HANDLER(m, regs.b);
}
-static void Op1029(void) // LBVS
+static void OpF2(void) // SBCB ABS
{
- uint16_t word = FetchW();
+ uint8_t m = READ_ABS;
+ OP_SBC_HANDLER(m, regs.b);
+}
- if (regs.cc & 0x02)
- regs.pc += word;
+/*
+ +-----------------------------------------------------------------+
+ | 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 += 5;
+// STA opcodes
+
+#define OP_STA_HANDLER(m, acc) \
+ regs.WrMem(m, acc); \
+ CLR_V; \
+ SET_ZN(acc)
+
+#define OP_STA_HANDLER16(m, acc) \
+ WrMemW(m, acc); \
+ CLR_V; \
+ SET_ZN16(acc)
+
+static void Op97(void) // STA DP
+{
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER(addr, regs.a);
}
-static void Op102A(void) // LBPL
+static void Op9F(void) // STX DP
+{
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.x);
+}
+
+static void OpA7(void) // STA IDX
{
- uint16_t word = FetchW();
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER(addr, regs.a);
+}
- if (!(regs.cc & 0x08))
- regs.pc += word;
+static void OpAF(void) // STX IDX
+{
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.x);
+}
- regs.clock += 5;
+static void OpB7(void) // STA ABS
+{
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER(addr, regs.a);
}
-static void Op102B(void) // LBMI
+static void OpBF(void) // STX ABS
{
- uint16_t word = FetchW();
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.x);
+}
- if (regs.cc & 0x08)
- regs.pc += word;
+static void OpD7(void) // STB DP
+{
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER(addr, regs.b);
+}
- regs.clock += 5;
+static void OpDD(void) // STD DP
+{
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
}
-static void Op102C(void) // LBGE
+static void OpDF(void) // STU DP
{
- uint16_t word = FetchW();
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.u);
+}
- if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
- regs.pc += word;
+static void OpE7(void) // STB IDX
+{
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER(addr, regs.b);
+}
- regs.clock += 5;
+static void OpED(void) // STD IDX
+{
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
}
-static void Op102D(void) // LBLT
+static void OpEF(void) // STU IDX
+{
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.u);
+}
+
+static void OpF7(void) // STB ABS
{
- uint16_t word = FetchW();
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER(addr, regs.b);
+}
- if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
- regs.pc += word;
+static void OpFD(void) // STD ABS
+{
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
+}
- regs.clock += 5;
+static void OpFF(void) // STU ABS
+{
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.u);
}
-static void Op102E(void) // LBGT
+static void Op109F(void) // STY DP
+{
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.y);
+}
+
+static void Op10AF(void) // STY IDX
{
- uint16_t word = FetchW();
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.y);
+}
- if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
- regs.pc += word;
+static void Op10BF(void) // STY ABS
+{
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.y);
+}
- regs.clock += 5;
+static void Op10DF(void) // STS DP
+{
+ uint16_t addr = EA_DP;
+ OP_STA_HANDLER16(addr, regs.s);
}
-static void Op102F(void) // LBLE
+static void Op10EF(void) // STS IDX
+{
+ uint16_t addr = EA_IDX;
+ OP_STA_HANDLER16(addr, regs.s);
+}
+
+static void Op10FF(void) // STS ABS
+{
+ uint16_t addr = EA_ABS;
+ OP_STA_HANDLER16(addr, regs.s);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
+ | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
+ | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
+ | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
+ | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
+ | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
+ | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
+ | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
+ | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
+ | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
+ | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
+ | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
+*/
+
+// SUB opcodes
+
+#define OP_SUB_HANDLER(m, acc) \
+ uint16_t sum = (uint16_t)acc - (m); \
+ flagC = (sum >> 8) & 0x01; \
+ SET_V(m, acc, sum); \
+ acc = (uint8_t)sum; \
+ SET_ZN(acc)
+
+#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)
+
+static void Op80(void) // SUBA #
+{
+ uint8_t m = READ_IMM;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void Op83(void) // SUBD #
+{
+ uint16_t m = READ_IMM16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void Op90(void) // SUBA DP
+{
+ uint8_t m = READ_DP;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void Op93(void) // SUBD DP
+{
+ uint16_t m = READ_DP16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void OpA0(void) // SUBA IDX
+{
+ uint8_t m = READ_IDX;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void OpA3(void) // SUBD IDX
+{
+ uint16_t m = READ_IDX16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void OpB0(void) // SUBA ABS
+{
+ uint8_t m = READ_ABS;
+ OP_SUB_HANDLER(m, regs.a);
+}
+
+static void OpB3(void) // SUBD ABS
+{
+ uint16_t m = READ_ABS16;
+ OP_SUB_HANDLER16D(m);
+}
+
+static void OpC0(void) // SUBB #
+{
+ uint8_t m = READ_IMM;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+static void OpD0(void) // SUBB DP
+{
+ uint8_t m = READ_DP;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+static void OpE0(void) // SUBB IDX
+{
+ uint8_t m = READ_IDX;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+static void OpF0(void) // SUBB ABS
+{
+ uint8_t m = READ_ABS;
+ OP_SUB_HANDLER(m, regs.b);
+}
+
+/*
+ +-----------------------------------------------------------------+
+ | Opcode | | Addressing | | |
+ | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
+ +------------+-------------+--------------+-------+-------+-------+
+ | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
+ | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
+ | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
+ | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
+ | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
+*/
+
+// TST opcodes
+
+#define OP_TST_HANDLER(m) \
+ SET_ZN(m); \
+ CLR_V
+
+static void Op0D(void) // TST DP
{
- 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_DP;
+ OP_TST_HANDLER(m);
+}
+
+static void Op4D(void) // TSTA
+{
+ OP_TST_HANDLER(regs.a);
+}
+
+static void Op5D(void) // TSTB
+{
+ OP_TST_HANDLER(regs.b);
+}
+
+static void Op6D(void) // TST IDX
+{
+ uint8_t m = READ_IDX;
+ OP_TST_HANDLER(m);
+}
+
+static void Op7D(void) // TST ABS
+{
+ uint8_t m = READ_ABS;
+ OP_TST_HANDLER(m);
}
//
-// Page two opcodes' execute code
+// Undocumented Opcodes
//
+static void Op01(void)
+{
+ Op00(); // NEG DP
+}
-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;
-}
-
-//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;
regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
-#ifdef __DEBUG__
-/*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
-for(int i=0; i<256; i++)
+}
+
+//
+// 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)
{
- Decode6809(btPC[(btPtr + i) & 0xFF]);
- WriteLog("\n");
-}//*/
-#endif
+ uint8_t opcode = regs.RdMem(regs.pc++);
+ exec_op1[opcode]();
+ regs.clock += page1Cycles[opcode];
}
+// Page 2 opcode
+static void Op11(void)
+{
+ 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!)
//
// Function to execute 6809 instructions
//
-//#define DEBUG_ILLEGAL
-#ifdef DEBUG_ILLEGAL
-#include "log.h"
-#include "dis6809.h"
-uint8_t btPtr = 0;
-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 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!
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)
{
-#ifdef DEBUG_ILLEGAL
-if (!tripped)
-{
- backTrace[btPtr] = regs.RdMem(regs.pc);
- btRegs[btPtr] = regs;
- btPtr = (btPtr + 1) & 0xFF;
-
- if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
- {
- WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
- regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
-
- for(uint16_t i=btPtr; i<btPtr+256; i++)
- {
- Decode6809(btRegs[i & 0xFF].pc);
-// Note that these values are *before* execution, so stale...
- WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
- btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
- }
-
- tripped = true;
- }
-}
-#endif
-#ifdef __DEBUG__
-//Decode6809(regs.pc);
-if (disasm) Decode6809(regs);
-/*//if (regs.pc == 0x15BA) disasm = true;
-//if (regs.pc == 0xFE76) disasm = true;
-if (regs.x == 0xFED4) disasm = true;
-if (disasm) Decode6809(regs.pc);
-//if (regs.pc == 0x164A) disasm = false;//*/
-
-//temp, for testing...
-/*backTrace[btPtr] = regs.RdMem(regs.pc);
-btPC[btPtr] = regs.pc;
-btPtr = (btPtr + 1) & 0xFF;//*/
-#endif
- exec_op0[regs.RdMem(regs.pc++)]();
+ uint8_t opcode = regs.RdMem(regs.pc++);
+ exec_op0[opcode]();
+ regs.clock += page0Cycles[opcode];
// Handle any pending interrupts
// uint32_t flags = context->cpuFlags;
uint32_t flags = regs.cpuFlags;
- if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
+ // *** RESET handler ***
+ if (flags & V6809_LINE_RESET)
{
-#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;
- regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
+ context->cpuFlags &= ~V6809_LINE_RESET;
+ regs.cpuFlags &= ~V6809_LINE_RESET;
}
- else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
+ // *** NMI handler ***
+ else if (flags & V6809_LINE_NMI)
{
-#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)...
-// regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
}
- else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
+ // *** FIRQ handler ***
+ else if (flags & V6809_LINE_FIRQ)
{
-#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)...
-// regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
}
}
- else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
+ // *** IRQ handler ***
+ else if (flags & V6809_LINE_IRQ)
{
-#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" : "-"),
- 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
}
//
// Clear a line of the currently executing CPU
void ClearLineOfCurrentV6809(uint32_t line)
{
-#ifdef __DEBUG__
-if (disasm)
- WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
-#endif
regs.cpuFlags &= ~line;
}
+