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
15 // Mebbe someday I'll get around to fixing the core to be more like V65C02...
21 #include "dis6809.h" // Temporary...
22 #include "log.h" // Temporary...
25 // Private global variables
27 static V6809REGS regs;
28 static uint16 addr; // Temporary variables common to all funcs...
31 // Private function prototypes
33 static int SignedB(uint8); // Return signed byte from unsigned
34 static int SignedW(uint16); // Return signed word from unsigned
35 static uint16 FetchW(void);
36 static uint16 RdMemW(uint16 addr);
37 static void WrMemW(uint16 addr, uint16 w);
38 static uint16 ReadEXG(uint8); // Read TFR/EXG post byte
39 static void WriteEXG(uint8, uint16); // Set TFR/EXG data
40 static uint16 DecodeReg(uint8); // Decode register data
41 static uint16 DecodeIDX(uint8); // Decode IDX data
43 //static void (* exec_op1[256])();
44 //static void (* exec_op2[256])();
47 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
48 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
49 // even *try* to see if they're there).
51 #define FD(x) static void Op##x(); // FD -> "Forward Declaration"
52 #define FE(x) static void Op10##x();
53 #define FF(x) static void Op11##x();
55 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)
56 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)
57 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)
58 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)
59 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)
60 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)
61 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)
62 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)
63 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)
64 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)
65 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)
66 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)
67 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)
68 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)
69 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)
70 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)
73 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)
74 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)
75 FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
77 FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
85 // We can move these down and do away with the forward declarations... !!! FIX !!!
86 // Actually, we can't because these are used in a couple of the opcode functions.
87 // Have to think about how to fix that...
93 // Array of page zero opcode functions...
94 static void (* exec_op0[256])() = {
95 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
96 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
97 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
98 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
99 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
100 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
101 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
102 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
103 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
104 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
105 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
106 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
107 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
108 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
109 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
110 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
113 // Array of page one opcode functions...
114 static void (* exec_op1[256])() = {
115 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
116 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
117 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
118 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
119 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
120 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
121 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
122 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
123 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
124 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
125 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
126 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
127 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
128 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
129 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
130 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
133 // Array of page two opcode functions...
134 static void (* exec_op2[256])() = {
135 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
136 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
137 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
138 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
139 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
140 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
141 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
142 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
143 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
144 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
145 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
146 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
147 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
148 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
149 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
150 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
155 // Fetch a word out of 6809 memory (little endian format)
156 // This is a leftover from when fetches were separated from garden variety reads...
158 static uint16 FetchW()
160 uint16 w = RdMemW(regs.pc);
165 // Fetch word function
167 /*uint16 FetchW(void)
169 return (uint16)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
173 // Read word from memory function
175 uint16 RdMemW(uint16 addr)
177 return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
181 // Write word to memory function
183 void WrMemW(uint16 addr, uint16 w)
185 regs.WrMem(addr + 0, w >> 8);
186 regs.WrMem(addr + 1, w & 0xFF);
190 // return signed byte from unsigned
194 return (b & 0x80 ? b - 256 : b);
198 // return signed word from unsigned
200 int SignedW(uint16 w)
202 return (w & 0x8000 ? w - 65536 : w);
206 // Function to read TFR/EXG post byte
208 uint16 ReadEXG(uint8 code)
215 retval = (regs.a << 8) | regs.b;
252 // Function to set TFR/EXG data
254 void WriteEXG(uint8 code, uint16 data)
259 regs.a = data >> 8, regs.b = data & 0xFF; break;
261 regs.x = data; break;
263 regs.y = data; break;
265 regs.u = data; break;
267 regs.s = data; break;
269 regs.pc = data; break;
271 regs.a = data & 0xFF; break;
273 regs.b = data & 0xFF; break;
275 regs.cc = data & 0xFF; break;
277 regs.dp = data & 0xFF; break;
282 // Function to decode register data
284 uint16 DecodeReg(uint8 reg)
291 retval = regs.x; break;
293 retval = regs.y; break;
295 retval = regs.u; break;
297 retval = regs.s; break;
304 // Function to decode IDX data
306 uint16 DecodeIDX(uint8 code)
309 uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
311 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
312 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
320 woff = DecodeReg(reg);
324 case 0: regs.x += 2; break;
325 case 1: regs.y += 2; break;
326 case 2: regs.u += 2; break;
327 case 3: regs.s += 2; break;
333 case 0: regs.x -= 2; break;
334 case 1: regs.y -= 2; break;
335 case 2: regs.u -= 2; break;
336 case 3: regs.s -= 2; break;
338 woff = DecodeReg(reg);
342 woff = DecodeReg(reg);
346 woff = DecodeReg(reg) + SignedB(regs.b);
350 woff = DecodeReg(reg) + SignedB(regs.a);
354 woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++));
358 woff = DecodeReg(reg) + SignedW(FetchW());
362 woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b);
366 woff = regs.pc + SignedB(regs.RdMem(regs.pc++));
370 woff = regs.pc + SignedW(FetchW());
384 addr = DecodeReg(reg);
387 case 0: regs.x++; break;
388 case 1: regs.y++; break;
389 case 2: regs.u++; break;
390 case 3: regs.s++; break;
394 addr = DecodeReg(reg);
397 case 0: regs.x += 2; break;
398 case 1: regs.y += 2; break;
399 case 2: regs.u += 2; break;
400 case 3: regs.s += 2; break;
403 case 2: { switch(reg)
405 case 0: regs.x--; break;
406 case 1: regs.y--; break;
407 case 2: regs.u--; break;
408 case 3: regs.s--; break;
410 addr = DecodeReg(reg); break; }
411 case 3: { switch(reg)
413 case 0: regs.x--; regs.x--; break;
414 case 1: regs.y--; regs.y--; break;
415 case 2: regs.u--; regs.u--; break;
416 case 3: regs.s--; regs.s--; break;
418 addr = DecodeReg(reg); break; }
419 case 4: { addr = DecodeReg(reg); break; }
420 case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; }
421 case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; }
422 case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; }
423 case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; }
424 case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; }
425 case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; }
426 case 13: { addr = regs.pc + SignedW(FetchW()); break; }
435 // Page zero instructions...
438 static void Op00(void) // NEG DP
440 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
441 tmp = 256 - regs.RdMem(addr);
442 regs.WrMem(addr, tmp);
444 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
445 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
446 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
447 (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
452 static void Op01(void) // NEG DP (Undocumented)
457 static void Op03(void) // COM DP
459 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
460 tmp = 0xFF ^ regs.RdMem(addr);
461 regs.WrMem(addr, tmp);
463 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
464 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
465 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
470 static void Op04(void) // LSR DP
472 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
473 tmp = regs.RdMem(addr);
474 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
475 tmp >>= 1; regs.WrMem(addr, tmp);
476 regs.cc &= 0xF7; // CLN
477 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
480 static void Op06(void) // ROR DP
482 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
483 tmp = (tmp2>>1) + (regs.cc&0x01)*128;
484 regs.WrMem(addr, tmp);
485 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
486 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
487 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
490 static void Op07(void) // ASR DP
492 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
493 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
495 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
496 regs.WrMem(addr, tmp);
497 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
498 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
501 static void Op08(void) // LSL DP
503 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
504 tmp = regs.RdMem(addr);
505 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
507 regs.WrMem(addr, tmp);
508 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
509 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
512 static void Op09(void) // ROL DP
514 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
515 tmp = (tmp2<<1) + (regs.cc&0x01);
516 regs.WrMem(addr, tmp);
517 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
518 ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
519 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
520 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
523 static void Op0A(void) // DEC DP
525 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
526 tmp = regs.RdMem(addr) - 1;
527 regs.WrMem(addr, tmp);
528 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
529 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
530 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
533 static void Op0C(void) // INC DP
535 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
536 tmp = regs.RdMem(addr) + 1;
537 regs.WrMem(addr, tmp);
538 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
539 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
540 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
543 static void Op0D(void) // TST DP
545 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
546 regs.cc &= 0xFD; // CLV
547 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
548 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
551 static void Op0E(void) // JMP DP
553 regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
556 static void Op0F(void) // CLR DP
558 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
559 regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
563 static void Op10(void) // Page 1 opcode
565 exec_op1[regs.RdMem(regs.pc++)]();
568 static void Op11(void) // Page 2 opcode
570 exec_op2[regs.RdMem(regs.pc++)]();
573 static void Op12(void) // NOP
578 static void Op13(void) // SYNC
582 static void Op16(void) // LBRA
584 regs.pc += SignedW(FetchW());
587 static void Op17(void) // LBSR
590 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
591 regs.pc += SignedW(addr);
594 static void Op19(void) // DAA
596 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
598 regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry
600 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
602 regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
604 regs.cc &= 0xF1; // CL NZV
605 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
606 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
610 static void Op1A(void) // ORCC #
612 regs.cc |= regs.RdMem(regs.pc++);
617 static void Op1C(void) // ANDCC #
619 regs.cc &= regs.RdMem(regs.pc++);
624 static void Op1D(void) // SEX
626 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
628 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
629 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
634 static void Op1E(void) // EXG
636 tmp = regs.RdMem(regs.pc++);
637 addr = ReadEXG(tmp >> 4);
638 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
639 WriteEXG(tmp & 0xF, addr);
644 static void Op1F(void) // TFR
646 tmp = regs.RdMem(regs.pc++);
647 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
650 static void Op20(void) // BRA
652 regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
655 static void Op21(void) // BRN
657 regs.RdMem(regs.pc++);
660 static void Op22(void) // BHI
662 tmp = regs.RdMem(regs.pc++);
663 if (!(regs.cc&0x05)) regs.pc += SignedB(tmp);
666 static void Op23(void) // BLS
668 tmp = regs.RdMem(regs.pc++);
669 if (regs.cc&0x05) regs.pc += SignedB(tmp);
672 static void Op24(void) // BCC (BHS)
674 tmp = regs.RdMem(regs.pc++);
675 if (!(regs.cc&0x01)) regs.pc += SignedB(tmp);
678 static void Op25(void) // BCS (BLO)
680 tmp = regs.RdMem(regs.pc++);
681 if (regs.cc&0x01) regs.pc += SignedB(tmp);
684 static void Op26(void) // BNE
686 tmp = regs.RdMem(regs.pc++);
687 if (!(regs.cc&0x04)) regs.pc += SignedB(tmp);
690 static void Op27(void) // BEQ
692 tmp = regs.RdMem(regs.pc++);
693 if (regs.cc&0x04) regs.pc += SignedB(tmp);
696 static void Op28(void) // BVC
698 tmp = regs.RdMem(regs.pc++);
699 if (!(regs.cc&0x02)) regs.pc += SignedB(tmp);
702 static void Op29(void) // BVS
704 tmp = regs.RdMem(regs.pc++);
705 if (regs.cc&0x02) regs.pc += SignedB(tmp);
708 static void Op2A(void) // BPL
710 tmp = regs.RdMem(regs.pc++);
711 if (!(regs.cc&0x08)) regs.pc += SignedB(tmp);
714 static void Op2B(void) // BMI
716 tmp = regs.RdMem(regs.pc++);
717 if (regs.cc&0x08) regs.pc += SignedB(tmp);
720 static void Op2C(void) // BGE
722 tmp = regs.RdMem(regs.pc++);
723 if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp);
726 static void Op2D(void) // BLT
728 tmp = regs.RdMem(regs.pc++);
729 if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp);
732 static void Op2E(void) // BGT
734 tmp = regs.RdMem(regs.pc++);
735 if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp);
738 static void Op2F(void) // BLE
740 tmp = regs.RdMem(regs.pc++);
741 if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp);
744 static void Op30(void) // LEAX
746 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
747 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
750 static void Op31(void) // LEAY
752 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
753 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
756 static void Op32(void) // LEAS
758 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
759 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
762 static void Op33(void) // LEAU
764 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
765 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
768 static void Op34(void) // PSHS
770 tmp = regs.RdMem(regs.pc++);
771 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
772 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
773 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
774 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
775 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
776 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
777 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
778 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
781 static void Op35(void) // PULS
783 tmp = regs.RdMem(regs.pc++);
784 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
785 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
786 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
787 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
788 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
789 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
790 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
791 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
795 static void Op36(void) // PSHU
797 tmp = regs.RdMem(regs.pc++);
799 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
800 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
801 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
802 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
803 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
804 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
805 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
806 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
811 static void Op37(void) // PULU
813 tmp = regs.RdMem(regs.pc++);
814 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
815 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
816 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
817 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
818 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
819 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
820 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
821 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
824 static void Op39(void) // RTS
826 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
829 static void Op3A(void) // ABX
834 static void Op3B(void) // RTI
836 regs.cc = regs.RdMem(regs.s++);
837 if (regs.cc&0x80) // If E flag set, pull all regs
839 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
840 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
841 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
842 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
849 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
851 static void Op3C(void) // CWAI
853 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
854 regs.clock += 1000000; // Force interrupt
856 static void Op3D(void) // MUL
858 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
859 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
860 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
863 static void Op3E(void) // RESET
866 static void Op3F(void) // SWI
869 static void Op40(void) // NEGA
871 regs.a = 256 - regs.a;
872 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
873 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
874 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
875 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
878 static void Op43(void) // COMA
881 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
882 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
883 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
886 static void Op44(void) // LSRA
888 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
890 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
891 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
894 static void Op46(void) // RORA
896 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
897 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
898 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
899 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
902 static void Op47(void) // ASRA
904 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
905 regs.a >>= 1; // Do the shift
906 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
907 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
908 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
911 static void Op48(void) // LSLA [Keep checking from here...]
913 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
915 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
916 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
919 static void Op49(void) // ROLA
921 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
922 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
923 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
924 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
927 static void Op4A(void) // DECA
930 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
931 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
932 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
935 static void Op4C(void) // INCA
938 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
939 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
940 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
943 static void Op4D(void) // TSTA
945 regs.cc &= 0xFD; // Clear oVerflow flag
946 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
947 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
950 static void Op4F(void) // CLRA
953 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
956 static void Op50(void) // NEGB
958 regs.b = 256 - regs.b;
959 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
960 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
961 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
962 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
963 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
966 static void Op53(void) // COMB
969 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
970 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
971 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
974 static void Op54(void) // LSRB
976 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
978 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
979 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
982 static void Op56(void) // RORB
984 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
985 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
986 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
987 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
990 static void Op57(void) // ASRB
992 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
993 regs.b >>= 1; // Do the shift
994 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
995 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
996 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
999 static void Op58(void) // LSLB
1001 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1003 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1004 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1007 static void Op59(void) // ROLB
1010 regs.b = (tmp<<1) + (regs.cc&0x01);
1011 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1012 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1013 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1016 static void Op5A(void) // DECB
1019 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1020 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1021 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1024 static void Op5C(void) // INCB
1027 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1028 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1029 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1032 static void Op5D(void) // TSTB
1034 regs.cc &= 0xFD; // Clear oVerflow flag
1035 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1036 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1039 static void Op5F(void) // CLRB
1042 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1045 static void Op60(void) // NEG IDX
1047 addr = DecodeIDX(regs.RdMem(regs.pc++));
1048 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1049 regs.WrMem(addr, res);
1050 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1051 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1052 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1053 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1054 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1057 static void Op63(void) // COM IDX
1059 addr = DecodeIDX(regs.RdMem(regs.pc++));
1060 tmp = regs.RdMem(addr) ^ 0xFF;
1061 regs.WrMem(addr, tmp);
1062 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1063 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1064 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1067 static void Op64(void) // LSR IDX
1069 addr = DecodeIDX(regs.RdMem(regs.pc++));
1070 tmp = regs.RdMem(addr);
1071 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1072 tmp >>= 1; regs.WrMem(addr, tmp);
1073 regs.cc &= 0xF7; // CLN
1074 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1077 static void Op66(void) // ROR IDX
1079 addr = DecodeIDX(regs.RdMem(regs.pc++));
1080 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1081 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1082 regs.WrMem(addr, tmp);
1083 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1084 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1085 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1088 static void Op67(void) // ASR IDX
1090 addr = DecodeIDX(regs.RdMem(regs.pc++));
1091 tmp = regs.RdMem(addr);
1092 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1094 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1095 regs.WrMem(addr, tmp);
1096 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1097 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1100 static void Op68(void) // LSL IDX
1102 addr = DecodeIDX(regs.RdMem(regs.pc++));
1103 tmp = regs.RdMem(addr);
1104 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1106 regs.WrMem(addr, tmp);
1107 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1108 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1111 static void Op69(void) // ROL IDX
1113 uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1114 tmp = (tmp2<<1) + (regs.cc&0x01);
1115 regs.WrMem(addr, tmp);
1116 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1117 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1118 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1121 static void Op6A(void) // DEC IDX
1123 uint8 tmp; uint16 addr;
1124 addr = DecodeIDX(regs.RdMem(regs.pc++));
1125 tmp = regs.RdMem(addr) - 1;
1126 regs.WrMem(addr, tmp);
1127 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1128 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1129 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1132 static void Op6C(void) // INC IDX
1134 addr = DecodeIDX(regs.RdMem(regs.pc++));
1135 tmp = regs.RdMem(addr) + 1;
1136 regs.WrMem(addr, tmp);
1137 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1138 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1139 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1142 static void Op6D(void) // TST IDX
1144 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1145 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1146 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1149 static void Op6E(void) // JMP IDX
1151 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1154 static void Op6F(void) // CLR IDX
1156 addr = DecodeIDX(regs.RdMem(regs.pc++));
1157 regs.WrMem(addr, 0);
1158 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1161 static void Op70(void) // NEG ABS
1164 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
1165 regs.WrMem(addr, res);
1166 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1167 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1168 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1169 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1172 static void Op73(void) // COM ABS
1175 tmp = regs.RdMem(addr) ^ 0xFF;
1176 regs.WrMem(addr, tmp);
1177 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1178 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1179 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1182 static void Op74(void) // LSR ABS
1185 tmp = regs.RdMem(addr);
1186 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1187 tmp >>= 1; regs.WrMem(addr, tmp);
1188 regs.cc &= 0xF7; // CLN
1189 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1192 static void Op76(void) // ROR ABS
1194 uint8 tmp; uint16 addr;
1196 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
1197 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1198 regs.WrMem(addr, tmp);
1199 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1200 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1201 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1204 static void Op77(void) // ASR ABS
1206 uint8 tmp; uint16 addr;
1208 tmp = regs.RdMem(addr);
1209 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1211 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1212 regs.WrMem(addr, tmp);
1213 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1214 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1217 static void Op78(void) // LSL ABS
1219 uint8 tmp; uint16 addr;
1221 tmp = regs.RdMem(addr);
1222 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1224 regs.WrMem(addr, tmp);
1225 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1226 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1229 static void Op79(void) // ROL ABS
1231 uint8 tmp2 = regs.RdMem(FetchW());
1232 tmp = (tmp2<<1) + (regs.cc&0x01);
1233 regs.WrMem(addr, tmp);
1234 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1235 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1236 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1239 static void Op7A(void) // DEC ABS
1241 uint8 tmp; uint16 addr;
1243 tmp = regs.RdMem(addr) - 1;
1244 regs.WrMem(addr, tmp);
1245 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1246 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1247 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1250 static void Op7C(void) // INC ABS
1252 uint8 tmp; uint16 addr;
1254 tmp = regs.RdMem(addr) + 1;
1255 regs.WrMem(addr, tmp);
1256 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1257 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1258 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1262 static void Op7D(void) // TST ABS
1264 uint8 tmp = regs.RdMem(FetchW());
1266 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1267 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1272 static void Op7E(void) // JMP ABS
1277 static void Op7F(void) // CLR ABS
1279 regs.WrMem(FetchW(), 0);
1280 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1283 static void Op80(void) // SUBA #
1285 uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1287 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1288 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1289 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1290 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1293 static void Op81(void) // CMPA #
1295 tmp = regs.RdMem(regs.pc++);
1296 uint8 db = regs.a - tmp;
1297 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1298 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1299 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1300 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1303 static void Op82(void) // SBCA #
1305 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
1306 regs.a = regs.a - tmp - (regs.cc&0x01);
1307 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1308 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1309 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1310 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1313 static void Op83(void) // SUBD #
1315 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1317 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1318 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1319 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1320 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1321 regs.a = dr>>8; regs.b = dr&0xFF;
1324 static void Op84(void) // ANDA #
1326 regs.a &= regs.RdMem(regs.pc++);
1327 regs.cc &= 0xFD; // Clear oVerflow flag
1328 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1329 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1332 static void Op85(void) // BITA #
1334 tmp = regs.a & regs.RdMem(regs.pc++);
1335 regs.cc &= 0xFD; // Clear oVerflow flag
1336 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1337 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1340 static void Op86(void) // LDA #
1342 regs.a = regs.RdMem(regs.pc++);
1343 regs.cc &= 0xFD; // CLV
1344 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1345 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1348 static void Op88(void) // EORA #
1350 regs.a ^= regs.RdMem(regs.pc++);
1351 regs.cc &= 0xFD; // CLV
1352 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1353 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1356 static void Op89(void) // ADCA #
1358 tmp = regs.RdMem(regs.pc++);
1359 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1360 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1361 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1362 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1363 regs.a = addr & 0xFF; // Set accumulator
1364 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1365 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1368 static void Op8A(void) // ORA #
1370 regs.a |= regs.RdMem(regs.pc++);
1371 regs.cc &= 0xFD; // CLV
1372 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1373 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1376 static void Op8B(void) // ADDA #
1378 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
1379 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1380 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1381 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1382 regs.a = addr & 0xFF; // Set accumulator
1383 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1384 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1387 static void Op8C(void) // CMPX #
1390 uint16 dw = regs.x - addr;
1391 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1392 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1393 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1394 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1397 static void Op8D(void) // Bregs.s
1399 tmp = regs.RdMem(regs.pc++);
1400 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1401 regs.pc += SignedB(tmp);
1404 static void Op8E(void) // LDX #
1407 regs.cc &= 0xFD; // CLV
1408 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1409 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1412 static void Op90(void) // SUBA DP
1414 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1416 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1417 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1418 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1419 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1422 static void Op91(void) // CMPA DP
1424 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1425 uint8 db = regs.a - tmp;
1426 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1427 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1428 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1429 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1432 static void Op92(void) // SBCA DP
1434 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
1435 regs.a = regs.a - tmp - (regs.cc&0x01);
1436 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1437 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1438 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1439 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1442 static void Op93(void) // SUBD DP
1444 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1445 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1447 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1448 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1449 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1450 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1451 regs.a = dr>>8; regs.b = dr&0xFF;
1454 static void Op94(void) // ANDA DP
1456 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1457 regs.cc &= 0xF1; // CLV CLZ CLN
1458 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
1459 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
1462 static void Op95(void) // BITA DP
1464 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1465 regs.cc &= 0xFD; // Clear oVerflow flag
1466 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1467 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1470 static void Op96(void) // LDA DP
1472 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1473 regs.cc &= 0xF1; // CLN CLZ CLV
1474 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1475 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1478 static void Op97(void) // STA DP
1480 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
1481 regs.cc &= 0xFD; // CLV
1482 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1483 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1486 static void Op98(void) // EORA DP
1488 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1489 regs.cc &= 0xFD; // CLV
1490 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1491 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1494 static void Op99(void) // ADCA DP
1496 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1497 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1498 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1499 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1500 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1501 regs.a = addr & 0xFF; // Set accumulator
1502 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1503 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1506 static void Op9A(void) // ORA DP
1508 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1509 regs.cc &= 0xFD; // CLV
1510 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1511 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1514 static void Op9B(void) // ADDA DP
1516 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1517 addr = (uint16)regs.a + (uint16)tmp;
1518 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1519 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1520 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1521 regs.a = addr & 0xFF; // Set accumulator
1522 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1523 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1526 static void Op9C(void) // CMPX DP
1528 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1529 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1530 uint16 dw = regs.x - adr2;
1531 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1532 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1533 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1534 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1537 static void Op9D(void) // JSR DP
1539 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1540 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1541 regs.pc = addr; // JSR to DP location...
1544 static void Op9E(void) // LDX DP
1546 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1547 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1548 regs.cc &= 0xFD; // CLV
1549 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1550 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1553 static void Op9F(void) // STX DP
1555 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1556 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1557 regs.cc &= 0xFD; // CLV
1558 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1559 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1562 static void OpA0(void) // SUBA IDX
1564 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1566 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1567 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1568 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1569 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1572 static void OpA1(void) // CMPA IDX
1574 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1575 uint8 db = regs.a - tmp;
1576 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1577 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1578 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1579 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1582 static void OpA2(void) // SBCA IDX
1584 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1585 regs.a = regs.a - tmp - (regs.cc&0x01);
1586 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1587 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1588 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1589 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1592 static void OpA3(void) // SUBD IDX
1594 addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1595 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1597 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1598 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1599 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1600 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1601 regs.a = dr>>8; regs.b = dr&0xFF;
1604 static void OpA4(void) // ANDA IDX
1606 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1607 regs.cc &= 0xFD; // Clear oVerflow flag
1608 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1609 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1612 static void OpA5(void) // BITA IDX
1614 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1615 regs.cc &= 0xFD; // Clear oVerflow flag
1616 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1617 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1620 static void OpA6(void) // LDA IDX
1622 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1623 regs.cc &= 0xF1; // CLV CLZ CLN
1624 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1625 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1628 static void OpA7(void) // STA IDX
1630 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1631 regs.cc &= 0xF1; // CLV CLZ CLN
1632 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1633 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1636 static void OpA8(void) // EORA IDX
1638 regs.a ^= regs.RdMem(DecodeIDX(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 OpA9(void) // ADCA IDX
1646 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1647 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
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 OpAA(void) // ORA IDX
1658 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1659 regs.cc &= 0xFD; // CLV
1660 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1661 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1664 static void OpAB(void) // ADDA IDX
1666 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1667 addr = (uint16)regs.a + (uint16)tmp;
1668 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1669 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1670 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1671 regs.a = addr & 0xFF; // Set accumulator
1672 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1673 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1676 static void OpAC(void) // CMPX IDX
1678 addr = DecodeIDX(regs.RdMem(regs.pc++));
1679 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1680 uint16 dw = regs.x - addr2;
1681 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1682 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1683 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1684 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1687 static void OpAD(void) // JSR IDX
1689 addr = DecodeIDX(regs.RdMem(regs.pc++));
1690 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1691 regs.pc = addr; // Jregs.s directly to IDX ptr
1694 static void OpAE(void) // LDX IDX
1696 addr = DecodeIDX(regs.RdMem(regs.pc++));
1697 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1698 regs.cc &= 0xFD; // CLV
1699 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1700 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1703 static void OpAF(void) // STX IDX
1705 addr = DecodeIDX(regs.RdMem(regs.pc++));
1706 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1707 regs.cc &= 0xF1; // CLV CLZ CLN
1708 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1709 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1712 static void OpB0(void) // SUBA ABS
1714 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1716 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1717 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1718 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1719 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1722 static void OpB1(void) // CMPA ABS
1724 tmp = regs.RdMem(FetchW());
1725 uint8 db = regs.a - tmp;
1726 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1727 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1728 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1729 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1732 static void OpB2(void) // SBCA ABS
1734 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1735 regs.a = regs.a - tmp - (regs.cc&0x01);
1736 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1737 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
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 OpB3(void) // SUBD ABS
1744 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
1745 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1747 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1748 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1749 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1750 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1751 regs.a = dr>>8; regs.b = dr&0xFF;
1754 static void OpB4(void) // ANDA ABS
1756 regs.a &= regs.RdMem(FetchW());
1757 regs.cc &= 0xFD; // Clear oVerflow flag
1758 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1759 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1762 static void OpB5(void) // BITA ABS
1764 tmp = regs.a & regs.RdMem(FetchW());
1765 regs.cc &= 0xFD; // Clear oVerflow flag
1766 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1767 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1770 static void OpB6(void) // LDA ABS
1772 regs.a = regs.RdMem(FetchW());
1773 regs.cc &= 0xFD; // CLV
1774 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1775 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1778 static void OpB7(void) // STA ABS
1780 regs.WrMem(FetchW(), regs.a);
1781 regs.cc &= 0xFD; // CLV
1782 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1783 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1786 static void OpB8(void) // EORA ABS
1788 regs.a ^= regs.RdMem(FetchW());
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 OpB9(void) // ADCA ABS
1796 tmp = regs.RdMem(FetchW());
1797 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
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); // oVerflow
1801 regs.a = addr; // 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 OpBA(void) // ORA ABS
1808 regs.a |= regs.RdMem(FetchW());
1809 regs.cc &= 0xFD; // CLV
1810 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1811 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1814 static void OpBB(void) // ADDA ABS
1816 tmp = regs.RdMem(FetchW());
1817 addr = (uint16)regs.a + (uint16)tmp;
1818 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1819 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1820 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1821 regs.a = addr & 0xFF; // Set accumulator
1822 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1823 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1826 static void OpBC(void) // CMPX ABS
1828 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1829 uint16 dw = regs.x - addr2;
1830 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1831 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1832 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1833 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1836 static void OpBD(void) // JSR ABS
1839 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1840 regs.pc = addr; // Go to absolute address (Not indir)
1844 static void OpBE(void) // LDX ABS
1847 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1848 regs.x = RdMemW(FetchW());
1850 regs.cc &= 0xFD; // CLV
1851 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1852 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1857 static void OpBF(void) // STX ABS
1860 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1861 WrMemW(FetchW(), regs.x);
1863 regs.cc &= 0xFD; // CLV
1864 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1865 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1870 static void OpC0(void) // SUBB #
1872 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
1874 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1875 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1876 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1877 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1880 static void OpC1(void) // CMPB #
1882 tmp = regs.RdMem(regs.pc++);
1883 uint8 db = regs.b - tmp;
1884 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1885 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1886 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1887 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1890 static void OpC2(void) // SBCB #
1892 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
1893 regs.b = regs.b - tmp - (regs.cc&0x01);
1894 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1895 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1896 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1897 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1900 static void OpC3(void) // ADDD #
1902 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
1904 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1906 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1907 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1908 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1909 regs.a = dr>>8; regs.b = dr&0xFF;
1912 static void OpC4(void) // ANDB #
1914 regs.b &= regs.RdMem(regs.pc++);
1915 regs.cc &= 0xFD; // Clear oVerflow flag
1916 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1917 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1920 static void OpC5(void) // BITB #
1922 tmp = regs.b & regs.RdMem(regs.pc++);
1923 regs.cc &= 0xF1; // CLV CLZ CLN
1924 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
1925 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
1928 static void OpC6(void) // LDB #
1930 regs.b = regs.RdMem(regs.pc++);
1931 regs.cc &= 0xF1; // CLV CLZ CLN
1932 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
1933 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
1936 static void OpC8(void) // EORB #
1938 regs.b ^= regs.RdMem(regs.pc++);
1939 regs.cc &= 0xFD; // CLV
1940 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1941 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1944 static void OpC9(void) // ADCB #
1946 tmp = regs.RdMem(regs.pc++);
1947 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1948 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1949 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1950 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1951 regs.b = addr & 0xFF; // Set accumulator
1952 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1953 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1956 static void OpCA(void) // ORB #
1958 regs.b |= regs.RdMem(regs.pc++);
1959 regs.cc &= 0xFD; // CLV
1960 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1961 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1964 static void OpCB(void) // ADDB #
1966 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
1967 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1968 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1969 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1970 regs.b = addr & 0xFF; // Set accumulator
1971 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1972 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1975 static void OpCC(void) // LDD #
1977 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
1978 regs.cc &= 0xFD; // CLV
1979 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1980 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1983 static void OpCE(void) // LDU #
1986 regs.cc &= 0xFD; // CLV
1987 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1988 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1991 static void OpD0(void) // SUBB DP
1993 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
1995 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1996 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1997 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1998 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2001 static void OpD1(void) // CMPB DP
2003 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2004 uint8 db = regs.b - tmp;
2005 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2006 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2007 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2008 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2011 static void OpD2(void) // SBCB DP
2013 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
2014 regs.b = regs.b - tmp - (regs.cc&0x01);
2015 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2016 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2017 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2018 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2021 static void OpD3(void) // ADDD DP
2023 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2024 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2026 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2028 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2029 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2030 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2031 regs.a = dr>>8; regs.b = dr&0xFF;
2034 static void OpD4(void) // ANDB DP
2036 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2037 regs.cc &= 0xFD; // Clear oVerflow flag
2038 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2039 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2042 static void OpD5(void) // BITB DP
2044 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2045 regs.cc &= 0xFD; // Clear oVerflow flag
2046 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2047 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2050 static void OpD6(void) // LDB DP
2052 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2053 regs.cc &= 0xFD; // CLV
2054 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2055 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2058 static void OpD7(void) // STB DP
2060 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2061 regs.cc &= 0xFD; // CLV
2062 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2063 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2066 static void OpD8(void) // EORB DP
2068 regs.b ^= regs.RdMem((regs.dp<<8)|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 OpD9(void) // ADCB DP
2076 tmp = regs.RdMem((regs.dp<<8)|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); // oVerflow
2081 regs.b = addr; // 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 OpDA(void) // ORB DP
2088 regs.b |= regs.RdMem((regs.dp<<8)|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 OpDB(void) // ADDB DP
2096 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2097 addr = (uint16)regs.b + (uint16)tmp;
2098 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2099 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2100 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2101 regs.b = addr & 0xFF; // Set accumulator
2102 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2103 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2106 static void OpDC(void) // LDD DP
2108 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2109 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2110 regs.cc &= 0xFD; // CLV
2111 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2112 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2115 static void OpDD(void) // STD DP
2117 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2118 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2119 regs.cc &= 0xFD; // CLV
2120 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2121 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2124 static void OpDE(void) // LDU DP
2126 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2127 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2128 regs.cc &= 0xFD; // CLV
2129 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2130 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2133 static void OpDF(void) // STU DP
2135 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2136 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2137 regs.cc &= 0xFD; // CLV
2138 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2139 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2142 static void OpE0(void) // SUBB IDX
2144 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2146 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2147 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2148 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2149 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2152 static void OpE1(void) // CMPB IDX
2154 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2155 uint8 db = regs.b - tmp;
2156 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2157 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2158 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2159 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2162 static void OpE2(void) // SBCB IDX
2164 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
2165 regs.b = regs.b - tmp - (regs.cc&0x01);
2166 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2167 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
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 OpE3(void) // ADDD IDX
2174 addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2175 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2177 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2179 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2180 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2181 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2182 regs.a = dr>>8; regs.b = dr&0xFF;
2185 static void OpE4(void) // ANDB IDX
2187 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2188 regs.cc &= 0xFD; // Clear oVerflow flag
2189 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2190 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2193 static void OpE5(void) // BITB IDX
2195 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2196 regs.cc &= 0xFD; // Clear oVerflow flag
2197 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2198 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2201 static void OpE6(void) // LDB IDX
2203 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2204 regs.cc &= 0xFD; // CLV
2205 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2206 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2209 static void OpE7(void) // STB IDX
2211 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2212 regs.cc &= 0xF1; // CLV CLZ CLN
2213 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
2214 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
2217 static void OpE8(void) // EORB IDX
2219 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2220 regs.cc &= 0xFD; // CLV
2221 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2222 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2225 static void OpE9(void) // ADCB IDX
2227 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2228 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
2229 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2230 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2231 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2232 regs.b = addr; // Set accumulator
2233 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2234 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2237 static void OpEA(void) // ORB IDX
2239 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2240 regs.cc &= 0xFD; // CLV
2241 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2242 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2245 static void OpEB(void) // ADDB IDX
2247 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2248 addr = (uint16)regs.b + (uint16)tmp;
2249 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2250 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2251 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2252 regs.b = addr; // Set accumulator
2253 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2254 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2257 static void OpEC(void) // LDD IDX
2259 addr = DecodeIDX(regs.RdMem(regs.pc++));
2260 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2261 regs.cc &= 0xF1; // CLV CLZ CLN
2262 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2263 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2266 static void OpED(void) // STD IDX
2268 addr = DecodeIDX(regs.RdMem(regs.pc++));
2269 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2270 regs.cc &= 0xF1; // CLV CLZ CLZ
2271 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2272 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2275 static void OpEE(void) // LDU IDX
2277 addr = DecodeIDX(regs.RdMem(regs.pc++));
2278 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2279 regs.cc &= 0xF1; // CLV CLZ CLN
2280 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2281 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2284 static void OpEF(void) // STU IDX
2286 addr = DecodeIDX(regs.RdMem(regs.pc++));
2287 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2288 regs.cc &= 0xF1; // CLV CLZ CLN
2289 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2290 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2293 static void OpF0(void) // SUBB ABS
2295 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2297 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2298 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2299 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2300 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2302 static void OpF1(void) // CMPB ABS
2304 tmp = regs.RdMem(FetchW());
2305 uint8 db = regs.b - tmp;
2306 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2307 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2308 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2309 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2312 static void OpF2(void) // SBCB ABS
2314 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
2315 regs.b = regs.b - tmp - (regs.cc&0x01);
2316 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2317 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2318 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2319 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2322 static void OpF3(void) // ADDD ABS
2324 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2325 uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2327 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2329 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2330 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2331 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2332 regs.a = dr>>8; regs.b = dr&0xFF;
2335 static void OpF4(void) // ANDB ABS
2337 regs.b &= regs.RdMem(FetchW());
2338 regs.cc &= 0xFD; // Clear oVerflow flag
2339 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2340 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2343 static void OpF5(void) // BITB ABS
2345 tmp = regs.b & regs.RdMem(FetchW());
2346 regs.cc &= 0xFD; // Clear oVerflow flag
2347 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2348 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2351 static void OpF6(void) // LDB ABS
2353 regs.b = regs.RdMem(FetchW());
2354 regs.cc &= 0xFD; // CLV
2355 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2356 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2359 static void OpF7(void) // STB ABS
2361 regs.WrMem(FetchW(), regs.b);
2362 regs.cc &= 0xFD; // CLV
2363 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2364 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2367 static void OpF8(void) // EORB ABS
2369 regs.b ^= regs.RdMem(FetchW());
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 OpF9(void) // ADCB ABS
2377 tmp = regs.RdMem(FetchW());
2378 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
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); // oVerflo
2382 regs.b = addr & 0xFF; // 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 OpFA(void) // ORB ABS
2389 regs.b |= regs.RdMem(FetchW());
2390 regs.cc &= 0xFD; // CLV
2391 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2392 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2395 static void OpFB(void) // ADDB ABS
2397 tmp = regs.RdMem(FetchW());
2398 addr = (uint16)regs.b + (uint16)tmp;
2399 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2400 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2401 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2402 regs.b = addr & 0xFF; // Set accumulator
2403 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2404 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2407 static void OpFC(void) // LDD ABS
2410 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2411 regs.cc &= 0xFD; // CLV
2412 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2413 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2416 static void OpFD(void) // STD ABS
2419 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2420 regs.cc &= 0xFD; // CLV
2421 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2422 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2425 static void OpFE(void) // LDU ABS
2428 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2429 regs.cc &= 0xFD; // CLV
2430 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2431 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2434 static void OpFF(void) // STU ABS
2437 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2438 regs.cc &= 0xFD; // CLV
2439 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2440 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2445 // Page one opcodes' execute code
2448 static void Op1021(void) // LBRN
2453 static void Op1022(void) // LBHI
2456 if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr);
2459 static void Op1023(void) // LBLS
2462 if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr);
2465 static void Op1024(void) // LBCC (LBHS)
2468 if (!(regs.cc&0x01)) regs.pc += SignedW(addr);
2471 static void Op1025(void) // LBCS (LBLO)
2474 if (regs.cc&0x01) regs.pc += SignedW(addr);
2477 static void Op1026(void) // LBNE
2480 if (!(regs.cc&0x04)) regs.pc += SignedW(addr);
2483 static void Op1027(void) // LBEQ
2486 if (regs.cc&0x04) regs.pc += SignedW(addr);
2489 static void Op1028(void) // LBVC
2492 if (!(regs.cc&0x02)) regs.pc += SignedW(addr);
2495 static void Op1029(void) // LBVS
2498 if (regs.cc&0x02) regs.pc += SignedW(addr);
2501 static void Op102A(void) // LBPL
2504 if (!(regs.cc&0x08)) regs.pc += SignedW(addr);
2507 static void Op102B(void) // LBMI
2510 if (regs.cc&0x08) regs.pc += SignedW(addr);
2513 static void Op102C(void) // LBGE
2516 if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
2519 static void Op102D(void) // LBLT
2522 if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr);
2525 static void Op102E(void) // LBGT
2528 if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr);
2531 static void Op102F(void) // LBLE
2534 if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
2537 static void Op103F(void) // SWI2 (Not yet implemented)
2541 static void Op1083(void) // CMPD #
2543 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2544 uint16 dw = dr - addr;
2545 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2546 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2547 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2548 ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2551 static void Op108C(void) // CMPY #
2554 uint16 dw = regs.y - addr;
2555 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2556 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2557 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2558 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2561 static void Op108E(void) // LDY #
2564 regs.cc &= 0xFD; // CLV
2565 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2566 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2569 static void Op1093(void) // CMPD DP
2571 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2572 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2573 uint16 dw = dr - addr;
2574 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2575 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2576 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2577 ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2580 static void Op109C(void) // CMPY DP
2582 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2583 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2584 uint16 dw = regs.y - addr;
2585 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2586 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2587 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2588 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2592 static void Op109E(void) // LDY DP
2594 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2595 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2596 regs.cc &= 0xFD; // CLV
2597 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2598 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2602 static void Op109F(void) // STY DP
2604 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2605 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2606 regs.cc &= 0xFD; // CLV
2607 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2608 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2611 static void Op10A3(void) // CMPD IDX
2613 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2614 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2615 uint16 dw = dr - addr;
2616 regs.cc &= 0xF0; // CLC CLV CLZ CLN
2617 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
2618 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
2619 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
2620 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
2623 static void Op10AC(void) // CMPY IDX
2625 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2626 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2627 uint16 dw = regs.y - addr;
2628 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2629 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2630 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2631 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2634 static void Op10AE(void) // LDY IDX
2636 addr = DecodeIDX(regs.RdMem(regs.pc++));
2637 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2638 regs.cc &= 0xF1; // CLV CLZ CLN
2639 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
2640 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
2643 static void Op10AF(void) // STY IDX
2645 addr = DecodeIDX(regs.RdMem(regs.pc++));
2646 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2647 regs.cc &= 0xFD; // CLV
2648 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2649 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2652 static void Op10B3(void) // CMPD ABS
2654 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
2655 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2656 uint16 dw = dr - addr2;
2657 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2658 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2659 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2660 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2663 static void Op10BC(void) // CMPY ABS
2665 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2666 uint16 dw = regs.y - addr2;
2667 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2668 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2669 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2670 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2673 static void Op10BE(void) // LDY ABS
2676 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2677 regs.cc &= 0xFD; // CLV
2678 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2679 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2682 static void Op10BF(void) // STY ABS
2685 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2686 regs.cc &= 0xFD; // CLV
2687 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2688 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2691 static void Op10CE(void) // LDS #
2694 regs.cc &= 0xFD; // CLV
2695 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2696 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2699 static void Op10DE(void) // LDS DP
2701 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2702 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2703 regs.cc &= 0xFD; // CLV
2704 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2705 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2708 static void Op10DF(void) // STS DP
2710 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2711 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2712 regs.cc &= 0xFD; // CLV
2713 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2714 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2717 static void Op10EE(void) // LDS IDX
2719 addr = DecodeIDX(regs.RdMem(regs.pc++));
2720 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2721 regs.cc &= 0xFD; // CLV
2722 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2723 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2726 static void Op10EF(void) // STS IDX
2728 addr = DecodeIDX(regs.RdMem(regs.pc++));
2729 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2730 regs.cc &= 0xFD; // CLV
2731 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2732 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2735 static void Op10FE(void) // LDS ABS
2738 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2739 regs.cc &= 0xFD; // CLV
2740 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2741 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2744 static void Op10FF(void) // STS ABS
2747 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2748 regs.cc &= 0xFD; // CLV
2749 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2750 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2755 // Page two opcodes' execute code
2758 static void Op113F(void) // SWI3
2762 static void Op1183(void) // CMPU #
2765 uint16 dw = regs.u - addr;
2766 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2767 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2768 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2769 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2772 static void Op118C(void) // CMPS #
2775 uint16 dw = regs.s - addr;
2776 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2777 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2778 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2779 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2782 static void Op1193(void) // CMPU DP
2784 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2785 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2786 uint16 dw = regs.u - addr;
2787 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2788 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2789 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2790 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2793 static void Op119C(void) // CMPS DP
2795 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2796 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2797 uint16 dw = regs.s - addr;
2798 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2799 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2800 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2801 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2804 static void Op11A3(void) // CMPU IDX
2806 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2807 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2808 uint16 dw = regs.u - addr;
2809 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2810 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2811 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2812 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2815 static void Op11AC(void) // CMPS IDX
2817 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2818 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2819 uint16 dw = regs.s - addr;
2820 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2821 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2822 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2823 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2826 static void Op11B3(void) // CMPU ABS
2828 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2829 uint16 dw = regs.u - addr2;
2830 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2831 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2832 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2833 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2837 static void Op11BC(void) // CMPS ABS
2839 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2840 uint16 dw = regs.s - addr2;
2841 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2842 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2843 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2844 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2848 //temp, for testing...
2849 /*static uint8 backTrace[256];
2850 static uint16 btPC[256];
2851 static int btPtr = 0;//*/
2852 static void Op__(void) // Illegal opcode
2856 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
2857 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
2858 for(int i=0; i<256; i++)
2860 dpc = btPC[(btPtr+i)&0xFF];
2867 // Internal "memcpy" (so we don't have to link with any external libraries!)
2869 static void myMemcpy(void * dst, void * src, uint32 size)
2871 uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
2873 for(uint32 i=0; i<size; i++)
2878 // Function to execute 6809 instructions
2880 void Execute6809(V6809REGS * context, uint32 cycles)
2882 myMemcpy(®s, context, sizeof(V6809REGS));
2885 while (regs.clock < cycles)
2887 /*static bool disasm = false;
2888 if (regs.pc == 0x15BA) disasm = true;
2889 if (disasm) { dpc = regs.pc; Decode_6809(); }
2890 if (regs.pc == 0x164A) disasm = false;//*/
2892 //temp, for testing...
2893 /*backTrace[btPtr] = regs.RdMem(regs.pc);
2894 btPC[btPtr] = regs.pc;
2895 btPtr = (btPtr++) & 0xFF;//*/
2896 exec_op0[regs.RdMem(regs.pc++)]();
2898 // Handle any pending interrupts
2900 uint32 flags = context->cpuFlags;
2902 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
2904 regs.cc |= (FLAG_F | FLAG_I); // Set F, I
2905 regs.dp = 0; // Reset direct page register
2906 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
2907 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
2908 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
2910 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
2912 regs.cc |= FLAG_E; // Set the Entire flag
2914 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
2915 regs.WrMem(--regs.s, regs.pc >> 8);
2916 regs.WrMem(--regs.s, regs.u & 0xFF);
2917 regs.WrMem(--regs.s, regs.u >> 8);
2918 regs.WrMem(--regs.s, regs.y & 0xFF);
2919 regs.WrMem(--regs.s, regs.y >> 8);
2920 regs.WrMem(--regs.s, regs.x & 0xFF);
2921 regs.WrMem(--regs.s, regs.x >> 8);
2922 regs.WrMem(--regs.s, regs.dp);
2923 regs.WrMem(--regs.s, regs.b);
2924 regs.WrMem(--regs.s, regs.a);
2925 regs.WrMem(--regs.s, regs.cc);
2927 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
2928 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
2930 context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
2931 regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
2933 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
2935 if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
2937 regs.cc &= ~FLAG_E; // Clear the Entire flag
2939 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
2940 regs.WrMem(--regs.s, regs.pc >> 8);
2941 regs.WrMem(--regs.s, regs.cc);
2943 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
2944 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
2946 context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
2947 regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
2950 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
2952 if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
2954 regs.cc |= FLAG_E; // Set the Entire flag
2956 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
2957 regs.WrMem(--regs.s, regs.pc >> 8);
2958 regs.WrMem(--regs.s, regs.u & 0xFF);
2959 regs.WrMem(--regs.s, regs.u >> 8);
2960 regs.WrMem(--regs.s, regs.y & 0xFF);
2961 regs.WrMem(--regs.s, regs.y >> 8);
2962 regs.WrMem(--regs.s, regs.x & 0xFF);
2963 regs.WrMem(--regs.s, regs.x >> 8);
2964 regs.WrMem(--regs.s, regs.dp);
2965 regs.WrMem(--regs.s, regs.b);
2966 regs.WrMem(--regs.s, regs.a);
2967 regs.WrMem(--regs.s, regs.cc);
2969 regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
2970 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
2972 context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
2973 regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
2976 /*if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
2977 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
2980 myMemcpy(context, ®s, sizeof(V6809REGS));
2984 // Get the clock of the currently executing CPU
2986 uint32 GetCurrentV6809Clock(void)