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... ;-)
25 #include "dis6809.h" // Temporary...
26 #include "log.h" // Temporary...
31 #define CLR_Z (regs.cc &= ~FLAG_Z)
32 #define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N))
33 #define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C))
34 #define CLR_V (regs.cc &= ~FLAG_V)
35 #define CLR_N (regs.cc &= ~FLAG_N)
36 #define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z))
37 #define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
39 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
40 #define SET_C_ADD(a,b) (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
41 //#define SET_C_SUB(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
42 #define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
43 #define SET_ZN(r) SET_N(r); SET_Z(r)
44 #define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
45 //#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
46 #define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b)
48 //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
49 //Hmm, why not do like we did for READ_ABS*???
50 //Because the EA_* macros are usually used as an argument to a function call, that's why.
51 #define EA_IMM regs.pc++
52 #define EA_ZP regs.RdMem(regs.pc++)
53 #define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) & 0xFF
54 #define EA_ZP_Y (regs.RdMem(regs.pc++) + regs.y) & 0xFF
55 #define EA_ABS RdMemW(regs.pc)
56 #define EA_ABS_X RdMemW(regs.pc) + regs.x
57 #define EA_ABS_Y RdMemW(regs.pc) + regs.y
58 #define EA_IND_ZP_X RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF)
59 #define EA_IND_ZP_Y RdMemW(regs.RdMem(regs.pc++)) + regs.y
60 #define EA_IND_ZP RdMemW(regs.RdMem(regs.pc++))
62 #define READ_IMM regs.RdMem(EA_IMM)
63 #define READ_ZP regs.RdMem(EA_ZP)
64 #define READ_ZP_X regs.RdMem(EA_ZP_X)
65 #define READ_ZP_Y regs.RdMem(EA_ZP_Y)
66 #define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2
67 #define READ_ABS_X regs.RdMem(EA_ABS_X); regs.pc += 2
68 #define READ_ABS_Y regs.RdMem(EA_ABS_Y); regs.pc += 2
69 #define READ_IND_ZP_X regs.RdMem(EA_IND_ZP_X)
70 #define READ_IND_ZP_Y regs.RdMem(EA_IND_ZP_Y)
71 #define READ_IND_ZP regs.RdMem(EA_IND_ZP)
73 #define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr)
74 #define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr)
75 #define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr)
76 #define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2
77 #define READ_ABS_X_WB(v) uint16 addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2
78 #define READ_ABS_Y_WB(v) uint16 addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2
79 #define READ_IND_ZP_X_WB(v) uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr)
80 #define READ_IND_ZP_Y_WB(v) uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
81 #define READ_IND_ZP_WB(v) uint16 addr = EA_IND_ZP; v = regs.RdMem(addr)
83 #define WRITE_BACK(d) regs.WrMem(addr, (d))
85 // Private global variables
87 static V6809REGS regs;
88 //Let's see if we can nuke this shit.
89 static uint16 addr; // Temporary variables common to all funcs...
92 // Private function prototypes
94 static uint16 FetchW(void);
95 static uint16 RdMemW(uint16 addr);
96 static void WrMemW(uint16 addr, uint16 w);
97 static uint16 ReadEXG(uint8); // Read TFR/EXG post byte
98 static void WriteEXG(uint8, uint16); // Set TFR/EXG data
99 static uint16 DecodeReg(uint8); // Decode register data
100 static uint16 DecodeIDX(uint8); // Decode IDX data
102 //static void (* exec_op1[256])();
103 //static void (* exec_op2[256])();
106 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
107 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
108 // even *try* to see if they're there).
110 #define FD(x) static void Op##x(); // FD -> "Forward Declaration"
111 #define FE(x) static void Op10##x();
112 #define FF(x) static void Op11##x();
114 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)
115 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)
116 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)
117 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)
118 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)
119 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)
120 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)
121 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)
122 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)
123 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)
124 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)
125 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)
126 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)
127 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)
128 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)
129 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)
132 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)
133 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)
134 FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
136 FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
144 // We can move these down and do away with the forward declarations... !!! FIX !!!
145 // Actually, we can't because these are used in a couple of the opcode functions.
146 // Have to think about how to fix that...
152 // Array of page zero opcode functions...
153 static void (* exec_op0[256])() = {
154 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
155 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
156 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
157 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
158 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
159 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
160 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
161 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
162 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
163 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
164 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
165 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
166 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
167 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
168 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
169 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
172 // Array of page one opcode functions...
173 static void (* exec_op1[256])() = {
174 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
175 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
176 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
177 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
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__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
182 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
183 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
184 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
185 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
186 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
187 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
188 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
189 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
192 // Array of page two opcode functions...
193 static void (* exec_op2[256])() = {
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__, Op__,
197 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
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__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
202 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
203 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
204 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
205 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, 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__,
209 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
214 // Fetch a word out of 6809 memory (little endian format)
215 // This is a leftover from when fetches were separated from garden variety reads...
217 static uint16 FetchW()
219 uint16 w = RdMemW(regs.pc);
225 // Read word from memory function
227 uint16 RdMemW(uint16 addr)
229 return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
233 // Write word to memory function
235 void WrMemW(uint16 addr, uint16 w)
237 regs.WrMem(addr + 0, w >> 8);
238 regs.WrMem(addr + 1, w & 0xFF);
242 // Function to read TFR/EXG post byte
244 uint16 ReadEXG(uint8 code)
251 retval = (regs.a << 8) | regs.b;
288 // Function to set TFR/EXG data
290 void WriteEXG(uint8 code, uint16 data)
295 regs.a = data >> 8, regs.b = data & 0xFF; break;
297 regs.x = data; break;
299 regs.y = data; break;
301 regs.u = data; break;
303 regs.s = data; break;
305 regs.pc = data; break;
307 regs.a = data & 0xFF; break;
309 regs.b = data & 0xFF; break;
311 regs.cc = data & 0xFF; break;
313 regs.dp = data & 0xFF; break;
318 // Function to decode register data
320 uint16 DecodeReg(uint8 reg)
327 retval = regs.x; break;
329 retval = regs.y; break;
331 retval = regs.u; break;
333 retval = regs.s; break;
340 // Function to decode IDX data
342 uint16 DecodeIDX(uint8 code)
345 uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
347 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
348 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
356 woff = DecodeReg(reg);
360 case 0: regs.x += 2; break;
361 case 1: regs.y += 2; break;
362 case 2: regs.u += 2; break;
363 case 3: regs.s += 2; break;
369 case 0: regs.x -= 2; break;
370 case 1: regs.y -= 2; break;
371 case 2: regs.u -= 2; break;
372 case 3: regs.s -= 2; break;
374 woff = DecodeReg(reg);
378 woff = DecodeReg(reg);
382 woff = DecodeReg(reg) + (int16)(int8)regs.b;
386 woff = DecodeReg(reg) + (int16)(int8)regs.a;
390 woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);
394 woff = DecodeReg(reg) + FetchW();
398 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
402 woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);
406 woff = regs.pc + FetchW();
420 addr = DecodeReg(reg);
423 case 0: regs.x++; break;
424 case 1: regs.y++; break;
425 case 2: regs.u++; break;
426 case 3: regs.s++; break;
430 addr = DecodeReg(reg);
433 case 0: regs.x += 2; break;
434 case 1: regs.y += 2; break;
435 case 2: regs.u += 2; break;
436 case 3: regs.s += 2; break;
439 case 2: { switch(reg)
441 case 0: regs.x--; break;
442 case 1: regs.y--; break;
443 case 2: regs.u--; break;
444 case 3: regs.s--; break;
446 addr = DecodeReg(reg); break; }
447 case 3: { switch(reg)
449 case 0: regs.x--; regs.x--; break;
450 case 1: regs.y--; regs.y--; break;
451 case 2: regs.u--; regs.u--; break;
452 case 3: regs.s--; regs.s--; break;
454 addr = DecodeReg(reg); break; }
455 case 4: { addr = DecodeReg(reg); break; }
456 case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; }
457 case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; }
458 case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; }
459 case 9: { addr = DecodeReg(reg) + FetchW(); break; }
460 case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
461 case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; }
462 case 13: { addr = regs.pc + FetchW(); break; }
471 // Page zero instructions...
474 static void Op00(void) // NEG DP
476 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
477 tmp = 256 - regs.RdMem(addr);
478 regs.WrMem(addr, tmp);
480 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
481 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
482 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
483 (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
488 static void Op01(void) // NEG DP (Undocumented)
493 static void Op03(void) // COM DP
495 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
496 tmp = 0xFF ^ regs.RdMem(addr);
497 regs.WrMem(addr, tmp);
499 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
500 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
501 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
506 static void Op04(void) // LSR DP
508 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
509 tmp = regs.RdMem(addr);
510 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
511 tmp >>= 1; regs.WrMem(addr, tmp);
512 regs.cc &= 0xF7; // CLN
513 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
516 static void Op06(void) // ROR DP
518 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
519 tmp = (tmp2>>1) + (regs.cc&0x01)*128;
520 regs.WrMem(addr, tmp);
521 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
522 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
523 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
526 static void Op07(void) // ASR DP
528 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
529 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
531 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
532 regs.WrMem(addr, tmp);
533 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
534 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
537 static void Op08(void) // LSL DP
539 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
540 tmp = regs.RdMem(addr);
541 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
543 regs.WrMem(addr, tmp);
544 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
545 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
548 static void Op09(void) // ROL DP
550 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
551 tmp = (tmp2<<1) + (regs.cc&0x01);
552 regs.WrMem(addr, tmp);
553 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
554 ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
555 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
556 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
559 static void Op0A(void) // DEC DP
561 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
562 tmp = regs.RdMem(addr) - 1;
563 regs.WrMem(addr, tmp);
564 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
565 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
566 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
569 static void Op0C(void) // INC DP
571 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
572 tmp = regs.RdMem(addr) + 1;
573 regs.WrMem(addr, tmp);
574 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
575 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
576 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
579 static void Op0D(void) // TST DP
581 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
582 regs.cc &= 0xFD; // CLV
583 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
584 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
587 static void Op0E(void) // JMP DP
589 regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
592 static void Op0F(void) // CLR DP
594 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
595 regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
599 static void Op10(void) // Page 1 opcode
601 exec_op1[regs.RdMem(regs.pc++)]();
604 static void Op11(void) // Page 2 opcode
606 exec_op2[regs.RdMem(regs.pc++)]();
609 static void Op12(void) // NOP
614 static void Op13(void) // SYNC
616 // Fix this so it does the right thing (software interrupt!)
620 static void Op16(void) // LBRA
622 // regs.pc += SignedW(FetchW());
623 regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities
628 static void Op17(void) // LBSR
630 uint16 word = FetchW();
631 regs.WrMem(--regs.s, regs.pc & 0xFF);
632 regs.WrMem(--regs.s, regs.pc >> 8);
633 // regs.pc += SignedW(addr);
634 regs.pc += word; // No need to make signed, both are 16 bit
639 static void Op19(void) // DAA
641 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
643 regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry
645 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
647 regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
649 regs.cc &= 0xF1; // CL NZV
650 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
651 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
655 static void Op1A(void) // ORCC #
657 regs.cc |= regs.RdMem(regs.pc++);
662 static void Op1C(void) // ANDCC #
664 regs.cc &= regs.RdMem(regs.pc++);
669 static void Op1D(void) // SEX
671 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
673 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
674 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
679 static void Op1E(void) // EXG
681 tmp = regs.RdMem(regs.pc++);
682 addr = ReadEXG(tmp >> 4);
683 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
684 WriteEXG(tmp & 0xF, addr);
689 static void Op1F(void) // TFR
691 tmp = regs.RdMem(regs.pc++);
692 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
696 static void Op20(void) // BRA
698 // regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
699 regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1; // Branch always
704 static void Op21(void) // BRN
706 regs.RdMem(regs.pc++);
711 static void Op22(void) // BHI
713 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
715 if (!(regs.cc & 0x05))
721 static void Op23(void) // BLS
723 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
731 static void Op24(void) // BCC (BHS)
733 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
735 if (!(regs.cc & 0x01))
741 static void Op25(void) // BCS (BLO)
743 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
751 static void Op26(void) // BNE
753 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
755 if (!(regs.cc & 0x04))
761 static void Op27(void) // BEQ
763 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
771 static void Op28(void) // BVC
773 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
775 if (!(regs.cc & 0x02))
781 static void Op29(void) // BVS
783 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
791 static void Op2A(void) // BPL
793 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
795 if (!(regs.cc & 0x08))
801 static void Op2B(void) // BMI
803 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
811 static void Op2C(void) // BGE
813 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
815 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
821 static void Op2D(void) // BLT
823 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
825 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
831 static void Op2E(void) // BGT
833 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
835 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
841 static void Op2F(void) // BLE
843 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
845 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
851 static void Op30(void) // LEAX
853 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
854 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
857 static void Op31(void) // LEAY
859 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
860 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
863 static void Op32(void) // LEAS
865 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
866 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
869 static void Op33(void) // LEAU
871 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
872 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
875 static void Op34(void) // PSHS
877 tmp = regs.RdMem(regs.pc++);
878 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
879 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
880 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
881 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
882 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
883 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
884 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
885 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
888 static void Op35(void) // PULS
890 tmp = regs.RdMem(regs.pc++);
891 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
892 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
893 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
894 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
895 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
896 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
897 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
898 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
902 static void Op36(void) // PSHU
904 tmp = regs.RdMem(regs.pc++);
906 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
907 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
908 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
909 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
910 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
911 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
912 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
913 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
918 static void Op37(void) // PULU
920 tmp = regs.RdMem(regs.pc++);
921 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
922 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
923 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
924 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
925 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
926 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
927 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
928 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
931 static void Op39(void) // RTS
933 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
936 static void Op3A(void) // ABX
941 static void Op3B(void) // RTI
943 regs.cc = regs.RdMem(regs.s++);
944 if (regs.cc&0x80) // If E flag set, pull all regs
946 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
947 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
948 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
949 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
956 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
958 static void Op3C(void) // CWAI
960 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
961 regs.clock += 1000000; // Force interrupt
963 static void Op3D(void) // MUL
965 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
966 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
967 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
970 static void Op3E(void) // RESET
973 static void Op3F(void) // SWI
976 static void Op40(void) // NEGA
978 regs.a = 256 - regs.a;
979 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
980 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
981 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
982 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
985 static void Op43(void) // COMA
988 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
989 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
990 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
993 static void Op44(void) // LSRA
995 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
997 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
998 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1001 static void Op46(void) // RORA
1003 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
1004 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1005 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1006 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1009 static void Op47(void) // ASRA
1011 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1012 regs.a >>= 1; // Do the shift
1013 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
1014 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1015 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1018 static void Op48(void) // LSLA [Keep checking from here...]
1020 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1022 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1023 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1026 static void Op49(void) // ROLA
1028 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
1029 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1030 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1031 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1034 static void Op4A(void) // DECA
1037 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1038 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1039 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1042 static void Op4C(void) // INCA
1045 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1046 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1047 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1050 static void Op4D(void) // TSTA
1052 regs.cc &= 0xFD; // Clear oVerflow flag
1053 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1054 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1057 static void Op4F(void) // CLRA
1060 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1063 static void Op50(void) // NEGB
1065 regs.b = 256 - regs.b;
1066 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1067 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1068 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1069 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1070 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1073 static void Op53(void) // COMB
1076 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1077 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1078 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1081 static void Op54(void) // LSRB
1083 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1085 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1086 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1089 static void Op56(void) // RORB
1091 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
1092 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
1093 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1094 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1097 static void Op57(void) // ASRB
1099 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1100 regs.b >>= 1; // Do the shift
1101 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
1102 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1103 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1106 static void Op58(void) // LSLB
1108 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1110 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1111 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1114 static void Op59(void) // ROLB
1117 regs.b = (tmp<<1) + (regs.cc&0x01);
1118 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1119 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1120 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1123 static void Op5A(void) // DECB
1126 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1127 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1128 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1131 static void Op5C(void) // INCB
1134 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1135 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1136 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1139 static void Op5D(void) // TSTB
1141 regs.cc &= 0xFD; // Clear oVerflow flag
1142 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1143 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1146 static void Op5F(void) // CLRB
1149 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1152 static void Op60(void) // NEG IDX
1154 addr = DecodeIDX(regs.RdMem(regs.pc++));
1155 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1156 regs.WrMem(addr, res);
1157 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1158 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1159 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1160 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1161 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1164 static void Op63(void) // COM IDX
1166 addr = DecodeIDX(regs.RdMem(regs.pc++));
1167 tmp = regs.RdMem(addr) ^ 0xFF;
1168 regs.WrMem(addr, tmp);
1169 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1170 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1171 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1174 static void Op64(void) // LSR IDX
1176 addr = DecodeIDX(regs.RdMem(regs.pc++));
1177 tmp = regs.RdMem(addr);
1178 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1179 tmp >>= 1; regs.WrMem(addr, tmp);
1180 regs.cc &= 0xF7; // CLN
1181 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1184 static void Op66(void) // ROR IDX
1186 addr = DecodeIDX(regs.RdMem(regs.pc++));
1187 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1188 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1189 regs.WrMem(addr, tmp);
1190 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1191 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1192 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1195 static void Op67(void) // ASR IDX
1197 addr = DecodeIDX(regs.RdMem(regs.pc++));
1198 tmp = regs.RdMem(addr);
1199 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1201 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1202 regs.WrMem(addr, tmp);
1203 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1204 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1207 static void Op68(void) // LSL IDX
1209 addr = DecodeIDX(regs.RdMem(regs.pc++));
1210 tmp = regs.RdMem(addr);
1211 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1213 regs.WrMem(addr, tmp);
1214 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1215 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1218 static void Op69(void) // ROL IDX
1220 uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1221 tmp = (tmp2<<1) + (regs.cc&0x01);
1222 regs.WrMem(addr, tmp);
1223 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1224 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1225 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1228 static void Op6A(void) // DEC IDX
1230 uint8 tmp; uint16 addr;
1231 addr = DecodeIDX(regs.RdMem(regs.pc++));
1232 tmp = regs.RdMem(addr) - 1;
1233 regs.WrMem(addr, tmp);
1234 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1235 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1236 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1239 static void Op6C(void) // INC IDX
1241 addr = DecodeIDX(regs.RdMem(regs.pc++));
1242 tmp = regs.RdMem(addr) + 1;
1243 regs.WrMem(addr, tmp);
1244 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1245 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1246 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1249 static void Op6D(void) // TST IDX
1251 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1252 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1253 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1256 static void Op6E(void) // JMP IDX
1258 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1261 static void Op6F(void) // CLR IDX
1263 addr = DecodeIDX(regs.RdMem(regs.pc++));
1264 regs.WrMem(addr, 0);
1265 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1268 static void Op70(void) // NEG ABS
1271 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1272 regs.WrMem(addr, res);
1273 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1274 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1275 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1276 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1279 static void Op73(void) // COM ABS
1282 tmp = regs.RdMem(addr) ^ 0xFF;
1283 regs.WrMem(addr, tmp);
1284 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1285 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1286 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1289 static void Op74(void) // LSR ABS
1292 tmp = regs.RdMem(addr);
1293 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1294 tmp >>= 1; regs.WrMem(addr, tmp);
1295 regs.cc &= 0xF7; // CLN
1296 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1299 static void Op76(void) // ROR ABS
1301 uint8 tmp; uint16 addr;
1303 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1304 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1305 regs.WrMem(addr, tmp);
1306 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1307 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1308 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1311 static void Op77(void) // ASR ABS
1313 uint8 tmp; uint16 addr;
1315 tmp = regs.RdMem(addr);
1316 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1318 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1319 regs.WrMem(addr, tmp);
1320 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1321 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1324 static void Op78(void) // LSL ABS
1326 uint8 tmp; uint16 addr;
1328 tmp = regs.RdMem(addr);
1329 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1331 regs.WrMem(addr, tmp);
1332 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1333 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1336 static void Op79(void) // ROL ABS
1338 uint8 tmp2 = regs.RdMem(FetchW());
1339 tmp = (tmp2<<1) + (regs.cc&0x01);
1340 regs.WrMem(addr, tmp);
1341 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1342 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1343 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1346 static void Op7A(void) // DEC ABS
1348 uint8 tmp; uint16 addr;
1350 tmp = regs.RdMem(addr) - 1;
1351 regs.WrMem(addr, tmp);
1352 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1353 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1354 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1357 static void Op7C(void) // INC ABS
1359 uint8 tmp; uint16 addr;
1361 tmp = regs.RdMem(addr) + 1;
1362 regs.WrMem(addr, tmp);
1363 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1364 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1365 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1369 static void Op7D(void) // TST ABS
1371 uint8 tmp = regs.RdMem(FetchW());
1373 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1374 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1379 static void Op7E(void) // JMP ABS
1384 static void Op7F(void) // CLR ABS
1386 regs.WrMem(FetchW(), 0);
1387 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1390 static void Op80(void) // SUBA #
1392 uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1394 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1395 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1396 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1397 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1400 static void Op81(void) // CMPA #
1402 tmp = regs.RdMem(regs.pc++);
1403 uint8 db = regs.a - tmp;
1404 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1405 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1406 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1407 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1410 static void Op82(void) // SBCA #
1412 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1413 regs.a = regs.a - tmp - (regs.cc&0x01);
1414 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1415 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1416 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1417 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1420 static void Op83(void) // SUBD #
1422 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1424 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1425 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1426 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1427 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1428 regs.a = dr>>8; regs.b = dr&0xFF;
1431 static void Op84(void) // ANDA #
1433 regs.a &= regs.RdMem(regs.pc++);
1434 regs.cc &= 0xFD; // Clear oVerflow flag
1435 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1436 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1439 static void Op85(void) // BITA #
1441 tmp = regs.a & regs.RdMem(regs.pc++);
1442 regs.cc &= 0xFD; // Clear oVerflow flag
1443 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1444 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1447 static void Op86(void) // LDA #
1449 regs.a = regs.RdMem(regs.pc++);
1450 regs.cc &= 0xFD; // CLV
1451 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1452 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1455 static void Op88(void) // EORA #
1457 regs.a ^= regs.RdMem(regs.pc++);
1458 regs.cc &= 0xFD; // CLV
1459 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1460 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1463 static void Op89(void) // ADCA #
1465 tmp = regs.RdMem(regs.pc++);
1466 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1467 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1468 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1469 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1470 regs.a = addr & 0xFF; // Set accumulator
1471 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1472 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1475 static void Op8A(void) // ORA #
1477 regs.a |= regs.RdMem(regs.pc++);
1478 regs.cc &= 0xFD; // CLV
1479 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1480 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1483 static void Op8B(void) // ADDA #
1485 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
1486 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1487 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1488 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1489 regs.a = addr & 0xFF; // Set accumulator
1490 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1491 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1494 static void Op8C(void) // CMPX #
1497 uint16 dw = regs.x - addr;
1498 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1499 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1500 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1501 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1505 static void Op8D(void) // Bregs.s
1507 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
1508 regs.WrMem(--regs.s, regs.pc & 0xFF);
1509 regs.WrMem(--regs.s, regs.pc >> 8);
1515 static void Op8E(void) // LDX #
1518 regs.cc &= 0xFD; // CLV
1519 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1520 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1523 static void Op90(void) // SUBA DP
1525 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1527 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1528 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1529 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1530 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1533 static void Op91(void) // CMPA DP
1535 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1536 uint8 db = regs.a - tmp;
1537 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1538 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1539 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1540 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1543 static void Op92(void) // SBCA DP
1545 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1546 regs.a = regs.a - tmp - (regs.cc&0x01);
1547 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1548 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1549 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1550 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1553 static void Op93(void) // SUBD DP
1555 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1556 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1558 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1559 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1560 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1561 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1562 regs.a = dr>>8; regs.b = dr&0xFF;
1565 static void Op94(void) // ANDA DP
1567 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1568 regs.cc &= 0xF1; // CLV CLZ CLN
1569 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
1570 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
1573 static void Op95(void) // BITA DP
1575 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1576 regs.cc &= 0xFD; // Clear oVerflow flag
1577 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1578 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1581 static void Op96(void) // LDA DP
1583 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1584 regs.cc &= 0xF1; // CLN CLZ CLV
1585 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1586 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1589 static void Op97(void) // STA DP
1591 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
1592 regs.cc &= 0xFD; // CLV
1593 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1594 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1597 static void Op98(void) // EORA DP
1599 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1600 regs.cc &= 0xFD; // CLV
1601 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1602 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1605 static void Op99(void) // ADCA DP
1607 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1608 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1609 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1610 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1611 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1612 regs.a = addr & 0xFF; // Set accumulator
1613 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1614 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1617 static void Op9A(void) // ORA DP
1619 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1620 regs.cc &= 0xFD; // CLV
1621 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1622 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1625 static void Op9B(void) // ADDA DP
1627 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1628 addr = (uint16)regs.a + (uint16)tmp;
1629 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1630 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1631 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1632 regs.a = addr & 0xFF; // Set accumulator
1633 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1634 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1637 static void Op9C(void) // CMPX DP
1639 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1640 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1641 uint16 dw = regs.x - adr2;
1642 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1643 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1644 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1645 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1648 static void Op9D(void) // JSR DP
1650 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1651 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1652 regs.pc = addr; // JSR to DP location...
1655 static void Op9E(void) // LDX DP
1657 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1658 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1659 regs.cc &= 0xFD; // CLV
1660 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1661 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1664 static void Op9F(void) // STX DP
1666 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1667 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1668 regs.cc &= 0xFD; // CLV
1669 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1670 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1673 static void OpA0(void) // SUBA IDX
1675 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1677 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1678 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1679 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1680 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1683 static void OpA1(void) // CMPA IDX
1685 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1686 uint8 db = regs.a - tmp;
1687 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1688 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1689 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1690 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1693 static void OpA2(void) // SBCA IDX
1695 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1696 regs.a = regs.a - tmp - (regs.cc&0x01);
1697 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1698 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1699 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1700 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1703 static void OpA3(void) // SUBD IDX
1705 addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1706 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1708 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1709 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1710 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1711 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1712 regs.a = dr>>8; regs.b = dr&0xFF;
1715 static void OpA4(void) // ANDA IDX
1717 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1718 regs.cc &= 0xFD; // Clear oVerflow flag
1719 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1720 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1723 static void OpA5(void) // BITA IDX
1725 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1726 regs.cc &= 0xFD; // Clear oVerflow flag
1727 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1728 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1731 static void OpA6(void) // LDA IDX
1733 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1734 regs.cc &= 0xF1; // CLV CLZ CLN
1735 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1736 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1739 static void OpA7(void) // STA IDX
1741 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1742 regs.cc &= 0xF1; // CLV CLZ CLN
1743 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1744 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1747 static void OpA8(void) // EORA IDX
1749 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1750 regs.cc &= 0xFD; // CLV
1751 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1752 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1755 static void OpA9(void) // ADCA IDX
1757 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1758 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1759 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1760 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1761 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1762 regs.a = addr & 0xFF; // Set accumulator
1763 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1764 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1767 static void OpAA(void) // ORA IDX
1769 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1770 regs.cc &= 0xFD; // CLV
1771 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1772 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1775 static void OpAB(void) // ADDA IDX
1777 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1778 addr = (uint16)regs.a + (uint16)tmp;
1779 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1780 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1781 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1782 regs.a = addr & 0xFF; // Set accumulator
1783 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1784 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1787 static void OpAC(void) // CMPX IDX
1789 addr = DecodeIDX(regs.RdMem(regs.pc++));
1790 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1791 uint16 dw = regs.x - addr2;
1792 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1793 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1794 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1795 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1798 static void OpAD(void) // JSR IDX
1800 addr = DecodeIDX(regs.RdMem(regs.pc++));
1801 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1802 regs.pc = addr; // Jregs.s directly to IDX ptr
1805 static void OpAE(void) // LDX IDX
1807 addr = DecodeIDX(regs.RdMem(regs.pc++));
1808 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1809 regs.cc &= 0xFD; // CLV
1810 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1811 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1814 static void OpAF(void) // STX IDX
1816 addr = DecodeIDX(regs.RdMem(regs.pc++));
1817 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1818 regs.cc &= 0xF1; // CLV CLZ CLN
1819 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1820 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1823 static void OpB0(void) // SUBA ABS
1825 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1827 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1828 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1829 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1830 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1833 static void OpB1(void) // CMPA ABS
1835 tmp = regs.RdMem(FetchW());
1836 uint8 db = regs.a - tmp;
1837 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1838 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1839 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1840 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1843 static void OpB2(void) // SBCA ABS
1845 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1846 regs.a = regs.a - tmp - (regs.cc&0x01);
1847 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1848 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1849 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1850 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1853 static void OpB3(void) // SUBD ABS
1855 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1856 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1858 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1859 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1860 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1861 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1862 regs.a = dr>>8; regs.b = dr&0xFF;
1865 static void OpB4(void) // ANDA ABS
1867 regs.a &= regs.RdMem(FetchW());
1868 regs.cc &= 0xFD; // Clear oVerflow flag
1869 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1870 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1873 static void OpB5(void) // BITA ABS
1875 tmp = regs.a & regs.RdMem(FetchW());
1876 regs.cc &= 0xFD; // Clear oVerflow flag
1877 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1878 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1881 static void OpB6(void) // LDA ABS
1883 regs.a = regs.RdMem(FetchW());
1884 regs.cc &= 0xFD; // CLV
1885 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1886 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1889 static void OpB7(void) // STA ABS
1891 regs.WrMem(FetchW(), regs.a);
1892 regs.cc &= 0xFD; // CLV
1893 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1894 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1897 static void OpB8(void) // EORA ABS
1899 regs.a ^= regs.RdMem(FetchW());
1900 regs.cc &= 0xFD; // CLV
1901 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1902 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1905 static void OpB9(void) // ADCA ABS
1907 tmp = regs.RdMem(FetchW());
1908 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1909 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1910 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1911 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1912 regs.a = addr; // Set accumulator
1913 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1914 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1917 static void OpBA(void) // ORA ABS
1919 regs.a |= regs.RdMem(FetchW());
1920 regs.cc &= 0xFD; // CLV
1921 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1922 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1925 static void OpBB(void) // ADDA ABS
1927 tmp = regs.RdMem(FetchW());
1928 addr = (uint16)regs.a + (uint16)tmp;
1929 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1930 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1931 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1932 regs.a = addr & 0xFF; // Set accumulator
1933 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1934 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1937 static void OpBC(void) // CMPX ABS
1939 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1940 uint16 dw = regs.x - addr2;
1941 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1942 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1943 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1944 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1947 static void OpBD(void) // JSR ABS
1950 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1951 regs.pc = addr; // Go to absolute address (Not indir)
1955 static void OpBE(void) // LDX ABS
1958 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1959 regs.x = RdMemW(FetchW());
1961 regs.cc &= 0xFD; // CLV
1962 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1963 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1968 static void OpBF(void) // STX ABS
1971 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1972 WrMemW(FetchW(), regs.x);
1974 regs.cc &= 0xFD; // CLV
1975 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1976 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1981 static void OpC0(void) // SUBB #
1983 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
1985 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1986 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1987 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1988 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1991 static void OpC1(void) // CMPB #
1993 tmp = regs.RdMem(regs.pc++);
1994 uint8 db = regs.b - tmp;
1995 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1996 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1997 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1998 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2001 static void OpC2(void) // SBCB #
2003 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
2004 regs.b = regs.b - tmp - (regs.cc&0x01);
2005 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2006 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2007 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2008 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2011 static void OpC3(void) // ADDD #
2013 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2015 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2017 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2018 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2019 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2020 regs.a = dr>>8; regs.b = dr&0xFF;
2023 static void OpC4(void) // ANDB #
2025 regs.b &= regs.RdMem(regs.pc++);
2026 regs.cc &= 0xFD; // Clear oVerflow flag
2027 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2028 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2031 static void OpC5(void) // BITB #
2033 tmp = regs.b & regs.RdMem(regs.pc++);
2034 regs.cc &= 0xF1; // CLV CLZ CLN
2035 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
2036 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
2039 static void OpC6(void) // LDB #
2041 regs.b = regs.RdMem(regs.pc++);
2042 regs.cc &= 0xF1; // CLV CLZ CLN
2043 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
2044 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
2047 static void OpC8(void) // EORB #
2049 regs.b ^= regs.RdMem(regs.pc++);
2050 regs.cc &= 0xFD; // CLV
2051 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2052 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2055 static void OpC9(void) // ADCB #
2057 tmp = regs.RdMem(regs.pc++);
2058 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2059 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2060 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2061 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2062 regs.b = addr & 0xFF; // Set accumulator
2063 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2064 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2067 static void OpCA(void) // ORB #
2069 regs.b |= regs.RdMem(regs.pc++);
2070 regs.cc &= 0xFD; // CLV
2071 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2072 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2075 static void OpCB(void) // ADDB #
2077 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
2078 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2079 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2080 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2081 regs.b = addr & 0xFF; // Set accumulator
2082 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2083 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2086 static void OpCC(void) // LDD #
2088 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
2089 regs.cc &= 0xFD; // CLV
2090 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2091 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2094 static void OpCE(void) // LDU #
2097 regs.cc &= 0xFD; // CLV
2098 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2099 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2102 static void OpD0(void) // SUBB DP
2104 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2106 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2107 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2108 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2109 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2112 static void OpD1(void) // CMPB DP
2114 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2115 uint8 db = regs.b - tmp;
2116 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2117 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2118 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2119 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2122 static void OpD2(void) // SBCB DP
2124 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2125 regs.b = regs.b - tmp - (regs.cc&0x01);
2126 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2127 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2128 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2129 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2132 static void OpD3(void) // ADDD DP
2134 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2135 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2137 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2139 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2140 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2141 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2142 regs.a = dr>>8; regs.b = dr&0xFF;
2145 static void OpD4(void) // ANDB DP
2147 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2148 regs.cc &= 0xFD; // Clear oVerflow flag
2149 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2150 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2153 static void OpD5(void) // BITB DP
2155 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2156 regs.cc &= 0xFD; // Clear oVerflow flag
2157 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2158 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2161 static void OpD6(void) // LDB DP
2163 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2164 regs.cc &= 0xFD; // CLV
2165 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2166 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2169 static void OpD7(void) // STB DP
2171 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2172 regs.cc &= 0xFD; // CLV
2173 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2174 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2177 static void OpD8(void) // EORB DP
2179 regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2180 regs.cc &= 0xFD; // CLV
2181 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2182 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2185 static void OpD9(void) // ADCB DP
2187 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2188 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2189 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2190 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2191 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2192 regs.b = addr; // Set accumulator
2193 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2194 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2197 static void OpDA(void) // ORB DP
2199 regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2200 regs.cc &= 0xFD; // CLV
2201 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2202 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2205 static void OpDB(void) // ADDB DP
2207 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2208 addr = (uint16)regs.b + (uint16)tmp;
2209 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2210 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2211 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2212 regs.b = addr & 0xFF; // Set accumulator
2213 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2214 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2217 static void OpDC(void) // LDD DP
2219 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2220 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2221 regs.cc &= 0xFD; // CLV
2222 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2223 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2226 static void OpDD(void) // STD DP
2228 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2229 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2230 regs.cc &= 0xFD; // CLV
2231 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2232 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2235 static void OpDE(void) // LDU DP
2237 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2238 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2239 regs.cc &= 0xFD; // CLV
2240 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2241 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2244 static void OpDF(void) // STU DP
2246 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2247 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2248 regs.cc &= 0xFD; // CLV
2249 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2250 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2253 static void OpE0(void) // SUBB IDX
2255 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2257 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2258 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2259 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2260 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2263 static void OpE1(void) // CMPB IDX
2265 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2266 uint8 db = regs.b - tmp;
2267 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2268 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2269 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2270 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2273 static void OpE2(void) // SBCB IDX
2275 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2276 regs.b = regs.b - tmp - (regs.cc&0x01);
2277 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2278 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2279 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2280 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2283 static void OpE3(void) // ADDD IDX
2285 addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2286 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2288 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2290 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2291 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2292 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2293 regs.a = dr>>8; regs.b = dr&0xFF;
2296 static void OpE4(void) // ANDB IDX
2298 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2299 regs.cc &= 0xFD; // Clear oVerflow flag
2300 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2301 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2304 static void OpE5(void) // BITB IDX
2306 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2307 regs.cc &= 0xFD; // Clear oVerflow flag
2308 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2309 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2312 static void OpE6(void) // LDB IDX
2314 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2315 regs.cc &= 0xFD; // CLV
2316 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2317 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2320 static void OpE7(void) // STB IDX
2322 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2323 regs.cc &= 0xF1; // CLV CLZ CLN
2324 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
2325 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
2328 static void OpE8(void) // EORB IDX
2330 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2331 regs.cc &= 0xFD; // CLV
2332 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2333 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2336 static void OpE9(void) // ADCB IDX
2338 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2339 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2340 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2341 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2342 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2343 regs.b = addr; // Set accumulator
2344 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2345 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2348 static void OpEA(void) // ORB IDX
2350 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2351 regs.cc &= 0xFD; // CLV
2352 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2353 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2356 static void OpEB(void) // ADDB IDX
2358 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2359 addr = (uint16)regs.b + (uint16)tmp;
2360 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2361 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2362 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2363 regs.b = addr; // Set accumulator
2364 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2365 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2368 static void OpEC(void) // LDD IDX
2370 addr = DecodeIDX(regs.RdMem(regs.pc++));
2371 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2372 regs.cc &= 0xF1; // CLV CLZ CLN
2373 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2374 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2377 static void OpED(void) // STD IDX
2379 addr = DecodeIDX(regs.RdMem(regs.pc++));
2380 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2381 regs.cc &= 0xF1; // CLV CLZ CLZ
2382 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2383 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2386 static void OpEE(void) // LDU IDX
2388 addr = DecodeIDX(regs.RdMem(regs.pc++));
2389 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2390 regs.cc &= 0xF1; // CLV CLZ CLN
2391 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2392 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2395 static void OpEF(void) // STU IDX
2397 addr = DecodeIDX(regs.RdMem(regs.pc++));
2398 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2399 regs.cc &= 0xF1; // CLV CLZ CLN
2400 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2401 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2404 static void OpF0(void) // SUBB ABS
2406 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2408 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2409 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2410 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2411 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2413 static void OpF1(void) // CMPB ABS
2415 tmp = regs.RdMem(FetchW());
2416 uint8 db = regs.b - tmp;
2417 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2418 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2419 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2420 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2423 static void OpF2(void) // SBCB ABS
2425 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2426 regs.b = regs.b - tmp - (regs.cc&0x01);
2427 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2428 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2429 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2430 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2433 static void OpF3(void) // ADDD ABS
2435 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2436 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2438 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2440 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2441 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2442 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2443 regs.a = dr>>8; regs.b = dr&0xFF;
2446 static void OpF4(void) // ANDB ABS
2448 regs.b &= regs.RdMem(FetchW());
2449 regs.cc &= 0xFD; // Clear oVerflow flag
2450 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2451 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2454 static void OpF5(void) // BITB ABS
2456 tmp = regs.b & regs.RdMem(FetchW());
2457 regs.cc &= 0xFD; // Clear oVerflow flag
2458 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2459 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2462 static void OpF6(void) // LDB ABS
2464 regs.b = regs.RdMem(FetchW());
2465 regs.cc &= 0xFD; // CLV
2466 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2467 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2470 static void OpF7(void) // STB ABS
2472 regs.WrMem(FetchW(), regs.b);
2473 regs.cc &= 0xFD; // CLV
2474 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2475 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2478 static void OpF8(void) // EORB ABS
2480 regs.b ^= regs.RdMem(FetchW());
2481 regs.cc &= 0xFD; // CLV
2482 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2483 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2486 static void OpF9(void) // ADCB ABS
2488 tmp = regs.RdMem(FetchW());
2489 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2490 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2491 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2492 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2493 regs.b = addr & 0xFF; // Set accumulator
2494 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2495 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2498 static void OpFA(void) // ORB ABS
2500 regs.b |= regs.RdMem(FetchW());
2501 regs.cc &= 0xFD; // CLV
2502 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2503 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2506 static void OpFB(void) // ADDB ABS
2508 tmp = regs.RdMem(FetchW());
2509 addr = (uint16)regs.b + (uint16)tmp;
2510 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2511 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2512 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2513 regs.b = addr & 0xFF; // Set accumulator
2514 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2515 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2518 static void OpFC(void) // LDD ABS
2521 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2522 regs.cc &= 0xFD; // CLV
2523 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2524 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2527 static void OpFD(void) // STD ABS
2530 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2531 regs.cc &= 0xFD; // CLV
2532 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2533 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2536 static void OpFE(void) // LDU ABS
2539 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2540 regs.cc &= 0xFD; // CLV
2541 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2542 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2545 static void OpFF(void) // STU ABS
2548 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2549 regs.cc &= 0xFD; // CLV
2550 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2551 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2556 // Page one opcodes' execute code
2559 static void Op1021(void) // LBRN
2566 static void Op1022(void) // LBHI
2568 uint16 word = FetchW();
2570 if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
2576 static void Op1023(void) // LBLS
2578 uint16 word = FetchW();
2580 if ((regs.cc & 0x01) | (regs.cc & 0x04))
2586 static void Op1024(void) // LBCC (LBHS)
2588 uint16 word = FetchW();
2590 if (!(regs.cc & 0x01))
2596 static void Op1025(void) // LBCS (LBLO)
2598 uint16 word = FetchW();
2606 static void Op1026(void) // LBNE
2608 uint16 word = FetchW();
2610 if (!(regs.cc & 0x04))
2616 static void Op1027(void) // LBEQ
2618 uint16 word = FetchW();
2626 static void Op1028(void) // LBVC
2628 uint16 word = FetchW();
2630 if (!(regs.cc & 0x02))
2636 static void Op1029(void) // LBVS
2638 uint16 word = FetchW();
2646 static void Op102A(void) // LBPL
2648 uint16 word = FetchW();
2650 if (!(regs.cc & 0x08))
2656 static void Op102B(void) // LBMI
2658 uint16 word = FetchW();
2666 static void Op102C(void) // LBGE
2668 uint16 word = FetchW();
2670 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2676 static void Op102D(void) // LBLT
2678 uint16 word = FetchW();
2680 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
2686 static void Op102E(void) // LBGT
2688 uint16 word = FetchW();
2690 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
2696 static void Op102F(void) // LBLE
2698 uint16 word = FetchW();
2700 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2706 static void Op103F(void) // SWI2 (Not yet implemented)
2710 static void Op1083(void) // CMPD #
2712 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2713 uint16 dw = dr - addr;
2714 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2715 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2716 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2717 ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2720 static void Op108C(void) // CMPY #
2723 uint16 dw = regs.y - addr;
2724 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2725 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2726 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2727 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2730 static void Op108E(void) // LDY #
2733 regs.cc &= 0xFD; // CLV
2734 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2735 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2738 static void Op1093(void) // CMPD DP
2740 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2741 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2742 uint16 dw = dr - addr;
2743 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2744 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2745 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2746 ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2749 static void Op109C(void) // CMPY DP
2751 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2752 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2753 uint16 dw = regs.y - addr;
2754 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2755 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2756 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2757 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2761 static void Op109E(void) // LDY DP
2763 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2764 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2765 regs.cc &= 0xFD; // CLV
2766 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2767 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2771 static void Op109F(void) // STY DP
2773 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2774 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2775 regs.cc &= 0xFD; // CLV
2776 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2777 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2780 static void Op10A3(void) // CMPD IDX
2782 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2783 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2784 uint16 dw = dr - addr;
2785 regs.cc &= 0xF0; // CLC CLV CLZ CLN
2786 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
2787 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
2788 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
2789 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
2792 static void Op10AC(void) // CMPY IDX
2794 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2795 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2796 uint16 dw = regs.y - addr;
2797 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2798 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2799 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2800 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2803 static void Op10AE(void) // LDY IDX
2805 addr = DecodeIDX(regs.RdMem(regs.pc++));
2806 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2807 regs.cc &= 0xF1; // CLV CLZ CLN
2808 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
2809 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
2812 static void Op10AF(void) // STY IDX
2814 addr = DecodeIDX(regs.RdMem(regs.pc++));
2815 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2816 regs.cc &= 0xFD; // CLV
2817 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2818 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2821 static void Op10B3(void) // CMPD ABS
2823 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2824 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2825 uint16 dw = dr - addr2;
2826 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2827 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2828 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2829 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2832 static void Op10BC(void) // CMPY ABS
2834 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2835 uint16 dw = regs.y - addr2;
2836 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2837 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2838 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2839 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2842 static void Op10BE(void) // LDY ABS
2845 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2846 regs.cc &= 0xFD; // CLV
2847 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2848 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2851 static void Op10BF(void) // STY ABS
2854 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2855 regs.cc &= 0xFD; // CLV
2856 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2857 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2860 static void Op10CE(void) // LDS #
2863 regs.cc &= 0xFD; // CLV
2864 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2865 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2868 static void Op10DE(void) // LDS DP
2870 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2871 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2872 regs.cc &= 0xFD; // CLV
2873 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2874 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2877 static void Op10DF(void) // STS DP
2879 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2880 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2881 regs.cc &= 0xFD; // CLV
2882 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2883 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2886 static void Op10EE(void) // LDS IDX
2888 addr = DecodeIDX(regs.RdMem(regs.pc++));
2889 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2890 regs.cc &= 0xFD; // CLV
2891 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2892 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2895 static void Op10EF(void) // STS IDX
2897 addr = DecodeIDX(regs.RdMem(regs.pc++));
2898 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2899 regs.cc &= 0xFD; // CLV
2900 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2901 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2904 static void Op10FE(void) // LDS ABS
2907 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2908 regs.cc &= 0xFD; // CLV
2909 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2910 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2913 static void Op10FF(void) // STS ABS
2916 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2917 regs.cc &= 0xFD; // CLV
2918 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2919 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2924 // Page two opcodes' execute code
2927 static void Op113F(void) // SWI3
2931 static void Op1183(void) // CMPU #
2934 uint16 dw = regs.u - addr;
2935 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2936 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2937 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2938 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2941 static void Op118C(void) // CMPS #
2944 uint16 dw = regs.s - addr;
2945 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2946 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2947 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2948 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2951 static void Op1193(void) // CMPU DP
2953 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2954 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2955 uint16 dw = regs.u - addr;
2956 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2957 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2958 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2959 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2962 static void Op119C(void) // CMPS DP
2964 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2965 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2966 uint16 dw = regs.s - addr;
2967 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2968 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2969 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2970 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2973 static void Op11A3(void) // CMPU IDX
2975 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2976 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2977 uint16 dw = regs.u - addr;
2978 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2979 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2980 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2981 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2984 static void Op11AC(void) // CMPS IDX
2986 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2987 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2988 uint16 dw = regs.s - addr;
2989 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2990 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2991 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2992 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2995 static void Op11B3(void) // CMPU ABS
2997 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2998 uint16 dw = regs.u - addr2;
2999 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3000 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3001 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3002 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3006 static void Op11BC(void) // CMPS ABS
3008 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3009 uint16 dw = regs.s - addr2;
3010 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3011 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3012 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3013 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3017 //temp, for testing...
3019 static uint8 backTrace[256];
3020 static uint16 btPC[256];
3021 static int btPtr = 0;//*/
3023 static void Op__(void) // Illegal opcode
3027 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3029 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3030 for(int i=0; i<256; i++)
3032 Decode6809(btPC[(btPtr + i) & 0xFF]);
3040 // Internal "memcpy" (so we don't have to link with any external libraries!)
3042 static void myMemcpy(void * dst, void * src, uint32 size)
3044 uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
3046 for(uint32 i=0; i<size; i++)
3051 // Function to execute 6809 instructions
3053 //#define DEBUG_ILLEGAL
3054 #ifdef DEBUG_ILLEGAL
3056 #include "dis6809.h"
3058 uint8 backTrace[256];
3059 V6809REGS btRegs[256];
3060 bool tripped = false;
3062 void Execute6809(V6809REGS * context, uint32 cycles)
3064 // If this is not in place, the clockOverrun calculations can cause the V6809 to get
3065 // stuck in an infinite loop.
3066 if (cycles == 0) // Nothing to do, so bail!
3069 myMemcpy(®s, context, sizeof(V6809REGS));
3073 // Since we can't guarantee that we'll execute the number of cycles passed in
3074 // exactly, we have to keep track of how much we overran the number of cycles
3075 // the last time we executed. Since we already executed those cycles, this time
3076 // through we remove them from the cycles passed in in order to come out
3077 // approximately even. Over the long run, this unevenness in execution times
3079 uint64 endCycles = regs.clock + (uint64)(cycles - regs.clockOverrun);
3081 while (regs.clock < endCycles)
3083 #ifdef DEBUG_ILLEGAL
3086 backTrace[btPtr] = regs.RdMem(regs.pc);
3087 btRegs[btPtr] = regs;
3088 btPtr = (btPtr + 1) & 0xFF;
3090 if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3092 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3093 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3095 for(uint16 i=btPtr; i<btPtr+256; i++)
3097 Decode6809(btRegs[i & 0xFF].pc);
3098 // Note that these values are *before* execution, so stale...
3099 WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3100 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);//*/
3108 //Decode6809(regs.pc);
3109 static bool disasm = false;
3110 /*//if (regs.pc == 0x15BA) disasm = true;
3111 //if (regs.pc == 0xFE76) disasm = true;
3112 if (regs.x == 0xFED4) disasm = true;
3113 if (disasm) Decode6809(regs.pc);
3114 //if (regs.pc == 0x164A) disasm = false;//*/
3116 //temp, for testing...
3117 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3118 btPC[btPtr] = regs.pc;
3119 btPtr = (btPtr + 1) & 0xFF;//*/
3121 exec_op0[regs.RdMem(regs.pc++)]();
3123 // Handle any pending interrupts
3125 uint32 flags = context->cpuFlags;
3127 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
3130 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3132 regs.cc |= (FLAG_F | FLAG_I); // Set F, I
3133 regs.dp = 0; // Reset direct page register
3134 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3135 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3136 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3138 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
3141 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3143 regs.cc |= FLAG_E; // Set the Entire flag
3145 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3146 regs.WrMem(--regs.s, regs.pc >> 8);
3147 regs.WrMem(--regs.s, regs.u & 0xFF);
3148 regs.WrMem(--regs.s, regs.u >> 8);
3149 regs.WrMem(--regs.s, regs.y & 0xFF);
3150 regs.WrMem(--regs.s, regs.y >> 8);
3151 regs.WrMem(--regs.s, regs.x & 0xFF);
3152 regs.WrMem(--regs.s, regs.x >> 8);
3153 regs.WrMem(--regs.s, regs.dp);
3154 regs.WrMem(--regs.s, regs.b);
3155 regs.WrMem(--regs.s, regs.a);
3156 regs.WrMem(--regs.s, regs.cc);
3158 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3159 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3161 // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3162 // regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
3164 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
3167 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3169 if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
3172 if (disasm) WriteLog(" FIRQ taken...\n");
3174 regs.cc &= ~FLAG_E; // Clear the Entire flag
3176 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
3177 regs.WrMem(--regs.s, regs.pc >> 8);
3178 regs.WrMem(--regs.s, regs.cc);
3180 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3181 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3183 // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3184 // regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3187 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
3190 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3192 if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
3195 if (disasm) WriteLog(" IRQ taken...\n");
3197 regs.cc |= FLAG_E; // Set the Entire flag
3199 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3200 regs.WrMem(--regs.s, regs.pc >> 8);
3201 regs.WrMem(--regs.s, regs.u & 0xFF);
3202 regs.WrMem(--regs.s, regs.u >> 8);
3203 regs.WrMem(--regs.s, regs.y & 0xFF);
3204 regs.WrMem(--regs.s, regs.y >> 8);
3205 regs.WrMem(--regs.s, regs.x & 0xFF);
3206 regs.WrMem(--regs.s, regs.x >> 8);
3207 regs.WrMem(--regs.s, regs.dp);
3208 regs.WrMem(--regs.s, regs.b);
3209 regs.WrMem(--regs.s, regs.a);
3210 regs.WrMem(--regs.s, regs.cc);
3212 regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3213 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3215 // Apparently, not done here!
3216 // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3217 // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3221 if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3222 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3223 /*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);//*/
3228 // Keep track of how much we overran so we can adjust on the next run...
3229 regs.clockOverrun = (uint32)(regs.clock - endCycles);
3231 myMemcpy(context, ®s, sizeof(V6809REGS));
3235 // Get the clock of the currently executing CPU
3237 uint64 GetCurrentV6809Clock(void)
3243 // Get the PC of the currently executing CPU
3245 uint16 GetCurrentV6809PC(void)
3250 // Set a line of the currently executing CPU
3251 void SetLine(uint32 line)
3253 regs.cpuFlags |= line;
3256 // Clear a line of the currently executing CPU
3257 void ClearLine(uint32 line)
3259 regs.cpuFlags &= ~line;