2 // Virtual 6809 v1.2 (Last build: 2/27/2004)
6 // (c) 1997,2004 Underground Software
12 #include "dis6809.h" // Temporary...
13 #include "log.h" // Temporary...
16 // Private global variables
18 static V6809REGS regs;
19 static WORD addr; // Temporary variables common to all funcs...
22 // Private function prototypes
24 static int SignedB(BYTE); // Return signed byte from unsigned
25 static int SignedW(WORD); // Return signed word from unsigned
26 static WORD FetchW(void);
27 static WORD RdMemW(WORD addr);
28 static void WrMemW(WORD addr, WORD w);
29 static WORD ReadEXG(BYTE); // Read TFR/EXG post byte
30 static void WriteEXG(BYTE, WORD); // Set TFR/EXG data
31 static WORD DecodeReg(BYTE); // Decode register data
32 static WORD DecodeIDX(BYTE); // Decode IDX data
34 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
35 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
36 // even *try* to see if they're there).
38 #define FD(x) static void Op##x(); // FD -> "Forward Declaration"
39 #define FE(x) static void Op10##x();
40 #define FF(x) static void Op11##x();
42 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)
43 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)
44 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)
45 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)
46 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)
47 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)
48 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)
49 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)
50 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)
51 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)
52 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)
53 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)
54 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)
55 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)
56 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)
57 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)
60 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)
61 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)
62 FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
64 FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
74 // Array of page zero opcode functions...
75 static void (* exec_op0[256])() = {
76 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
77 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
78 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
79 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
80 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
81 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
82 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
83 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
84 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
85 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
86 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
87 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
88 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
89 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
90 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
91 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
94 // Array of page one opcode functions...
95 static void (* exec_op1[256])() = {
96 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
97 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
98 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
99 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
100 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
101 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
102 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
103 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
104 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
105 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
106 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
107 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
108 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
109 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
110 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
111 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
114 // Array of page two opcode functions...
115 static void (* exec_op2[256])() = {
116 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
117 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
118 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
119 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
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__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
124 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
125 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
126 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
127 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
128 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
129 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
130 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
131 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
136 // Fetch a word out of 6809 memory (little endian format)
137 // This is a leftover from when fetches were separated from garden variety reads...
141 WORD w = RdMemW(regs.pc);
146 // Fetch word function
150 return (WORD)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
154 // Read word from memory function
156 WORD RdMemW(WORD addr)
158 return (WORD)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
162 // Write word to memory function
164 void WrMemW(WORD addr, WORD w)
166 regs.WrMem(addr + 0, w >> 8);
167 regs.WrMem(addr + 1, w & 0xFF);
171 // return signed byte from unsigned
175 return (b & 0x80 ? b - 256 : b);
179 // return signed word from unsigned
183 return (w & 0x8000 ? w - 65536 : w);
187 // Function to read TFR/EXG post byte
189 WORD ReadEXG(BYTE code)
196 retval = (regs.a << 8) | regs.b;
233 // Function to set TFR/EXG data
235 void WriteEXG(BYTE code, WORD data)
240 regs.a = data >> 8, regs.b = data & 0xFF; break;
242 regs.x = data; break;
244 regs.y = data; break;
246 regs.u = data; break;
248 regs.s = data; break;
250 regs.pc = data; break;
252 regs.a = data & 0xFF; break;
254 regs.b = data & 0xFF; break;
256 regs.cc = data & 0xFF; break;
258 regs.dp = data & 0xFF; break;
263 // Function to decode register data
265 WORD DecodeReg(BYTE reg)
272 retval = regs.x; break;
274 retval = regs.y; break;
276 retval = regs.u; break;
278 retval = regs.s; break;
285 // Function to decode IDX data
287 WORD DecodeIDX(BYTE code)
290 BYTE reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
292 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
293 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
301 woff = DecodeReg(reg);
305 case 0: regs.x += 2; break;
306 case 1: regs.y += 2; break;
307 case 2: regs.u += 2; break;
308 case 3: regs.s += 2; break;
314 case 0: regs.x -= 2; break;
315 case 1: regs.y -= 2; break;
316 case 2: regs.u -= 2; break;
317 case 3: regs.s -= 2; break;
319 woff = DecodeReg(reg);
323 woff = DecodeReg(reg);
327 woff = DecodeReg(reg) + SignedB(regs.b);
331 woff = DecodeReg(reg) + SignedB(regs.a);
335 woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++));
339 woff = DecodeReg(reg) + SignedW(FetchW());
343 woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b);
347 woff = regs.pc + SignedB(regs.RdMem(regs.pc++));
351 woff = regs.pc + SignedW(FetchW());
365 addr = DecodeReg(reg);
368 case 0: regs.x++; break;
369 case 1: regs.y++; break;
370 case 2: regs.u++; break;
371 case 3: regs.s++; break;
375 addr = DecodeReg(reg);
378 case 0: regs.x += 2; break;
379 case 1: regs.y += 2; break;
380 case 2: regs.u += 2; break;
381 case 3: regs.s += 2; break;
384 case 2: { switch(reg)
386 case 0: regs.x--; break;
387 case 1: regs.y--; break;
388 case 2: regs.u--; break;
389 case 3: regs.s--; break;
391 addr = DecodeReg(reg); break; }
392 case 3: { switch(reg)
394 case 0: regs.x--; regs.x--; break;
395 case 1: regs.y--; regs.y--; break;
396 case 2: regs.u--; regs.u--; break;
397 case 3: regs.s--; regs.s--; break;
399 addr = DecodeReg(reg); break; }
400 case 4: { addr = DecodeReg(reg); break; }
401 case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; }
402 case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; }
403 case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; }
404 case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; }
405 case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; }
406 case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; }
407 case 13: { addr = regs.pc + SignedW(FetchW()); break; }
416 // Page zero instructions...
419 static void Op00(void) // NEG DP
421 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
422 tmp = 256 - regs.RdMem(addr);
423 regs.WrMem(addr, tmp);
425 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
426 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
427 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
428 (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
433 static void Op01(void) // NEG DP (Undocumented)
438 static void Op03(void) // COM DP
440 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
441 tmp = 0xFF ^ regs.RdMem(addr);
442 regs.WrMem(addr, tmp);
444 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
445 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
446 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
451 static void Op04(void) // LSR DP
453 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
454 tmp = regs.RdMem(addr);
455 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
456 tmp >>= 1; regs.WrMem(addr, tmp);
457 regs.cc &= 0xF7; // CLN
458 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
461 static void Op06(void) // ROR DP
463 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); BYTE tmp2 = regs.RdMem(addr);
464 tmp = (tmp2>>1) + (regs.cc&0x01)*128;
465 regs.WrMem(addr, tmp);
466 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
467 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
468 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
471 static void Op07(void) // ASR DP
473 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
474 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
476 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
477 regs.WrMem(addr, tmp);
478 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
479 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
482 static void Op08(void) // LSL DP
484 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
485 tmp = regs.RdMem(addr);
486 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
488 regs.WrMem(addr, tmp);
489 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
490 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
493 static void Op09(void) // ROL DP
495 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); BYTE tmp2 = regs.RdMem(addr);
496 tmp = (tmp2<<1) + (regs.cc&0x01);
497 regs.WrMem(addr, tmp);
498 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
499 ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
500 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
501 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
504 static void Op0A(void) // DEC DP
506 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
507 tmp = regs.RdMem(addr) - 1;
508 regs.WrMem(addr, tmp);
509 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
510 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
511 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
514 static void Op0C(void) // INC DP
516 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
517 tmp = regs.RdMem(addr) + 1;
518 regs.WrMem(addr, tmp);
519 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
520 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
521 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
524 static void Op0D(void) // TST DP
526 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
527 regs.cc &= 0xFD; // CLV
528 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
529 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
532 static void Op0E(void) // JMP DP
534 regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
537 static void Op0F(void) // CLR DP
539 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
540 regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
544 static void Op10(void) // Page 1 opcode
546 exec_op1[regs.RdMem(regs.pc++)]();
549 static void Op11(void) // Page 2 opcode
551 exec_op2[regs.RdMem(regs.pc++)]();
554 static void Op12(void) // NOP
559 static void Op13(void) // SYNC
563 static void Op16(void) // LBRA
565 regs.pc += SignedW(FetchW());
568 static void Op17(void) // LBSR
571 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
572 regs.pc += SignedW(addr);
575 static void Op19(void) // DAA
577 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
579 regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry
581 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
583 regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
585 regs.cc &= 0xF1; // CL NZV
586 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
587 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
591 static void Op1A(void) // ORCC #
593 regs.cc |= regs.RdMem(regs.pc++);
598 static void Op1C(void) // ANDCC #
600 regs.cc &= regs.RdMem(regs.pc++);
605 static void Op1D(void) // SEX
607 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
609 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
610 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
615 static void Op1E(void) // EXG
617 tmp = regs.RdMem(regs.pc++);
618 addr = ReadEXG(tmp >> 4);
619 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
620 WriteEXG(tmp & 0xF, addr);
625 static void Op1F(void) // TFR
627 tmp = regs.RdMem(regs.pc++);
628 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
631 static void Op20(void) // BRA
633 regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
636 static void Op21(void) // BRN
638 regs.RdMem(regs.pc++);
641 static void Op22(void) // BHI
643 tmp = regs.RdMem(regs.pc++);
644 if (!(regs.cc&0x05)) regs.pc += SignedB(tmp);
647 static void Op23(void) // BLS
649 tmp = regs.RdMem(regs.pc++);
650 if (regs.cc&0x05) regs.pc += SignedB(tmp);
653 static void Op24(void) // BCC (BHS)
655 tmp = regs.RdMem(regs.pc++);
656 if (!(regs.cc&0x01)) regs.pc += SignedB(tmp);
659 static void Op25(void) // BCS (BLO)
661 tmp = regs.RdMem(regs.pc++);
662 if (regs.cc&0x01) regs.pc += SignedB(tmp);
665 static void Op26(void) // BNE
667 tmp = regs.RdMem(regs.pc++);
668 if (!(regs.cc&0x04)) regs.pc += SignedB(tmp);
671 static void Op27(void) // BEQ
673 tmp = regs.RdMem(regs.pc++);
674 if (regs.cc&0x04) regs.pc += SignedB(tmp);
677 static void Op28(void) // BVC
679 tmp = regs.RdMem(regs.pc++);
680 if (!(regs.cc&0x02)) regs.pc += SignedB(tmp);
683 static void Op29(void) // BVS
685 tmp = regs.RdMem(regs.pc++);
686 if (regs.cc&0x02) regs.pc += SignedB(tmp);
689 static void Op2A(void) // BPL
691 tmp = regs.RdMem(regs.pc++);
692 if (!(regs.cc&0x08)) regs.pc += SignedB(tmp);
695 static void Op2B(void) // BMI
697 tmp = regs.RdMem(regs.pc++);
698 if (regs.cc&0x08) regs.pc += SignedB(tmp);
701 static void Op2C(void) // BGE
703 tmp = regs.RdMem(regs.pc++);
704 if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp);
707 static void Op2D(void) // BLT
709 tmp = regs.RdMem(regs.pc++);
710 if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp);
713 static void Op2E(void) // BGT
715 tmp = regs.RdMem(regs.pc++);
716 if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp);
719 static void Op2F(void) // BLE
721 tmp = regs.RdMem(regs.pc++);
722 if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp);
725 static void Op30(void) // LEAX
727 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
728 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
731 static void Op31(void) // LEAY
733 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
734 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
737 static void Op32(void) // LEAS
739 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
740 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
743 static void Op33(void) // LEAU
745 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
746 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
749 static void Op34(void) // PSHS
751 tmp = regs.RdMem(regs.pc++);
752 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
753 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
754 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
755 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
756 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
757 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
758 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
759 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
762 static void Op35(void) // PULS
764 tmp = regs.RdMem(regs.pc++);
765 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
766 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
767 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
768 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
769 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
770 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
771 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
772 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
776 static void Op36(void) // PSHU
778 tmp = regs.RdMem(regs.pc++);
780 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
781 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
782 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
783 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
784 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
785 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
786 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
787 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
792 static void Op37(void) // PULU
794 tmp = regs.RdMem(regs.pc++);
795 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
796 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
797 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
798 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
799 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
800 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
801 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
802 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
805 static void Op39(void) // RTS
807 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
810 static void Op3A(void) // ABX
815 static void Op3B(void) // RTI
817 regs.cc = regs.RdMem(regs.s++);
818 if (regs.cc&0x80) // If E flag set, pull all regs
820 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
821 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
822 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
823 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
830 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
832 static void Op3C(void) // CWAI
834 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
835 regs.clock += 1000000; // Force interrupt
837 static void Op3D(void) // MUL
839 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
840 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
841 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
844 static void Op3E(void) // RESET
847 static void Op3F(void) // SWI
850 static void Op40(void) // NEGA
852 regs.a = 256 - regs.a;
853 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
854 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
855 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
856 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
859 static void Op43(void) // COMA
862 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
863 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
864 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
867 static void Op44(void) // LSRA
869 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
871 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
872 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
875 static void Op46(void) // RORA
877 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
878 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
879 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
880 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
883 static void Op47(void) // ASRA
885 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
886 regs.a >>= 1; // Do the shift
887 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
888 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
889 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
892 static void Op48(void) // LSLA [Keep checking from here...]
894 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
896 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
897 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
900 static void Op49(void) // ROLA
902 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
903 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
904 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
905 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
908 static void Op4A(void) // DECA
911 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
912 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
913 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
916 static void Op4C(void) // INCA
919 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
920 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
921 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
924 static void Op4D(void) // TSTA
926 regs.cc &= 0xFD; // Clear oVerflow flag
927 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
928 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
931 static void Op4F(void) // CLRA
934 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
937 static void Op50(void) // NEGB
939 regs.b = 256 - regs.b;
940 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
941 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
942 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
943 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
944 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
947 static void Op53(void) // COMB
950 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
951 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
952 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
955 static void Op54(void) // LSRB
957 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
959 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
960 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
963 static void Op56(void) // RORB
965 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
966 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
967 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
968 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
971 static void Op57(void) // ASRB
973 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
974 regs.b >>= 1; // Do the shift
975 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
976 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
977 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
980 static void Op58(void) // LSLB
982 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
984 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
985 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
988 static void Op59(void) // ROLB
991 regs.b = (tmp<<1) + (regs.cc&0x01);
992 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
993 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
994 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
997 static void Op5A(void) // DECB
1000 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1001 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1002 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1005 static void Op5C(void) // INCB
1008 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1009 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1010 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1013 static void Op5D(void) // TSTB
1015 regs.cc &= 0xFD; // Clear oVerflow flag
1016 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1017 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1020 static void Op5F(void) // CLRB
1023 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1026 static void Op60(void) // NEG IDX
1028 addr = DecodeIDX(regs.RdMem(regs.pc++));
1029 tmp = regs.RdMem(addr); BYTE res = 256 - tmp;
1030 regs.WrMem(addr, res);
1031 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1032 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1033 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1034 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1035 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1038 static void Op63(void) // COM IDX
1040 addr = DecodeIDX(regs.RdMem(regs.pc++));
1041 tmp = regs.RdMem(addr) ^ 0xFF;
1042 regs.WrMem(addr, tmp);
1043 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1044 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1045 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1048 static void Op64(void) // LSR IDX
1050 addr = DecodeIDX(regs.RdMem(regs.pc++));
1051 tmp = regs.RdMem(addr);
1052 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1053 tmp >>= 1; regs.WrMem(addr, tmp);
1054 regs.cc &= 0xF7; // CLN
1055 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1058 static void Op66(void) // ROR IDX
1060 addr = DecodeIDX(regs.RdMem(regs.pc++));
1061 tmp = regs.RdMem(addr); BYTE tmp2 = tmp;
1062 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1063 regs.WrMem(addr, tmp);
1064 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1065 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1066 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1069 static void Op67(void) // ASR IDX
1071 addr = DecodeIDX(regs.RdMem(regs.pc++));
1072 tmp = regs.RdMem(addr);
1073 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1075 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1076 regs.WrMem(addr, tmp);
1077 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1078 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1081 static void Op68(void) // LSL IDX
1083 addr = DecodeIDX(regs.RdMem(regs.pc++));
1084 tmp = regs.RdMem(addr);
1085 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1087 regs.WrMem(addr, tmp);
1088 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1089 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1092 static void Op69(void) // ROL IDX
1094 BYTE tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1095 tmp = (tmp2<<1) + (regs.cc&0x01);
1096 regs.WrMem(addr, tmp);
1097 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1098 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1099 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1102 static void Op6A(void) // DEC IDX
1104 BYTE tmp; WORD addr;
1105 addr = DecodeIDX(regs.RdMem(regs.pc++));
1106 tmp = regs.RdMem(addr) - 1;
1107 regs.WrMem(addr, tmp);
1108 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1109 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1110 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1113 static void Op6C(void) // INC IDX
1115 addr = DecodeIDX(regs.RdMem(regs.pc++));
1116 tmp = regs.RdMem(addr) + 1;
1117 regs.WrMem(addr, tmp);
1118 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1119 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1120 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1123 static void Op6D(void) // TST IDX
1125 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1126 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1127 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1130 static void Op6E(void) // JMP IDX
1132 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1135 static void Op6F(void) // CLR IDX
1137 addr = DecodeIDX(regs.RdMem(regs.pc++));
1138 regs.WrMem(addr, 0);
1139 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1142 static void Op70(void) // NEG ABS
1145 tmp = regs.RdMem(addr); BYTE res = 256 - tmp;
1146 regs.WrMem(addr, res);
1147 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1148 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1149 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1150 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1153 static void Op73(void) // COM ABS
1156 tmp = regs.RdMem(addr) ^ 0xFF;
1157 regs.WrMem(addr, tmp);
1158 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
1159 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1160 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1163 static void Op74(void) // LSR ABS
1166 tmp = regs.RdMem(addr);
1167 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
1168 tmp >>= 1; regs.WrMem(addr, tmp);
1169 regs.cc &= 0xF7; // CLN
1170 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1173 static void Op76(void) // ROR ABS
1175 BYTE tmp; WORD addr;
1177 tmp = regs.RdMem(addr); BYTE tmp2 = tmp;
1178 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1179 regs.WrMem(addr, tmp);
1180 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1181 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1182 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1185 static void Op77(void) // ASR ABS
1187 BYTE tmp; WORD addr;
1189 tmp = regs.RdMem(addr);
1190 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1192 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
1193 regs.WrMem(addr, tmp);
1194 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1195 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1198 static void Op78(void) // LSL ABS
1200 BYTE tmp; WORD addr;
1202 tmp = regs.RdMem(addr);
1203 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1205 regs.WrMem(addr, tmp);
1206 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1207 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1210 static void Op79(void) // ROL ABS
1212 BYTE tmp2 = regs.RdMem(FetchW());
1213 tmp = (tmp2<<1) + (regs.cc&0x01);
1214 regs.WrMem(addr, tmp);
1215 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1216 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1217 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1220 static void Op7A(void) // DEC ABS
1222 BYTE tmp; WORD addr;
1224 tmp = regs.RdMem(addr) - 1;
1225 regs.WrMem(addr, tmp);
1226 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1227 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1228 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1231 static void Op7C(void) // INC ABS
1233 BYTE tmp; WORD addr;
1235 tmp = regs.RdMem(addr) + 1;
1236 regs.WrMem(addr, tmp);
1237 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1238 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1239 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1243 static void Op7D(void) // TST ABS
1245 BYTE tmp = regs.RdMem(FetchW());
1247 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1248 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1253 static void Op7E(void) // JMP ABS
1258 static void Op7F(void) // CLR ABS
1260 regs.WrMem(FetchW(), 0);
1261 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
1264 static void Op80(void) // SUBA #
1266 BYTE tmp = regs.RdMem(regs.pc++); BYTE as = regs.a;
1268 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1269 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1270 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1271 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1274 static void Op81(void) // CMPA #
1276 tmp = regs.RdMem(regs.pc++);
1277 BYTE db = regs.a - tmp;
1278 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1279 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1280 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1281 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1284 static void Op82(void) // SBCA #
1286 tmp = regs.RdMem(regs.pc++); BYTE as = regs.a;
1287 regs.a = regs.a - tmp - (regs.cc&0x01);
1288 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1289 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1290 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1291 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1294 static void Op83(void) // SUBD #
1296 addr = FetchW(); WORD dr = (regs.a<<8)|regs.b, ds = dr;
1298 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1299 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1300 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1301 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1302 regs.a = dr>>8; regs.b = dr&0xFF;
1305 static void Op84(void) // ANDA #
1307 regs.a &= regs.RdMem(regs.pc++);
1308 regs.cc &= 0xFD; // Clear oVerflow flag
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 Op85(void) // BITA #
1315 tmp = regs.a & regs.RdMem(regs.pc++);
1316 regs.cc &= 0xFD; // Clear oVerflow flag
1317 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1318 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1321 static void Op86(void) // LDA #
1323 regs.a = regs.RdMem(regs.pc++);
1324 regs.cc &= 0xFD; // CLV
1325 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1326 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1329 static void Op88(void) // EORA #
1331 regs.a ^= regs.RdMem(regs.pc++);
1332 regs.cc &= 0xFD; // CLV
1333 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1334 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1337 static void Op89(void) // ADCA #
1339 tmp = regs.RdMem(regs.pc++);
1340 addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01);
1341 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1342 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1343 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1344 regs.a = addr & 0xFF; // Set accumulator
1345 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1346 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1349 static void Op8A(void) // ORA #
1351 regs.a |= regs.RdMem(regs.pc++);
1352 regs.cc &= 0xFD; // CLV
1353 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1354 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1357 static void Op8B(void) // ADDA #
1359 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
1360 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
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); // Set Zero flag
1365 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1368 static void Op8C(void) // CMPX #
1371 WORD dw = regs.x - addr;
1372 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1373 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1374 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1375 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1378 static void Op8D(void) // Bregs.s
1380 tmp = regs.RdMem(regs.pc++);
1381 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1382 regs.pc += SignedB(tmp);
1385 static void Op8E(void) // LDX #
1388 regs.cc &= 0xFD; // CLV
1389 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1390 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1393 static void Op90(void) // SUBA DP
1395 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE as = regs.a;
1397 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1398 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1399 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1400 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1403 static void Op91(void) // CMPA DP
1405 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1406 BYTE db = regs.a - tmp;
1407 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1408 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1409 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1410 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1413 static void Op92(void) // SBCA DP
1415 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE as = regs.a;
1416 regs.a = regs.a - tmp - (regs.cc&0x01);
1417 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1418 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1419 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1420 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1423 static void Op93(void) // SUBD DP
1425 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); WORD dr = (regs.a<<8)|regs.b, ds = dr;
1426 WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1428 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1429 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1430 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1431 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1432 regs.a = dr>>8; regs.b = dr&0xFF;
1435 static void Op94(void) // ANDA DP
1437 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1438 regs.cc &= 0xF1; // CLV CLZ CLN
1439 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
1440 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
1443 static void Op95(void) // BITA DP
1445 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1446 regs.cc &= 0xFD; // Clear oVerflow flag
1447 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1448 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1451 static void Op96(void) // LDA DP
1453 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1454 regs.cc &= 0xF1; // CLN CLZ CLV
1455 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1456 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1459 static void Op97(void) // STA DP
1461 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
1462 regs.cc &= 0xFD; // CLV
1463 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1464 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1467 static void Op98(void) // EORA DP
1469 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1470 regs.cc &= 0xFD; // CLV
1471 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1472 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1475 static void Op99(void) // ADCA DP
1477 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1478 addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01);
1479 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1480 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1481 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1482 regs.a = addr & 0xFF; // Set accumulator
1483 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1484 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1487 static void Op9A(void) // ORA DP
1489 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1490 regs.cc &= 0xFD; // CLV
1491 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1492 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1495 static void Op9B(void) // ADDA DP
1497 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1498 addr = (WORD)regs.a + (WORD)tmp;
1499 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1500 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1501 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1502 regs.a = addr & 0xFF; // Set accumulator
1503 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1504 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1507 static void Op9C(void) // CMPX DP
1509 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1510 WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1511 WORD dw = regs.x - adr2;
1512 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1513 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1514 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1515 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1518 static void Op9D(void) // JSR DP
1520 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1521 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1522 regs.pc = addr; // JSR to DP location...
1525 static void Op9E(void) // LDX DP
1527 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1528 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1529 regs.cc &= 0xFD; // CLV
1530 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1531 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1534 static void Op9F(void) // STX DP
1536 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1537 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1538 regs.cc &= 0xFD; // CLV
1539 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1540 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1543 static void OpA0(void) // SUBA IDX
1545 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE as = regs.a;
1547 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1548 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1549 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1550 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1553 static void OpA1(void) // CMPA IDX
1555 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1556 BYTE db = regs.a - tmp;
1557 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1558 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1559 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1560 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1563 static void OpA2(void) // SBCA IDX
1565 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE as = regs.a;
1566 regs.a = regs.a - tmp - (regs.cc&0x01);
1567 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1568 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1569 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1570 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1573 static void OpA3(void) // SUBD IDX
1575 addr = DecodeIDX(regs.RdMem(regs.pc++)); WORD dr = (regs.a<<8)|regs.b, ds = dr;
1576 WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1578 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1579 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1580 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1581 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1582 regs.a = dr>>8; regs.b = dr&0xFF;
1585 static void OpA4(void) // ANDA IDX
1587 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1588 regs.cc &= 0xFD; // Clear oVerflow flag
1589 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1590 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1593 static void OpA5(void) // BITA IDX
1595 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1596 regs.cc &= 0xFD; // Clear oVerflow flag
1597 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1598 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1601 static void OpA6(void) // LDA IDX
1603 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1604 regs.cc &= 0xF1; // CLV CLZ CLN
1605 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1606 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1609 static void OpA7(void) // STA IDX
1611 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1612 regs.cc &= 0xF1; // CLV CLZ CLN
1613 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1614 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1617 static void OpA8(void) // EORA IDX
1619 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1620 regs.cc &= 0xFD; // CLV
1621 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1622 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1625 static void OpA9(void) // ADCA IDX
1627 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1628 addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01);
1629 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1630 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1631 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1632 regs.a = addr & 0xFF; // Set accumulator
1633 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1634 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1637 static void OpAA(void) // ORA IDX
1639 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1640 regs.cc &= 0xFD; // CLV
1641 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1642 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1645 static void OpAB(void) // ADDA IDX
1647 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1648 addr = (WORD)regs.a + (WORD)tmp;
1649 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1650 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1651 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1652 regs.a = addr & 0xFF; // Set accumulator
1653 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1654 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1657 static void OpAC(void) // CMPX IDX
1659 addr = DecodeIDX(regs.RdMem(regs.pc++));
1660 WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1661 WORD dw = regs.x - addr2;
1662 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1663 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1664 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1665 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1668 static void OpAD(void) // JSR IDX
1670 addr = DecodeIDX(regs.RdMem(regs.pc++));
1671 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1672 regs.pc = addr; // Jregs.s directly to IDX ptr
1675 static void OpAE(void) // LDX IDX
1677 addr = DecodeIDX(regs.RdMem(regs.pc++));
1678 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1679 regs.cc &= 0xFD; // CLV
1680 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1681 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1684 static void OpAF(void) // STX IDX
1686 addr = DecodeIDX(regs.RdMem(regs.pc++));
1687 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1688 regs.cc &= 0xF1; // CLV CLZ CLN
1689 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1690 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1693 static void OpB0(void) // SUBA ABS
1695 tmp = regs.RdMem(FetchW()); BYTE as = regs.a;
1697 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1698 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1699 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1700 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1703 static void OpB1(void) // CMPA ABS
1705 tmp = regs.RdMem(FetchW());
1706 BYTE db = regs.a - tmp;
1707 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1708 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1709 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1710 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1713 static void OpB2(void) // SBCA ABS
1715 tmp = regs.RdMem(FetchW()); BYTE as = regs.a;
1716 regs.a = regs.a - tmp - (regs.cc&0x01);
1717 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1718 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1719 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1720 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1723 static void OpB3(void) // SUBD ABS
1725 addr = FetchW(); WORD dr = (regs.a<<8)|regs.b, ds = dr;
1726 WORD adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1728 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1729 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1730 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1731 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1732 regs.a = dr>>8; regs.b = dr&0xFF;
1735 static void OpB4(void) // ANDA ABS
1737 regs.a &= regs.RdMem(FetchW());
1738 regs.cc &= 0xFD; // Clear oVerflow flag
1739 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1740 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1743 static void OpB5(void) // BITA ABS
1745 tmp = regs.a & regs.RdMem(FetchW());
1746 regs.cc &= 0xFD; // Clear oVerflow flag
1747 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1748 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1751 static void OpB6(void) // LDA ABS
1753 regs.a = regs.RdMem(FetchW());
1754 regs.cc &= 0xFD; // CLV
1755 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1756 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1759 static void OpB7(void) // STA ABS
1761 regs.WrMem(FetchW(), regs.a);
1762 regs.cc &= 0xFD; // CLV
1763 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1764 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1767 static void OpB8(void) // EORA ABS
1769 regs.a ^= regs.RdMem(FetchW());
1770 regs.cc &= 0xFD; // CLV
1771 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1772 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1775 static void OpB9(void) // ADCA ABS
1777 tmp = regs.RdMem(FetchW());
1778 addr = (WORD)regs.a + (WORD)tmp + (WORD)(regs.cc&0x01);
1779 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1780 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1781 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1782 regs.a = addr; // Set accumulator
1783 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1784 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1787 static void OpBA(void) // ORA ABS
1789 regs.a |= regs.RdMem(FetchW());
1790 regs.cc &= 0xFD; // CLV
1791 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1792 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1795 static void OpBB(void) // ADDA ABS
1797 tmp = regs.RdMem(FetchW());
1798 addr = (WORD)regs.a + (WORD)tmp;
1799 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1800 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1801 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1802 regs.a = addr & 0xFF; // Set accumulator
1803 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1804 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1807 static void OpBC(void) // CMPX ABS
1809 addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1810 WORD dw = regs.x - addr2;
1811 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1812 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1813 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1814 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1817 static void OpBD(void) // JSR ABS
1820 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
1821 regs.pc = addr; // Go to absolute address (Not indir)
1825 static void OpBE(void) // LDX ABS
1828 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1829 regs.x = RdMemW(FetchW());
1831 regs.cc &= 0xFD; // CLV
1832 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1833 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1838 static void OpBF(void) // STX ABS
1841 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1842 WrMemW(FetchW(), regs.x);
1844 regs.cc &= 0xFD; // CLV
1845 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1846 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1851 static void OpC0(void) // SUBB #
1853 tmp = regs.RdMem(regs.pc++); BYTE bs = regs.b;
1855 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1856 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1857 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1858 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1861 static void OpC1(void) // CMPB #
1863 tmp = regs.RdMem(regs.pc++);
1864 BYTE db = regs.b - tmp;
1865 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1866 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1867 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1868 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1871 static void OpC2(void) // SBCB #
1873 tmp = regs.RdMem(regs.pc++); BYTE bs = regs.b;
1874 regs.b = regs.b - tmp - (regs.cc&0x01);
1875 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1876 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1877 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1878 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1881 static void OpC3(void) // ADDD #
1883 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
1885 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1887 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1888 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1889 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1890 regs.a = dr>>8; regs.b = dr&0xFF;
1893 static void OpC4(void) // ANDB #
1895 regs.b &= regs.RdMem(regs.pc++);
1896 regs.cc &= 0xFD; // Clear oVerflow flag
1897 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1898 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1901 static void OpC5(void) // BITB #
1903 tmp = regs.b & regs.RdMem(regs.pc++);
1904 regs.cc &= 0xF1; // CLV CLZ CLN
1905 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
1906 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
1909 static void OpC6(void) // LDB #
1911 regs.b = regs.RdMem(regs.pc++);
1912 regs.cc &= 0xF1; // CLV CLZ CLN
1913 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
1914 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
1917 static void OpC8(void) // EORB #
1919 regs.b ^= regs.RdMem(regs.pc++);
1920 regs.cc &= 0xFD; // CLV
1921 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1922 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1925 static void OpC9(void) // ADCB #
1927 tmp = regs.RdMem(regs.pc++);
1928 addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01);
1929 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1930 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
1931 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1932 regs.b = addr & 0xFF; // Set accumulator
1933 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1934 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1937 static void OpCA(void) // ORB #
1939 regs.b |= regs.RdMem(regs.pc++);
1940 regs.cc &= 0xFD; // CLV
1941 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1942 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1945 static void OpCB(void) // ADDB #
1947 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
1948 (addr > 0xFF ? 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 OpCC(void) // LDD #
1958 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
1959 regs.cc &= 0xFD; // CLV
1960 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1961 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1964 static void OpCE(void) // LDU #
1967 regs.cc &= 0xFD; // CLV
1968 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1969 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1972 static void OpD0(void) // SUBB DP
1974 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE bs = regs.b;
1976 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1977 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1978 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1979 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1982 static void OpD1(void) // CMPB DP
1984 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1985 BYTE db = regs.b - tmp;
1986 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1987 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1988 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1989 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1992 static void OpD2(void) // SBCB DP
1994 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); BYTE bs = regs.b;
1995 regs.b = regs.b - tmp - (regs.cc&0x01);
1996 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1997 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1998 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1999 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2002 static void OpD3(void) // ADDD DP
2004 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2005 WORD adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2007 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2009 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2010 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2011 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2012 regs.a = dr>>8; regs.b = dr&0xFF;
2015 static void OpD4(void) // ANDB DP
2017 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2018 regs.cc &= 0xFD; // Clear oVerflow flag
2019 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2020 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2023 static void OpD5(void) // BITB DP
2025 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2026 regs.cc &= 0xFD; // Clear oVerflow flag
2027 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2028 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2031 static void OpD6(void) // LDB DP
2033 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2034 regs.cc &= 0xFD; // CLV
2035 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2036 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2039 static void OpD7(void) // STB DP
2041 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2042 regs.cc &= 0xFD; // CLV
2043 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2044 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2047 static void OpD8(void) // EORB DP
2049 regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2050 regs.cc &= 0xFD; // CLV
2051 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2052 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2055 static void OpD9(void) // ADCB DP
2057 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2058 addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01);
2059 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2060 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2061 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2062 regs.b = addr; // Set accumulator
2063 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2064 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2067 static void OpDA(void) // ORB DP
2069 regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2070 regs.cc &= 0xFD; // CLV
2071 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2072 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2075 static void OpDB(void) // ADDB DP
2077 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2078 addr = (WORD)regs.b + (WORD)tmp;
2079 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2080 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2081 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2082 regs.b = addr & 0xFF; // Set accumulator
2083 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2084 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2087 static void OpDC(void) // LDD DP
2089 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2090 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2091 regs.cc &= 0xFD; // CLV
2092 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2093 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2096 static void OpDD(void) // STD DP
2098 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2099 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2100 regs.cc &= 0xFD; // CLV
2101 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2102 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2105 static void OpDE(void) // LDU DP
2107 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2108 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2109 regs.cc &= 0xFD; // CLV
2110 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2111 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2114 static void OpDF(void) // STU DP
2116 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2117 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2118 regs.cc &= 0xFD; // CLV
2119 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2120 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2123 static void OpE0(void) // SUBB IDX
2125 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE bs = regs.b;
2127 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2128 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2129 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2130 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2133 static void OpE1(void) // CMPB IDX
2135 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2136 BYTE db = regs.b - tmp;
2137 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2138 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2139 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2140 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2143 static void OpE2(void) // SBCB IDX
2145 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); BYTE bs = regs.b;
2146 regs.b = regs.b - tmp - (regs.cc&0x01);
2147 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2148 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2149 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2150 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2153 static void OpE3(void) // ADDD IDX
2155 addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2156 WORD adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2158 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2160 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2161 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2162 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2163 regs.a = dr>>8; regs.b = dr&0xFF;
2166 static void OpE4(void) // ANDB IDX
2168 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2169 regs.cc &= 0xFD; // Clear oVerflow flag
2170 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2171 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2174 static void OpE5(void) // BITB IDX
2176 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2177 regs.cc &= 0xFD; // Clear oVerflow flag
2178 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2179 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2182 static void OpE6(void) // LDB IDX
2184 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2185 regs.cc &= 0xFD; // CLV
2186 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2187 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2190 static void OpE7(void) // STB IDX
2192 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2193 regs.cc &= 0xF1; // CLV CLZ CLN
2194 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
2195 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
2198 static void OpE8(void) // EORB IDX
2200 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2201 regs.cc &= 0xFD; // CLV
2202 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2203 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2206 static void OpE9(void) // ADCB IDX
2208 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2209 addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01);
2210 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2211 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2212 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2213 regs.b = addr; // Set accumulator
2214 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2215 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2218 static void OpEA(void) // ORB IDX
2220 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2221 regs.cc &= 0xFD; // CLV
2222 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2223 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2226 static void OpEB(void) // ADDB IDX
2228 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2229 addr = (WORD)regs.b + (WORD)tmp;
2230 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2231 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2232 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2233 regs.b = addr; // Set accumulator
2234 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2235 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2238 static void OpEC(void) // LDD IDX
2240 addr = DecodeIDX(regs.RdMem(regs.pc++));
2241 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2242 regs.cc &= 0xF1; // CLV CLZ CLN
2243 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2244 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2247 static void OpED(void) // STD IDX
2249 addr = DecodeIDX(regs.RdMem(regs.pc++));
2250 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2251 regs.cc &= 0xF1; // CLV CLZ CLZ
2252 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
2253 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
2256 static void OpEE(void) // LDU IDX
2258 addr = DecodeIDX(regs.RdMem(regs.pc++));
2259 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2260 regs.cc &= 0xF1; // CLV CLZ CLN
2261 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2262 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2265 static void OpEF(void) // STU IDX
2267 addr = DecodeIDX(regs.RdMem(regs.pc++));
2268 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2269 regs.cc &= 0xF1; // CLV CLZ CLN
2270 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
2271 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
2274 static void OpF0(void) // SUBB ABS
2276 tmp = regs.RdMem(FetchW()); BYTE bs = regs.b;
2278 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2279 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2280 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2281 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2283 static void OpF1(void) // CMPB ABS
2285 tmp = regs.RdMem(FetchW());
2286 BYTE db = regs.b - tmp;
2287 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2288 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2289 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2290 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2293 static void OpF2(void) // SBCB ABS
2295 tmp = regs.RdMem(FetchW()); BYTE bs = regs.b;
2296 regs.b = regs.b - tmp - (regs.cc&0x01);
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
2303 static void OpF3(void) // ADDD ABS
2305 addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2306 WORD adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2308 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2310 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2311 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2312 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2313 regs.a = dr>>8; regs.b = dr&0xFF;
2316 static void OpF4(void) // ANDB ABS
2318 regs.b &= regs.RdMem(FetchW());
2319 regs.cc &= 0xFD; // Clear oVerflow flag
2320 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2321 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2324 static void OpF5(void) // BITB ABS
2326 tmp = regs.b & regs.RdMem(FetchW());
2327 regs.cc &= 0xFD; // Clear oVerflow flag
2328 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2329 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2332 static void OpF6(void) // LDB ABS
2334 regs.b = regs.RdMem(FetchW());
2335 regs.cc &= 0xFD; // CLV
2336 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2337 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2340 static void OpF7(void) // STB ABS
2342 regs.WrMem(FetchW(), regs.b);
2343 regs.cc &= 0xFD; // CLV
2344 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2345 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2348 static void OpF8(void) // EORB ABS
2350 regs.b ^= regs.RdMem(FetchW());
2351 regs.cc &= 0xFD; // CLV
2352 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2353 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2356 static void OpF9(void) // ADCB ABS
2358 tmp = regs.RdMem(FetchW());
2359 addr = (WORD)regs.b + (WORD)tmp + (WORD)(regs.cc&0x01);
2360 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2361 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2362 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2363 regs.b = addr & 0xFF; // Set accumulator
2364 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2365 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2368 static void OpFA(void) // ORB ABS
2370 regs.b |= regs.RdMem(FetchW());
2371 regs.cc &= 0xFD; // CLV
2372 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2373 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2376 static void OpFB(void) // ADDB ABS
2378 tmp = regs.RdMem(FetchW());
2379 addr = (WORD)regs.b + (WORD)tmp;
2380 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
2381 ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
2382 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2383 regs.b = addr & 0xFF; // Set accumulator
2384 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
2385 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
2388 static void OpFC(void) // LDD ABS
2391 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
2392 regs.cc &= 0xFD; // CLV
2393 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2394 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2397 static void OpFD(void) // STD ABS
2400 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
2401 regs.cc &= 0xFD; // CLV
2402 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2403 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2406 static void OpFE(void) // LDU ABS
2409 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2410 regs.cc &= 0xFD; // CLV
2411 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2412 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2415 static void OpFF(void) // STU ABS
2418 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
2419 regs.cc &= 0xFD; // CLV
2420 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2421 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2426 // Page one opcodes' execute code
2429 static void Op1021(void) // LBRN
2434 static void Op1022(void) // LBHI
2437 if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr);
2440 static void Op1023(void) // LBLS
2443 if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr);
2446 static void Op1024(void) // LBCC (LBHS)
2449 if (!(regs.cc&0x01)) regs.pc += SignedW(addr);
2452 static void Op1025(void) // LBCS (LBLO)
2455 if (regs.cc&0x01) regs.pc += SignedW(addr);
2458 static void Op1026(void) // LBNE
2461 if (!(regs.cc&0x04)) regs.pc += SignedW(addr);
2464 static void Op1027(void) // LBEQ
2467 if (regs.cc&0x04) regs.pc += SignedW(addr);
2470 static void Op1028(void) // LBVC
2473 if (!(regs.cc&0x02)) regs.pc += SignedW(addr);
2476 static void Op1029(void) // LBVS
2479 if (regs.cc&0x02) regs.pc += SignedW(addr);
2482 static void Op102A(void) // LBPL
2485 if (!(regs.cc&0x08)) regs.pc += SignedW(addr);
2488 static void Op102B(void) // LBMI
2491 if (regs.cc&0x08) regs.pc += SignedW(addr);
2494 static void Op102C(void) // LBGE
2497 if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
2500 static void Op102D(void) // LBLT
2503 if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr);
2506 static void Op102E(void) // LBGT
2509 if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr);
2512 static void Op102F(void) // LBLE
2515 if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr);
2518 static void Op103F(void) // SWI2 (Not yet implemented)
2522 static void Op1083(void) // CMPD #
2524 addr = FetchW(); WORD dr = (regs.a<<8)|regs.b;
2525 WORD dw = dr - addr;
2526 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2527 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2528 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2529 ((dr^addr^dw^((WORD)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2532 static void Op108C(void) // CMPY #
2535 WORD dw = regs.y - addr;
2536 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2537 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2538 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2539 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2542 static void Op108E(void) // LDY #
2545 regs.cc &= 0xFD; // CLV
2546 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2547 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2550 static void Op1093(void) // CMPD DP
2552 WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2553 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2554 WORD dw = dr - 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 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2558 ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2561 static void Op109C(void) // CMPY DP
2563 WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2564 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2565 WORD dw = regs.y - addr;
2566 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2567 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2568 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2569 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2573 static void Op109E(void) // LDY DP
2575 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2576 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2577 regs.cc &= 0xFD; // CLV
2578 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2579 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2583 static void Op109F(void) // STY DP
2585 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2586 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2587 regs.cc &= 0xFD; // CLV
2588 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2589 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2592 static void Op10A3(void) // CMPD IDX
2594 WORD adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2595 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2596 WORD dw = dr - addr;
2597 regs.cc &= 0xF0; // CLC CLV CLZ CLN
2598 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
2599 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
2600 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
2601 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
2604 static void Op10AC(void) // CMPY IDX
2606 WORD adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2607 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2608 WORD dw = regs.y - addr;
2609 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2610 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2611 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2612 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2615 static void Op10AE(void) // LDY IDX
2617 addr = DecodeIDX(regs.RdMem(regs.pc++));
2618 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2619 regs.cc &= 0xF1; // CLV CLZ CLN
2620 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
2621 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
2624 static void Op10AF(void) // STY IDX
2626 addr = DecodeIDX(regs.RdMem(regs.pc++));
2627 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2628 regs.cc &= 0xFD; // CLV
2629 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2630 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2633 static void Op10B3(void) // CMPD ABS
2635 addr = FetchW(); WORD dr = (regs.a<<8)|regs.b;
2636 WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2637 WORD dw = dr - addr2;
2638 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2639 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2640 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2641 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2644 static void Op10BC(void) // CMPY ABS
2646 addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2647 WORD dw = regs.y - addr2;
2648 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2649 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2650 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2651 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2654 static void Op10BE(void) // LDY ABS
2657 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2658 regs.cc &= 0xFD; // CLV
2659 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2660 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2663 static void Op10BF(void) // STY ABS
2666 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
2667 regs.cc &= 0xFD; // CLV
2668 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2669 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2672 static void Op10CE(void) // LDS #
2675 regs.cc &= 0xFD; // CLV
2676 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2677 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2680 static void Op10DE(void) // LDS DP
2682 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2683 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2684 regs.cc &= 0xFD; // CLV
2685 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2686 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2689 static void Op10DF(void) // STS DP
2691 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2692 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2693 regs.cc &= 0xFD; // CLV
2694 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2695 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2698 static void Op10EE(void) // LDS IDX
2700 addr = DecodeIDX(regs.RdMem(regs.pc++));
2701 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2702 regs.cc &= 0xFD; // CLV
2703 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2704 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2707 static void Op10EF(void) // STS IDX
2709 addr = DecodeIDX(regs.RdMem(regs.pc++));
2710 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2711 regs.cc &= 0xFD; // CLV
2712 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2713 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2716 static void Op10FE(void) // LDS ABS
2719 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2720 regs.cc &= 0xFD; // CLV
2721 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2722 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2725 static void Op10FF(void) // STS ABS
2728 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
2729 regs.cc &= 0xFD; // CLV
2730 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2731 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2736 // Page two opcodes' execute code
2739 static void Op113F(void) // SWI3
2743 static void Op1183(void) // CMPU #
2746 WORD dw = regs.u - addr;
2747 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2748 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2749 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2750 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2753 static void Op118C(void) // CMPS #
2756 WORD dw = regs.s - addr;
2757 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2758 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2759 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2760 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2763 static void Op1193(void) // CMPU DP
2765 WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2766 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2767 WORD dw = regs.u - addr;
2768 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2769 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2770 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2771 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2774 static void Op119C(void) // CMPS DP
2776 WORD adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2777 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2778 WORD dw = regs.s - addr;
2779 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2780 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2781 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2782 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2785 static void Op11A3(void) // CMPU IDX
2787 WORD addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2788 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2789 WORD dw = regs.u - addr;
2790 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2791 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2792 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2793 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2796 static void Op11AC(void) // CMPS IDX
2798 WORD addr2 = DecodeIDX(regs.RdMem(regs.pc++));
2799 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
2800 WORD dw = regs.s - addr;
2801 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2802 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2803 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2804 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2807 static void Op11B3(void) // CMPU ABS
2809 addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2810 WORD dw = regs.u - addr2;
2811 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2812 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2813 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2814 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2818 static void Op11BC(void) // CMPS ABS
2820 addr = FetchW(); WORD addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2821 WORD dw = regs.s - addr2;
2822 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
2823 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
2824 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
2825 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2829 //temp, for testing...
2830 /*static BYTE backTrace[256];
2831 static WORD btPC[256];
2832 static int btPtr = 0;//*/
2833 static void Op__(void) // Illegal opcode
2837 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
2838 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
2839 for(int i=0; i<256; i++)
2841 dpc = btPC[(btPtr+i)&0xFF];
2848 // Internal "memcpy" (so we don't have to link with any external libraries!)
2850 static void myMemcpy(void * dst, void * src, DWORD size)
2852 BYTE * d = (BYTE *)dst, * s = (BYTE *)src;
2854 for(DWORD i=0; i<size; i++)
2859 // Function to execute 6809 instructions
2861 void Execute6809(V6809REGS * context, DWORD cycles)
2863 myMemcpy(®s, context, sizeof(V6809REGS));
2866 DWORD clockSave = regs.clock;
2868 while (regs.clock < cycles)
2870 /*static bool disasm = false;
2871 if (regs.pc == 0x15BA) disasm = true;
2872 if (disasm) { dpc = regs.pc; Decode_6809(); }
2873 if (regs.pc == 0x164A) disasm = false;//*/
2875 //temp, for testing...
2876 /*backTrace[btPtr] = regs.RdMem(regs.pc);
2877 btPC[btPtr] = regs.pc;
2878 btPtr = (btPtr++) & 0xFF;//*/
2879 exec_op0[regs.RdMem(regs.pc++)]();
2881 // Handle any pending interrupts
2883 DWORD flags = context->cpuFlags;
2885 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
2887 regs.cc |= (FLAG_F | FLAG_I); // Set F, I
2888 regs.dp = 0; // Reset direct page register
2889 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
2890 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
2891 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
2893 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
2895 regs.cc |= FLAG_E; // Set the Entire flag
2897 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
2898 regs.WrMem(--regs.s, regs.pc >> 8);
2899 regs.WrMem(--regs.s, regs.u & 0xFF);
2900 regs.WrMem(--regs.s, regs.u >> 8);
2901 regs.WrMem(--regs.s, regs.y & 0xFF);
2902 regs.WrMem(--regs.s, regs.y >> 8);
2903 regs.WrMem(--regs.s, regs.x & 0xFF);
2904 regs.WrMem(--regs.s, regs.x >> 8);
2905 regs.WrMem(--regs.s, regs.dp);
2906 regs.WrMem(--regs.s, regs.b);
2907 regs.WrMem(--regs.s, regs.a);
2908 regs.WrMem(--regs.s, regs.cc);
2910 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
2911 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
2913 context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
2914 regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
2916 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
2918 if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)?
2920 regs.cc &= ~FLAG_E; // Clear the Entire flag
2922 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs...
2923 regs.WrMem(--regs.s, regs.pc >> 8);
2924 regs.WrMem(--regs.s, regs.cc);
2926 regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags
2927 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
2929 context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
2930 regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
2933 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
2935 if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)?
2937 regs.cc |= FLAG_E; // Set the Entire flag
2939 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
2940 regs.WrMem(--regs.s, regs.pc >> 8);
2941 regs.WrMem(--regs.s, regs.u & 0xFF);
2942 regs.WrMem(--regs.s, regs.u >> 8);
2943 regs.WrMem(--regs.s, regs.y & 0xFF);
2944 regs.WrMem(--regs.s, regs.y >> 8);
2945 regs.WrMem(--regs.s, regs.x & 0xFF);
2946 regs.WrMem(--regs.s, regs.x >> 8);
2947 regs.WrMem(--regs.s, regs.dp);
2948 regs.WrMem(--regs.s, regs.b);
2949 regs.WrMem(--regs.s, regs.a);
2950 regs.WrMem(--regs.s, regs.cc);
2952 regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
2953 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
2955 context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
2956 regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
2959 /*if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
2960 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
2962 regs.clock += clockSave;
2964 myMemcpy(context, ®s, sizeof(V6809REGS));