5 // (c) 1997, 2014 Underground Software
7 // JLH = James Hammons <jlhamm@acm.org>
10 // --- ---------- -----------------------------------------------------------
11 // JLH 06/15/2006 Added changelog ;-)
12 // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code
13 // JLH 11/11/2006 Removed all SignedX() references
16 // Mebbe someday I'll get around to fixing the core to be more like V65C02...
17 // We have a start... ;-)
24 #include "dis6809.h" // Temporary...
25 #include "log.h" // Temporary...
30 #define CLR_Z (regs.cc &= ~FLAG_Z)
31 #define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N))
32 #define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C))
33 #define CLR_V (regs.cc &= ~FLAG_V)
34 #define CLR_N (regs.cc &= ~FLAG_N)
35 #define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z))
36 #define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
38 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
39 #define SET_C_ADD(a,b) (regs.cc = ((uint8_t)(b) > (uint8_t)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
40 //#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
41 #define SET_C_CMP(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
42 #define SET_ZN(r) SET_N(r); SET_Z(r)
43 #define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
44 //#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
45 #define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b)
47 //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
48 //Hmm, why not do like we did for READ_ABS*???
49 //Because the EA_* macros are usually used as an argument to a function call, that's why.
50 #define EA_IMM regs.pc++
51 #define EA_ZP regs.RdMem(regs.pc++)
52 #define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) & 0xFF
53 #define EA_ZP_Y (regs.RdMem(regs.pc++) + regs.y) & 0xFF
54 #define EA_ABS RdMemW(regs.pc)
55 #define EA_ABS_X RdMemW(regs.pc) + regs.x
56 #define EA_ABS_Y RdMemW(regs.pc) + regs.y
57 #define EA_IND_ZP_X RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF)
58 #define EA_IND_ZP_Y RdMemW(regs.RdMem(regs.pc++)) + regs.y
59 #define EA_IND_ZP RdMemW(regs.RdMem(regs.pc++))
61 #define READ_IMM regs.RdMem(EA_IMM)
62 #define READ_ZP regs.RdMem(EA_ZP)
63 #define READ_ZP_X regs.RdMem(EA_ZP_X)
64 #define READ_ZP_Y regs.RdMem(EA_ZP_Y)
65 #define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2
66 #define READ_ABS_X regs.RdMem(EA_ABS_X); regs.pc += 2
67 #define READ_ABS_Y regs.RdMem(EA_ABS_Y); regs.pc += 2
68 #define READ_IND_ZP_X regs.RdMem(EA_IND_ZP_X)
69 #define READ_IND_ZP_Y regs.RdMem(EA_IND_ZP_Y)
70 #define READ_IND_ZP regs.RdMem(EA_IND_ZP)
72 #define READ_IMM_WB(v) uint16_t addr = EA_IMM; v = regs.RdMem(addr)
73 #define READ_ZP_WB(v) uint16_t addr = EA_ZP; v = regs.RdMem(addr)
74 #define READ_ZP_X_WB(v) uint16_t addr = EA_ZP_X; v = regs.RdMem(addr)
75 #define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2
76 #define READ_ABS_X_WB(v) uint16_t addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2
77 #define READ_ABS_Y_WB(v) uint16_t addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2
78 #define READ_IND_ZP_X_WB(v) uint16_t addr = EA_IND_ZP_X; v = regs.RdMem(addr)
79 #define READ_IND_ZP_Y_WB(v) uint16_t addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
80 #define READ_IND_ZP_WB(v) uint16_t addr = EA_IND_ZP; v = regs.RdMem(addr)
82 #define WRITE_BACK(d) regs.WrMem(addr, (d))
84 // Private global variables
86 static V6809REGS regs;
87 //Let's see if we can nuke this shit.
88 static uint16_t addr; // Temporary variables common to all funcs...
91 // Private function prototypes
93 static uint16_t FetchW(void);
94 static uint16_t RdMemW(uint16_t addr);
95 static void WrMemW(uint16_t addr, uint16_t w);
96 static uint16_t ReadEXG(uint8_t); // Read TFR/EXG post byte
97 static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data
98 static uint16_t DecodeReg(uint8_t); // Decode register data
99 static uint16_t DecodeIDX(uint8_t); // Decode IDX data
101 //static void (* exec_op1[256])();
102 //static void (* exec_op2[256])();
105 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
106 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
107 // even *try* to see if they're there).
109 #define FD(x) static void Op##x(); // FD -> "Forward Declaration"
110 #define FE(x) static void Op10##x();
111 #define FF(x) static void Op11##x();
113 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)
114 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)
115 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)
116 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)
117 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)
118 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)
119 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)
120 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)
121 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)
122 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)
123 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)
124 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)
125 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)
126 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)
127 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)
128 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)
131 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)
132 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)
133 FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
135 FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
143 // We can move these down and do away with the forward declarations... !!! FIX !!!
144 // Actually, we can't because these are used in a couple of the opcode functions.
145 // Have to think about how to fix that...
151 // Array of page zero opcode functions...
152 static void (* exec_op0[256])() = {
153 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
154 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
155 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
156 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
157 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
158 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
159 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
160 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
161 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
162 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
163 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
164 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
165 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
166 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
167 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
168 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
171 // Array of page one opcode functions...
172 static void (* exec_op1[256])() = {
173 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
174 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
175 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
176 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
177 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
178 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
179 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
180 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
181 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
182 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
183 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
184 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
185 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
186 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
187 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
188 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
191 // Array of page two opcode functions...
192 static void (* exec_op2[256])() = {
193 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
194 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
195 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
196 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
197 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
198 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
199 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
200 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
201 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
202 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
203 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
204 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
205 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
206 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
207 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
208 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
213 // Fetch a word out of 6809 memory (little endian format)
214 // This is a leftover from when fetches were separated from garden variety reads...
216 static uint16_t FetchW()
218 uint16_t w = RdMemW(regs.pc);
224 // Read word from memory function
226 uint16_t RdMemW(uint16_t addr)
228 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
232 // Write word to memory function
234 void WrMemW(uint16_t addr, uint16_t w)
236 regs.WrMem(addr + 0, w >> 8);
237 regs.WrMem(addr + 1, w & 0xFF);
241 // Function to read TFR/EXG post byte
243 uint16_t ReadEXG(uint8_t code)
250 retval = (regs.a << 8) | regs.b;
287 // Function to set TFR/EXG data
289 void WriteEXG(uint8_t code, uint16_t data)
294 regs.a = data >> 8, regs.b = data & 0xFF; break;
296 regs.x = data; break;
298 regs.y = data; break;
300 regs.u = data; break;
302 regs.s = data; break;
304 regs.pc = data; break;
306 regs.a = data & 0xFF; break;
308 regs.b = data & 0xFF; break;
310 regs.cc = data & 0xFF; break;
312 regs.dp = data & 0xFF; break;
317 // Function to decode register data
319 uint16_t DecodeReg(uint8_t reg)
326 retval = regs.x; break;
328 retval = regs.y; break;
330 retval = regs.u; break;
332 retval = regs.s; break;
339 // Function to decode IDX data
341 uint16_t DecodeIDX(uint8_t code)
344 uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
346 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
347 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
355 woff = DecodeReg(reg);
359 case 0: regs.x += 2; break;
360 case 1: regs.y += 2; break;
361 case 2: regs.u += 2; break;
362 case 3: regs.s += 2; break;
368 case 0: regs.x -= 2; break;
369 case 1: regs.y -= 2; break;
370 case 2: regs.u -= 2; break;
371 case 3: regs.s -= 2; break;
373 woff = DecodeReg(reg);
377 woff = DecodeReg(reg);
381 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
385 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
389 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
393 woff = DecodeReg(reg) + FetchW();
397 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
401 woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
405 woff = regs.pc + FetchW();
419 addr = DecodeReg(reg);
422 case 0: regs.x++; break;
423 case 1: regs.y++; break;
424 case 2: regs.u++; break;
425 case 3: regs.s++; break;
429 addr = DecodeReg(reg);
432 case 0: regs.x += 2; break;
433 case 1: regs.y += 2; break;
434 case 2: regs.u += 2; break;
435 case 3: regs.s += 2; break;
438 case 2: { switch(reg)
440 case 0: regs.x--; break;
441 case 1: regs.y--; break;
442 case 2: regs.u--; break;
443 case 3: regs.s--; break;
445 addr = DecodeReg(reg); break; }
446 case 3: { switch(reg)
448 case 0: regs.x--; regs.x--; break;
449 case 1: regs.y--; regs.y--; break;
450 case 2: regs.u--; regs.u--; break;
451 case 3: regs.s--; regs.s--; break;
453 addr = DecodeReg(reg); break; }
454 case 4: { addr = DecodeReg(reg); break; }
455 case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; }
456 case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; }
457 case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
458 case 9: { addr = DecodeReg(reg) + FetchW(); break; }
459 case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
460 case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
461 case 13: { addr = regs.pc + FetchW(); break; }
470 // Page zero instructions...
473 static void Op00(void) // NEG DP
475 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
476 tmp = 256 - regs.RdMem(addr);
477 regs.WrMem(addr, tmp);
479 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
480 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
481 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
482 (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
487 static void Op01(void) // NEG DP (Undocumented)
492 static void Op03(void) // COM DP
494 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
495 tmp = 0xFF ^ regs.RdMem(addr);
496 regs.WrMem(addr, tmp);
498 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
499 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
500 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
505 static void Op04(void) // LSR DP
507 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
508 tmp = regs.RdMem(addr);
509 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
510 tmp >>= 1; regs.WrMem(addr, tmp);
511 regs.cc &= 0xF7; // CLN
512 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
515 static void Op06(void) // ROR DP
517 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8_t tmp2 = regs.RdMem(addr);
518 tmp = (tmp2>>1) + (regs.cc&0x01)*128;
519 regs.WrMem(addr, tmp);
520 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
521 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
522 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
525 static void Op07(void) // ASR DP
527 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
528 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
530 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
531 regs.WrMem(addr, tmp);
532 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
533 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
536 static void Op08(void) // LSL DP
538 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
539 tmp = regs.RdMem(addr);
540 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
542 regs.WrMem(addr, tmp);
543 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
544 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
547 static void Op09(void) // ROL DP
549 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8_t tmp2 = regs.RdMem(addr);
550 tmp = (tmp2<<1) + (regs.cc&0x01);
551 regs.WrMem(addr, tmp);
552 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
553 ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
554 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
555 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
558 static void Op0A(void) // DEC DP
560 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
561 tmp = regs.RdMem(addr) - 1;
562 regs.WrMem(addr, tmp);
563 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
564 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
565 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
568 static void Op0C(void) // INC DP
570 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
571 tmp = regs.RdMem(addr) + 1;
572 regs.WrMem(addr, tmp);
573 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
574 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
575 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
578 static void Op0D(void) // TST DP
580 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
581 regs.cc &= 0xFD; // CLV
582 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
583 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
586 static void Op0E(void) // JMP DP
588 regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
591 static void Op0F(void) // CLR DP
593 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
594 regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
598 static void Op10(void) // Page 1 opcode
600 exec_op1[regs.RdMem(regs.pc++)]();
603 static void Op11(void) // Page 2 opcode
605 exec_op2[regs.RdMem(regs.pc++)]();
608 static void Op12(void) // NOP
613 static void Op13(void) // SYNC
615 // Fix this so it does the right thing (software interrupt!)
619 static void Op16(void) // LBRA
621 // regs.pc += SignedW(FetchW());
622 regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities
627 static void Op17(void) // LBSR
629 uint16_t word = FetchW();
630 regs.WrMem(--regs.s, regs.pc & 0xFF);
631 regs.WrMem(--regs.s, regs.pc >> 8);
632 // regs.pc += SignedW(addr);
633 regs.pc += word; // No need to make signed, both are 16 bit
638 static void Op19(void) // DAA
641 uint8_t result = regs.a;
643 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
647 regs.cc |= 0x20; // Then adjust & set half carry
650 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
654 regs.cc |= 0x01; // Then adjust & set carry
659 regs.cc &= 0xF1; // CL NZV
660 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
661 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
663 uint16_t result = (uint16_t)regs.a;
665 if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
668 if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
671 regs.a = (uint8_t)result;
673 // CLR_V; // Not sure this is correct...
674 regs.cc &= 0xF1; // CL NZV
675 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
676 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
677 // flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
678 regs.cc |= (result & 0x100) > 8;
683 static void Op1A(void) // ORCC #
685 regs.cc |= regs.RdMem(regs.pc++);
690 static void Op1C(void) // ANDCC #
692 regs.cc &= regs.RdMem(regs.pc++);
697 static void Op1D(void) // SEX
699 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
701 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
702 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
707 static void Op1E(void) // EXG
709 tmp = regs.RdMem(regs.pc++);
710 addr = ReadEXG(tmp >> 4);
711 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
712 WriteEXG(tmp & 0xF, addr);
717 static void Op1F(void) // TFR
719 tmp = regs.RdMem(regs.pc++);
720 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
724 static void Op20(void) // BRA
726 // regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
727 regs.pc += (int16_t)(int8_t)regs.RdMem(regs.pc) + 1; // Branch always
732 static void Op21(void) // BRN
734 regs.RdMem(regs.pc++);
739 static void Op22(void) // BHI
741 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
743 if (!(regs.cc & 0x05))
749 static void Op23(void) // BLS
751 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
759 static void Op24(void) // BCC (BHS)
761 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
763 if (!(regs.cc & 0x01))
769 static void Op25(void) // BCS (BLO)
771 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
779 static void Op26(void) // BNE
781 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
783 if (!(regs.cc & 0x04))
789 static void Op27(void) // BEQ
791 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
799 static void Op28(void) // BVC
801 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
803 if (!(regs.cc & 0x02))
809 static void Op29(void) // BVS
811 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
819 static void Op2A(void) // BPL
821 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
823 if (!(regs.cc & 0x08))
829 static void Op2B(void) // BMI
831 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
839 static void Op2C(void) // BGE
841 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
843 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
849 static void Op2D(void) // BLT
851 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
853 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
859 static void Op2E(void) // BGT
861 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
863 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
869 static void Op2F(void) // BLE
871 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
873 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
879 static void Op30(void) // LEAX
881 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
882 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
885 static void Op31(void) // LEAY
887 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
888 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
891 static void Op32(void) // LEAS
893 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
894 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
897 static void Op33(void) // LEAU
899 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
900 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
903 static void Op34(void) // PSHS
905 tmp = regs.RdMem(regs.pc++);
906 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
907 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
908 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
909 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
910 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
911 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
912 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
913 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
916 static void Op35(void) // PULS
918 tmp = regs.RdMem(regs.pc++);
919 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
920 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
921 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
922 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
923 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
924 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
925 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
926 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
930 static void Op36(void) // PSHU
932 tmp = regs.RdMem(regs.pc++);
934 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
935 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
936 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
937 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
938 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
939 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
940 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
941 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
946 static void Op37(void) // PULU
948 tmp = regs.RdMem(regs.pc++);
949 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
950 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
951 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
952 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
953 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
954 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
955 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
956 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
959 static void Op39(void) // RTS
961 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
964 static void Op3A(void) // ABX
969 static void Op3B(void) // RTI
971 regs.cc = regs.RdMem(regs.s++);
972 if (regs.cc&0x80) // If E flag set, pull all regs
974 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
975 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
976 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
977 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
984 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
986 static void Op3C(void) // CWAI
988 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
989 regs.clock += 1000000; // Force interrupt
991 static void Op3D(void) // MUL
993 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
994 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
995 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
998 static void Op3E(void) // RESET
1001 static void Op3F(void) // SWI
1004 static void Op40(void) // NEGA
1006 regs.a = 256 - regs.a;
1007 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1008 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1009 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1010 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1013 static void Op43(void) // COMA
1016 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1017 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1018 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1021 static void Op44(void) // LSRA
1023 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1025 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1026 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1029 static void Op46(void) // RORA
1031 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
1032 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1033 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1034 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1037 static void Op47(void) // ASRA
1039 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1040 regs.a >>= 1; // Do the shift
1041 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
1042 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1043 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1046 static void Op48(void) // LSLA [Keep checking from here...]
1048 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1050 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1051 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1054 static void Op49(void) // ROLA
1056 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
1057 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1058 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1059 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1062 static void Op4A(void) // DECA
1065 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1066 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1067 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1070 static void Op4C(void) // INCA
1073 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1074 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1075 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1078 static void Op4D(void) // TSTA
1080 regs.cc &= 0xFD; // Clear oVerflow flag
1081 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1082 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1085 static void Op4F(void) // CLRA
1088 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1091 static void Op50(void) // NEGB
1093 regs.b = 256 - regs.b;
1094 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1095 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1096 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1097 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1098 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1101 static void Op53(void) // COMB
1104 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1105 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1106 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1109 static void Op54(void) // LSRB
1111 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1113 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1114 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1117 static void Op56(void) // RORB
1119 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
1120 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
1121 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1122 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1125 static void Op57(void) // ASRB
1127 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1128 regs.b >>= 1; // Do the shift
1129 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
1130 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1131 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1134 static void Op58(void) // LSLB
1136 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1138 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1139 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1142 static void Op59(void) // ROLB
1145 regs.b = (tmp<<1) + (regs.cc&0x01);
1146 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1147 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1148 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1151 static void Op5A(void) // DECB
1154 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1155 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1156 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1159 static void Op5C(void) // INCB
1162 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1163 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1164 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1167 static void Op5D(void) // TSTB
1169 regs.cc &= 0xFD; // Clear oVerflow flag
1170 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1171 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1174 static void Op5F(void) // CLRB
1177 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1180 static void Op60(void) // NEG IDX
1182 addr = DecodeIDX(regs.RdMem(regs.pc++));
1183 tmp = regs.RdMem(addr); uint8_t res = 256 - tmp;
1184 regs.WrMem(addr, res);
1185 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1186 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1187 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1188 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1189 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1192 static void Op63(void) // COM IDX
1194 addr = DecodeIDX(regs.RdMem(regs.pc++));
1195 tmp = regs.RdMem(addr) ^ 0xFF;
1196 regs.WrMem(addr, tmp);
1197 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1198 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1199 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1202 static void Op64(void) // LSR IDX
1204 addr = DecodeIDX(regs.RdMem(regs.pc++));
1205 tmp = regs.RdMem(addr);
1206 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1207 tmp >>= 1; regs.WrMem(addr, tmp);
1208 regs.cc &= 0xF7; // CLN
1209 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1212 static void Op66(void) // ROR IDX
1214 addr = DecodeIDX(regs.RdMem(regs.pc++));
1215 tmp = regs.RdMem(addr); uint8_t tmp2 = tmp;
1216 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1217 regs.WrMem(addr, tmp);
1218 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1219 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1220 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1223 static void Op67(void) // ASR IDX
1225 addr = DecodeIDX(regs.RdMem(regs.pc++));
1226 tmp = regs.RdMem(addr);
1227 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1229 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1230 regs.WrMem(addr, tmp);
1231 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1232 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1235 static void Op68(void) // LSL IDX
1237 addr = DecodeIDX(regs.RdMem(regs.pc++));
1238 tmp = regs.RdMem(addr);
1239 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1241 regs.WrMem(addr, tmp);
1242 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1243 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1246 static void Op69(void) // ROL IDX
1248 uint8_t tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1249 tmp = (tmp2<<1) + (regs.cc&0x01);
1250 regs.WrMem(addr, tmp);
1251 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1252 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1253 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1256 static void Op6A(void) // DEC IDX
1258 uint8_t tmp; uint16_t addr;
1259 addr = DecodeIDX(regs.RdMem(regs.pc++));
1260 tmp = regs.RdMem(addr) - 1;
1261 regs.WrMem(addr, tmp);
1262 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1263 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1264 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1267 static void Op6C(void) // INC IDX
1269 addr = DecodeIDX(regs.RdMem(regs.pc++));
1270 tmp = regs.RdMem(addr) + 1;
1271 regs.WrMem(addr, tmp);
1272 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1273 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1274 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1277 static void Op6D(void) // TST IDX
1279 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1280 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1281 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1284 static void Op6E(void) // JMP IDX
1286 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1289 static void Op6F(void) // CLR IDX
1291 addr = DecodeIDX(regs.RdMem(regs.pc++));
1292 regs.WrMem(addr, 0);
1293 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1296 static void Op70(void) // NEG ABS
1299 tmp = regs.RdMem(addr); uint8_t res = 256 - tmp;
1300 regs.WrMem(addr, res);
1301 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1302 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1303 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1304 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1307 static void Op73(void) // COM ABS
1310 tmp = regs.RdMem(addr) ^ 0xFF;
1311 regs.WrMem(addr, tmp);
1312 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1313 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1314 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1317 static void Op74(void) // LSR ABS
1320 tmp = regs.RdMem(addr);
1321 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1322 tmp >>= 1; regs.WrMem(addr, tmp);
1323 regs.cc &= 0xF7; // CLN
1324 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1327 static void Op76(void) // ROR ABS
1329 uint8_t tmp; uint16_t addr;
1331 tmp = regs.RdMem(addr); uint8_t tmp2 = tmp;
1332 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1333 regs.WrMem(addr, tmp);
1334 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1335 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1336 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1339 static void Op77(void) // ASR ABS
1341 uint8_t tmp; uint16_t addr;
1343 tmp = regs.RdMem(addr);
1344 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1346 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1347 regs.WrMem(addr, tmp);
1348 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1349 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1352 static void Op78(void) // LSL ABS
1354 uint8_t tmp; uint16_t addr;
1356 tmp = regs.RdMem(addr);
1357 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1359 regs.WrMem(addr, tmp);
1360 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1361 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1364 static void Op79(void) // ROL ABS
1366 uint8_t tmp2 = regs.RdMem(FetchW());
1367 tmp = (tmp2<<1) + (regs.cc&0x01);
1368 regs.WrMem(addr, tmp);
1369 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1370 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1371 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1374 static void Op7A(void) // DEC ABS
1376 uint8_t tmp; uint16_t addr;
1378 tmp = regs.RdMem(addr) - 1;
1379 regs.WrMem(addr, tmp);
1380 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1381 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1382 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1385 static void Op7C(void) // INC ABS
1387 uint8_t tmp; uint16_t addr;
1389 tmp = regs.RdMem(addr) + 1;
1390 regs.WrMem(addr, tmp);
1391 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1392 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1393 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1397 static void Op7D(void) // TST ABS
1399 uint8_t tmp = regs.RdMem(FetchW());
1401 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1402 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1407 static void Op7E(void) // JMP ABS
1412 static void Op7F(void) // CLR ABS
1414 regs.WrMem(FetchW(), 0);
1415 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1418 static void Op80(void) // SUBA #
1420 uint8_t tmp = regs.RdMem(regs.pc++); uint8_t as = regs.a;
1422 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1423 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1424 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1425 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1428 static void Op81(void) // CMPA #
1430 tmp = regs.RdMem(regs.pc++);
1431 uint8_t db = regs.a - tmp;
1432 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1433 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1434 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1435 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1438 static void Op82(void) // SBCA #
1440 tmp = regs.RdMem(regs.pc++); uint8_t as = regs.a;
1441 regs.a = regs.a - tmp - (regs.cc&0x01);
1442 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1443 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1444 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1445 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1448 static void Op83(void) // SUBD #
1450 addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1452 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1453 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1454 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1455 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1456 regs.a = dr>>8; regs.b = dr&0xFF;
1459 static void Op84(void) // ANDA #
1461 regs.a &= regs.RdMem(regs.pc++);
1462 regs.cc &= 0xFD; // Clear oVerflow flag
1463 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1464 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1467 static void Op85(void) // BITA #
1469 tmp = regs.a & regs.RdMem(regs.pc++);
1470 regs.cc &= 0xFD; // Clear oVerflow flag
1471 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1472 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1475 static void Op86(void) // LDA #
1477 regs.a = regs.RdMem(regs.pc++);
1478 regs.cc &= 0xFD; // CLV
1479 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1480 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1483 static void Op88(void) // EORA #
1485 regs.a ^= regs.RdMem(regs.pc++);
1486 regs.cc &= 0xFD; // CLV
1487 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1488 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1491 static void Op89(void) // ADCA #
1493 tmp = regs.RdMem(regs.pc++);
1494 addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1495 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1496 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1497 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1498 regs.a = addr & 0xFF; // Set accumulator
1499 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1500 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1503 static void Op8A(void) // ORA #
1505 regs.a |= regs.RdMem(regs.pc++);
1506 regs.cc &= 0xFD; // CLV
1507 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1508 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1511 static void Op8B(void) // ADDA #
1513 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
1514 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1515 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1516 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1517 regs.a = addr & 0xFF; // Set accumulator
1518 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1519 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1522 static void Op8C(void) // CMPX #
1525 uint16_t dw = regs.x - addr;
1526 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1527 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1528 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1529 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1533 static void Op8D(void) // Bregs.s
1535 uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
1536 regs.WrMem(--regs.s, regs.pc & 0xFF);
1537 regs.WrMem(--regs.s, regs.pc >> 8);
1543 static void Op8E(void) // LDX #
1546 regs.cc &= 0xFD; // CLV
1547 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1548 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1551 static void Op90(void) // SUBA DP
1553 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t as = regs.a;
1555 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1556 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1557 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1558 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1561 static void Op91(void) // CMPA DP
1563 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1564 uint8_t db = regs.a - tmp;
1565 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1566 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1567 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1568 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1571 static void Op92(void) // SBCA DP
1573 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t as = regs.a;
1574 regs.a = regs.a - tmp - (regs.cc&0x01);
1575 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1576 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1577 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1578 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1581 static void Op93(void) // SUBD DP
1583 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1584 uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1586 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1587 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1588 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1589 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1590 regs.a = dr>>8; regs.b = dr&0xFF;
1593 static void Op94(void) // ANDA DP
1595 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1596 regs.cc &= 0xF1; // CLV CLZ CLN
1597 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
1598 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
1601 static void Op95(void) // BITA DP
1603 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1604 regs.cc &= 0xFD; // Clear oVerflow flag
1605 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1606 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1609 static void Op96(void) // LDA DP
1611 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1612 regs.cc &= 0xF1; // CLN CLZ CLV
1613 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1614 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1617 static void Op97(void) // STA DP
1619 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
1620 regs.cc &= 0xFD; // CLV
1621 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1622 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1625 static void Op98(void) // EORA DP
1627 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1628 regs.cc &= 0xFD; // CLV
1629 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1630 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1633 static void Op99(void) // ADCA DP
1635 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1636 addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1637 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1638 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1639 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1640 regs.a = addr & 0xFF; // Set accumulator
1641 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1642 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1645 static void Op9A(void) // ORA DP
1647 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1648 regs.cc &= 0xFD; // CLV
1649 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1650 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1653 static void Op9B(void) // ADDA DP
1655 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1656 addr = (uint16_t)regs.a + (uint16_t)tmp;
1657 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1658 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1659 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1660 regs.a = addr & 0xFF; // Set accumulator
1661 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1662 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1665 static void Op9C(void) // CMPX DP
1667 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1668 uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1669 uint16_t dw = regs.x - adr2;
1670 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1671 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1672 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1673 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1676 static void Op9D(void) // JSR DP
1678 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1679 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1680 regs.pc = addr; // JSR to DP location...
1683 static void Op9E(void) // LDX DP
1685 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1686 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1687 regs.cc &= 0xFD; // CLV
1688 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1689 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1692 static void Op9F(void) // STX DP
1694 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1695 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1696 regs.cc &= 0xFD; // CLV
1697 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1698 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1701 static void OpA0(void) // SUBA IDX
1703 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t as = regs.a;
1705 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1706 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1707 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1708 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1711 static void OpA1(void) // CMPA IDX
1713 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1714 uint8_t db = regs.a - tmp;
1715 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1716 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1717 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1718 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1721 static void OpA2(void) // SBCA IDX
1723 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t as = regs.a;
1724 regs.a = regs.a - tmp - (regs.cc&0x01);
1725 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1726 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1727 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1728 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1731 static void OpA3(void) // SUBD IDX
1733 addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1734 uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1736 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1737 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1738 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1739 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1740 regs.a = dr>>8; regs.b = dr&0xFF;
1743 static void OpA4(void) // ANDA IDX
1745 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1746 regs.cc &= 0xFD; // Clear oVerflow flag
1747 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1748 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1751 static void OpA5(void) // BITA IDX
1753 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1754 regs.cc &= 0xFD; // Clear oVerflow flag
1755 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1756 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1759 static void OpA6(void) // LDA IDX
1761 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1762 regs.cc &= 0xF1; // CLV CLZ CLN
1763 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1764 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1767 static void OpA7(void) // STA IDX
1769 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1770 regs.cc &= 0xF1; // CLV CLZ CLN
1771 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1772 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1775 static void OpA8(void) // EORA IDX
1777 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1778 regs.cc &= 0xFD; // CLV
1779 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1780 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1783 static void OpA9(void) // ADCA IDX
1785 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1786 addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1787 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1788 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1789 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1790 regs.a = addr & 0xFF; // Set accumulator
1791 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1792 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1795 static void OpAA(void) // ORA IDX
1797 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1798 regs.cc &= 0xFD; // CLV
1799 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1800 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1803 static void OpAB(void) // ADDA IDX
1805 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1806 addr = (uint16_t)regs.a + (uint16_t)tmp;
1807 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1808 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1809 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1810 regs.a = addr & 0xFF; // Set accumulator
1811 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1812 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1815 static void OpAC(void) // CMPX IDX
1817 addr = DecodeIDX(regs.RdMem(regs.pc++));
1818 uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1819 uint16_t dw = regs.x - addr2;
1820 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1821 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1822 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1823 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1826 static void OpAD(void) // JSR IDX
1828 addr = DecodeIDX(regs.RdMem(regs.pc++));
1829 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1830 regs.pc = addr; // Jregs.s directly to IDX ptr
1833 static void OpAE(void) // LDX IDX
1835 addr = DecodeIDX(regs.RdMem(regs.pc++));
1836 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1837 regs.cc &= 0xFD; // CLV
1838 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1839 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1842 static void OpAF(void) // STX IDX
1844 addr = DecodeIDX(regs.RdMem(regs.pc++));
1845 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1846 regs.cc &= 0xF1; // CLV CLZ CLN
1847 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1848 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1851 static void OpB0(void) // SUBA ABS
1853 tmp = regs.RdMem(FetchW()); uint8_t as = regs.a;
1855 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1856 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1857 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1858 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1861 static void OpB1(void) // CMPA ABS
1863 tmp = regs.RdMem(FetchW());
1864 uint8_t db = regs.a - tmp;
1865 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1866 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1867 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1868 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1871 static void OpB2(void) // SBCA ABS
1873 tmp = regs.RdMem(FetchW()); uint8_t as = regs.a;
1874 regs.a = regs.a - tmp - (regs.cc&0x01);
1875 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1876 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1877 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1878 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1881 static void OpB3(void) // SUBD ABS
1883 addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1884 uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1886 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1887 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1888 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1889 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1890 regs.a = dr>>8; regs.b = dr&0xFF;
1893 static void OpB4(void) // ANDA ABS
1895 regs.a &= regs.RdMem(FetchW());
1896 regs.cc &= 0xFD; // Clear oVerflow flag
1897 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1898 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1901 static void OpB5(void) // BITA ABS
1903 tmp = regs.a & regs.RdMem(FetchW());
1904 regs.cc &= 0xFD; // Clear oVerflow flag
1905 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1906 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1909 static void OpB6(void) // LDA ABS
1911 regs.a = regs.RdMem(FetchW());
1912 regs.cc &= 0xFD; // CLV
1913 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1914 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1917 static void OpB7(void) // STA ABS
1919 regs.WrMem(FetchW(), regs.a);
1920 regs.cc &= 0xFD; // CLV
1921 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1922 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1925 static void OpB8(void) // EORA ABS
1927 regs.a ^= regs.RdMem(FetchW());
1928 regs.cc &= 0xFD; // CLV
1929 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1930 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1933 static void OpB9(void) // ADCA ABS
1935 tmp = regs.RdMem(FetchW());
1936 addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1937 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1938 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1939 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1940 regs.a = addr; // Set accumulator
1941 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1942 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1945 static void OpBA(void) // ORA ABS
1947 regs.a |= regs.RdMem(FetchW());
1948 regs.cc &= 0xFD; // CLV
1949 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1950 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1953 static void OpBB(void) // ADDA ABS
1955 tmp = regs.RdMem(FetchW());
1956 addr = (uint16_t)regs.a + (uint16_t)tmp;
1957 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1958 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1959 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1960 regs.a = addr & 0xFF; // Set accumulator
1961 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1962 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1965 static void OpBC(void) // CMPX ABS
1967 addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1968 uint16_t dw = regs.x - addr2;
1969 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1970 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1971 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1972 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1975 static void OpBD(void) // JSR ABS
1978 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1979 regs.pc = addr; // Go to absolute address (Not indir)
1983 static void OpBE(void) // LDX ABS
1986 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1987 regs.x = RdMemW(FetchW());
1989 regs.cc &= 0xFD; // CLV
1990 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1991 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1996 static void OpBF(void) // STX ABS
1999 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
2000 WrMemW(FetchW(), regs.x);
2002 regs.cc &= 0xFD; // CLV
2003 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2004 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2009 static void OpC0(void) // SUBB #
2011 tmp = regs.RdMem(regs.pc++); uint8_t bs = regs.b;
2013 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2014 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2015 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2016 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2019 static void OpC1(void) // CMPB #
2021 tmp = regs.RdMem(regs.pc++);
2022 uint8_t db = regs.b - tmp;
2023 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2024 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2025 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2026 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2029 static void OpC2(void) // SBCB #
2031 tmp = regs.RdMem(regs.pc++); uint8_t bs = regs.b;
2032 regs.b = regs.b - tmp - (regs.cc&0x01);
2033 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2034 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2035 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2036 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2039 static void OpC3(void) // ADDD #
2041 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2043 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2045 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2046 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2047 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2048 regs.a = dr>>8; regs.b = dr&0xFF;
2051 static void OpC4(void) // ANDB #
2053 regs.b &= regs.RdMem(regs.pc++);
2054 regs.cc &= 0xFD; // Clear oVerflow flag
2055 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2056 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2059 static void OpC5(void) // BITB #
2061 tmp = regs.b & regs.RdMem(regs.pc++);
2062 regs.cc &= 0xF1; // CLV CLZ CLN
2063 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
2064 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
2067 static void OpC6(void) // LDB #
2069 regs.b = regs.RdMem(regs.pc++);
2070 regs.cc &= 0xF1; // CLV CLZ CLN
2071 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
2072 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
2075 static void OpC8(void) // EORB #
2077 regs.b ^= regs.RdMem(regs.pc++);
2078 regs.cc &= 0xFD; // CLV
2079 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2080 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2083 static void OpC9(void) // ADCB #
2085 tmp = regs.RdMem(regs.pc++);
2086 addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2087 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2088 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2089 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2090 regs.b = addr & 0xFF; // Set accumulator
2091 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2092 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2095 static void OpCA(void) // ORB #
2097 regs.b |= regs.RdMem(regs.pc++);
2098 regs.cc &= 0xFD; // CLV
2099 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2100 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2103 static void OpCB(void) // ADDB #
2105 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
2106 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2107 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2108 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2109 regs.b = addr & 0xFF; // Set accumulator
2110 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2111 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2114 static void OpCC(void) // LDD #
2116 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
2117 regs.cc &= 0xFD; // CLV
2118 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2119 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2122 static void OpCE(void) // LDU #
2125 regs.cc &= 0xFD; // CLV
2126 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2127 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2130 static void OpD0(void) // SUBB DP
2132 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t bs = regs.b;
2134 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2135 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2136 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2137 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2140 static void OpD1(void) // CMPB DP
2142 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2143 uint8_t db = regs.b - tmp;
2144 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2145 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2146 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2147 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2150 static void OpD2(void) // SBCB DP
2152 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t bs = regs.b;
2153 regs.b = regs.b - tmp - (regs.cc&0x01);
2154 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2155 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2156 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2157 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2160 static void OpD3(void) // ADDD DP
2162 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2163 uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2165 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2167 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2168 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2169 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2170 regs.a = dr>>8; regs.b = dr&0xFF;
2173 static void OpD4(void) // ANDB DP
2175 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2176 regs.cc &= 0xFD; // Clear oVerflow flag
2177 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2178 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2181 static void OpD5(void) // BITB DP
2183 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2184 regs.cc &= 0xFD; // Clear oVerflow flag
2185 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2186 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2189 static void OpD6(void) // LDB DP
2191 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2192 regs.cc &= 0xFD; // CLV
2193 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2194 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2197 static void OpD7(void) // STB DP
2199 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2200 regs.cc &= 0xFD; // CLV
2201 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2202 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2205 static void OpD8(void) // EORB DP
2207 regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2208 regs.cc &= 0xFD; // CLV
2209 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2210 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2213 static void OpD9(void) // ADCB DP
2215 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2216 addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2217 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2218 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2219 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2220 regs.b = addr; // Set accumulator
2221 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2222 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2225 static void OpDA(void) // ORB DP
2227 regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2228 regs.cc &= 0xFD; // CLV
2229 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2230 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2233 static void OpDB(void) // ADDB DP
2235 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2236 addr = (uint16_t)regs.b + (uint16_t)tmp;
2237 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2238 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2239 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2240 regs.b = addr & 0xFF; // Set accumulator
2241 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2242 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2245 static void OpDC(void) // LDD DP
2247 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2248 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2249 regs.cc &= 0xFD; // CLV
2250 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2251 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2254 static void OpDD(void) // STD DP
2256 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2257 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2258 regs.cc &= 0xFD; // CLV
2259 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2260 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2263 static void OpDE(void) // LDU DP
2265 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2266 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2267 regs.cc &= 0xFD; // CLV
2268 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2269 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2272 static void OpDF(void) // STU DP
2274 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2275 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2276 regs.cc &= 0xFD; // CLV
2277 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2278 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2281 static void OpE0(void) // SUBB IDX
2283 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t bs = regs.b;
2285 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2286 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2287 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2288 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2291 static void OpE1(void) // CMPB IDX
2293 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2294 uint8_t db = regs.b - tmp;
2295 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2296 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2297 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2298 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2301 static void OpE2(void) // SBCB IDX
2303 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t bs = regs.b;
2304 regs.b = regs.b - tmp - (regs.cc&0x01);
2305 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2306 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2307 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2308 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2311 static void OpE3(void) // ADDD IDX
2313 addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2314 uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2316 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2318 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2319 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2320 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2321 regs.a = dr>>8; regs.b = dr&0xFF;
2324 static void OpE4(void) // ANDB IDX
2326 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2327 regs.cc &= 0xFD; // Clear oVerflow flag
2328 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2329 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2332 static void OpE5(void) // BITB IDX
2334 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2335 regs.cc &= 0xFD; // Clear oVerflow flag
2336 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2337 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2340 static void OpE6(void) // LDB IDX
2342 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2343 regs.cc &= 0xFD; // CLV
2344 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2345 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2348 static void OpE7(void) // STB IDX
2350 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2351 regs.cc &= 0xF1; // CLV CLZ CLN
2352 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
2353 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
2356 static void OpE8(void) // EORB IDX
2358 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2359 regs.cc &= 0xFD; // CLV
2360 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2361 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2364 static void OpE9(void) // ADCB IDX
2366 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2367 addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2368 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2369 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2370 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2371 regs.b = addr; // Set accumulator
2372 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2373 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2376 static void OpEA(void) // ORB IDX
2378 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2379 regs.cc &= 0xFD; // CLV
2380 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2381 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2384 static void OpEB(void) // ADDB IDX
2386 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2387 addr = (uint16_t)regs.b + (uint16_t)tmp;
2388 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2389 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2390 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2391 regs.b = addr; // Set accumulator
2392 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2393 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2396 static void OpEC(void) // LDD IDX
2398 addr = DecodeIDX(regs.RdMem(regs.pc++));
2399 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2400 regs.cc &= 0xF1; // CLV CLZ CLN
2401 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2402 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2405 static void OpED(void) // STD IDX
2407 addr = DecodeIDX(regs.RdMem(regs.pc++));
2408 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2409 regs.cc &= 0xF1; // CLV CLZ CLZ
2410 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2411 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2414 static void OpEE(void) // LDU IDX
2416 addr = DecodeIDX(regs.RdMem(regs.pc++));
2417 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2418 regs.cc &= 0xF1; // CLV CLZ CLN
2419 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2420 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2423 static void OpEF(void) // STU IDX
2425 addr = DecodeIDX(regs.RdMem(regs.pc++));
2426 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2427 regs.cc &= 0xF1; // CLV CLZ CLN
2428 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2429 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2432 static void OpF0(void) // SUBB ABS
2434 tmp = regs.RdMem(FetchW()); uint8_t bs = regs.b;
2436 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2437 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2438 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2439 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2441 static void OpF1(void) // CMPB ABS
2443 tmp = regs.RdMem(FetchW());
2444 uint8_t db = regs.b - tmp;
2445 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2446 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2447 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2448 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2451 static void OpF2(void) // SBCB ABS
2453 tmp = regs.RdMem(FetchW()); uint8_t bs = regs.b;
2454 regs.b = regs.b - tmp - (regs.cc&0x01);
2455 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2456 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2457 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2458 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2461 static void OpF3(void) // ADDD ABS
2463 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2464 uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2466 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2468 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2469 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2470 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2471 regs.a = dr>>8; regs.b = dr&0xFF;
2474 static void OpF4(void) // ANDB ABS
2476 regs.b &= regs.RdMem(FetchW());
2477 regs.cc &= 0xFD; // Clear oVerflow flag
2478 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2479 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2482 static void OpF5(void) // BITB ABS
2484 tmp = regs.b & regs.RdMem(FetchW());
2485 regs.cc &= 0xFD; // Clear oVerflow flag
2486 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2487 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2490 static void OpF6(void) // LDB ABS
2492 regs.b = regs.RdMem(FetchW());
2493 regs.cc &= 0xFD; // CLV
2494 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2495 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2498 static void OpF7(void) // STB ABS
2500 regs.WrMem(FetchW(), regs.b);
2501 regs.cc &= 0xFD; // CLV
2502 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2503 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2506 static void OpF8(void) // EORB ABS
2508 regs.b ^= regs.RdMem(FetchW());
2509 regs.cc &= 0xFD; // CLV
2510 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2511 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2514 static void OpF9(void) // ADCB ABS
2516 tmp = regs.RdMem(FetchW());
2517 addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2518 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2519 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2520 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2521 regs.b = addr & 0xFF; // Set accumulator
2522 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2523 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2526 static void OpFA(void) // ORB ABS
2528 regs.b |= regs.RdMem(FetchW());
2529 regs.cc &= 0xFD; // CLV
2530 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2531 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2534 static void OpFB(void) // ADDB ABS
2536 tmp = regs.RdMem(FetchW());
2537 addr = (uint16_t)regs.b + (uint16_t)tmp;
2538 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2539 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2540 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2541 regs.b = addr & 0xFF; // Set accumulator
2542 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2543 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2546 static void OpFC(void) // LDD ABS
2549 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2550 regs.cc &= 0xFD; // CLV
2551 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2552 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2555 static void OpFD(void) // STD ABS
2558 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2559 regs.cc &= 0xFD; // CLV
2560 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2561 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2564 static void OpFE(void) // LDU ABS
2567 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2568 regs.cc &= 0xFD; // CLV
2569 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2570 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2573 static void OpFF(void) // STU ABS
2576 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2577 regs.cc &= 0xFD; // CLV
2578 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2579 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2584 // Page one opcodes' execute code
2587 static void Op1021(void) // LBRN
2594 static void Op1022(void) // LBHI
2596 uint16_t word = FetchW();
2598 if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
2604 static void Op1023(void) // LBLS
2606 uint16_t word = FetchW();
2608 if ((regs.cc & 0x01) | (regs.cc & 0x04))
2614 static void Op1024(void) // LBCC (LBHS)
2616 uint16_t word = FetchW();
2618 if (!(regs.cc & 0x01))
2624 static void Op1025(void) // LBCS (LBLO)
2626 uint16_t word = FetchW();
2634 static void Op1026(void) // LBNE
2636 uint16_t word = FetchW();
2638 if (!(regs.cc & 0x04))
2644 static void Op1027(void) // LBEQ
2646 uint16_t word = FetchW();
2654 static void Op1028(void) // LBVC
2656 uint16_t word = FetchW();
2658 if (!(regs.cc & 0x02))
2664 static void Op1029(void) // LBVS
2666 uint16_t word = FetchW();
2674 static void Op102A(void) // LBPL
2676 uint16_t word = FetchW();
2678 if (!(regs.cc & 0x08))
2684 static void Op102B(void) // LBMI
2686 uint16_t word = FetchW();
2694 static void Op102C(void) // LBGE
2696 uint16_t word = FetchW();
2698 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2704 static void Op102D(void) // LBLT
2706 uint16_t word = FetchW();
2708 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
2714 static void Op102E(void) // LBGT
2716 uint16_t word = FetchW();
2718 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
2724 static void Op102F(void) // LBLE
2726 uint16_t word = FetchW();
2728 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2734 static void Op103F(void) // SWI2 (Not yet implemented)
2738 static void Op1083(void) // CMPD #
2740 addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b;
2741 uint16_t dw = dr - addr;
2742 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2743 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2744 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2745 ((dr^addr^dw^((uint16_t)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2748 static void Op108C(void) // CMPY #
2751 uint16_t dw = regs.y - addr;
2752 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2753 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2754 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2755 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2758 static void Op108E(void) // LDY #
2761 regs.cc &= 0xFD; // CLV
2762 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2763 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2766 static void Op1093(void) // CMPD DP
2768 uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2769 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2770 uint16_t dw = dr - addr;
2771 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2772 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2773 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2774 ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2777 static void Op109C(void) // CMPY DP
2779 uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2780 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2781 uint16_t dw = regs.y - addr;
2782 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2783 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2784 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2785 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2789 static void Op109E(void) // LDY DP
2791 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2792 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2793 regs.cc &= 0xFD; // CLV
2794 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2795 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2799 static void Op109F(void) // STY DP
2801 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2802 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2803 regs.cc &= 0xFD; // CLV
2804 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2805 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2808 static void Op10A3(void) // CMPD IDX
2810 uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2811 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2812 uint16_t dw = dr - addr;
2813 regs.cc &= 0xF0; // CLC CLV CLZ CLN
2814 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
2815 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
2816 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
2817 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
2820 static void Op10AC(void) // CMPY IDX
2822 uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2823 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2824 uint16_t dw = regs.y - addr;
2825 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2826 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2827 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2828 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2831 static void Op10AE(void) // LDY IDX
2833 addr = DecodeIDX(regs.RdMem(regs.pc++));
2834 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2835 regs.cc &= 0xF1; // CLV CLZ CLN
2836 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
2837 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
2840 static void Op10AF(void) // STY IDX
2842 addr = DecodeIDX(regs.RdMem(regs.pc++));
2843 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2844 regs.cc &= 0xFD; // CLV
2845 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2846 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2849 static void Op10B3(void) // CMPD ABS
2851 addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b;
2852 uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2853 uint16_t dw = dr - addr2;
2854 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2855 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2856 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2857 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2860 static void Op10BC(void) // CMPY ABS
2862 addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2863 uint16_t dw = regs.y - addr2;
2864 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2865 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2866 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2867 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2870 static void Op10BE(void) // LDY ABS
2873 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2874 regs.cc &= 0xFD; // CLV
2875 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2876 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2879 static void Op10BF(void) // STY ABS
2882 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2883 regs.cc &= 0xFD; // CLV
2884 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2885 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2888 static void Op10CE(void) // LDS #
2891 regs.cc &= 0xFD; // CLV
2892 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2893 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2896 static void Op10DE(void) // LDS DP
2898 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2899 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2900 regs.cc &= 0xFD; // CLV
2901 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2902 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2905 static void Op10DF(void) // STS DP
2907 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2908 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2909 regs.cc &= 0xFD; // CLV
2910 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2911 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2914 static void Op10EE(void) // LDS IDX
2916 addr = DecodeIDX(regs.RdMem(regs.pc++));
2917 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2918 regs.cc &= 0xFD; // CLV
2919 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2920 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2923 static void Op10EF(void) // STS IDX
2925 addr = DecodeIDX(regs.RdMem(regs.pc++));
2926 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2927 regs.cc &= 0xFD; // CLV
2928 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2929 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2932 static void Op10FE(void) // LDS ABS
2935 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2936 regs.cc &= 0xFD; // CLV
2937 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2938 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2941 static void Op10FF(void) // STS ABS
2944 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2945 regs.cc &= 0xFD; // CLV
2946 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2947 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2952 // Page two opcodes' execute code
2955 static void Op113F(void) // SWI3
2959 static void Op1183(void) // CMPU #
2962 uint16_t dw = regs.u - addr;
2963 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2964 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2965 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2966 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2969 static void Op118C(void) // CMPS #
2972 uint16_t dw = regs.s - addr;
2973 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2974 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2975 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2976 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2979 static void Op1193(void) // CMPU DP
2981 uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2982 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2983 uint16_t dw = regs.u - addr;
2984 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2985 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2986 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2987 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2990 static void Op119C(void) // CMPS DP
2992 uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2993 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2994 uint16_t dw = regs.s - addr;
2995 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2996 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2997 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2998 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3001 static void Op11A3(void) // CMPU IDX
3003 uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++));
3004 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
3005 uint16_t dw = regs.u - addr;
3006 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3007 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3008 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3009 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3012 static void Op11AC(void) // CMPS IDX
3014 uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++));
3015 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
3016 uint16_t dw = regs.s - addr;
3017 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3018 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3019 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3020 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3023 static void Op11B3(void) // CMPU ABS
3025 addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3026 uint16_t dw = regs.u - addr2;
3027 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3028 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3029 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3030 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3034 static void Op11BC(void) // CMPS ABS
3036 addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3037 uint16_t dw = regs.s - addr2;
3038 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3039 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3040 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3041 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3045 //temp, for testing...
3047 static uint8_t backTrace[256];
3048 static uint16_t btPC[256];
3049 static int btPtr = 0;//*/
3051 static void Op__(void) // Illegal opcode
3055 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3057 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3058 for(int i=0; i<256; i++)
3060 Decode6809(btPC[(btPtr + i) & 0xFF]);
3068 // Internal "memcpy" (so we don't have to link with any external libraries!)
3070 static void myMemcpy(void * dst, void * src, uint32_t size)
3072 uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3074 for(uint32_t i=0; i<size; i++)
3079 // Function to execute 6809 instructions
3081 //#define DEBUG_ILLEGAL
3082 #ifdef DEBUG_ILLEGAL
3084 #include "dis6809.h"
3086 uint8_t backTrace[256];
3087 V6809REGS btRegs[256];
3088 bool tripped = false;
3091 //Here so this can be externally linked
3092 bool disasm = false;
3093 //bool disasm = true;
3095 void Execute6809(V6809REGS * context, uint32_t cycles)
3097 // If this is not in place, the clockOverrun calculations can cause the V6809 to get
3098 // stuck in an infinite loop.
3099 if (cycles == 0) // Nothing to do, so bail!
3102 myMemcpy(®s, context, sizeof(V6809REGS));
3106 // Since we can't guarantee that we'll execute the number of cycles passed in
3107 // exactly, we have to keep track of how much we overran the number of cycles
3108 // the last time we executed. Since we already executed those cycles, this time
3109 // through we remove them from the cycles passed in in order to come out
3110 // approximately even. Over the long run, this unevenness in execution times
3112 uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3114 while (regs.clock < endCycles)
3116 #ifdef DEBUG_ILLEGAL
3119 backTrace[btPtr] = regs.RdMem(regs.pc);
3120 btRegs[btPtr] = regs;
3121 btPtr = (btPtr + 1) & 0xFF;
3123 if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3125 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3126 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3128 for(uint16_t i=btPtr; i<btPtr+256; i++)
3130 Decode6809(btRegs[i & 0xFF].pc);
3131 // Note that these values are *before* execution, so stale...
3132 WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3133 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);//*/
3141 //Decode6809(regs.pc);
3142 if (disasm) Decode6809(regs);
3143 /*//if (regs.pc == 0x15BA) disasm = true;
3144 //if (regs.pc == 0xFE76) disasm = true;
3145 if (regs.x == 0xFED4) disasm = true;
3146 if (disasm) Decode6809(regs.pc);
3147 //if (regs.pc == 0x164A) disasm = false;//*/
3149 //temp, for testing...
3150 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3151 btPC[btPtr] = regs.pc;
3152 btPtr = (btPtr + 1) & 0xFF;//*/
3154 exec_op0[regs.RdMem(regs.pc++)]();
3156 // Handle any pending interrupts
3158 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3159 // uint32_t flags = context->cpuFlags;
3160 uint32_t flags = regs.cpuFlags;
3162 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
3165 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3167 regs.cc |= (FLAG_F | FLAG_I); // Set F, I
3168 regs.dp = 0; // Reset direct page register
3169 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3170 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3171 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3173 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
3176 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3178 regs.cc |= FLAG_E; // Set the Entire flag
3180 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3181 regs.WrMem(--regs.s, regs.pc >> 8);
3182 regs.WrMem(--regs.s, regs.u & 0xFF);
3183 regs.WrMem(--regs.s, regs.u >> 8);
3184 regs.WrMem(--regs.s, regs.y & 0xFF);
3185 regs.WrMem(--regs.s, regs.y >> 8);
3186 regs.WrMem(--regs.s, regs.x & 0xFF);
3187 regs.WrMem(--regs.s, regs.x >> 8);
3188 regs.WrMem(--regs.s, regs.dp);
3189 regs.WrMem(--regs.s, regs.b);
3190 regs.WrMem(--regs.s, regs.a);
3191 regs.WrMem(--regs.s, regs.cc);
3193 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3194 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3196 // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3197 // regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
3199 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
3202 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3204 if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
3207 if (disasm) WriteLog(" FIRQ taken...\n");
3209 regs.cc &= ~FLAG_E; // Clear the Entire flag
3211 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
3212 regs.WrMem(--regs.s, regs.pc >> 8);
3213 regs.WrMem(--regs.s, regs.cc);
3215 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3216 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3218 // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3219 // regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3222 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
3225 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3227 if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
3230 if (disasm) WriteLog(" IRQ taken...\n");
3232 regs.cc |= FLAG_E; // Set the Entire flag
3234 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3235 regs.WrMem(--regs.s, regs.pc >> 8);
3236 regs.WrMem(--regs.s, regs.u & 0xFF);
3237 regs.WrMem(--regs.s, regs.u >> 8);
3238 regs.WrMem(--regs.s, regs.y & 0xFF);
3239 regs.WrMem(--regs.s, regs.y >> 8);
3240 regs.WrMem(--regs.s, regs.x & 0xFF);
3241 regs.WrMem(--regs.s, regs.x >> 8);
3242 regs.WrMem(--regs.s, regs.dp);
3243 regs.WrMem(--regs.s, regs.b);
3244 regs.WrMem(--regs.s, regs.a);
3245 regs.WrMem(--regs.s, regs.cc);
3247 regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3248 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3250 // Apparently, not done here!
3251 // Need to put IRQ handling in somewhere... It shouldn't be cleared here!
3252 // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3253 // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3257 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",
3258 (regs.cc & FLAG_E ? "E" : "-"), (regs.cc & FLAG_F ? "F" : "-"), (regs.cc & FLAG_H ? "H" : "-"),
3259 (regs.cc & FLAG_I ? "I" : "-"), (regs.cc & FLAG_N ? "N" : "-"), (regs.cc & FLAG_Z ? "Z" : "-"),
3260 (regs.cc & FLAG_V ? "V" : "-"), (regs.cc & FLAG_C ? "C" : "-"),
3261 regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3262 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3263 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3266 // Keep track of how much we overran so we can adjust on the next run...
3267 regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3269 myMemcpy(context, ®s, sizeof(V6809REGS));
3273 WriteLog("\n*** CONTEXT SWITCH ***\n\n");
3278 // Get the clock of the currently executing CPU
3280 uint64_t GetCurrentV6809Clock(void)
3286 // Get the PC of the currently executing CPU
3288 uint16_t GetCurrentV6809PC(void)
3293 // Set a line of the currently executing CPU
3294 void SetLineOfCurrentV6809(uint32_t line)
3296 regs.cpuFlags |= line;
3299 // Clear a line of the currently executing CPU
3300 void ClearLineOfCurrentV6809(uint32_t line)
3304 WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
3306 regs.cpuFlags &= ~line;