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 #define EA_IMM regs.pc++
50 #define EA_ZP regs.RdMem(regs.pc++)
51 #define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) & 0xFF
52 #define EA_ZP_Y (regs.RdMem(regs.pc++) + regs.y) & 0xFF
53 #define EA_ABS RdMemW(regs.pc)
54 #define EA_ABS_X RdMemW(regs.pc) + regs.x
55 #define EA_ABS_Y RdMemW(regs.pc) + regs.y
56 #define EA_IND_ZP_X RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF)
57 #define EA_IND_ZP_Y RdMemW(regs.RdMem(regs.pc++)) + regs.y
58 #define EA_IND_ZP RdMemW(regs.RdMem(regs.pc++))
60 #define READ_IMM regs.RdMem(EA_IMM)
61 #define READ_ZP regs.RdMem(EA_ZP)
62 #define READ_ZP_X regs.RdMem(EA_ZP_X)
63 #define READ_ZP_Y regs.RdMem(EA_ZP_Y)
64 #define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2
65 #define READ_ABS_X regs.RdMem(EA_ABS_X); regs.pc += 2
66 #define READ_ABS_Y regs.RdMem(EA_ABS_Y); regs.pc += 2
67 #define READ_IND_ZP_X regs.RdMem(EA_IND_ZP_X)
68 #define READ_IND_ZP_Y regs.RdMem(EA_IND_ZP_Y)
69 #define READ_IND_ZP regs.RdMem(EA_IND_ZP)
71 #define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr)
72 #define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr)
73 #define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr)
74 #define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2
75 #define READ_ABS_X_WB(v) uint16 addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2
76 #define READ_ABS_Y_WB(v) uint16 addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2
77 #define READ_IND_ZP_X_WB(v) uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr)
78 #define READ_IND_ZP_Y_WB(v) uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
79 #define READ_IND_ZP_WB(v) uint16 addr = EA_IND_ZP; v = regs.RdMem(addr)
81 #define WRITE_BACK(d) regs.WrMem(addr, (d))
83 // Private global variables
85 static V6809REGS regs;
86 //Let's see if we can nuke this shit.
87 static uint16 addr; // Temporary variables common to all funcs...
90 // Private function prototypes
92 static uint16 FetchW(void);
93 static uint16 RdMemW(uint16 addr);
94 static void WrMemW(uint16 addr, uint16 w);
95 static uint16 ReadEXG(uint8); // Read TFR/EXG post byte
96 static void WriteEXG(uint8, uint16); // Set TFR/EXG data
97 static uint16 DecodeReg(uint8); // Decode register data
98 static uint16 DecodeIDX(uint8); // Decode IDX data
100 //static void (* exec_op1[256])();
101 //static void (* exec_op2[256])();
104 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
105 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
106 // even *try* to see if they're there).
108 #define FD(x) static void Op##x(); // FD -> "Forward Declaration"
109 #define FE(x) static void Op10##x();
110 #define FF(x) static void Op11##x();
112 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)
113 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)
114 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)
115 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)
116 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)
117 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)
118 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)
119 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)
120 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)
121 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)
122 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)
123 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)
124 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)
125 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)
126 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)
127 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)
130 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)
131 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)
132 FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
134 FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
142 // We can move these down and do away with the forward declarations... !!! FIX !!!
143 // Actually, we can't because these are used in a couple of the opcode functions.
144 // Have to think about how to fix that...
150 // Array of page zero opcode functions...
151 static void (* exec_op0[256])() = {
152 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
153 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
154 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
155 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
156 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
157 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
158 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
159 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
160 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
161 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
162 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
163 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
164 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
165 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
166 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
167 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
170 // Array of page one opcode functions...
171 static void (* exec_op1[256])() = {
172 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
173 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
174 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
175 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
176 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
177 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
178 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
179 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
180 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
181 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
182 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
183 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
184 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
185 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
186 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
187 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
190 // Array of page two opcode functions...
191 static void (* exec_op2[256])() = {
192 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
193 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
194 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
195 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
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__, Op__,
198 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
199 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
200 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
201 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
202 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
203 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
204 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
205 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
206 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
207 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
212 // Fetch a word out of 6809 memory (little endian format)
213 // This is a leftover from when fetches were separated from garden variety reads...
215 static uint16 FetchW()
217 uint16 w = RdMemW(regs.pc);
222 // Fetch word function
224 /*uint16 FetchW(void)
226 return (uint16)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
230 // Read word from memory function
232 uint16 RdMemW(uint16 addr)
234 return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
238 // Write word to memory function
240 void WrMemW(uint16 addr, uint16 w)
242 regs.WrMem(addr + 0, w >> 8);
243 regs.WrMem(addr + 1, w & 0xFF);
247 // Function to read TFR/EXG post byte
249 uint16 ReadEXG(uint8 code)
256 retval = (regs.a << 8) | regs.b;
293 // Function to set TFR/EXG data
295 void WriteEXG(uint8 code, uint16 data)
300 regs.a = data >> 8, regs.b = data & 0xFF; break;
302 regs.x = data; break;
304 regs.y = data; break;
306 regs.u = data; break;
308 regs.s = data; break;
310 regs.pc = data; break;
312 regs.a = data & 0xFF; break;
314 regs.b = data & 0xFF; break;
316 regs.cc = data & 0xFF; break;
318 regs.dp = data & 0xFF; break;
323 // Function to decode register data
325 uint16 DecodeReg(uint8 reg)
332 retval = regs.x; break;
334 retval = regs.y; break;
336 retval = regs.u; break;
338 retval = regs.s; break;
345 // Function to decode IDX data
347 uint16 DecodeIDX(uint8 code)
350 uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
352 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
353 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
361 woff = DecodeReg(reg);
365 case 0: regs.x += 2; break;
366 case 1: regs.y += 2; break;
367 case 2: regs.u += 2; break;
368 case 3: regs.s += 2; break;
374 case 0: regs.x -= 2; break;
375 case 1: regs.y -= 2; break;
376 case 2: regs.u -= 2; break;
377 case 3: regs.s -= 2; break;
379 woff = DecodeReg(reg);
383 woff = DecodeReg(reg);
387 // woff = DecodeReg(reg) + SignedB(regs.b);
388 woff = DecodeReg(reg) + (int16)(int8)regs.b;
392 // woff = DecodeReg(reg) + SignedB(regs.a);
393 woff = DecodeReg(reg) + (int16)(int8)regs.a;
397 // woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++));
398 woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);
402 // woff = DecodeReg(reg) + SignedW(FetchW());
403 woff = DecodeReg(reg) + FetchW();
407 // woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b);
408 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
412 // woff = regs.pc + SignedB(regs.RdMem(regs.pc++));
413 woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);
417 // woff = regs.pc + SignedW(FetchW());
418 woff = regs.pc + FetchW();
432 addr = DecodeReg(reg);
435 case 0: regs.x++; break;
436 case 1: regs.y++; break;
437 case 2: regs.u++; break;
438 case 3: regs.s++; break;
442 addr = DecodeReg(reg);
445 case 0: regs.x += 2; break;
446 case 1: regs.y += 2; break;
447 case 2: regs.u += 2; break;
448 case 3: regs.s += 2; break;
451 case 2: { switch(reg)
453 case 0: regs.x--; break;
454 case 1: regs.y--; break;
455 case 2: regs.u--; break;
456 case 3: regs.s--; break;
458 addr = DecodeReg(reg); break; }
459 case 3: { switch(reg)
461 case 0: regs.x--; regs.x--; break;
462 case 1: regs.y--; regs.y--; break;
463 case 2: regs.u--; regs.u--; break;
464 case 3: regs.s--; regs.s--; break;
466 addr = DecodeReg(reg); break; }
467 case 4: { addr = DecodeReg(reg); break; }
468 // case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; }
469 case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; }
470 // case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; }
471 case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; }
472 // case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; }
473 case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; }
474 // case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; }
475 case 9: { addr = DecodeReg(reg) + FetchW(); break; }
476 // case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; }
477 case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
478 // case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; }
479 case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; }
480 // case 13: { addr = regs.pc + SignedW(FetchW()); break; }
481 case 13: { addr = regs.pc + FetchW(); break; }
490 // Page zero instructions...
493 static void Op00(void) // NEG DP
495 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
496 tmp = 256 - regs.RdMem(addr);
497 regs.WrMem(addr, tmp);
499 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
500 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
501 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
502 (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
507 static void Op01(void) // NEG DP (Undocumented)
512 static void Op03(void) // COM DP
514 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
515 tmp = 0xFF ^ regs.RdMem(addr);
516 regs.WrMem(addr, tmp);
518 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
519 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
520 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
525 static void Op04(void) // LSR DP
527 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
528 tmp = regs.RdMem(addr);
529 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
530 tmp >>= 1; regs.WrMem(addr, tmp);
531 regs.cc &= 0xF7; // CLN
532 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
535 static void Op06(void) // ROR DP
537 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
538 tmp = (tmp2>>1) + (regs.cc&0x01)*128;
539 regs.WrMem(addr, tmp);
540 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
541 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
542 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
545 static void Op07(void) // ASR DP
547 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
548 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
550 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
551 regs.WrMem(addr, tmp);
552 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
553 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
556 static void Op08(void) // LSL DP
558 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
559 tmp = regs.RdMem(addr);
560 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
562 regs.WrMem(addr, tmp);
563 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
564 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
567 static void Op09(void) // ROL DP
569 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
570 tmp = (tmp2<<1) + (regs.cc&0x01);
571 regs.WrMem(addr, tmp);
572 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
573 ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
574 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
575 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
578 static void Op0A(void) // DEC DP
580 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
581 tmp = regs.RdMem(addr) - 1;
582 regs.WrMem(addr, tmp);
583 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
584 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
585 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
588 static void Op0C(void) // INC DP
590 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
591 tmp = regs.RdMem(addr) + 1;
592 regs.WrMem(addr, tmp);
593 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
594 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
595 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
598 static void Op0D(void) // TST DP
600 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
601 regs.cc &= 0xFD; // CLV
602 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
603 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
606 static void Op0E(void) // JMP DP
608 regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
611 static void Op0F(void) // CLR DP
613 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
614 regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
618 static void Op10(void) // Page 1 opcode
620 exec_op1[regs.RdMem(regs.pc++)]();
623 static void Op11(void) // Page 2 opcode
625 exec_op2[regs.RdMem(regs.pc++)]();
628 static void Op12(void) // NOP
633 static void Op13(void) // SYNC
635 // Fix this so it does the right thing (software interrupt!)
639 static void Op16(void) // LBRA
641 // regs.pc += SignedW(FetchW());
642 regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities
647 static void Op17(void) // LBSR
649 uint16 word = FetchW();
650 regs.WrMem(--regs.s, regs.pc & 0xFF);
651 regs.WrMem(--regs.s, regs.pc >> 8);
652 // regs.pc += SignedW(addr);
653 regs.pc += word; // No need to make signed, both are 16 bit
658 static void Op19(void) // DAA
660 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
662 regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry
664 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
666 regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
668 regs.cc &= 0xF1; // CL NZV
669 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
670 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
674 static void Op1A(void) // ORCC #
676 regs.cc |= regs.RdMem(regs.pc++);
681 static void Op1C(void) // ANDCC #
683 regs.cc &= regs.RdMem(regs.pc++);
688 static void Op1D(void) // SEX
690 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
692 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
693 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
698 static void Op1E(void) // EXG
700 tmp = regs.RdMem(regs.pc++);
701 addr = ReadEXG(tmp >> 4);
702 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
703 WriteEXG(tmp & 0xF, addr);
708 static void Op1F(void) // TFR
710 tmp = regs.RdMem(regs.pc++);
711 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
715 static void Op20(void) // BRA
717 // regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
718 regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1; // Branch always
723 static void Op21(void) // BRN
725 regs.RdMem(regs.pc++);
730 static void Op22(void) // BHI
732 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
734 if (!(regs.cc & 0x05))
740 static void Op23(void) // BLS
742 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
750 static void Op24(void) // BCC (BHS)
752 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
754 if (!(regs.cc & 0x01))
760 static void Op25(void) // BCS (BLO)
762 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
770 static void Op26(void) // BNE
772 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
774 if (!(regs.cc & 0x04))
780 static void Op27(void) // BEQ
782 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
790 static void Op28(void) // BVC
792 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
794 if (!(regs.cc & 0x02))
800 static void Op29(void) // BVS
802 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
810 static void Op2A(void) // BPL
812 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
814 if (!(regs.cc & 0x08))
820 static void Op2B(void) // BMI
822 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
830 static void Op2C(void) // BGE
832 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
834 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
840 static void Op2D(void) // BLT
842 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
844 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
850 static void Op2E(void) // BGT
852 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
854 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
860 static void Op2F(void) // BLE
862 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
864 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
870 static void Op30(void) // LEAX
872 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
873 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
876 static void Op31(void) // LEAY
878 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
879 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
882 static void Op32(void) // LEAS
884 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
885 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
888 static void Op33(void) // LEAU
890 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
891 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
894 static void Op34(void) // PSHS
896 tmp = regs.RdMem(regs.pc++);
897 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
898 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
899 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
900 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
901 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
902 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
903 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
904 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
907 static void Op35(void) // PULS
909 tmp = regs.RdMem(regs.pc++);
910 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
911 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
912 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
913 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
914 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
915 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
916 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
917 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
921 static void Op36(void) // PSHU
923 tmp = regs.RdMem(regs.pc++);
925 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
926 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
927 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
928 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
929 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
930 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
931 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
932 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
937 static void Op37(void) // PULU
939 tmp = regs.RdMem(regs.pc++);
940 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
941 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
942 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
943 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
944 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
945 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
946 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
947 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
950 static void Op39(void) // RTS
952 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
955 static void Op3A(void) // ABX
960 static void Op3B(void) // RTI
962 regs.cc = regs.RdMem(regs.s++);
963 if (regs.cc&0x80) // If E flag set, pull all regs
965 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
966 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
967 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
968 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
975 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
977 static void Op3C(void) // CWAI
979 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
980 regs.clock += 1000000; // Force interrupt
982 static void Op3D(void) // MUL
984 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
985 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
986 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
989 static void Op3E(void) // RESET
992 static void Op3F(void) // SWI
995 static void Op40(void) // NEGA
997 regs.a = 256 - regs.a;
998 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
999 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1000 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1001 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1004 static void Op43(void) // COMA
1007 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1008 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1009 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1012 static void Op44(void) // LSRA
1014 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1016 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1017 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1020 static void Op46(void) // RORA
1022 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
1023 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1024 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1025 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1028 static void Op47(void) // ASRA
1030 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1031 regs.a >>= 1; // Do the shift
1032 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
1033 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1034 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1037 static void Op48(void) // LSLA [Keep checking from here...]
1039 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1041 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1042 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1045 static void Op49(void) // ROLA
1047 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
1048 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1049 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1050 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1053 static void Op4A(void) // DECA
1056 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1057 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1058 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1061 static void Op4C(void) // INCA
1064 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1065 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1066 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1069 static void Op4D(void) // TSTA
1071 regs.cc &= 0xFD; // Clear oVerflow flag
1072 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1073 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1076 static void Op4F(void) // CLRA
1079 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1082 static void Op50(void) // NEGB
1084 regs.b = 256 - regs.b;
1085 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1086 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1087 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1088 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1089 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1092 static void Op53(void) // COMB
1095 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1096 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1097 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1100 static void Op54(void) // LSRB
1102 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1104 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1105 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1108 static void Op56(void) // RORB
1110 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
1111 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
1112 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1113 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1116 static void Op57(void) // ASRB
1118 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1119 regs.b >>= 1; // Do the shift
1120 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
1121 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1122 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1125 static void Op58(void) // LSLB
1127 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1129 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1130 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1133 static void Op59(void) // ROLB
1136 regs.b = (tmp<<1) + (regs.cc&0x01);
1137 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1138 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1139 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1142 static void Op5A(void) // DECB
1145 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1146 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1147 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1150 static void Op5C(void) // INCB
1153 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1154 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1155 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1158 static void Op5D(void) // TSTB
1160 regs.cc &= 0xFD; // Clear oVerflow flag
1161 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1162 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1165 static void Op5F(void) // CLRB
1168 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1171 static void Op60(void) // NEG IDX
1173 addr = DecodeIDX(regs.RdMem(regs.pc++));
1174 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1175 regs.WrMem(addr, res);
1176 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1177 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1178 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1179 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1180 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1183 static void Op63(void) // COM IDX
1185 addr = DecodeIDX(regs.RdMem(regs.pc++));
1186 tmp = regs.RdMem(addr) ^ 0xFF;
1187 regs.WrMem(addr, tmp);
1188 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1189 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1190 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1193 static void Op64(void) // LSR IDX
1195 addr = DecodeIDX(regs.RdMem(regs.pc++));
1196 tmp = regs.RdMem(addr);
1197 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1198 tmp >>= 1; regs.WrMem(addr, tmp);
1199 regs.cc &= 0xF7; // CLN
1200 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1203 static void Op66(void) // ROR IDX
1205 addr = DecodeIDX(regs.RdMem(regs.pc++));
1206 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1207 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1208 regs.WrMem(addr, tmp);
1209 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1210 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1211 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1214 static void Op67(void) // ASR IDX
1216 addr = DecodeIDX(regs.RdMem(regs.pc++));
1217 tmp = regs.RdMem(addr);
1218 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1220 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1221 regs.WrMem(addr, tmp);
1222 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1223 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1226 static void Op68(void) // LSL IDX
1228 addr = DecodeIDX(regs.RdMem(regs.pc++));
1229 tmp = regs.RdMem(addr);
1230 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1232 regs.WrMem(addr, tmp);
1233 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1234 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1237 static void Op69(void) // ROL IDX
1239 uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1240 tmp = (tmp2<<1) + (regs.cc&0x01);
1241 regs.WrMem(addr, tmp);
1242 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1243 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1244 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1247 static void Op6A(void) // DEC IDX
1249 uint8 tmp; uint16 addr;
1250 addr = DecodeIDX(regs.RdMem(regs.pc++));
1251 tmp = regs.RdMem(addr) - 1;
1252 regs.WrMem(addr, tmp);
1253 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1254 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1255 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1258 static void Op6C(void) // INC IDX
1260 addr = DecodeIDX(regs.RdMem(regs.pc++));
1261 tmp = regs.RdMem(addr) + 1;
1262 regs.WrMem(addr, tmp);
1263 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1264 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1265 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1268 static void Op6D(void) // TST IDX
1270 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1271 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1272 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1275 static void Op6E(void) // JMP IDX
1277 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1280 static void Op6F(void) // CLR IDX
1282 addr = DecodeIDX(regs.RdMem(regs.pc++));
1283 regs.WrMem(addr, 0);
1284 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1287 static void Op70(void) // NEG ABS
1290 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1291 regs.WrMem(addr, res);
1292 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1293 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1294 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1295 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1298 static void Op73(void) // COM ABS
1301 tmp = regs.RdMem(addr) ^ 0xFF;
1302 regs.WrMem(addr, tmp);
1303 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1304 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1305 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1308 static void Op74(void) // LSR ABS
1311 tmp = regs.RdMem(addr);
1312 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1313 tmp >>= 1; regs.WrMem(addr, tmp);
1314 regs.cc &= 0xF7; // CLN
1315 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1318 static void Op76(void) // ROR ABS
1320 uint8 tmp; uint16 addr;
1322 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1323 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1324 regs.WrMem(addr, tmp);
1325 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1326 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1327 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1330 static void Op77(void) // ASR ABS
1332 uint8 tmp; uint16 addr;
1334 tmp = regs.RdMem(addr);
1335 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1337 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1338 regs.WrMem(addr, tmp);
1339 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1340 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1343 static void Op78(void) // LSL ABS
1345 uint8 tmp; uint16 addr;
1347 tmp = regs.RdMem(addr);
1348 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1350 regs.WrMem(addr, tmp);
1351 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1352 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1355 static void Op79(void) // ROL ABS
1357 uint8 tmp2 = regs.RdMem(FetchW());
1358 tmp = (tmp2<<1) + (regs.cc&0x01);
1359 regs.WrMem(addr, tmp);
1360 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1361 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1362 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1365 static void Op7A(void) // DEC ABS
1367 uint8 tmp; uint16 addr;
1369 tmp = regs.RdMem(addr) - 1;
1370 regs.WrMem(addr, tmp);
1371 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1372 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1373 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1376 static void Op7C(void) // INC ABS
1378 uint8 tmp; uint16 addr;
1380 tmp = regs.RdMem(addr) + 1;
1381 regs.WrMem(addr, tmp);
1382 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1383 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1384 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1388 static void Op7D(void) // TST ABS
1390 uint8 tmp = regs.RdMem(FetchW());
1392 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1393 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1398 static void Op7E(void) // JMP ABS
1403 static void Op7F(void) // CLR ABS
1405 regs.WrMem(FetchW(), 0);
1406 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1409 static void Op80(void) // SUBA #
1411 uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1413 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1414 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1415 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1416 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1419 static void Op81(void) // CMPA #
1421 tmp = regs.RdMem(regs.pc++);
1422 uint8 db = regs.a - tmp;
1423 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1424 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1425 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1426 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1429 static void Op82(void) // SBCA #
1431 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1432 regs.a = regs.a - tmp - (regs.cc&0x01);
1433 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1434 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
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 Op83(void) // SUBD #
1441 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1443 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1444 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1445 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1446 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1447 regs.a = dr>>8; regs.b = dr&0xFF;
1450 static void Op84(void) // ANDA #
1452 regs.a &= regs.RdMem(regs.pc++);
1453 regs.cc &= 0xFD; // Clear oVerflow flag
1454 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1455 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1458 static void Op85(void) // BITA #
1460 tmp = regs.a & regs.RdMem(regs.pc++);
1461 regs.cc &= 0xFD; // Clear oVerflow flag
1462 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1463 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1466 static void Op86(void) // LDA #
1468 regs.a = regs.RdMem(regs.pc++);
1469 regs.cc &= 0xFD; // CLV
1470 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1471 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1474 static void Op88(void) // EORA #
1476 regs.a ^= regs.RdMem(regs.pc++);
1477 regs.cc &= 0xFD; // CLV
1478 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1479 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1482 static void Op89(void) // ADCA #
1484 tmp = regs.RdMem(regs.pc++);
1485 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1486 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
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); // Adjust Zero
1491 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1494 static void Op8A(void) // ORA #
1496 regs.a |= regs.RdMem(regs.pc++);
1497 regs.cc &= 0xFD; // CLV
1498 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1499 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1502 static void Op8B(void) // ADDA #
1504 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
1505 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1506 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1507 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1508 regs.a = addr & 0xFF; // Set accumulator
1509 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1510 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1513 static void Op8C(void) // CMPX #
1516 uint16 dw = regs.x - addr;
1517 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1518 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1519 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1520 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1524 static void Op8D(void) // Bregs.s
1526 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
1527 regs.WrMem(--regs.s, regs.pc & 0xFF);
1528 regs.WrMem(--regs.s, regs.pc >> 8);
1534 static void Op8E(void) // LDX #
1537 regs.cc &= 0xFD; // CLV
1538 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1539 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1542 static void Op90(void) // SUBA DP
1544 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1546 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1547 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1548 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1549 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1552 static void Op91(void) // CMPA DP
1554 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1555 uint8 db = regs.a - tmp;
1556 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1557 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1558 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1559 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1562 static void Op92(void) // SBCA DP
1564 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1565 regs.a = regs.a - tmp - (regs.cc&0x01);
1566 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1567 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1568 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1569 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1572 static void Op93(void) // SUBD DP
1574 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1575 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1577 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1578 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1579 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1580 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1581 regs.a = dr>>8; regs.b = dr&0xFF;
1584 static void Op94(void) // ANDA DP
1586 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1587 regs.cc &= 0xF1; // CLV CLZ CLN
1588 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
1589 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
1592 static void Op95(void) // BITA DP
1594 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1595 regs.cc &= 0xFD; // Clear oVerflow flag
1596 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1597 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1600 static void Op96(void) // LDA DP
1602 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1603 regs.cc &= 0xF1; // CLN CLZ CLV
1604 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1605 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1608 static void Op97(void) // STA DP
1610 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
1611 regs.cc &= 0xFD; // CLV
1612 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1613 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1616 static void Op98(void) // EORA DP
1618 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1619 regs.cc &= 0xFD; // CLV
1620 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1621 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1624 static void Op99(void) // ADCA DP
1626 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1627 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1628 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1629 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1630 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1631 regs.a = addr & 0xFF; // Set accumulator
1632 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1633 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1636 static void Op9A(void) // ORA DP
1638 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1639 regs.cc &= 0xFD; // CLV
1640 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1641 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1644 static void Op9B(void) // ADDA DP
1646 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1647 addr = (uint16)regs.a + (uint16)tmp;
1648 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1649 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1650 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1651 regs.a = addr & 0xFF; // Set accumulator
1652 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1653 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1656 static void Op9C(void) // CMPX DP
1658 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1659 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1660 uint16 dw = regs.x - adr2;
1661 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1662 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1663 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1664 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1667 static void Op9D(void) // JSR DP
1669 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1670 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1671 regs.pc = addr; // JSR to DP location...
1674 static void Op9E(void) // LDX DP
1676 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1677 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1678 regs.cc &= 0xFD; // CLV
1679 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1680 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1683 static void Op9F(void) // STX DP
1685 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1686 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1687 regs.cc &= 0xFD; // CLV
1688 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1689 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1692 static void OpA0(void) // SUBA IDX
1694 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1696 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1697 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1698 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1699 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1702 static void OpA1(void) // CMPA IDX
1704 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1705 uint8 db = regs.a - tmp;
1706 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1707 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1708 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1709 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1712 static void OpA2(void) // SBCA IDX
1714 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1715 regs.a = regs.a - tmp - (regs.cc&0x01);
1716 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1717 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1718 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1719 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1722 static void OpA3(void) // SUBD IDX
1724 addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1725 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1727 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1728 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1729 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1730 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1731 regs.a = dr>>8; regs.b = dr&0xFF;
1734 static void OpA4(void) // ANDA IDX
1736 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1737 regs.cc &= 0xFD; // Clear oVerflow flag
1738 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1739 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1742 static void OpA5(void) // BITA IDX
1744 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1745 regs.cc &= 0xFD; // Clear oVerflow flag
1746 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1747 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1750 static void OpA6(void) // LDA IDX
1752 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1753 regs.cc &= 0xF1; // CLV CLZ CLN
1754 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1755 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1758 static void OpA7(void) // STA IDX
1760 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1761 regs.cc &= 0xF1; // CLV CLZ CLN
1762 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1763 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1766 static void OpA8(void) // EORA IDX
1768 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1769 regs.cc &= 0xFD; // CLV
1770 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1771 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1774 static void OpA9(void) // ADCA IDX
1776 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1777 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1778 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1779 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1780 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1781 regs.a = addr & 0xFF; // Set accumulator
1782 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1783 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1786 static void OpAA(void) // ORA IDX
1788 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1789 regs.cc &= 0xFD; // CLV
1790 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1791 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1794 static void OpAB(void) // ADDA IDX
1796 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1797 addr = (uint16)regs.a + (uint16)tmp;
1798 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1799 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1800 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1801 regs.a = addr & 0xFF; // Set accumulator
1802 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1803 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1806 static void OpAC(void) // CMPX IDX
1808 addr = DecodeIDX(regs.RdMem(regs.pc++));
1809 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1810 uint16 dw = regs.x - addr2;
1811 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1812 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1813 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1814 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1817 static void OpAD(void) // JSR IDX
1819 addr = DecodeIDX(regs.RdMem(regs.pc++));
1820 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1821 regs.pc = addr; // Jregs.s directly to IDX ptr
1824 static void OpAE(void) // LDX IDX
1826 addr = DecodeIDX(regs.RdMem(regs.pc++));
1827 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1828 regs.cc &= 0xFD; // CLV
1829 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1830 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1833 static void OpAF(void) // STX IDX
1835 addr = DecodeIDX(regs.RdMem(regs.pc++));
1836 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1837 regs.cc &= 0xF1; // CLV CLZ CLN
1838 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1839 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1842 static void OpB0(void) // SUBA ABS
1844 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1846 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1847 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1848 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1849 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1852 static void OpB1(void) // CMPA ABS
1854 tmp = regs.RdMem(FetchW());
1855 uint8 db = regs.a - tmp;
1856 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1857 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1858 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1859 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1862 static void OpB2(void) // SBCA ABS
1864 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1865 regs.a = regs.a - tmp - (regs.cc&0x01);
1866 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1867 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1868 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1869 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1872 static void OpB3(void) // SUBD ABS
1874 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1875 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1877 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1878 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1879 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1880 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1881 regs.a = dr>>8; regs.b = dr&0xFF;
1884 static void OpB4(void) // ANDA ABS
1886 regs.a &= regs.RdMem(FetchW());
1887 regs.cc &= 0xFD; // Clear oVerflow flag
1888 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1889 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1892 static void OpB5(void) // BITA ABS
1894 tmp = regs.a & regs.RdMem(FetchW());
1895 regs.cc &= 0xFD; // Clear oVerflow flag
1896 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1897 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1900 static void OpB6(void) // LDA ABS
1902 regs.a = regs.RdMem(FetchW());
1903 regs.cc &= 0xFD; // CLV
1904 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1905 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1908 static void OpB7(void) // STA ABS
1910 regs.WrMem(FetchW(), regs.a);
1911 regs.cc &= 0xFD; // CLV
1912 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1913 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1916 static void OpB8(void) // EORA ABS
1918 regs.a ^= regs.RdMem(FetchW());
1919 regs.cc &= 0xFD; // CLV
1920 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1921 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1924 static void OpB9(void) // ADCA ABS
1926 tmp = regs.RdMem(FetchW());
1927 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1928 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1929 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1930 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1931 regs.a = addr; // Set accumulator
1932 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1933 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1936 static void OpBA(void) // ORA ABS
1938 regs.a |= regs.RdMem(FetchW());
1939 regs.cc &= 0xFD; // CLV
1940 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1941 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1944 static void OpBB(void) // ADDA ABS
1946 tmp = regs.RdMem(FetchW());
1947 addr = (uint16)regs.a + (uint16)tmp;
1948 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1949 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1950 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1951 regs.a = addr & 0xFF; // Set accumulator
1952 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1953 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1956 static void OpBC(void) // CMPX ABS
1958 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1959 uint16 dw = regs.x - addr2;
1960 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1961 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1962 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1963 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1966 static void OpBD(void) // JSR ABS
1969 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1970 regs.pc = addr; // Go to absolute address (Not indir)
1974 static void OpBE(void) // LDX ABS
1977 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1978 regs.x = RdMemW(FetchW());
1980 regs.cc &= 0xFD; // CLV
1981 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1982 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1987 static void OpBF(void) // STX ABS
1990 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1991 WrMemW(FetchW(), regs.x);
1993 regs.cc &= 0xFD; // CLV
1994 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1995 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2000 static void OpC0(void) // SUBB #
2002 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
2004 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2005 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2006 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2007 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2010 static void OpC1(void) // CMPB #
2012 tmp = regs.RdMem(regs.pc++);
2013 uint8 db = regs.b - tmp;
2014 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2015 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2016 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2017 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2020 static void OpC2(void) // SBCB #
2022 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
2023 regs.b = regs.b - tmp - (regs.cc&0x01);
2024 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2025 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2026 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2027 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2030 static void OpC3(void) // ADDD #
2032 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2034 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2036 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2037 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2038 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2039 regs.a = dr>>8; regs.b = dr&0xFF;
2042 static void OpC4(void) // ANDB #
2044 regs.b &= regs.RdMem(regs.pc++);
2045 regs.cc &= 0xFD; // Clear oVerflow flag
2046 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2047 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2050 static void OpC5(void) // BITB #
2052 tmp = regs.b & regs.RdMem(regs.pc++);
2053 regs.cc &= 0xF1; // CLV CLZ CLN
2054 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
2055 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
2058 static void OpC6(void) // LDB #
2060 regs.b = regs.RdMem(regs.pc++);
2061 regs.cc &= 0xF1; // CLV CLZ CLN
2062 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
2063 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
2066 static void OpC8(void) // EORB #
2068 regs.b ^= regs.RdMem(regs.pc++);
2069 regs.cc &= 0xFD; // CLV
2070 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2071 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2074 static void OpC9(void) // ADCB #
2076 tmp = regs.RdMem(regs.pc++);
2077 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2078 (addr > 0x00FF ? 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 OpCA(void) // ORB #
2088 regs.b |= regs.RdMem(regs.pc++);
2089 regs.cc &= 0xFD; // CLV
2090 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2091 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2094 static void OpCB(void) // ADDB #
2096 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
2097 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2098 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2099 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2100 regs.b = addr & 0xFF; // Set accumulator
2101 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2102 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2105 static void OpCC(void) // LDD #
2107 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
2108 regs.cc &= 0xFD; // CLV
2109 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2110 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2113 static void OpCE(void) // LDU #
2116 regs.cc &= 0xFD; // CLV
2117 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2118 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2121 static void OpD0(void) // SUBB DP
2123 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2125 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2126 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2127 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2128 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2131 static void OpD1(void) // CMPB DP
2133 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2134 uint8 db = regs.b - tmp;
2135 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2136 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2137 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2138 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2141 static void OpD2(void) // SBCB DP
2143 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2144 regs.b = regs.b - tmp - (regs.cc&0x01);
2145 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2146 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2147 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2148 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2151 static void OpD3(void) // ADDD DP
2153 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2154 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2156 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2158 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2159 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2160 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2161 regs.a = dr>>8; regs.b = dr&0xFF;
2164 static void OpD4(void) // ANDB DP
2166 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2167 regs.cc &= 0xFD; // Clear oVerflow flag
2168 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2169 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2172 static void OpD5(void) // BITB DP
2174 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2175 regs.cc &= 0xFD; // Clear oVerflow flag
2176 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2177 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2180 static void OpD6(void) // LDB DP
2182 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2183 regs.cc &= 0xFD; // CLV
2184 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2185 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2188 static void OpD7(void) // STB DP
2190 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2191 regs.cc &= 0xFD; // CLV
2192 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2193 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2196 static void OpD8(void) // EORB DP
2198 regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2199 regs.cc &= 0xFD; // CLV
2200 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2201 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2204 static void OpD9(void) // ADCB DP
2206 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2207 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2208 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2209 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2210 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2211 regs.b = addr; // Set accumulator
2212 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2213 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2216 static void OpDA(void) // ORB DP
2218 regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2219 regs.cc &= 0xFD; // CLV
2220 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2221 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2224 static void OpDB(void) // ADDB DP
2226 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2227 addr = (uint16)regs.b + (uint16)tmp;
2228 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2229 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2230 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2231 regs.b = addr & 0xFF; // Set accumulator
2232 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2233 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2236 static void OpDC(void) // LDD DP
2238 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2239 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2240 regs.cc &= 0xFD; // CLV
2241 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2242 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2245 static void OpDD(void) // STD DP
2247 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2248 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2249 regs.cc &= 0xFD; // CLV
2250 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2251 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2254 static void OpDE(void) // LDU DP
2256 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2257 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2258 regs.cc &= 0xFD; // CLV
2259 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2260 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2263 static void OpDF(void) // STU DP
2265 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2266 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2267 regs.cc &= 0xFD; // CLV
2268 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2269 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2272 static void OpE0(void) // SUBB IDX
2274 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2276 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2277 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2278 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2279 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2282 static void OpE1(void) // CMPB IDX
2284 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2285 uint8 db = regs.b - tmp;
2286 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2287 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2288 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2289 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2292 static void OpE2(void) // SBCB IDX
2294 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2295 regs.b = regs.b - tmp - (regs.cc&0x01);
2296 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2297 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2298 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2299 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2302 static void OpE3(void) // ADDD IDX
2304 addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2305 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2307 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2309 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2310 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2311 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2312 regs.a = dr>>8; regs.b = dr&0xFF;
2315 static void OpE4(void) // ANDB IDX
2317 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2318 regs.cc &= 0xFD; // Clear oVerflow flag
2319 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2320 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2323 static void OpE5(void) // BITB IDX
2325 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2326 regs.cc &= 0xFD; // Clear oVerflow flag
2327 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2328 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2331 static void OpE6(void) // LDB IDX
2333 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2334 regs.cc &= 0xFD; // CLV
2335 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2336 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2339 static void OpE7(void) // STB IDX
2341 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2342 regs.cc &= 0xF1; // CLV CLZ CLN
2343 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
2344 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
2347 static void OpE8(void) // EORB IDX
2349 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2350 regs.cc &= 0xFD; // CLV
2351 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2352 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2355 static void OpE9(void) // ADCB IDX
2357 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2358 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2359 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2360 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2361 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2362 regs.b = addr; // Set accumulator
2363 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2364 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2367 static void OpEA(void) // ORB IDX
2369 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2370 regs.cc &= 0xFD; // CLV
2371 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2372 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2375 static void OpEB(void) // ADDB IDX
2377 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2378 addr = (uint16)regs.b + (uint16)tmp;
2379 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2380 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2381 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2382 regs.b = addr; // Set accumulator
2383 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2384 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2387 static void OpEC(void) // LDD IDX
2389 addr = DecodeIDX(regs.RdMem(regs.pc++));
2390 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2391 regs.cc &= 0xF1; // CLV CLZ CLN
2392 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2393 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2396 static void OpED(void) // STD IDX
2398 addr = DecodeIDX(regs.RdMem(regs.pc++));
2399 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2400 regs.cc &= 0xF1; // CLV CLZ CLZ
2401 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2402 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2405 static void OpEE(void) // LDU IDX
2407 addr = DecodeIDX(regs.RdMem(regs.pc++));
2408 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2409 regs.cc &= 0xF1; // CLV CLZ CLN
2410 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2411 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2414 static void OpEF(void) // STU IDX
2416 addr = DecodeIDX(regs.RdMem(regs.pc++));
2417 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2418 regs.cc &= 0xF1; // CLV CLZ CLN
2419 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2420 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2423 static void OpF0(void) // SUBB ABS
2425 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
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
2432 static void OpF1(void) // CMPB ABS
2434 tmp = regs.RdMem(FetchW());
2435 uint8 db = regs.b - tmp;
2436 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2437 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2438 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2439 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2442 static void OpF2(void) // SBCB ABS
2444 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2445 regs.b = regs.b - tmp - (regs.cc&0x01);
2446 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2447 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2448 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2449 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2452 static void OpF3(void) // ADDD ABS
2454 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2455 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2457 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2459 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2460 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2461 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2462 regs.a = dr>>8; regs.b = dr&0xFF;
2465 static void OpF4(void) // ANDB ABS
2467 regs.b &= regs.RdMem(FetchW());
2468 regs.cc &= 0xFD; // Clear oVerflow flag
2469 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2470 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2473 static void OpF5(void) // BITB ABS
2475 tmp = regs.b & regs.RdMem(FetchW());
2476 regs.cc &= 0xFD; // Clear oVerflow flag
2477 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2478 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2481 static void OpF6(void) // LDB ABS
2483 regs.b = regs.RdMem(FetchW());
2484 regs.cc &= 0xFD; // CLV
2485 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2486 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2489 static void OpF7(void) // STB ABS
2491 regs.WrMem(FetchW(), regs.b);
2492 regs.cc &= 0xFD; // CLV
2493 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2494 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2497 static void OpF8(void) // EORB ABS
2499 regs.b ^= regs.RdMem(FetchW());
2500 regs.cc &= 0xFD; // CLV
2501 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2502 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2505 static void OpF9(void) // ADCB ABS
2507 tmp = regs.RdMem(FetchW());
2508 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2509 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2510 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2511 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2512 regs.b = addr & 0xFF; // Set accumulator
2513 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2514 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2517 static void OpFA(void) // ORB ABS
2519 regs.b |= regs.RdMem(FetchW());
2520 regs.cc &= 0xFD; // CLV
2521 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2522 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2525 static void OpFB(void) // ADDB ABS
2527 tmp = regs.RdMem(FetchW());
2528 addr = (uint16)regs.b + (uint16)tmp;
2529 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2530 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2531 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2532 regs.b = addr & 0xFF; // Set accumulator
2533 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2534 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2537 static void OpFC(void) // LDD ABS
2540 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2541 regs.cc &= 0xFD; // CLV
2542 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2543 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2546 static void OpFD(void) // STD ABS
2549 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2550 regs.cc &= 0xFD; // CLV
2551 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2552 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2555 static void OpFE(void) // LDU ABS
2558 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2559 regs.cc &= 0xFD; // CLV
2560 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2561 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2564 static void OpFF(void) // STU ABS
2567 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2568 regs.cc &= 0xFD; // CLV
2569 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2570 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2575 // Page one opcodes' execute code
2578 static void Op1021(void) // LBRN
2585 static void Op1022(void) // LBHI
2587 uint16 word = FetchW();
2589 if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
2595 static void Op1023(void) // LBLS
2597 uint16 word = FetchW();
2599 if ((regs.cc & 0x01) | (regs.cc & 0x04))
2605 static void Op1024(void) // LBCC (LBHS)
2607 uint16 word = FetchW();
2609 if (!(regs.cc & 0x01))
2615 static void Op1025(void) // LBCS (LBLO)
2617 uint16 word = FetchW();
2625 static void Op1026(void) // LBNE
2627 uint16 word = FetchW();
2629 if (!(regs.cc & 0x04))
2635 static void Op1027(void) // LBEQ
2637 uint16 word = FetchW();
2645 static void Op1028(void) // LBVC
2647 uint16 word = FetchW();
2649 if (!(regs.cc & 0x02))
2655 static void Op1029(void) // LBVS
2657 uint16 word = FetchW();
2665 static void Op102A(void) // LBPL
2667 uint16 word = FetchW();
2669 if (!(regs.cc & 0x08))
2675 static void Op102B(void) // LBMI
2677 uint16 word = FetchW();
2685 static void Op102C(void) // LBGE
2687 uint16 word = FetchW();
2689 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2695 static void Op102D(void) // LBLT
2697 uint16 word = FetchW();
2699 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
2705 static void Op102E(void) // LBGT
2707 uint16 word = FetchW();
2709 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
2715 static void Op102F(void) // LBLE
2717 uint16 word = FetchW();
2719 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2725 static void Op103F(void) // SWI2 (Not yet implemented)
2729 static void Op1083(void) // CMPD #
2731 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2732 uint16 dw = dr - addr;
2733 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2734 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2735 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2736 ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2739 static void Op108C(void) // CMPY #
2742 uint16 dw = regs.y - 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 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2746 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2749 static void Op108E(void) // LDY #
2752 regs.cc &= 0xFD; // CLV
2753 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2754 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2757 static void Op1093(void) // CMPD DP
2759 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2760 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2761 uint16 dw = dr - addr;
2762 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2763 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2764 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2765 ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2768 static void Op109C(void) // CMPY DP
2770 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2771 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2772 uint16 dw = regs.y - addr;
2773 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2774 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2775 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2776 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2780 static void Op109E(void) // LDY DP
2782 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2783 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2784 regs.cc &= 0xFD; // CLV
2785 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2786 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2790 static void Op109F(void) // STY DP
2792 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2793 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2794 regs.cc &= 0xFD; // CLV
2795 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2796 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2799 static void Op10A3(void) // CMPD IDX
2801 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2802 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2803 uint16 dw = dr - addr;
2804 regs.cc &= 0xF0; // CLC CLV CLZ CLN
2805 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
2806 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
2807 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
2808 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
2811 static void Op10AC(void) // CMPY IDX
2813 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2814 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2815 uint16 dw = regs.y - addr;
2816 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2817 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2818 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2819 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2822 static void Op10AE(void) // LDY IDX
2824 addr = DecodeIDX(regs.RdMem(regs.pc++));
2825 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2826 regs.cc &= 0xF1; // CLV CLZ CLN
2827 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
2828 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
2831 static void Op10AF(void) // STY IDX
2833 addr = DecodeIDX(regs.RdMem(regs.pc++));
2834 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2835 regs.cc &= 0xFD; // CLV
2836 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2837 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2840 static void Op10B3(void) // CMPD ABS
2842 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2843 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2844 uint16 dw = dr - addr2;
2845 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2846 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2847 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2848 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2851 static void Op10BC(void) // CMPY ABS
2853 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2854 uint16 dw = regs.y - addr2;
2855 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2856 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2857 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2858 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2861 static void Op10BE(void) // LDY ABS
2864 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2865 regs.cc &= 0xFD; // CLV
2866 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2867 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2870 static void Op10BF(void) // STY ABS
2873 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2874 regs.cc &= 0xFD; // CLV
2875 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2876 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2879 static void Op10CE(void) // LDS #
2882 regs.cc &= 0xFD; // CLV
2883 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2884 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2887 static void Op10DE(void) // LDS DP
2889 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2890 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2891 regs.cc &= 0xFD; // CLV
2892 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2893 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2896 static void Op10DF(void) // STS DP
2898 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2899 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2900 regs.cc &= 0xFD; // CLV
2901 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2902 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2905 static void Op10EE(void) // LDS IDX
2907 addr = DecodeIDX(regs.RdMem(regs.pc++));
2908 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2909 regs.cc &= 0xFD; // CLV
2910 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2911 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2914 static void Op10EF(void) // STS IDX
2916 addr = DecodeIDX(regs.RdMem(regs.pc++));
2917 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2918 regs.cc &= 0xFD; // CLV
2919 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2920 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2923 static void Op10FE(void) // LDS ABS
2926 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2927 regs.cc &= 0xFD; // CLV
2928 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2929 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2932 static void Op10FF(void) // STS ABS
2935 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2936 regs.cc &= 0xFD; // CLV
2937 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2938 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2943 // Page two opcodes' execute code
2946 static void Op113F(void) // SWI3
2950 static void Op1183(void) // CMPU #
2953 uint16 dw = regs.u - addr;
2954 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2955 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2956 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2957 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2960 static void Op118C(void) // CMPS #
2963 uint16 dw = regs.s - addr;
2964 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2965 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2966 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2967 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2970 static void Op1193(void) // CMPU DP
2972 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2973 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2974 uint16 dw = regs.u - addr;
2975 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2976 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2977 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2978 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2981 static void Op119C(void) // CMPS DP
2983 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2984 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2985 uint16 dw = regs.s - addr;
2986 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2987 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2988 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2989 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2992 static void Op11A3(void) // CMPU IDX
2994 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2995 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2996 uint16 dw = regs.u - addr;
2997 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2998 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2999 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3000 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3003 static void Op11AC(void) // CMPS IDX
3005 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
3006 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
3007 uint16 dw = regs.s - addr;
3008 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3009 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3010 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3011 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3014 static void Op11B3(void) // CMPU ABS
3016 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3017 uint16 dw = regs.u - addr2;
3018 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3019 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3020 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3021 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3025 static void Op11BC(void) // CMPS ABS
3027 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3028 uint16 dw = regs.s - addr2;
3029 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3030 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3031 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
3032 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3036 //temp, for testing...
3038 static uint8 backTrace[256];
3039 static uint16 btPC[256];
3040 static int btPtr = 0;//*/
3042 static void Op__(void) // Illegal opcode
3046 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3048 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3049 for(int i=0; i<256; i++)
3051 Decode6809(btPC[(btPtr + i) & 0xFF]);
3059 // Internal "memcpy" (so we don't have to link with any external libraries!)
3061 static void myMemcpy(void * dst, void * src, uint32 size)
3063 uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
3065 for(uint32 i=0; i<size; i++)
3070 // Function to execute 6809 instructions
3072 void Execute6809(V6809REGS * context, uint32 cycles)
3074 myMemcpy(®s, context, sizeof(V6809REGS));
3077 while (regs.clock < cycles)
3080 //Decode6809(regs.pc);
3081 static bool disasm = false;
3082 /*//if (regs.pc == 0x15BA) disasm = true;
3083 //if (regs.pc == 0xFE76) disasm = true;
3084 if (regs.x == 0xFED4) disasm = true;
3085 if (disasm) Decode6809(regs.pc);
3086 //if (regs.pc == 0x164A) disasm = false;//*/
3088 //temp, for testing...
3089 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3090 btPC[btPtr] = regs.pc;
3091 btPtr = (btPtr + 1) & 0xFF;//*/
3093 exec_op0[regs.RdMem(regs.pc++)]();
3095 // Handle any pending interrupts
3097 uint32 flags = context->cpuFlags;
3099 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
3102 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3104 regs.cc |= (FLAG_F | FLAG_I); // Set F, I
3105 regs.dp = 0; // Reset direct page register
3106 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3107 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3108 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3110 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
3113 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3115 regs.cc |= FLAG_E; // Set the Entire flag
3117 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3118 regs.WrMem(--regs.s, regs.pc >> 8);
3119 regs.WrMem(--regs.s, regs.u & 0xFF);
3120 regs.WrMem(--regs.s, regs.u >> 8);
3121 regs.WrMem(--regs.s, regs.y & 0xFF);
3122 regs.WrMem(--regs.s, regs.y >> 8);
3123 regs.WrMem(--regs.s, regs.x & 0xFF);
3124 regs.WrMem(--regs.s, regs.x >> 8);
3125 regs.WrMem(--regs.s, regs.dp);
3126 regs.WrMem(--regs.s, regs.b);
3127 regs.WrMem(--regs.s, regs.a);
3128 regs.WrMem(--regs.s, regs.cc);
3130 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3131 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3133 context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3134 regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
3136 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
3139 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3141 if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
3144 if (disasm) WriteLog(" FIRQ taken...\n");
3146 regs.cc &= ~FLAG_E; // Clear the Entire flag
3148 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
3149 regs.WrMem(--regs.s, regs.pc >> 8);
3150 regs.WrMem(--regs.s, regs.cc);
3152 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
3153 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3155 context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3156 regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3159 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
3162 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3164 if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
3167 if (disasm) WriteLog(" IRQ taken...\n");
3169 regs.cc |= FLAG_E; // Set the Entire flag
3171 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
3172 regs.WrMem(--regs.s, regs.pc >> 8);
3173 regs.WrMem(--regs.s, regs.u & 0xFF);
3174 regs.WrMem(--regs.s, regs.u >> 8);
3175 regs.WrMem(--regs.s, regs.y & 0xFF);
3176 regs.WrMem(--regs.s, regs.y >> 8);
3177 regs.WrMem(--regs.s, regs.x & 0xFF);
3178 regs.WrMem(--regs.s, regs.x >> 8);
3179 regs.WrMem(--regs.s, regs.dp);
3180 regs.WrMem(--regs.s, regs.b);
3181 regs.WrMem(--regs.s, regs.a);
3182 regs.WrMem(--regs.s, regs.cc);
3184 regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3185 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3187 // Apparently, not done here!
3188 // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3189 // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3193 if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3194 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3195 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3196 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3200 myMemcpy(context, ®s, sizeof(V6809REGS));
3204 // Get the clock of the currently executing CPU
3206 uint32 GetCurrentV6809Clock(void)
3212 // Get the PC of the currently executing CPU
3214 uint16 GetCurrentV6809PC(void)
3219 // Set a line of the currently executing CPU
3220 void SetLine(uint32 line)
3222 regs.cpuFlags |= line;
3225 // Clear a line of the currently executing CPU
3226 void ClearLine(uint32 line)
3228 regs.cpuFlags &= ~line;