5 // (c) 1997, 2006 Underground Software
7 // JLH = James L. 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)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
40 //#define SET_C_SUB(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
41 #define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) >= (uint8)(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 addr = EA_IMM; v = regs.RdMem(addr)
73 #define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr)
74 #define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr)
75 #define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2
76 #define READ_ABS_X_WB(v) uint16 addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2
77 #define READ_ABS_Y_WB(v) uint16 addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2
78 #define READ_IND_ZP_X_WB(v) uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr)
79 #define READ_IND_ZP_Y_WB(v) uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
80 #define READ_IND_ZP_WB(v) uint16 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 addr; // Temporary variables common to all funcs...
91 // Private function prototypes
93 static uint16 FetchW(void);
94 static uint16 RdMemW(uint16 addr);
95 static void WrMemW(uint16 addr, uint16 w);
96 static uint16 ReadEXG(uint8); // Read TFR/EXG post byte
97 static void WriteEXG(uint8, uint16); // Set TFR/EXG data
98 static uint16 DecodeReg(uint8); // Decode register data
99 static uint16 DecodeIDX(uint8); // 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 FetchW()
218 uint16 w = RdMemW(regs.pc);
224 // Read word from memory function
226 uint16 RdMemW(uint16 addr)
228 return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
232 // Write word to memory function
234 void WrMemW(uint16 addr, uint16 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 ReadEXG(uint8 code)
250 retval = (regs.a << 8) | regs.b;
287 // Function to set TFR/EXG data
289 void WriteEXG(uint8 code, uint16 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 DecodeReg(uint8 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 DecodeIDX(uint8 code)
344 uint8 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)(int8)regs.b;
385 woff = DecodeReg(reg) + (int16)(int8)regs.a;
389 woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);
393 woff = DecodeReg(reg) + FetchW();
397 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
401 woff = regs.pc + (int16)(int8)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)(int8)regs.b; break; }
456 case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; }
457 case 8: { addr = DecodeReg(reg) + (int16)(int8)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)(int8)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 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 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 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
640 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
642 regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry
644 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
646 regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
648 regs.cc &= 0xF1; // CL NZV
649 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
650 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
654 static void Op1A(void) // ORCC #
656 regs.cc |= regs.RdMem(regs.pc++);
661 static void Op1C(void) // ANDCC #
663 regs.cc &= regs.RdMem(regs.pc++);
668 static void Op1D(void) // SEX
670 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
672 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
673 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
678 static void Op1E(void) // EXG
680 tmp = regs.RdMem(regs.pc++);
681 addr = ReadEXG(tmp >> 4);
682 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
683 WriteEXG(tmp & 0xF, addr);
688 static void Op1F(void) // TFR
690 tmp = regs.RdMem(regs.pc++);
691 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
695 static void Op20(void) // BRA
697 // regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
698 regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1; // Branch always
703 static void Op21(void) // BRN
705 regs.RdMem(regs.pc++);
710 static void Op22(void) // BHI
712 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
714 if (!(regs.cc & 0x05))
720 static void Op23(void) // BLS
722 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
730 static void Op24(void) // BCC (BHS)
732 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
734 if (!(regs.cc & 0x01))
740 static void Op25(void) // BCS (BLO)
742 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
750 static void Op26(void) // BNE
752 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
754 if (!(regs.cc & 0x04))
760 static void Op27(void) // BEQ
762 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
770 static void Op28(void) // BVC
772 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
774 if (!(regs.cc & 0x02))
780 static void Op29(void) // BVS
782 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
790 static void Op2A(void) // BPL
792 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
794 if (!(regs.cc & 0x08))
800 static void Op2B(void) // BMI
802 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
810 static void Op2C(void) // BGE
812 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
814 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
820 static void Op2D(void) // BLT
822 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
824 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
830 static void Op2E(void) // BGT
832 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
834 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
840 static void Op2F(void) // BLE
842 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
844 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
850 static void Op30(void) // LEAX
852 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
853 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
856 static void Op31(void) // LEAY
858 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
859 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
862 static void Op32(void) // LEAS
864 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
865 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
868 static void Op33(void) // LEAU
870 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
871 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
874 static void Op34(void) // PSHS
876 tmp = regs.RdMem(regs.pc++);
877 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
878 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
879 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
880 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
881 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
882 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
883 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
884 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
887 static void Op35(void) // PULS
889 tmp = regs.RdMem(regs.pc++);
890 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
891 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
892 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
893 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
894 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
895 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
896 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
897 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
901 static void Op36(void) // PSHU
903 tmp = regs.RdMem(regs.pc++);
905 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
906 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
907 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
908 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
909 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
910 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
911 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
912 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
917 static void Op37(void) // PULU
919 tmp = regs.RdMem(regs.pc++);
920 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
921 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
922 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
923 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
924 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
925 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
926 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
927 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
930 static void Op39(void) // RTS
932 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
935 static void Op3A(void) // ABX
940 static void Op3B(void) // RTI
942 regs.cc = regs.RdMem(regs.s++);
943 if (regs.cc&0x80) // If E flag set, pull all regs
945 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
946 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
947 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
948 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
955 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
957 static void Op3C(void) // CWAI
959 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
960 regs.clock += 1000000; // Force interrupt
962 static void Op3D(void) // MUL
964 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
965 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
966 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
969 static void Op3E(void) // RESET
972 static void Op3F(void) // SWI
975 static void Op40(void) // NEGA
977 regs.a = 256 - regs.a;
978 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
979 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
980 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
981 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
984 static void Op43(void) // COMA
987 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
988 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
989 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
992 static void Op44(void) // LSRA
994 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
996 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
997 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1000 static void Op46(void) // RORA
1002 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
1003 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1004 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1005 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1008 static void Op47(void) // ASRA
1010 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1011 regs.a >>= 1; // Do the shift
1012 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
1013 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1014 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1017 static void Op48(void) // LSLA [Keep checking from here...]
1019 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1021 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1022 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1025 static void Op49(void) // ROLA
1027 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
1028 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1029 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1030 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1033 static void Op4A(void) // DECA
1036 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1037 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1038 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1041 static void Op4C(void) // INCA
1044 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1045 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1046 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1049 static void Op4D(void) // TSTA
1051 regs.cc &= 0xFD; // Clear oVerflow flag
1052 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1053 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1056 static void Op4F(void) // CLRA
1059 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1062 static void Op50(void) // NEGB
1064 regs.b = 256 - regs.b;
1065 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1066 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1067 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1068 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1069 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1072 static void Op53(void) // COMB
1075 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1076 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1077 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1080 static void Op54(void) // LSRB
1082 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1084 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1085 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1088 static void Op56(void) // RORB
1090 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
1091 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
1092 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1093 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1096 static void Op57(void) // ASRB
1098 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1099 regs.b >>= 1; // Do the shift
1100 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
1101 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1102 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1105 static void Op58(void) // LSLB
1107 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1109 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1110 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1113 static void Op59(void) // ROLB
1116 regs.b = (tmp<<1) + (regs.cc&0x01);
1117 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1118 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1119 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1122 static void Op5A(void) // DECB
1125 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1126 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1127 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1130 static void Op5C(void) // INCB
1133 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1134 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1135 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1138 static void Op5D(void) // TSTB
1140 regs.cc &= 0xFD; // Clear oVerflow flag
1141 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1142 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1145 static void Op5F(void) // CLRB
1148 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1151 static void Op60(void) // NEG IDX
1153 addr = DecodeIDX(regs.RdMem(regs.pc++));
1154 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1155 regs.WrMem(addr, res);
1156 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1157 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1158 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1159 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1160 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1163 static void Op63(void) // COM IDX
1165 addr = DecodeIDX(regs.RdMem(regs.pc++));
1166 tmp = regs.RdMem(addr) ^ 0xFF;
1167 regs.WrMem(addr, tmp);
1168 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1169 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1170 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1173 static void Op64(void) // LSR IDX
1175 addr = DecodeIDX(regs.RdMem(regs.pc++));
1176 tmp = regs.RdMem(addr);
1177 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1178 tmp >>= 1; regs.WrMem(addr, tmp);
1179 regs.cc &= 0xF7; // CLN
1180 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1183 static void Op66(void) // ROR IDX
1185 addr = DecodeIDX(regs.RdMem(regs.pc++));
1186 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1187 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1188 regs.WrMem(addr, tmp);
1189 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1190 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1191 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1194 static void Op67(void) // ASR IDX
1196 addr = DecodeIDX(regs.RdMem(regs.pc++));
1197 tmp = regs.RdMem(addr);
1198 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1200 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1201 regs.WrMem(addr, tmp);
1202 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1203 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1206 static void Op68(void) // LSL IDX
1208 addr = DecodeIDX(regs.RdMem(regs.pc++));
1209 tmp = regs.RdMem(addr);
1210 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1212 regs.WrMem(addr, tmp);
1213 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1214 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1217 static void Op69(void) // ROL IDX
1219 uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1220 tmp = (tmp2<<1) + (regs.cc&0x01);
1221 regs.WrMem(addr, tmp);
1222 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1223 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1224 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1227 static void Op6A(void) // DEC IDX
1229 uint8 tmp; uint16 addr;
1230 addr = DecodeIDX(regs.RdMem(regs.pc++));
1231 tmp = regs.RdMem(addr) - 1;
1232 regs.WrMem(addr, tmp);
1233 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1234 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1235 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1238 static void Op6C(void) // INC IDX
1240 addr = DecodeIDX(regs.RdMem(regs.pc++));
1241 tmp = regs.RdMem(addr) + 1;
1242 regs.WrMem(addr, tmp);
1243 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1244 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1245 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1248 static void Op6D(void) // TST IDX
1250 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1251 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1252 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1255 static void Op6E(void) // JMP IDX
1257 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1260 static void Op6F(void) // CLR IDX
1262 addr = DecodeIDX(regs.RdMem(regs.pc++));
1263 regs.WrMem(addr, 0);
1264 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1267 static void Op70(void) // NEG ABS
1270 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1271 regs.WrMem(addr, res);
1272 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1273 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1274 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1275 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1278 static void Op73(void) // COM ABS
1281 tmp = regs.RdMem(addr) ^ 0xFF;
1282 regs.WrMem(addr, tmp);
1283 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1284 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1285 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1288 static void Op74(void) // LSR ABS
1291 tmp = regs.RdMem(addr);
1292 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1293 tmp >>= 1; regs.WrMem(addr, tmp);
1294 regs.cc &= 0xF7; // CLN
1295 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1298 static void Op76(void) // ROR ABS
1300 uint8 tmp; uint16 addr;
1302 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1303 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1304 regs.WrMem(addr, tmp);
1305 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1306 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1307 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1310 static void Op77(void) // ASR ABS
1312 uint8 tmp; uint16 addr;
1314 tmp = regs.RdMem(addr);
1315 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1317 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1318 regs.WrMem(addr, tmp);
1319 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1320 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1323 static void Op78(void) // LSL ABS
1325 uint8 tmp; uint16 addr;
1327 tmp = regs.RdMem(addr);
1328 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1330 regs.WrMem(addr, tmp);
1331 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1332 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1335 static void Op79(void) // ROL ABS
1337 uint8 tmp2 = regs.RdMem(FetchW());
1338 tmp = (tmp2<<1) + (regs.cc&0x01);
1339 regs.WrMem(addr, tmp);
1340 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1341 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1342 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1345 static void Op7A(void) // DEC ABS
1347 uint8 tmp; uint16 addr;
1349 tmp = regs.RdMem(addr) - 1;
1350 regs.WrMem(addr, tmp);
1351 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1352 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1353 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1356 static void Op7C(void) // INC ABS
1358 uint8 tmp; uint16 addr;
1360 tmp = regs.RdMem(addr) + 1;
1361 regs.WrMem(addr, tmp);
1362 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1363 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1364 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1368 static void Op7D(void) // TST ABS
1370 uint8 tmp = regs.RdMem(FetchW());
1372 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1373 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1378 static void Op7E(void) // JMP ABS
1383 static void Op7F(void) // CLR ABS
1385 regs.WrMem(FetchW(), 0);
1386 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1389 static void Op80(void) // SUBA #
1391 uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1393 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1394 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1395 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1396 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1399 static void Op81(void) // CMPA #
1401 tmp = regs.RdMem(regs.pc++);
1402 uint8 db = regs.a - tmp;
1403 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1404 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1405 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1406 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1409 static void Op82(void) // SBCA #
1411 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1412 regs.a = regs.a - tmp - (regs.cc&0x01);
1413 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1414 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1415 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1416 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1419 static void Op83(void) // SUBD #
1421 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1423 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1424 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1425 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1426 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1427 regs.a = dr>>8; regs.b = dr&0xFF;
1430 static void Op84(void) // ANDA #
1432 regs.a &= regs.RdMem(regs.pc++);
1433 regs.cc &= 0xFD; // Clear oVerflow flag
1434 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1435 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1438 static void Op85(void) // BITA #
1440 tmp = regs.a & regs.RdMem(regs.pc++);
1441 regs.cc &= 0xFD; // Clear oVerflow flag
1442 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1443 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1446 static void Op86(void) // LDA #
1448 regs.a = regs.RdMem(regs.pc++);
1449 regs.cc &= 0xFD; // CLV
1450 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1451 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1454 static void Op88(void) // EORA #
1456 regs.a ^= regs.RdMem(regs.pc++);
1457 regs.cc &= 0xFD; // CLV
1458 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1459 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1462 static void Op89(void) // ADCA #
1464 tmp = regs.RdMem(regs.pc++);
1465 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1466 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1467 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1468 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1469 regs.a = addr & 0xFF; // Set accumulator
1470 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1471 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1474 static void Op8A(void) // ORA #
1476 regs.a |= regs.RdMem(regs.pc++);
1477 regs.cc &= 0xFD; // CLV
1478 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1479 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1482 static void Op8B(void) // ADDA #
1484 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
1485 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1486 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1487 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1488 regs.a = addr & 0xFF; // Set accumulator
1489 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1490 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1493 static void Op8C(void) // CMPX #
1496 uint16 dw = regs.x - addr;
1497 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1498 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1499 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1500 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1504 static void Op8D(void) // Bregs.s
1506 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
1507 regs.WrMem(--regs.s, regs.pc & 0xFF);
1508 regs.WrMem(--regs.s, regs.pc >> 8);
1514 static void Op8E(void) // LDX #
1517 regs.cc &= 0xFD; // CLV
1518 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1519 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1522 static void Op90(void) // SUBA DP
1524 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1526 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1527 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1528 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1529 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1532 static void Op91(void) // CMPA DP
1534 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1535 uint8 db = regs.a - tmp;
1536 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1537 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1538 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1539 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1542 static void Op92(void) // SBCA DP
1544 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1545 regs.a = regs.a - tmp - (regs.cc&0x01);
1546 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1547 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1548 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1549 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1552 static void Op93(void) // SUBD DP
1554 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1555 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1557 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1558 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1559 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1560 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1561 regs.a = dr>>8; regs.b = dr&0xFF;
1564 static void Op94(void) // ANDA DP
1566 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1567 regs.cc &= 0xF1; // CLV CLZ CLN
1568 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
1569 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
1572 static void Op95(void) // BITA DP
1574 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1575 regs.cc &= 0xFD; // Clear oVerflow flag
1576 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1577 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1580 static void Op96(void) // LDA DP
1582 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1583 regs.cc &= 0xF1; // CLN CLZ CLV
1584 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1585 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1588 static void Op97(void) // STA DP
1590 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
1591 regs.cc &= 0xFD; // CLV
1592 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1593 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1596 static void Op98(void) // EORA DP
1598 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1599 regs.cc &= 0xFD; // CLV
1600 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1601 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1604 static void Op99(void) // ADCA DP
1606 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1607 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1608 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1609 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1610 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1611 regs.a = addr & 0xFF; // Set accumulator
1612 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1613 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1616 static void Op9A(void) // ORA DP
1618 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1619 regs.cc &= 0xFD; // CLV
1620 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1621 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1624 static void Op9B(void) // ADDA DP
1626 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1627 addr = (uint16)regs.a + (uint16)tmp;
1628 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1629 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1630 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1631 regs.a = addr & 0xFF; // Set accumulator
1632 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1633 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1636 static void Op9C(void) // CMPX DP
1638 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1639 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1640 uint16 dw = regs.x - adr2;
1641 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1642 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1643 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1644 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1647 static void Op9D(void) // JSR DP
1649 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1650 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1651 regs.pc = addr; // JSR to DP location...
1654 static void Op9E(void) // LDX DP
1656 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1657 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1658 regs.cc &= 0xFD; // CLV
1659 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1660 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1663 static void Op9F(void) // STX DP
1665 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1666 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1667 regs.cc &= 0xFD; // CLV
1668 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1669 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1672 static void OpA0(void) // SUBA IDX
1674 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1676 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1677 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1678 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1679 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1682 static void OpA1(void) // CMPA IDX
1684 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1685 uint8 db = regs.a - tmp;
1686 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1687 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1688 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1689 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1692 static void OpA2(void) // SBCA IDX
1694 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1695 regs.a = regs.a - tmp - (regs.cc&0x01);
1696 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1697 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1698 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1699 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1702 static void OpA3(void) // SUBD IDX
1704 addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1705 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1707 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1708 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1709 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1710 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1711 regs.a = dr>>8; regs.b = dr&0xFF;
1714 static void OpA4(void) // ANDA IDX
1716 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1717 regs.cc &= 0xFD; // Clear oVerflow flag
1718 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1719 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1722 static void OpA5(void) // BITA IDX
1724 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1725 regs.cc &= 0xFD; // Clear oVerflow flag
1726 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1727 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1730 static void OpA6(void) // LDA IDX
1732 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1733 regs.cc &= 0xF1; // CLV CLZ CLN
1734 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1735 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1738 static void OpA7(void) // STA IDX
1740 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1741 regs.cc &= 0xF1; // CLV CLZ CLN
1742 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1743 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1746 static void OpA8(void) // EORA IDX
1748 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1749 regs.cc &= 0xFD; // CLV
1750 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1751 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1754 static void OpA9(void) // ADCA IDX
1756 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1757 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1758 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1759 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1760 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1761 regs.a = addr & 0xFF; // Set accumulator
1762 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1763 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1766 static void OpAA(void) // ORA IDX
1768 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1769 regs.cc &= 0xFD; // CLV
1770 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1771 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1774 static void OpAB(void) // ADDA IDX
1776 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1777 addr = (uint16)regs.a + (uint16)tmp;
1778 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1779 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1780 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1781 regs.a = addr & 0xFF; // Set accumulator
1782 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1783 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1786 static void OpAC(void) // CMPX IDX
1788 addr = DecodeIDX(regs.RdMem(regs.pc++));
1789 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1790 uint16 dw = regs.x - addr2;
1791 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1792 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1793 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1794 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1797 static void OpAD(void) // JSR IDX
1799 addr = DecodeIDX(regs.RdMem(regs.pc++));
1800 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1801 regs.pc = addr; // Jregs.s directly to IDX ptr
1804 static void OpAE(void) // LDX IDX
1806 addr = DecodeIDX(regs.RdMem(regs.pc++));
1807 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1808 regs.cc &= 0xFD; // CLV
1809 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1810 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1813 static void OpAF(void) // STX IDX
1815 addr = DecodeIDX(regs.RdMem(regs.pc++));
1816 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1817 regs.cc &= 0xF1; // CLV CLZ CLN
1818 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1819 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1822 static void OpB0(void) // SUBA ABS
1824 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1826 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1827 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1828 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1829 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1832 static void OpB1(void) // CMPA ABS
1834 tmp = regs.RdMem(FetchW());
1835 uint8 db = regs.a - tmp;
1836 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1837 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1838 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1839 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1842 static void OpB2(void) // SBCA ABS
1844 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1845 regs.a = regs.a - tmp - (regs.cc&0x01);
1846 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1847 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1848 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1849 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1852 static void OpB3(void) // SUBD ABS
1854 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1855 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1857 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1858 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1859 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1860 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1861 regs.a = dr>>8; regs.b = dr&0xFF;
1864 static void OpB4(void) // ANDA ABS
1866 regs.a &= regs.RdMem(FetchW());
1867 regs.cc &= 0xFD; // Clear oVerflow flag
1868 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1869 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1872 static void OpB5(void) // BITA ABS
1874 tmp = regs.a & regs.RdMem(FetchW());
1875 regs.cc &= 0xFD; // Clear oVerflow flag
1876 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1877 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1880 static void OpB6(void) // LDA ABS
1882 regs.a = regs.RdMem(FetchW());
1883 regs.cc &= 0xFD; // CLV
1884 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1885 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1888 static void OpB7(void) // STA ABS
1890 regs.WrMem(FetchW(), regs.a);
1891 regs.cc &= 0xFD; // CLV
1892 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1893 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1896 static void OpB8(void) // EORA ABS
1898 regs.a ^= regs.RdMem(FetchW());
1899 regs.cc &= 0xFD; // CLV
1900 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1901 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1904 static void OpB9(void) // ADCA ABS
1906 tmp = regs.RdMem(FetchW());
1907 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1908 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1909 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1910 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1911 regs.a = addr; // Set accumulator
1912 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1913 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1916 static void OpBA(void) // ORA ABS
1918 regs.a |= regs.RdMem(FetchW());
1919 regs.cc &= 0xFD; // CLV
1920 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1921 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1924 static void OpBB(void) // ADDA ABS
1926 tmp = regs.RdMem(FetchW());
1927 addr = (uint16)regs.a + (uint16)tmp;
1928 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1929 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1930 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1931 regs.a = addr & 0xFF; // Set accumulator
1932 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1933 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1936 static void OpBC(void) // CMPX ABS
1938 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1939 uint16 dw = regs.x - addr2;
1940 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1941 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1942 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1943 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1946 static void OpBD(void) // JSR ABS
1949 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1950 regs.pc = addr; // Go to absolute address (Not indir)
1954 static void OpBE(void) // LDX ABS
1957 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1958 regs.x = RdMemW(FetchW());
1960 regs.cc &= 0xFD; // CLV
1961 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1962 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1967 static void OpBF(void) // STX ABS
1970 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1971 WrMemW(FetchW(), regs.x);
1973 regs.cc &= 0xFD; // CLV
1974 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1975 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1980 static void OpC0(void) // SUBB #
1982 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
1984 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1985 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1986 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1987 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1990 static void OpC1(void) // CMPB #
1992 tmp = regs.RdMem(regs.pc++);
1993 uint8 db = regs.b - tmp;
1994 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1995 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1996 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1997 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2000 static void OpC2(void) // SBCB #
2002 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
2003 regs.b = regs.b - tmp - (regs.cc&0x01);
2004 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2005 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2006 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2007 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2010 static void OpC3(void) // ADDD #
2012 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2014 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2016 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2017 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2018 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2019 regs.a = dr>>8; regs.b = dr&0xFF;
2022 static void OpC4(void) // ANDB #
2024 regs.b &= regs.RdMem(regs.pc++);
2025 regs.cc &= 0xFD; // Clear oVerflow flag
2026 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2027 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2030 static void OpC5(void) // BITB #
2032 tmp = regs.b & regs.RdMem(regs.pc++);
2033 regs.cc &= 0xF1; // CLV CLZ CLN
2034 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
2035 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
2038 static void OpC6(void) // LDB #
2040 regs.b = regs.RdMem(regs.pc++);
2041 regs.cc &= 0xF1; // CLV CLZ CLN
2042 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
2043 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
2046 static void OpC8(void) // EORB #
2048 regs.b ^= regs.RdMem(regs.pc++);
2049 regs.cc &= 0xFD; // CLV
2050 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2051 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2054 static void OpC9(void) // ADCB #
2056 tmp = regs.RdMem(regs.pc++);
2057 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2058 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2059 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2060 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2061 regs.b = addr & 0xFF; // Set accumulator
2062 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2063 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2066 static void OpCA(void) // ORB #
2068 regs.b |= regs.RdMem(regs.pc++);
2069 regs.cc &= 0xFD; // CLV
2070 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2071 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2074 static void OpCB(void) // ADDB #
2076 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
2077 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2078 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2079 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2080 regs.b = addr & 0xFF; // Set accumulator
2081 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2082 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2085 static void OpCC(void) // LDD #
2087 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
2088 regs.cc &= 0xFD; // CLV
2089 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2090 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2093 static void OpCE(void) // LDU #
2096 regs.cc &= 0xFD; // CLV
2097 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2098 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2101 static void OpD0(void) // SUBB DP
2103 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2105 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2106 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2107 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2108 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2111 static void OpD1(void) // CMPB DP
2113 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2114 uint8 db = regs.b - tmp;
2115 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2116 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2117 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2118 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2121 static void OpD2(void) // SBCB DP
2123 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2124 regs.b = regs.b - tmp - (regs.cc&0x01);
2125 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2126 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2127 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2128 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2131 static void OpD3(void) // ADDD DP
2133 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2134 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2136 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2138 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2139 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2140 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2141 regs.a = dr>>8; regs.b = dr&0xFF;
2144 static void OpD4(void) // ANDB DP
2146 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2147 regs.cc &= 0xFD; // Clear oVerflow flag
2148 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2149 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2152 static void OpD5(void) // BITB DP
2154 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2155 regs.cc &= 0xFD; // Clear oVerflow flag
2156 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2157 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2160 static void OpD6(void) // LDB DP
2162 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2163 regs.cc &= 0xFD; // CLV
2164 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2165 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2168 static void OpD7(void) // STB DP
2170 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2171 regs.cc &= 0xFD; // CLV
2172 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2173 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2176 static void OpD8(void) // EORB DP
2178 regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2179 regs.cc &= 0xFD; // CLV
2180 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2181 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2184 static void OpD9(void) // ADCB DP
2186 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2187 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2188 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2189 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2190 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2191 regs.b = addr; // Set accumulator
2192 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2193 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2196 static void OpDA(void) // ORB DP
2198 regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2199 regs.cc &= 0xFD; // CLV
2200 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2201 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2204 static void OpDB(void) // ADDB DP
2206 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2207 addr = (uint16)regs.b + (uint16)tmp;
2208 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2209 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2210 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2211 regs.b = addr & 0xFF; // Set accumulator
2212 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2213 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2216 static void OpDC(void) // LDD DP
2218 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2219 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2220 regs.cc &= 0xFD; // CLV
2221 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2222 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2225 static void OpDD(void) // STD DP
2227 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2228 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2229 regs.cc &= 0xFD; // CLV
2230 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2231 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2234 static void OpDE(void) // LDU DP
2236 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2237 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2238 regs.cc &= 0xFD; // CLV
2239 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2240 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2243 static void OpDF(void) // STU DP
2245 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2246 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2247 regs.cc &= 0xFD; // CLV
2248 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2249 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2252 static void OpE0(void) // SUBB IDX
2254 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2256 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2257 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2258 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2259 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2262 static void OpE1(void) // CMPB IDX
2264 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2265 uint8 db = regs.b - tmp;
2266 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2267 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2268 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2269 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2272 static void OpE2(void) // SBCB IDX
2274 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2275 regs.b = regs.b - tmp - (regs.cc&0x01);
2276 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2277 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2278 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2279 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2282 static void OpE3(void) // ADDD IDX
2284 addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2285 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2287 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2289 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2290 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2291 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2292 regs.a = dr>>8; regs.b = dr&0xFF;
2295 static void OpE4(void) // ANDB IDX
2297 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2298 regs.cc &= 0xFD; // Clear oVerflow flag
2299 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2300 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2303 static void OpE5(void) // BITB IDX
2305 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2306 regs.cc &= 0xFD; // Clear oVerflow flag
2307 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2308 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2311 static void OpE6(void) // LDB IDX
2313 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2314 regs.cc &= 0xFD; // CLV
2315 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2316 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2319 static void OpE7(void) // STB IDX
2321 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2322 regs.cc &= 0xF1; // CLV CLZ CLN
2323 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
2324 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
2327 static void OpE8(void) // EORB IDX
2329 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2330 regs.cc &= 0xFD; // CLV
2331 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2332 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2335 static void OpE9(void) // ADCB IDX
2337 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2338 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2339 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2340 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2341 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2342 regs.b = addr; // Set accumulator
2343 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2344 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2347 static void OpEA(void) // ORB IDX
2349 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2350 regs.cc &= 0xFD; // CLV
2351 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2352 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2355 static void OpEB(void) // ADDB IDX
2357 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2358 addr = (uint16)regs.b + (uint16)tmp;
2359 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2360 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2361 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2362 regs.b = addr; // Set accumulator
2363 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2364 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2367 static void OpEC(void) // LDD IDX
2369 addr = DecodeIDX(regs.RdMem(regs.pc++));
2370 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2371 regs.cc &= 0xF1; // CLV CLZ CLN
2372 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2373 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2376 static void OpED(void) // STD IDX
2378 addr = DecodeIDX(regs.RdMem(regs.pc++));
2379 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2380 regs.cc &= 0xF1; // CLV CLZ CLZ
2381 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2382 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2385 static void OpEE(void) // LDU IDX
2387 addr = DecodeIDX(regs.RdMem(regs.pc++));
2388 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2389 regs.cc &= 0xF1; // CLV CLZ CLN
2390 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2391 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2394 static void OpEF(void) // STU IDX
2396 addr = DecodeIDX(regs.RdMem(regs.pc++));
2397 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2398 regs.cc &= 0xF1; // CLV CLZ CLN
2399 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2400 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2403 static void OpF0(void) // SUBB ABS
2405 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2407 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2408 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2409 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2410 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2412 static void OpF1(void) // CMPB ABS
2414 tmp = regs.RdMem(FetchW());
2415 uint8 db = regs.b - tmp;
2416 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2417 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2418 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2419 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2422 static void OpF2(void) // SBCB ABS
2424 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2425 regs.b = regs.b - tmp - (regs.cc&0x01);
2426 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2427 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2428 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2429 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2432 static void OpF3(void) // ADDD ABS
2434 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2435 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2437 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2439 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2440 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2441 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2442 regs.a = dr>>8; regs.b = dr&0xFF;
2445 static void OpF4(void) // ANDB ABS
2447 regs.b &= regs.RdMem(FetchW());
2448 regs.cc &= 0xFD; // Clear oVerflow flag
2449 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2450 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2453 static void OpF5(void) // BITB ABS
2455 tmp = regs.b & regs.RdMem(FetchW());
2456 regs.cc &= 0xFD; // Clear oVerflow flag
2457 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2458 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2461 static void OpF6(void) // LDB ABS
2463 regs.b = regs.RdMem(FetchW());
2464 regs.cc &= 0xFD; // CLV
2465 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2466 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2469 static void OpF7(void) // STB ABS
2471 regs.WrMem(FetchW(), regs.b);
2472 regs.cc &= 0xFD; // CLV
2473 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2474 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2477 static void OpF8(void) // EORB ABS
2479 regs.b ^= regs.RdMem(FetchW());
2480 regs.cc &= 0xFD; // CLV
2481 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2482 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2485 static void OpF9(void) // ADCB ABS
2487 tmp = regs.RdMem(FetchW());
2488 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2489 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2490 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2491 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2492 regs.b = addr & 0xFF; // Set accumulator
2493 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2494 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2497 static void OpFA(void) // ORB ABS
2499 regs.b |= regs.RdMem(FetchW());
2500 regs.cc &= 0xFD; // CLV
2501 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2502 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2505 static void OpFB(void) // ADDB ABS
2507 tmp = regs.RdMem(FetchW());
2508 addr = (uint16)regs.b + (uint16)tmp;
2509 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2510 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2511 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2512 regs.b = addr & 0xFF; // Set accumulator
2513 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2514 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2517 static void OpFC(void) // LDD ABS
2520 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2521 regs.cc &= 0xFD; // CLV
2522 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2523 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2526 static void OpFD(void) // STD ABS
2529 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2530 regs.cc &= 0xFD; // CLV
2531 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2532 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2535 static void OpFE(void) // LDU ABS
2538 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2539 regs.cc &= 0xFD; // CLV
2540 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2541 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2544 static void OpFF(void) // STU ABS
2547 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2548 regs.cc &= 0xFD; // CLV
2549 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2550 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2555 // Page one opcodes' execute code
2558 static void Op1021(void) // LBRN
2565 static void Op1022(void) // LBHI
2567 uint16 word = FetchW();
2569 if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
2575 static void Op1023(void) // LBLS
2577 uint16 word = FetchW();
2579 if ((regs.cc & 0x01) | (regs.cc & 0x04))
2585 static void Op1024(void) // LBCC (LBHS)
2587 uint16 word = FetchW();
2589 if (!(regs.cc & 0x01))
2595 static void Op1025(void) // LBCS (LBLO)
2597 uint16 word = FetchW();
2605 static void Op1026(void) // LBNE
2607 uint16 word = FetchW();
2609 if (!(regs.cc & 0x04))
2615 static void Op1027(void) // LBEQ
2617 uint16 word = FetchW();
2625 static void Op1028(void) // LBVC
2627 uint16 word = FetchW();
2629 if (!(regs.cc & 0x02))
2635 static void Op1029(void) // LBVS
2637 uint16 word = FetchW();
2645 static void Op102A(void) // LBPL
2647 uint16 word = FetchW();
2649 if (!(regs.cc & 0x08))
2655 static void Op102B(void) // LBMI
2657 uint16 word = FetchW();
2665 static void Op102C(void) // LBGE
2667 uint16 word = FetchW();
2669 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2675 static void Op102D(void) // LBLT
2677 uint16 word = FetchW();
2679 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
2685 static void Op102E(void) // LBGT
2687 uint16 word = FetchW();
2689 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
2695 static void Op102F(void) // LBLE
2697 uint16 word = FetchW();
2699 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2705 static void Op103F(void) // SWI2 (Not yet implemented)
2709 static void Op1083(void) // CMPD #
2711 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2712 uint16 dw = dr - addr;
2713 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2714 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2715 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2716 ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2719 static void Op108C(void) // CMPY #
2722 uint16 dw = regs.y - addr;
2723 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2724 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2725 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2726 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2729 static void Op108E(void) // LDY #
2732 regs.cc &= 0xFD; // CLV
2733 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2734 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2737 static void Op1093(void) // CMPD DP
2739 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2740 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2741 uint16 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^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2748 static void Op109C(void) // CMPY DP
2750 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2751 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2752 uint16 dw = regs.y - addr;
2753 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2754 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2755 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2756 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2760 static void Op109E(void) // LDY DP
2762 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2763 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2764 regs.cc &= 0xFD; // CLV
2765 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2766 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2770 static void Op109F(void) // STY DP
2772 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2773 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2774 regs.cc &= 0xFD; // CLV
2775 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2776 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2779 static void Op10A3(void) // CMPD IDX
2781 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2782 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2783 uint16 dw = dr - addr;
2784 regs.cc &= 0xF0; // CLC CLV CLZ CLN
2785 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
2786 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
2787 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
2788 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
2791 static void Op10AC(void) // CMPY IDX
2793 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2794 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2795 uint16 dw = regs.y - addr;
2796 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2797 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2798 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2799 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2802 static void Op10AE(void) // LDY IDX
2804 addr = DecodeIDX(regs.RdMem(regs.pc++));
2805 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2806 regs.cc &= 0xF1; // CLV CLZ CLN
2807 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
2808 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
2811 static void Op10AF(void) // STY IDX
2813 addr = DecodeIDX(regs.RdMem(regs.pc++));
2814 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2815 regs.cc &= 0xFD; // CLV
2816 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2817 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2820 static void Op10B3(void) // CMPD ABS
2822 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2823 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2824 uint16 dw = dr - addr2;
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 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2828 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2831 static void Op10BC(void) // CMPY ABS
2833 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2834 uint16 dw = regs.y - addr2;
2835 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2836 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2837 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2838 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2841 static void Op10BE(void) // LDY ABS
2844 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2845 regs.cc &= 0xFD; // CLV
2846 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2847 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2850 static void Op10BF(void) // STY ABS
2853 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2854 regs.cc &= 0xFD; // CLV
2855 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2856 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2859 static void Op10CE(void) // LDS #
2862 regs.cc &= 0xFD; // CLV
2863 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2864 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2867 static void Op10DE(void) // LDS DP
2869 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2870 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2871 regs.cc &= 0xFD; // CLV
2872 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2873 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2876 static void Op10DF(void) // STS DP
2878 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2879 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2880 regs.cc &= 0xFD; // CLV
2881 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2882 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2885 static void Op10EE(void) // LDS IDX
2887 addr = DecodeIDX(regs.RdMem(regs.pc++));
2888 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2889 regs.cc &= 0xFD; // CLV
2890 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2891 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2894 static void Op10EF(void) // STS IDX
2896 addr = DecodeIDX(regs.RdMem(regs.pc++));
2897 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2898 regs.cc &= 0xFD; // CLV
2899 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2900 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2903 static void Op10FE(void) // LDS ABS
2906 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2907 regs.cc &= 0xFD; // CLV
2908 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2909 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2912 static void Op10FF(void) // STS ABS
2915 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2916 regs.cc &= 0xFD; // CLV
2917 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2918 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2923 // Page two opcodes' execute code
2926 static void Op113F(void) // SWI3
2930 static void Op1183(void) // CMPU #
2933 uint16 dw = regs.u - addr;
2934 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2935 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2936 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2937 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2940 static void Op118C(void) // CMPS #
2943 uint16 dw = regs.s - addr;
2944 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2945 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2946 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2947 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2950 static void Op1193(void) // CMPU DP
2952 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2953 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2954 uint16 dw = regs.u - addr;
2955 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2956 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2957 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2958 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2961 static void Op119C(void) // CMPS DP
2963 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2964 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2965 uint16 dw = regs.s - addr;
2966 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2967 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2968 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2969 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2972 static void Op11A3(void) // CMPU IDX
2974 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2975 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2976 uint16 dw = regs.u - addr;
2977 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2978 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2979 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2980 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2983 static void Op11AC(void) // CMPS IDX
2985 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2986 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2987 uint16 dw = regs.s - addr;
2988 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2989 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2990 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2991 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2994 static void Op11B3(void) // CMPU ABS
2996 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2997 uint16 dw = regs.u - addr2;
2998 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2999 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3000 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3001 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3005 static void Op11BC(void) // CMPS ABS
3007 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3008 uint16 dw = regs.s - addr2;
3009 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3010 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3011 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3012 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3016 //temp, for testing...
3018 static uint8 backTrace[256];
3019 static uint16 btPC[256];
3020 static int btPtr = 0;//*/
3022 static void Op__(void) // Illegal opcode
3026 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3028 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3029 for(int i=0; i<256; i++)
3031 Decode6809(btPC[(btPtr + i) & 0xFF]);
3039 // Internal "memcpy" (so we don't have to link with any external libraries!)
3041 static void myMemcpy(void * dst, void * src, uint32 size)
3043 uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
3045 for(uint32 i=0; i<size; i++)
3050 // Function to execute 6809 instructions
3052 //#define DEBUG_ILLEGAL
3053 #ifdef DEBUG_ILLEGAL
3055 #include "dis6809.h"
3057 uint8 backTrace[256];
3058 V6809REGS btRegs[256];
3059 bool tripped = false;
3061 void Execute6809(V6809REGS * context, uint32 cycles)
3063 // If this is not in place, the clockOverrun calculations can cause the V6809 to get
3064 // stuck in an infinite loop.
3065 if (cycles == 0) // Nothing to do, so bail!
3068 myMemcpy(®s, context, sizeof(V6809REGS));
3072 // Since we can't guarantee that we'll execute the number of cycles passed in
3073 // exactly, we have to keep track of how much we overran the number of cycles
3074 // the last time we executed. Since we already executed those cycles, this time
3075 // through we remove them from the cycles passed in in order to come out
3076 // approximately even. Over the long run, this unevenness in execution times
3078 uint64 endCycles = regs.clock + (uint64)(cycles - regs.clockOverrun);
3080 while (regs.clock < endCycles)
3082 #ifdef DEBUG_ILLEGAL
3085 backTrace[btPtr] = regs.RdMem(regs.pc);
3086 btRegs[btPtr] = regs;
3087 btPtr = (btPtr + 1) & 0xFF;
3089 if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3091 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3092 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3094 for(uint16 i=btPtr; i<btPtr+256; i++)
3096 Decode6809(btRegs[i & 0xFF].pc);
3097 // Note that these values are *before* execution, so stale...
3098 WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3099 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);//*/
3107 //Decode6809(regs.pc);
3108 //static bool disasm = false;
3109 static bool disasm = true;
3110 if (disasm) Decode6809(regs);
3111 /*//if (regs.pc == 0x15BA) disasm = true;
3112 //if (regs.pc == 0xFE76) disasm = true;
3113 if (regs.x == 0xFED4) disasm = true;
3114 if (disasm) Decode6809(regs.pc);
3115 //if (regs.pc == 0x164A) disasm = false;//*/
3117 //temp, for testing...
3118 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3119 btPC[btPtr] = regs.pc;
3120 btPtr = (btPtr + 1) & 0xFF;//*/
3122 exec_op0[regs.RdMem(regs.pc++)]();
3124 // Handle any pending interrupts
3126 uint32 flags = context->cpuFlags;
3128 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
3131 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3133 regs.cc |= (FLAG_F | FLAG_I); // Set F, I
3134 regs.dp = 0; // Reset direct page register
3135 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3136 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3137 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3139 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
3142 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3144 regs.cc |= FLAG_E; // Set the Entire flag
3146 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3147 regs.WrMem(--regs.s, regs.pc >> 8);
3148 regs.WrMem(--regs.s, regs.u & 0xFF);
3149 regs.WrMem(--regs.s, regs.u >> 8);
3150 regs.WrMem(--regs.s, regs.y & 0xFF);
3151 regs.WrMem(--regs.s, regs.y >> 8);
3152 regs.WrMem(--regs.s, regs.x & 0xFF);
3153 regs.WrMem(--regs.s, regs.x >> 8);
3154 regs.WrMem(--regs.s, regs.dp);
3155 regs.WrMem(--regs.s, regs.b);
3156 regs.WrMem(--regs.s, regs.a);
3157 regs.WrMem(--regs.s, regs.cc);
3159 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3160 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3162 // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3163 // regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
3165 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
3168 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3170 if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
3173 if (disasm) WriteLog(" FIRQ taken...\n");
3175 regs.cc &= ~FLAG_E; // Clear the Entire flag
3177 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
3178 regs.WrMem(--regs.s, regs.pc >> 8);
3179 regs.WrMem(--regs.s, regs.cc);
3181 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3182 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3184 // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3185 // regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3188 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
3191 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3193 if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
3196 if (disasm) WriteLog(" IRQ taken...\n");
3198 regs.cc |= FLAG_E; // Set the Entire flag
3200 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3201 regs.WrMem(--regs.s, regs.pc >> 8);
3202 regs.WrMem(--regs.s, regs.u & 0xFF);
3203 regs.WrMem(--regs.s, regs.u >> 8);
3204 regs.WrMem(--regs.s, regs.y & 0xFF);
3205 regs.WrMem(--regs.s, regs.y >> 8);
3206 regs.WrMem(--regs.s, regs.x & 0xFF);
3207 regs.WrMem(--regs.s, regs.x >> 8);
3208 regs.WrMem(--regs.s, regs.dp);
3209 regs.WrMem(--regs.s, regs.b);
3210 regs.WrMem(--regs.s, regs.a);
3211 regs.WrMem(--regs.s, regs.cc);
3213 regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3214 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3216 // Apparently, not done here!
3217 // Need to put IRQ handling in somewhere... It shouldn't be cleared here!
3218 context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3219 regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3223 if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3224 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3225 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3226 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3230 // Keep track of how much we overran so we can adjust on the next run...
3231 regs.clockOverrun = (uint32)(regs.clock - endCycles);
3233 myMemcpy(context, ®s, sizeof(V6809REGS));
3237 // Get the clock of the currently executing CPU
3239 uint64 GetCurrentV6809Clock(void)
3245 // Get the PC of the currently executing CPU
3247 uint16 GetCurrentV6809PC(void)
3252 // Set a line of the currently executing CPU
3253 void SetLine(uint32 line)
3255 regs.cpuFlags |= line;
3258 // Clear a line of the currently executing CPU
3259 void ClearLine(uint32 line)
3261 regs.cpuFlags &= ~line;