]> Shamusworld >> Repos - thunder/blob - src/v6809.cpp
Code cleanup.
[thunder] / src / v6809.cpp
1 //
2 // Virtual 6809 v1.3
3 //
4 // by James Hammons
5 // (c) 1997, 2014 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  -----------------------------------------------------------
11 // JLH  06/15/2006  Added changelog ;-)
12 // JLH  06/15/2006  Scrubbed all BYTE, WORD & DWORD references from the code
13 // JLH  11/11/2006  Removed all SignedX() references
14 //
15
16 // Mebbe someday I'll get around to fixing the core to be more like V65C02...
17 // We have a start... ;-)
18 //
19
20 #include "v6809.h"
21
22 #define __DEBUG__
23 #ifdef __DEBUG__
24 #include "dis6809.h"    // Temporary...
25 #include "log.h"                // Temporary...
26 #endif
27
28 // Various macros
29
30 #define CLR_Z                           (regs.cc &= ~FLAG_Z)
31 #define CLR_ZN                          (regs.cc &= ~(FLAG_Z | FLAG_N))
32 #define CLR_ZNC                         (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C))
33 #define CLR_V                           (regs.cc &= ~FLAG_V)
34 #define CLR_N                           (regs.cc &= ~FLAG_N)
35 #define SET_Z(r)                        (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z))
36 #define SET_N(r)                        (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
37
38 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
39 #define SET_C_ADD(a,b)          (regs.cc = ((uint8_t)(b) > (uint8_t)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
40 //#define SET_C_SUB(a,b)                (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
41 #define SET_C_CMP(a,b)          (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
42 #define SET_ZN(r)                       SET_N(r); SET_Z(r)
43 #define SET_ZNC_ADD(a,b,r)      SET_N(r); SET_Z(r); SET_C_ADD(a,b)
44 //#define SET_ZNC_SUB(a,b,r)    SET_N(r); SET_Z(r); SET_C_SUB(a,b)
45 #define SET_ZNC_CMP(a,b,r)      SET_N(r); SET_Z(r); SET_C_CMP(a,b)
46
47 //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
48 //Hmm, why not do like we did for READ_ABS*???
49 //Because the EA_* macros are usually used as an argument to a function call, that's why.
50 #define EA_IMM                          regs.pc++
51 #define EA_ZP                           regs.RdMem(regs.pc++)
52 #define EA_ZP_X                         (regs.RdMem(regs.pc++) + regs.x) & 0xFF
53 #define EA_ZP_Y                         (regs.RdMem(regs.pc++) + regs.y) & 0xFF
54 #define EA_ABS                          RdMemW(regs.pc)
55 #define EA_ABS_X                        RdMemW(regs.pc) + regs.x
56 #define EA_ABS_Y                        RdMemW(regs.pc) + regs.y
57 #define EA_IND_ZP_X                     RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF)
58 #define EA_IND_ZP_Y                     RdMemW(regs.RdMem(regs.pc++)) + regs.y
59 #define EA_IND_ZP                       RdMemW(regs.RdMem(regs.pc++))
60
61 #define READ_IMM                        regs.RdMem(EA_IMM)
62 #define READ_ZP                         regs.RdMem(EA_ZP)
63 #define READ_ZP_X                       regs.RdMem(EA_ZP_X)
64 #define READ_ZP_Y                       regs.RdMem(EA_ZP_Y)
65 #define READ_ABS                        regs.RdMem(EA_ABS);     regs.pc += 2
66 #define READ_ABS_X                      regs.RdMem(EA_ABS_X);   regs.pc += 2
67 #define READ_ABS_Y                      regs.RdMem(EA_ABS_Y);   regs.pc += 2
68 #define READ_IND_ZP_X           regs.RdMem(EA_IND_ZP_X)
69 #define READ_IND_ZP_Y           regs.RdMem(EA_IND_ZP_Y)
70 #define READ_IND_ZP                     regs.RdMem(EA_IND_ZP)
71
72 #define READ_IMM_WB(v)          uint16_t addr = EA_IMM;      v = regs.RdMem(addr)
73 #define READ_ZP_WB(v)           uint16_t addr = EA_ZP;       v = regs.RdMem(addr)
74 #define READ_ZP_X_WB(v)         uint16_t addr = EA_ZP_X;     v = regs.RdMem(addr)
75 #define READ_ABS_WB(v)          uint16_t addr = EA_ABS;      v = regs.RdMem(addr); regs.pc += 2
76 #define READ_ABS_X_WB(v)        uint16_t addr = EA_ABS_X;    v = regs.RdMem(addr); regs.pc += 2
77 #define READ_ABS_Y_WB(v)        uint16_t addr = EA_ABS_Y;    v = regs.RdMem(addr); regs.pc += 2
78 #define READ_IND_ZP_X_WB(v)     uint16_t addr = EA_IND_ZP_X; v = regs.RdMem(addr)
79 #define READ_IND_ZP_Y_WB(v)     uint16_t addr = EA_IND_ZP_Y; v = regs.RdMem(addr)
80 #define READ_IND_ZP_WB(v)       uint16_t addr = EA_IND_ZP;   v = regs.RdMem(addr)
81
82 #define WRITE_BACK(d)           regs.WrMem(addr, (d))
83
84 // Private global variables
85
86 static V6809REGS regs;
87 //Let's see if we can nuke this shit.
88 static uint16_t addr;                                                           // Temporary variables common to all funcs...
89 static uint8_t tmp;
90
91 // Private function prototypes
92
93 static uint16_t FetchW(void);
94 static uint16_t RdMemW(uint16_t addr);
95 static void WrMemW(uint16_t addr, uint16_t w);
96 static uint16_t ReadEXG(uint8_t);                                       // Read TFR/EXG post byte
97 static void WriteEXG(uint8_t, uint16_t);                        // Set TFR/EXG data
98 static uint16_t DecodeReg(uint8_t);                                     // Decode register data
99 static uint16_t DecodeIDX(uint8_t);                                     // Decode IDX data
100
101 //static void (* exec_op1[256])();
102 //static void (* exec_op2[256])();
103 #if 1
104
105 // This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler
106 // isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't
107 // even *try* to see if they're there).
108
109 #define FD(x)           static void Op##x();            // FD -> "Forward Declaration"
110 #define FE(x)           static void Op10##x();
111 #define FF(x)           static void Op11##x();
112
113 FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11)
114 FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23)
115 FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31)
116 FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40)
117 FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56)
118 FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69)
119 FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C)
120 FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B)
121 FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A)
122 FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8)
123 FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6)
124 FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4)
125 FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5)
126 FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3)
127 FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1)
128 FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF)
129 FD(__) FD(01)
130
131 FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E)
132 FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3)
133 FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF)
134
135 FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC)
136
137 #undef FD
138 #undef FE
139 #undef FF
140
141 #endif
142
143 // We can move these down and do away with the forward declarations... !!! FIX !!!
144 // Actually, we can't because these are used in a couple of the opcode functions.
145 // Have to think about how to fix that...
146
147 //
148 // Function arrays
149 //
150
151 // Array of page zero opcode functions...
152 static void (* exec_op0[256])() = {
153         Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
154         Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
155         Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
156         Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
157         Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
158         Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
159         Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
160         Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
161         Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
162         Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
163         OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
164         OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
165         OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
166         OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
167         OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
168         OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
169 };
170
171 // Array of page one opcode functions...
172 static void (* exec_op1[256])() = {
173         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
174         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
175         Op__,   Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
176         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op103F,
177         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
178         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
179         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
180         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
181         Op__,   Op__,   Op__,   Op1083, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op108C, Op__,   Op108E, Op__,
182         Op__,   Op__,   Op__,   Op1093, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op109C, Op__,   Op109E, Op109F,
183         Op__,   Op__,   Op__,   Op10A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10AC, Op__,   Op10AE, Op10AF,
184         Op__,   Op__,   Op__,   Op10B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10BC, Op__,   Op10BE, Op10BF,
185         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10CE, Op__,
186         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10DE, Op10DF,
187         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10EE, Op10EF,
188         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10FE, Op10FF
189 };
190
191 // Array of page two opcode functions...
192 static void (* exec_op2[256])() = {
193         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
194         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
195         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
196         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op113F,
197         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
198         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
199         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
200         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
201         Op__,   Op__,   Op__,   Op1183, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op118C, Op__,   Op__,   Op__,
202         Op__,   Op__,   Op__,   Op1193, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op119C, Op__,   Op__,   Op__,
203         Op__,   Op__,   Op__,   Op11A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11AC, Op__,   Op__,   Op__,
204         Op__,   Op__,   Op__,   Op11B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11BC, Op__,   Op__,   Op__,
205         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
206         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
207         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
208         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__
209 };
210
211
212 //
213 // Fetch a word out of 6809 memory (little endian format)
214 // This is a leftover from when fetches were separated from garden variety reads...
215 //
216 static uint16_t FetchW()
217 {
218         uint16_t w = RdMemW(regs.pc);
219         regs.pc += 2;
220         return w;
221 }
222
223 //
224 // Read word from memory function
225 //
226 uint16_t RdMemW(uint16_t addr)
227 {
228         return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
229 }
230
231 //
232 // Write word to memory function
233 //
234 void WrMemW(uint16_t addr, uint16_t w)
235 {
236         regs.WrMem(addr + 0, w >> 8);
237         regs.WrMem(addr + 1, w & 0xFF);
238 }
239
240 //
241 // Function to read TFR/EXG post byte
242 //
243 uint16_t ReadEXG(uint8_t code)
244 {
245         uint16_t retval;
246
247         switch (code)
248         {
249         case 0:
250                 retval = (regs.a << 8) | regs.b;
251                 break;
252         case 1:
253                 retval = regs.x;
254                 break;
255         case 2:
256                 retval = regs.y;
257                 break;
258         case 3:
259                 retval = regs.u;
260                 break;
261         case 4:
262                 retval = regs.s;
263                 break;
264         case 5:
265                 retval = regs.pc;
266                 break;
267         case 8:
268                 retval = regs.a;
269                 break;
270         case 9:
271                 retval = regs.b;
272                 break;
273         case 10:
274                 retval = regs.cc;
275                 break;
276         case 11:
277                 retval = regs.dp;
278                 break;
279         default:
280                 retval = 0xFF;
281         }
282
283         return retval;
284 }
285
286 //
287 // Function to set TFR/EXG data
288 //
289 void WriteEXG(uint8_t code, uint16_t data)
290 {
291         switch (code)
292         {
293         case 0:
294                 regs.a = data >> 8, regs.b = data & 0xFF;  break;
295         case 1:
296                 regs.x = data;  break;
297         case 2:
298                 regs.y = data;  break;
299         case 3:
300                 regs.u = data;  break;
301         case 4:
302                 regs.s = data;  break;
303         case 5:
304                 regs.pc = data;  break;
305         case 8:
306                 regs.a = data & 0xFF;  break;
307         case 9:
308                 regs.b = data & 0xFF;  break;
309         case 10:
310                 regs.cc = data & 0xFF;  break;
311         case 11:
312                 regs.dp = data & 0xFF;  break;
313         }
314 }
315
316 //
317 // Function to decode register data
318 //
319 uint16_t DecodeReg(uint8_t reg)
320 {
321         uint16_t retval;
322
323         switch (reg)
324         {
325         case 0:
326         retval = regs.x;  break;
327         case 1:
328         retval = regs.y;  break;
329         case 2:
330         retval = regs.u;  break;
331         case 3:
332         retval = regs.s;  break;
333         }
334
335         return retval;
336 }
337
338 //
339 // Function to decode IDX data
340 //
341 uint16_t DecodeIDX(uint8_t code)
342 {
343         uint16_t addr, woff;
344         uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
345
346         if (!(code & 0x80))                                                     // Hi bit unset? Then decode 4 bit offset
347                 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
348         else
349         {
350                 if (idxind)
351                 {
352                         switch (lo_nyb)
353                         {
354                         case 1:
355                                 woff = DecodeReg(reg);
356                                 addr = RdMemW(woff);
357                                 switch (reg)
358                                 {
359                                 case 0:  regs.x += 2;  break;
360                                 case 1:  regs.y += 2;  break;
361                                 case 2:  regs.u += 2;  break;
362                                 case 3:  regs.s += 2;  break;
363                                 }
364                                 break;
365                         case 3:
366                                 switch (reg)
367                                 {
368                                 case 0:  regs.x -= 2;  break;
369                                 case 1:  regs.y -= 2;  break;
370                                 case 2:  regs.u -= 2;  break;
371                                 case 3:  regs.s -= 2;  break;
372                                 }
373                                 woff = DecodeReg(reg);
374                                 addr = RdMemW(woff);
375                                 break;
376                         case 4:
377                                 woff = DecodeReg(reg);
378                                 addr = RdMemW(woff);
379                                 break;
380                         case 5:
381                                 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
382                                 addr = RdMemW(woff);
383                                 break;
384                         case 6:
385                                 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
386                                 addr = RdMemW(woff);
387                                 break;
388                         case 8:
389                                 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
390                                 addr = RdMemW(woff);
391                                 break;
392                         case 9:
393                                 woff = DecodeReg(reg) + FetchW();
394                                 addr = RdMemW(woff);
395                                 break;
396                         case 11:
397                                 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
398                                 addr = RdMemW(woff);
399                                 break;
400                         case 12:
401                                 woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
402                                 addr = RdMemW(woff);
403                                 break;
404                         case 13:
405                                 woff = regs.pc + FetchW();
406                                 addr = RdMemW(woff);
407                                 break;
408                         case 15:
409                                 woff = FetchW();
410                                 addr = RdMemW(woff);
411                                 break;
412                         }
413                 }
414                 else
415                 {
416                         switch (lo_nyb)
417                         {
418                         case 0:
419                                 addr = DecodeReg(reg);
420                                 switch (reg)
421                                 {
422                                 case 0:  regs.x++;  break;
423                                 case 1:  regs.y++;  break;
424                                 case 2:  regs.u++;  break;
425                                 case 3:  regs.s++;  break;
426                                 }
427                                 break;
428                         case 1:
429                                 addr = DecodeReg(reg);
430                                 switch (reg)
431                                 {
432                                 case 0:  regs.x += 2;  break;
433                                 case 1:  regs.y += 2;  break;
434                                 case 2:  regs.u += 2;  break;
435                                 case 3:  regs.s += 2;  break;
436                                 }
437                                 break;
438         case 2:  { switch(reg)
439                    {
440                      case 0:  regs.x--;  break;
441                      case 1:  regs.y--;  break;
442                      case 2:  regs.u--;  break;
443                      case 3:  regs.s--;  break;
444                    }
445                    addr = DecodeReg(reg);  break; }
446         case 3:  { switch(reg)
447                    {
448                      case 0:  regs.x--;  regs.x--;  break;
449                      case 1:  regs.y--;  regs.y--;  break;
450                      case 2:  regs.u--;  regs.u--;  break;
451                      case 3:  regs.s--;  regs.s--;  break;
452                    }
453                    addr = DecodeReg(reg);  break; }
454         case 4:  { addr = DecodeReg(reg);  break; }
455         case 5:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b;  break; }
456         case 6:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a;  break; }
457         case 8:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
458         case 9:  { addr = DecodeReg(reg) + FetchW();  break; }
459         case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);  break; }
460         case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
461         case 13: { addr = regs.pc + FetchW();  break; }
462                         }
463                 }
464         }
465
466         return addr;
467 }
468
469 //
470 // Page zero instructions...
471 //
472
473 static void Op00(void)                                                                  // NEG DP
474 {
475         addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
476         tmp = 256 - regs.RdMem(addr);
477         regs.WrMem(addr, tmp);
478
479         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD);      // oVerflow
480         (tmp == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);      // Adjust Zero flag
481         (tmp & 0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);      // Adjust Negative flag
482         (tmp > 0x7F  ? regs.cc |= 0x01 : regs.cc &= 0xFE);      // Adjust carry
483
484         regs.clock += 6;
485 }
486
487 static void Op01(void)                                                                  // NEG DP (Undocumented)
488 {
489         Op00();
490 }
491
492 static void Op03(void)                                                                  // COM DP
493 {
494         addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
495         tmp = 0xFF ^ regs.RdMem(addr);
496         regs.WrMem(addr, tmp);
497
498         regs.cc &= 0xFD;  regs.cc |= 0x01;                                      // CLV SEC
499         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);         // Adjust Zero flag
500         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);         // Adjust Negative flag
501
502         regs.clock += 6;
503 }
504
505 static void Op04(void)  // LSR DP
506 {
507   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
508   tmp = regs.RdMem(addr);
509   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
510   tmp >>= 1;  regs.WrMem(addr, tmp);
511   regs.cc &= 0xF7;                             // CLN
512   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
513   regs.clock += 6;
514 }
515 static void Op06(void)  // ROR DP
516 {
517   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  uint8_t tmp2 = regs.RdMem(addr);
518   tmp = (tmp2>>1) + (regs.cc&0x01)*128;
519   regs.WrMem(addr, tmp);
520   (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
521   (tmp == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
522   (tmp&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
523   regs.clock += 6;
524 }
525 static void Op07(void)  // ASR DP
526 {
527   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  tmp = regs.RdMem(addr);
528   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
529   tmp >>= 1;
530   if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
531   regs.WrMem(addr, tmp);
532   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
533   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
534   regs.clock += 6;
535 }
536 static void Op08(void)  // LSL DP
537 {
538   addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
539   tmp = regs.RdMem(addr);
540   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
541   tmp <<= 1;
542   regs.WrMem(addr, tmp);
543   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
544   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
545   regs.clock += 6;
546 }
547 static void Op09(void)  // ROL DP
548 {
549   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  uint8_t tmp2 = regs.RdMem(addr);
550   tmp = (tmp2<<1) + (regs.cc&0x01);
551   regs.WrMem(addr, tmp);
552   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
553   ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
554   (tmp == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
555   (tmp&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
556   regs.clock += 6;
557 }
558 static void Op0A(void)  // DEC DP
559 {
560   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
561   tmp = regs.RdMem(addr) - 1;
562   regs.WrMem(addr, tmp);
563   (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
564   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
565   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
566   regs.clock += 6;
567 }
568 static void Op0C(void)  // INC DP
569 {
570   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
571   tmp = regs.RdMem(addr) + 1;
572   regs.WrMem(addr, tmp);
573   (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
574   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
575   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
576   regs.clock += 6;
577 }
578 static void Op0D(void)  // TST DP
579 {
580   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
581   regs.cc &= 0xFD;                              // CLV
582   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
583   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
584   regs.clock += 6;
585 }
586 static void Op0E(void)  // JMP DP
587 {
588   regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
589   regs.clock += 3;
590 }
591 static void Op0F(void)  // CLR DP
592 {
593   regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
594   regs.cc &= 0xF0;  regs.cc |= 0x04;                // CLN, SEZ, CLV, CLC
595   regs.clock += 6;
596 }
597
598 static void Op10(void)                                                                                  // Page 1 opcode
599 {
600         exec_op1[regs.RdMem(regs.pc++)]();
601 }
602
603 static void Op11(void)                                                  // Page 2 opcode
604 {
605         exec_op2[regs.RdMem(regs.pc++)]();
606 }
607
608 static void Op12(void)                                                  // NOP
609 {
610         regs.clock += 2;
611 }
612
613 static void Op13(void)                                                  // SYNC
614 {
615         // Fix this so it does the right thing (software interrupt!)
616         regs.clock += 2;
617 }
618
619 static void Op16(void)                                                  // LBRA
620 {
621 //      regs.pc += SignedW(FetchW());
622         regs.pc += FetchW();                                            // No need to make signed, both are 16 bit quantities
623
624         regs.clock += 5;
625 }
626
627 static void Op17(void)                                                  // LBSR
628 {
629         uint16_t word = FetchW();
630         regs.WrMem(--regs.s, regs.pc & 0xFF);
631         regs.WrMem(--regs.s, regs.pc >> 8);
632 //      regs.pc += SignedW(addr);
633         regs.pc += word;                                                        // No need to make signed, both are 16 bit
634
635         regs.clock += 9;
636 }
637
638 static void Op19(void)  // DAA
639 {
640 #if 0
641         uint8_t result = regs.a;
642
643         if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09))    // H set or lo nyb too big?
644         {
645 //              regs.a += 0x06;
646                 result += 0x06;
647                 regs.cc |= 0x20;              // Then adjust & set half carry
648         }
649
650         if ((regs.cc&0x01) || (regs.a > 0x9F))           // C set or hi nyb too big?
651         {
652 //              regs.a += 0x60;
653                 result += 0x60;
654                 regs.cc |= 0x01;              // Then adjust & set carry
655         }
656
657         regs.a = result;
658
659         regs.cc &= 0xF1;                             // CL NZV
660         if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
661         if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
662 #else
663         uint16_t result = (uint16_t)regs.a;
664
665         if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
666                 result += 0x06;
667
668         if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
669                 result += 0x60;
670
671         regs.a = (uint8_t)result;
672 //      SET_ZN(result);
673 //      CLR_V;                                                                          // Not sure this is correct...
674         regs.cc &= 0xF1;                             // CL NZV
675         if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
676         if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
677 //      flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
678         regs.cc |= (result & 0x100) > 8;
679 #endif
680         regs.clock += 2;
681 }
682
683 static void Op1A(void)                                                                  // ORCC #
684 {
685         regs.cc |= regs.RdMem(regs.pc++);
686
687         regs.clock += 3;
688 }
689
690 static void Op1C(void)                                                                  // ANDCC #
691 {
692         regs.cc &= regs.RdMem(regs.pc++);
693
694         regs.clock += 3;
695 }
696
697 static void Op1D(void)                                                  // SEX
698 {
699         (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
700
701         ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
702         (regs.a & 0x80          ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
703
704         regs.clock += 2;
705 }
706
707 static void Op1E(void)                                                  // EXG
708 {
709         tmp = regs.RdMem(regs.pc++);
710         addr = ReadEXG(tmp >> 4);
711         WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
712         WriteEXG(tmp & 0xF, addr);
713
714         regs.clock += 8;
715 }
716
717 static void Op1F(void)  // TFR
718 {
719   tmp = regs.RdMem(regs.pc++);
720   WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
721   regs.clock += 7;
722 }
723
724 static void Op20(void)                                                  // BRA
725 {
726 //      regs.pc += SignedB(regs.RdMem(regs.pc++));  // Branch always
727         regs.pc += (int16_t)(int8_t)regs.RdMem(regs.pc) + 1;    // Branch always
728
729         regs.clock += 3;
730 }
731
732 static void Op21(void)                                                  // BRN
733 {
734         regs.RdMem(regs.pc++);
735
736         regs.clock += 3;
737 }
738
739 static void Op22(void)                                                  // BHI
740 {
741         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
742
743         if (!(regs.cc & 0x05))
744                 regs.pc += word;
745
746         regs.clock += 3;
747 }
748
749 static void Op23(void)                                                  // BLS
750 {
751         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
752
753         if (regs.cc & 0x05)
754                 regs.pc += word;
755
756         regs.clock += 3;
757 }
758
759 static void Op24(void)                                                  // BCC (BHS)
760 {
761         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
762
763         if (!(regs.cc & 0x01))
764                 regs.pc += word;
765
766         regs.clock += 3;
767 }
768
769 static void Op25(void)                                                  // BCS (BLO)
770 {
771         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
772
773         if (regs.cc & 0x01)
774                 regs.pc += word;
775
776         regs.clock += 3;
777 }
778
779 static void Op26(void)                                                  // BNE
780 {
781         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
782
783         if (!(regs.cc & 0x04))
784                 regs.pc += word;
785
786         regs.clock += 3;
787 }
788
789 static void Op27(void)                                                  // BEQ
790 {
791         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
792
793         if (regs.cc & 0x04)
794                 regs.pc += word;
795
796         regs.clock += 3;
797 }
798
799 static void Op28(void)                                                  // BVC
800 {
801         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
802
803         if (!(regs.cc & 0x02))
804                 regs.pc += word;
805
806         regs.clock += 3;
807 }
808
809 static void Op29(void)                                                  // BVS
810 {
811         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
812
813         if (regs.cc & 0x02)
814                 regs.pc += word;
815
816         regs.clock += 3;
817 }
818
819 static void Op2A(void)                                                  // BPL
820 {
821         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
822
823         if (!(regs.cc & 0x08))
824                 regs.pc += word;
825
826         regs.clock += 3;
827 }
828
829 static void Op2B(void)                                                  // BMI
830 {
831         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
832
833         if (regs.cc & 0x08)
834                 regs.pc += word;
835
836         regs.clock += 3;
837 }
838
839 static void Op2C(void)                                                  // BGE
840 {
841         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
842
843         if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
844                 regs.pc += word;
845
846         regs.clock += 3;
847 }
848
849 static void Op2D(void)                                                  // BLT
850 {
851         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
852
853         if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
854                 regs.pc += word;
855
856         regs.clock += 3;
857 }
858
859 static void Op2E(void)                                                  // BGT
860 {
861         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
862
863         if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
864                 regs.pc += word;
865
866         regs.clock += 3;
867 }
868
869 static void Op2F(void)                                                  // BLE
870 {
871         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
872
873         if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
874                 regs.pc += word;
875
876         regs.clock += 3;
877 }
878
879 static void Op30(void)  // LEAX
880 {
881   regs.x = DecodeIDX(regs.RdMem(regs.pc++));
882   (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
883   regs.clock += 4;
884 }
885 static void Op31(void)  // LEAY
886 {
887   regs.y = DecodeIDX(regs.RdMem(regs.pc++));
888   (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
889   regs.clock += 4;
890 }
891 static void Op32(void)  // LEAS
892 {
893   regs.s = DecodeIDX(regs.RdMem(regs.pc++));
894   (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
895   regs.clock += 4;
896 }
897 static void Op33(void)  // LEAU
898 {
899   regs.u = DecodeIDX(regs.RdMem(regs.pc++));
900   (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
901   regs.clock += 4;
902 }
903 static void Op34(void)  // PSHS
904 {
905   tmp = regs.RdMem(regs.pc++);
906   if (tmp&0x80)  { regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8); }
907   if (tmp&0x40)  { regs.WrMem(--regs.s, regs.u&0xFF);  regs.WrMem(--regs.s, regs.u>>8); }
908   if (tmp&0x20)  { regs.WrMem(--regs.s, regs.y&0xFF);  regs.WrMem(--regs.s, regs.y>>8); }
909   if (tmp&0x10)  { regs.WrMem(--regs.s, regs.x&0xFF);  regs.WrMem(--regs.s, regs.x>>8); }
910   if (tmp&0x08)  regs.WrMem(--regs.s, regs.dp);
911   if (tmp&0x04)  regs.WrMem(--regs.s, regs.b);
912   if (tmp&0x02)  regs.WrMem(--regs.s, regs.a);
913   if (tmp&0x01)  regs.WrMem(--regs.s, regs.cc);
914   regs.clock += 5;
915 }
916 static void Op35(void)  // PULS
917 {
918   tmp = regs.RdMem(regs.pc++);
919   if (tmp&0x01)  regs.cc = regs.RdMem(regs.s++);
920   if (tmp&0x02)  regs.a  = regs.RdMem(regs.s++);
921   if (tmp&0x04)  regs.b  = regs.RdMem(regs.s++);
922   if (tmp&0x08)  regs.dp = regs.RdMem(regs.s++);
923   if (tmp&0x10)  regs.x  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
924   if (tmp&0x20)  regs.y  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
925   if (tmp&0x40)  regs.u  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
926   if (tmp&0x80)  regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
927   regs.clock += 5;
928 }
929
930 static void Op36(void)  // PSHU
931 {
932         tmp = regs.RdMem(regs.pc++);
933
934         if (tmp & 0x80)  { regs.WrMem(--regs.u, regs.pc & 0xFF);  regs.WrMem(--regs.u, regs.pc >> 8); }
935         if (tmp & 0x40)  { regs.WrMem(--regs.u, regs.s & 0xFF);  regs.WrMem(--regs.u, regs.s >> 8); }
936         if (tmp & 0x20)  { regs.WrMem(--regs.u, regs.y & 0xFF);  regs.WrMem(--regs.u, regs.y >> 8); }
937         if (tmp & 0x10)  { regs.WrMem(--regs.u, regs.x & 0xFF);  regs.WrMem(--regs.u, regs.x >> 8); }
938         if (tmp & 0x08)  regs.WrMem(--regs.u, regs.dp);
939         if (tmp & 0x04)  regs.WrMem(--regs.u, regs.b);
940         if (tmp & 0x02)  regs.WrMem(--regs.u, regs.a);
941         if (tmp & 0x01)  regs.WrMem(--regs.u, regs.cc);
942
943   regs.clock += 5;
944 }
945
946 static void Op37(void)  // PULU
947 {
948   tmp = regs.RdMem(regs.pc++);
949   if (tmp&0x01)  regs.cc = regs.RdMem(regs.u++);
950   if (tmp&0x02)  regs.a  = regs.RdMem(regs.u++);
951   if (tmp&0x04)  regs.b  = regs.RdMem(regs.u++);
952   if (tmp&0x08)  regs.dp = regs.RdMem(regs.u++);
953   if (tmp&0x10)  regs.x  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
954   if (tmp&0x20)  regs.y  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
955   if (tmp&0x40)  regs.s  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
956   if (tmp&0x80)  regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
957   regs.clock += 5;
958 }
959 static void Op39(void)  // RTS
960 {
961   regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
962   regs.clock += 5;
963 }
964 static void Op3A(void)  // ABX
965 {
966   regs.x += regs.b;
967   regs.clock += 3;
968 }
969 static void Op3B(void)  // RTI
970 {
971   regs.cc = regs.RdMem(regs.s++);
972   if (regs.cc&0x80)      // If E flag set, pull all regs
973   {
974     regs.a = regs.RdMem(regs.s++);  regs.b = regs.RdMem(regs.s++);  regs.dp = regs.RdMem(regs.s++);
975     regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
976     regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
977     regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
978     regs.clock += 15;
979   }
980   else
981   {
982     regs.clock += 6;
983   }
984   regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
985 }
986 static void Op3C(void)  // CWAI
987 {
988   regs.cc &= regs.RdMem(regs.pc++);  regs.cc |= 0x80;
989   regs.clock += 1000000;             // Force interrupt
990 }
991 static void Op3D(void)  // MUL
992 {
993   addr = regs.a * regs.b;  regs.a = addr>>8;  regs.b = addr&0xFF;
994   (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
995   (regs.b&0x80   ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
996   regs.clock += 11;
997 }
998 static void Op3E(void)  // RESET
999 {
1000 }
1001 static void Op3F(void)  // SWI
1002 {
1003 }
1004 static void Op40(void)  // NEGA
1005 {
1006   regs.a = 256 - regs.a;
1007   (regs.a > 0x7F  ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1008   (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1009   (regs.a == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1010   (regs.a&0x80    ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1011   regs.clock += 2;
1012 }
1013 static void Op43(void)  // COMA
1014 {
1015   regs.a ^= 0xFF;
1016   regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
1017   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1018   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1019   regs.clock += 2;
1020 }
1021 static void Op44(void)  // LSRA
1022 {
1023   (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
1024   regs.a >>= 1;
1025   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1026   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1027   regs.clock += 2;
1028 }
1029 static void Op46(void)  // RORA
1030 {
1031   tmp = regs.a;  regs.a = (tmp>>1) + (regs.cc&0x01)*128;
1032   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1033   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1034   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1035   regs.clock += 2;
1036 }
1037 static void Op47(void)  // ASRA
1038 {
1039   (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
1040   regs.a >>= 1;                               // Do the shift
1041   if (regs.a&0x40)  regs.a |= 0x80;               // Set neg if it was set
1042   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1043   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1044   regs.clock += 2;
1045 }
1046 static void Op48(void)  // LSLA  [Keep checking from here...]
1047 {
1048   (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
1049   regs.a <<= 1;
1050   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1051   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1052   regs.clock += 2;
1053 }
1054 static void Op49(void)  // ROLA
1055 {
1056   tmp = regs.a;  regs.a = (tmp<<1) + (regs.cc&0x01);
1057   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1058   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1059   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1060   regs.clock += 2;
1061 }
1062 static void Op4A(void)  // DECA
1063 {
1064   regs.a--;
1065   (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1066   (regs.a == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1067   (regs.a&0x80    ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1068   regs.clock += 2;
1069 }
1070 static void Op4C(void)  // INCA
1071       {
1072         regs.a++;
1073         (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1074         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1075         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1076         regs.clock += 2;
1077       }
1078 static void Op4D(void)  // TSTA
1079       {
1080         regs.cc &= 0xFD;                            // Clear oVerflow flag
1081         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1082         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1083         regs.clock += 2;
1084       }
1085 static void Op4F(void)  // CLRA
1086 {
1087   regs.a = 0;
1088   regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
1089   regs.clock += 2;
1090 }
1091 static void Op50(void)  // NEGB
1092       {
1093         regs.b = 256 - regs.b;
1094 //        ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1095         (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1096         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
1097         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
1098         (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1099         regs.clock += 2;
1100       }
1101 static void Op53(void)  // COMB
1102       {
1103         regs.b ^= 0xFF;
1104         regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
1105         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1106         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1107         regs.clock += 2;
1108       }
1109 static void Op54(void)  // LSRB
1110       {
1111         (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
1112         regs.b >>= 1;
1113         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1114         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1115         regs.clock += 2;
1116       }
1117 static void Op56(void)  // RORB
1118       {
1119         tmp = regs.b;  regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
1120         (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE);  // Shift bit into carry
1121         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1122         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1123         regs.clock += 2;
1124       }
1125 static void Op57(void)  // ASRB
1126       {
1127         (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
1128         regs.b >>= 1;                               // Do the shift
1129         if (regs.b&0x40)  regs.b |= 0x80;               // Set neg if it was set
1130         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1131         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1132         regs.clock += 2;
1133       }
1134 static void Op58(void)  // LSLB
1135       {
1136         (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
1137         regs.b <<= 1;
1138         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1139         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1140         regs.clock += 2;
1141       }
1142 static void Op59(void)  // ROLB
1143 {
1144   tmp = regs.b;
1145   regs.b = (tmp<<1) + (regs.cc&0x01);
1146   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1147   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1148   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1149   regs.clock += 2;
1150 }
1151 static void Op5A(void)  // DECB
1152       {
1153         regs.b--;
1154         (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1155         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1156         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1157         regs.clock += 2;
1158       }
1159 static void Op5C(void)  // INCB
1160       {
1161         regs.b++;
1162         (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1163         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1164         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1165         regs.clock += 2;
1166       }
1167 static void Op5D(void)  // TSTB
1168       {
1169         regs.cc &= 0xFD;                            // Clear oVerflow flag
1170         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1171         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1172         regs.clock += 2;
1173       }
1174 static void Op5F(void)  // CLRB
1175       {
1176         regs.b = 0;
1177         regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
1178         regs.clock += 2;
1179       }
1180 static void Op60(void)  // NEG IDX
1181       {
1182         addr = DecodeIDX(regs.RdMem(regs.pc++));
1183         tmp = regs.RdMem(addr);  uint8_t res = 256 - tmp;
1184         regs.WrMem(addr, res);
1185 //        ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
1186         (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1187         (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
1188         (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
1189         (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1190         regs.clock += 6;
1191       }
1192 static void Op63(void)  // COM IDX
1193       {
1194         addr = DecodeIDX(regs.RdMem(regs.pc++));
1195         tmp = regs.RdMem(addr) ^ 0xFF;
1196         regs.WrMem(addr, tmp);
1197         regs.cc &= 0xFD;  regs.cc |= 0x01;               // CLV, SEC
1198         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1199         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1200         regs.clock += 6;
1201       }
1202 static void Op64(void)  // LSR IDX
1203       {
1204         addr = DecodeIDX(regs.RdMem(regs.pc++));
1205         tmp = regs.RdMem(addr);
1206         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
1207         tmp >>= 1;  regs.WrMem(addr, tmp);
1208         regs.cc &= 0xF7;                             // CLN
1209         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1210         regs.clock += 6;
1211       }
1212 static void Op66(void)  // ROR IDX
1213       {
1214         addr = DecodeIDX(regs.RdMem(regs.pc++));
1215         tmp = regs.RdMem(addr);  uint8_t tmp2 = tmp;
1216         tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1217         regs.WrMem(addr, tmp);
1218         (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1219         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1220         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1221         regs.clock += 6;
1222       }
1223 static void Op67(void)  // ASR IDX
1224       {
1225         addr = DecodeIDX(regs.RdMem(regs.pc++));
1226         tmp = regs.RdMem(addr);
1227         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
1228         tmp >>= 1;
1229         if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
1230         regs.WrMem(addr, tmp);
1231         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1232         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1233         regs.clock += 6;
1234       }
1235 static void Op68(void)  // LSL IDX
1236       {
1237         addr = DecodeIDX(regs.RdMem(regs.pc++));
1238         tmp = regs.RdMem(addr);
1239         (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
1240         tmp <<= 1;
1241         regs.WrMem(addr, tmp);
1242         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1243         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1244         regs.clock += 6;
1245       }
1246 static void Op69(void)  // ROL IDX
1247 {
1248   uint8_t tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1249   tmp = (tmp2<<1) + (regs.cc&0x01);
1250   regs.WrMem(addr, tmp);
1251   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1252   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1253   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1254   regs.clock += 6;
1255 }
1256 static void Op6A(void)  // DEC IDX
1257       {
1258   uint8_t tmp;  uint16_t addr;
1259         addr = DecodeIDX(regs.RdMem(regs.pc++));
1260         tmp = regs.RdMem(addr) - 1;
1261         regs.WrMem(addr, tmp);
1262         (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1263         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1264         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1265         regs.clock += 6;
1266       }
1267 static void Op6C(void)  // INC IDX
1268       {
1269         addr = DecodeIDX(regs.RdMem(regs.pc++));
1270         tmp = regs.RdMem(addr) + 1;
1271         regs.WrMem(addr, tmp);
1272         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1273         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1274         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1275         regs.clock += 6;
1276       }
1277 static void Op6D(void)  // TST IDX
1278       {
1279         tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1280         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
1281         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
1282         regs.clock += 6;
1283       }
1284 static void Op6E(void)  // JMP IDX
1285 {
1286   regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
1287   regs.clock += 3;
1288 }
1289 static void Op6F(void)  // CLR IDX
1290 {
1291   addr = DecodeIDX(regs.RdMem(regs.pc++));
1292   regs.WrMem(addr, 0);
1293   regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
1294   regs.clock += 6;
1295 }
1296 static void Op70(void)  // NEG ABS
1297       {
1298         addr = FetchW();
1299         tmp = regs.RdMem(addr);  uint8_t res = 256 - tmp;
1300         regs.WrMem(addr, res);
1301         (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1302         (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
1303         (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
1304         (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
1305         regs.clock += 7;
1306       }
1307 static void Op73(void)  // COM ABS
1308       {
1309         addr = FetchW();
1310         tmp = regs.RdMem(addr) ^ 0xFF;
1311         regs.WrMem(addr, tmp);
1312         regs.cc &= 0xFD;  regs.cc |= 0x01;               // CLV, SEC
1313         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1314         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1315         regs.clock += 7;
1316       }
1317 static void Op74(void)  // LSR ABS
1318       {
1319         addr = FetchW();
1320         tmp = regs.RdMem(addr);
1321         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
1322         tmp >>= 1;  regs.WrMem(addr, tmp);
1323         regs.cc &= 0xF7;                             // CLN
1324         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1325         regs.clock += 7;
1326       }
1327 static void Op76(void)  // ROR ABS
1328       {
1329   uint8_t tmp;  uint16_t addr;
1330         addr = FetchW();
1331         tmp = regs.RdMem(addr);  uint8_t tmp2 = tmp;
1332         tmp = (tmp >> 1) + (regs.cc&0x01)*128;
1333         regs.WrMem(addr, tmp);
1334         (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
1335         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1336         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1337         regs.clock += 7;
1338       }
1339 static void Op77(void)  // ASR ABS
1340       {
1341   uint8_t tmp;  uint16_t addr;
1342         addr = FetchW();
1343         tmp = regs.RdMem(addr);
1344         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
1345         tmp >>= 1;
1346         if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
1347         regs.WrMem(addr, tmp);
1348         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1349         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1350         regs.clock += 7;
1351       }
1352 static void Op78(void)  // LSL ABS
1353       {
1354   uint8_t tmp;  uint16_t addr;
1355         addr = FetchW();
1356         tmp = regs.RdMem(addr);
1357         (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
1358         tmp <<= 1;
1359         regs.WrMem(addr, tmp);
1360         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1361         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1362         regs.clock += 7;
1363       }
1364 static void Op79(void)  // ROL ABS
1365 {
1366   uint8_t tmp2 = regs.RdMem(FetchW());
1367   tmp = (tmp2<<1) + (regs.cc&0x01);
1368   regs.WrMem(addr, tmp);
1369   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
1370   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1371   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1372   regs.clock += 7;
1373 }
1374 static void Op7A(void)  // DEC ABS
1375       {
1376   uint8_t tmp;  uint16_t addr;
1377         addr = FetchW();
1378         tmp = regs.RdMem(addr) - 1;
1379         regs.WrMem(addr, tmp);
1380         (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1381         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1382         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1383         regs.clock += 7;
1384       }
1385 static void Op7C(void)  // INC ABS
1386       {
1387   uint8_t tmp;  uint16_t addr;
1388         addr = FetchW();
1389         tmp = regs.RdMem(addr) + 1;
1390         regs.WrMem(addr, tmp);
1391         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
1392         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1393         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1394         regs.clock += 7;
1395       }
1396
1397 static void Op7D(void)  // TST ABS
1398 {
1399         uint8_t tmp = regs.RdMem(FetchW());
1400
1401         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
1402         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
1403
1404         regs.clock += 7;
1405 }
1406
1407 static void Op7E(void)  // JMP ABS
1408 {
1409   regs.pc = FetchW();
1410   regs.clock += 3;
1411 }
1412 static void Op7F(void)  // CLR ABS
1413       {
1414         regs.WrMem(FetchW(), 0);
1415         regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
1416         regs.clock += 7;
1417       }
1418 static void Op80(void)  // SUBA #
1419 {
1420   uint8_t tmp = regs.RdMem(regs.pc++);  uint8_t as = regs.a;
1421   regs.a -= tmp;
1422   (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1423   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1424   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1425   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1426   regs.clock += 2;
1427 }
1428 static void Op81(void)  // CMPA #
1429 {
1430   tmp = regs.RdMem(regs.pc++);
1431   uint8_t db = regs.a - tmp;
1432   (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1433   ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1434   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1435   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1436   regs.clock += 2;
1437 }
1438 static void Op82(void)  // SBCA #
1439 {
1440   tmp = regs.RdMem(regs.pc++);  uint8_t as = regs.a;
1441   regs.a = regs.a - tmp - (regs.cc&0x01);
1442   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1443   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1444   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1445   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1446   regs.clock += 2;
1447 }
1448 static void Op83(void)  // SUBD #
1449 {
1450   addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1451   dr -= addr;
1452   (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1453   ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1454   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1455   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1456   regs.a = dr>>8;  regs.b = dr&0xFF;
1457   regs.clock += 4;
1458 }
1459 static void Op84(void)  // ANDA #
1460       {
1461         regs.a &= regs.RdMem(regs.pc++);
1462         regs.cc &= 0xFD;                            // Clear oVerflow flag
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
1465         regs.clock += 2;
1466       }
1467 static void Op85(void)  // BITA #
1468       {
1469         tmp = regs.a & regs.RdMem(regs.pc++);
1470         regs.cc &= 0xFD;                             // Clear oVerflow flag
1471         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1472         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1473         regs.clock += 2;
1474       }
1475 static void Op86(void)  // LDA #
1476       {
1477         regs.a = regs.RdMem(regs.pc++);
1478         regs.cc &= 0xFD;                            // CLV
1479         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1480         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1481         regs.clock += 2;
1482       }
1483 static void Op88(void)  // EORA #
1484       {
1485         regs.a ^= regs.RdMem(regs.pc++);
1486         regs.cc &= 0xFD;                            // CLV
1487         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1488         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1489         regs.clock += 2;
1490       }
1491 static void Op89(void)  // ADCA #
1492 {
1493   tmp = regs.RdMem(regs.pc++);
1494   addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1495   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
1496   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1497   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1498   regs.a = addr & 0xFF;                       // Set accumulator
1499   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
1500   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
1501   regs.clock += 2;
1502 }
1503 static void Op8A(void)  // ORA #
1504       {
1505         regs.a |= regs.RdMem(regs.pc++);
1506         regs.cc &= 0xFD;                            // CLV
1507         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1508         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1509         regs.clock += 2;
1510       }
1511 static void Op8B(void)  // ADDA #
1512 {
1513   tmp = regs.RdMem(regs.pc++);  addr = regs.a + tmp;
1514   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1515   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1516   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1517   regs.a = addr & 0xFF;                       // Set accumulator
1518   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1519   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1520   regs.clock += 2;
1521 }
1522 static void Op8C(void)  // CMPX #
1523 {
1524         addr = FetchW();
1525         uint16_t dw = regs.x - addr;
1526         (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1527         ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1528         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1529         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1530         regs.clock += 4;
1531 }
1532
1533 static void Op8D(void)                                                  // Bregs.s
1534 {
1535         uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++);
1536         regs.WrMem(--regs.s, regs.pc & 0xFF);
1537         regs.WrMem(--regs.s, regs.pc >> 8);
1538         regs.pc += word;
1539
1540         regs.clock += 7;
1541 }
1542
1543 static void Op8E(void)  // LDX #
1544       {
1545         regs.x = FetchW();
1546         regs.cc &= 0xFD;                              // CLV
1547         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1548         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1549         regs.clock += 3;
1550       }
1551 static void Op90(void)  // SUBA DP
1552       {
1553         tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t as = regs.a;
1554         regs.a -= tmp;
1555         (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1556         (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1557         (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1558         ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1559         regs.clock += 4;
1560       }
1561 static void Op91(void)  // CMPA DP
1562       {
1563         tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1564         uint8_t db = regs.a - tmp;
1565         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1566         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1567         (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1568         ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1569         regs.clock += 4;
1570       }
1571 static void Op92(void)  // SBCA DP
1572 {
1573   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t as = regs.a;
1574   regs.a = regs.a - tmp - (regs.cc&0x01);
1575   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1576   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1577   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1578   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1579   regs.clock += 4;
1580 }
1581 static void Op93(void)  // SUBD DP
1582 {
1583   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1584   uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1585   dr -= adr2;
1586   (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1587   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1588   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1589   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1590   regs.a = dr>>8;  regs.b = dr&0xFF;
1591   regs.clock += 6;
1592 }
1593 static void Op94(void)  // ANDA DP
1594 {
1595   regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1596   regs.cc &= 0xF1;                   // CLV CLZ CLN
1597   if (regs.a == 0)  regs.cc |= 0x04;     // Adjust Zero flag
1598   if (regs.a&0x80)  regs.cc |= 0x08;     // Adjust Negative flag
1599   regs.clock += 4;
1600 }
1601 static void Op95(void)  // BITA DP
1602       {
1603         tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1604         regs.cc &= 0xFD;                             // Clear oVerflow flag
1605         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1606         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1607         regs.clock += 4;
1608       }
1609 static void Op96(void)  // LDA DP
1610 {
1611   regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1612   regs.cc &= 0xF1;                            // CLN CLZ CLV
1613   if (regs.a == 0)  regs.cc |= 0x04;              // Set Zero flag
1614   if (regs.a&0x80)  regs.cc |= 0x08;              // Set Negative flag
1615   regs.clock += 4;
1616 }
1617 static void Op97(void)  // STA DP
1618       {
1619         regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
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
1623         regs.clock += 4;
1624       }
1625 static void Op98(void)  // EORA DP
1626       {
1627         regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1628         regs.cc &= 0xFD;                            // CLV
1629         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1630         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1631         regs.clock += 4;
1632       }
1633 static void Op99(void)  // ADCA DP
1634 {
1635   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1636   addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1637   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
1638   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1639   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1640   regs.a = addr & 0xFF;                       // Set accumulator
1641   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
1642   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
1643   regs.clock += 4;
1644 }
1645 static void Op9A(void)  // ORA DP
1646       {
1647         regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1648         regs.cc &= 0xFD;                            // CLV
1649         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1650         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1651         regs.clock += 4;
1652       }
1653 static void Op9B(void)  // ADDA DP
1654 {
1655   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
1656   addr = (uint16_t)regs.a + (uint16_t)tmp;
1657   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1658   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1659   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1660   regs.a = addr & 0xFF;                       // Set accumulator
1661   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1662   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1663   regs.clock += 4;
1664 }
1665 static void Op9C(void)  // CMPX DP
1666       {
1667         addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
1668         uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1669         uint16_t dw = regs.x - adr2;
1670         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1671         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1672         (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1673         ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1674         regs.clock += 6;
1675       }
1676 static void Op9D(void)  // JSR DP
1677       {
1678         addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1679         regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
1680         regs.pc = addr;      // JSR to DP location...
1681         regs.clock += 7;
1682       }
1683 static void Op9E(void)  // LDX DP
1684       {
1685         addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1686         regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1687         regs.cc &= 0xFD;                              // CLV
1688         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1689         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1690         regs.clock += 5;
1691       }
1692 static void Op9F(void)  // STX DP
1693       {
1694         addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
1695         regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
1696         regs.cc &= 0xFD;                              // CLV
1697         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1698         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1699         regs.clock += 5;
1700       }
1701 static void OpA0(void)  // SUBA IDX
1702       {
1703         tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t as = regs.a;
1704         regs.a -= tmp;
1705         (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1706         (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1707         (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1708         ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1709         regs.clock += 4;
1710       }
1711 static void OpA1(void)  // CMPA IDX
1712       {
1713         tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1714         uint8_t db = regs.a - tmp;
1715         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1716         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1717         (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1718         ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1719         regs.clock += 4;
1720       }
1721 static void OpA2(void)  // SBCA IDX
1722 {
1723   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t as = regs.a;
1724   regs.a = regs.a - tmp - (regs.cc&0x01);
1725   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1726   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1727   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1728   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1729   regs.clock += 4;
1730 }
1731 static void OpA3(void)  // SUBD IDX
1732 {
1733   addr = DecodeIDX(regs.RdMem(regs.pc++));  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1734   uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1735   dr -= adr2;
1736   (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1737   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1738   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1739   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1740   regs.a = dr>>8;  regs.b = dr&0xFF;
1741   regs.clock += 6;
1742 }
1743 static void OpA4(void)  // ANDA IDX
1744       {
1745         regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1746         regs.cc &= 0xFD;                            // Clear oVerflow flag
1747         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1748         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1749         regs.clock += 4;
1750       }
1751 static void OpA5(void)  // BITA IDX
1752       {
1753         tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1754         regs.cc &= 0xFD;                             // Clear oVerflow flag
1755         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1756         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1757         regs.clock += 4;
1758       }
1759 static void OpA6(void)  // LDA IDX
1760 {
1761   regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1762   regs.cc &= 0xF1;                        // CLV CLZ CLN
1763   if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
1764   if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
1765   regs.clock += 4;
1766 }
1767 static void OpA7(void)  // STA IDX
1768 {
1769   regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1770   regs.cc &= 0xF1;                        // CLV CLZ CLN
1771   if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
1772   if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
1773   regs.clock += 4;
1774 }
1775 static void OpA8(void)  // EORA IDX
1776       {
1777         regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1778         regs.cc &= 0xFD;                            // CLV
1779         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1780         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1781         regs.clock += 4;
1782       }
1783 static void OpA9(void)  // ADCA IDX
1784 {
1785   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1786   addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1787   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1788   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1789   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1790   regs.a = addr & 0xFF;                       // Set accumulator
1791   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1792   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1793   regs.clock += 4;
1794 }
1795 static void OpAA(void)  // ORA IDX
1796 {
1797   regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1798   regs.cc &= 0xFD;                            // CLV
1799   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1800   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1801   regs.clock += 4;
1802 }
1803 static void OpAB(void)  // ADDA IDX
1804 {
1805   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1806   addr = (uint16_t)regs.a + (uint16_t)tmp;
1807   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1808   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1809   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1810   regs.a = addr & 0xFF;                       // Set accumulator
1811   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1812   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1813   regs.clock += 4;
1814 }
1815 static void OpAC(void)  // CMPX IDX
1816 {
1817   addr = DecodeIDX(regs.RdMem(regs.pc++));
1818   uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1819   uint16_t dw = regs.x - addr2;
1820   (dw == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1821   (dw&0x8000  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1822   (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1823   ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1824   regs.clock += 6;
1825 }
1826 static void OpAD(void)  // JSR IDX
1827 {
1828   addr = DecodeIDX(regs.RdMem(regs.pc++));
1829   regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
1830   regs.pc = addr;                               // Jregs.s directly to IDX ptr
1831   regs.clock += 7;
1832 }
1833 static void OpAE(void)  // LDX IDX
1834 {
1835   addr = DecodeIDX(regs.RdMem(regs.pc++));
1836   regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1837   regs.cc &= 0xFD;                              // CLV
1838   (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1839   (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1840   regs.clock += 5;
1841 }
1842 static void OpAF(void)  // STX IDX
1843 {
1844   addr = DecodeIDX(regs.RdMem(regs.pc++));
1845   regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
1846   regs.cc &= 0xF1;                              // CLV CLZ CLN
1847   if (regs.x == 0)    regs.cc |= 0x04;              // Set Zero flag
1848   if (regs.x&0x8000)  regs.cc |= 0x08;              // Set Negative flag
1849   regs.clock += 5;
1850 }
1851 static void OpB0(void)  // SUBA ABS
1852       {
1853         tmp = regs.RdMem(FetchW());  uint8_t as = regs.a;
1854         regs.a -= tmp;
1855         (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1856         (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1857         (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1858         ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1859         regs.clock += 5;
1860       }
1861 static void OpB1(void)  // CMPA ABS
1862       {
1863         tmp = regs.RdMem(FetchW());
1864         uint8_t db = regs.a - tmp;
1865         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1866         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1867         (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1868         ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1869         regs.clock += 5;
1870       }
1871 static void OpB2(void)  // SBCA ABS
1872 {
1873   tmp = regs.RdMem(FetchW());  uint8_t as = regs.a;
1874   regs.a = regs.a - tmp - (regs.cc&0x01);
1875   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1876   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1877   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1878   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1879   regs.clock += 5;
1880 }
1881 static void OpB3(void)  // SUBD ABS
1882 {
1883   addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b, ds = dr;
1884   uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1885   dr -= adr2;
1886   (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1887   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1888   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1889   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1890   regs.a = dr>>8;  regs.b = dr&0xFF;
1891   regs.clock += 7;
1892 }
1893 static void OpB4(void)  // ANDA ABS
1894 {
1895   regs.a &= regs.RdMem(FetchW());
1896   regs.cc &= 0xFD;                            // Clear oVerflow flag
1897   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1898   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1899   regs.clock += 5;
1900 }
1901 static void OpB5(void)  // BITA ABS
1902 {
1903   tmp = regs.a & regs.RdMem(FetchW());
1904   regs.cc &= 0xFD;                             // Clear oVerflow flag
1905   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1906   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1907   regs.clock += 5;
1908 }
1909 static void OpB6(void)  // LDA ABS
1910 {
1911   regs.a = regs.RdMem(FetchW());
1912   regs.cc &= 0xFD;                            // CLV
1913   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1914   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1915   regs.clock += 5;
1916 }
1917 static void OpB7(void)  // STA ABS
1918 {
1919   regs.WrMem(FetchW(), regs.a);
1920   regs.cc &= 0xFD;                            // CLV
1921   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1922   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1923   regs.clock += 5;
1924 }
1925 static void OpB8(void)  // EORA ABS
1926 {
1927   regs.a ^= regs.RdMem(FetchW());
1928   regs.cc &= 0xFD;                            // CLV
1929   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1930   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1931   regs.clock += 5;
1932 }
1933 static void OpB9(void)  // ADCA ABS
1934 {
1935   tmp = regs.RdMem(FetchW());
1936   addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
1937   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1938   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1939   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1940   regs.a = addr;                              // Set accumulator
1941   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1942   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1943   regs.clock += 5;
1944 }
1945 static void OpBA(void)  // ORA ABS
1946 {
1947   regs.a |= regs.RdMem(FetchW());
1948   regs.cc &= 0xFD;                            // CLV
1949   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1950   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1951   regs.clock += 5;
1952 }
1953 static void OpBB(void)  // ADDA ABS
1954 {
1955   tmp = regs.RdMem(FetchW());
1956   addr = (uint16_t)regs.a + (uint16_t)tmp;
1957   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
1958   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
1959   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1960   regs.a = addr & 0xFF;                       // Set accumulator
1961   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
1962   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
1963   regs.clock += 5;
1964 }
1965 static void OpBC(void)  // CMPX ABS
1966 {
1967   addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1968   uint16_t dw = regs.x - addr2;
1969   (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
1970   (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
1971   (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
1972   ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1973   regs.clock += 7;
1974 }
1975 static void OpBD(void)  // JSR ABS
1976 {
1977   addr = FetchW();
1978   regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
1979   regs.pc = addr;                          // Go to absolute address (Not indir)
1980   regs.clock += 8;
1981 }
1982
1983 static void OpBE(void)                                                                  // LDX ABS
1984 {
1985 //      addr = FetchW();
1986 //      regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1987         regs.x = RdMemW(FetchW());
1988
1989         regs.cc &= 0xFD;                                                                        // CLV
1990         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
1991         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
1992
1993         regs.clock += 6;
1994 }
1995
1996 static void OpBF(void)                                                                  // STX ABS
1997 {
1998 //      addr = FetchW();
1999 //      regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
2000         WrMemW(FetchW(), regs.x);
2001
2002         regs.cc &= 0xFD;                                                                        // CLV
2003         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
2004         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
2005
2006         regs.clock += 6;
2007 }
2008
2009 static void OpC0(void)  // SUBB #
2010       {
2011         tmp = regs.RdMem(regs.pc++);  uint8_t bs = regs.b;
2012         regs.b -= tmp;
2013         (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2014         (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2015         (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2016         ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2017         regs.clock += 2;
2018       }
2019 static void OpC1(void)  // CMPB #
2020       {
2021         tmp = regs.RdMem(regs.pc++);
2022         uint8_t db = regs.b - tmp;
2023         (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2024         ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2025         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2026         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2027         regs.clock += 2;
2028       }
2029 static void OpC2(void)  // SBCB #
2030 {
2031   tmp = regs.RdMem(regs.pc++);  uint8_t bs = regs.b;
2032   regs.b = regs.b - tmp - (regs.cc&0x01);
2033   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2034   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
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
2037   regs.clock += 2;
2038 }
2039 static void OpC3(void)  // ADDD #
2040 {
2041   addr = FetchW();  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2042   dr += addr;
2043   (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2044   dr &= 0xFFFF;
2045   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2046   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2047   ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2048   regs.a = dr>>8;  regs.b = dr&0xFF;
2049   regs.clock += 4;
2050 }
2051 static void OpC4(void)  // ANDB #
2052       {
2053         regs.b &= regs.RdMem(regs.pc++);
2054         regs.cc &= 0xFD;                            // Clear oVerflow flag
2055         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2056         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2057         regs.clock += 2;
2058       }
2059 static void OpC5(void)  // BITB #
2060 {
2061   tmp = regs.b & regs.RdMem(regs.pc++);
2062   regs.cc &= 0xF1;                             // CLV CLZ CLN
2063   if (tmp == 0)  regs.cc |= 0x04;              // Set Zero flag
2064   if (tmp&0x80)  regs.cc |= 0x08;              // Set Negative flag
2065   regs.clock += 2;
2066 }
2067 static void OpC6(void)  // LDB #
2068 {
2069   regs.b = regs.RdMem(regs.pc++);
2070   regs.cc &= 0xF1;                             // CLV CLZ CLN
2071   if (regs.b == 0)  regs.cc |= 0x04;               // Set Zero flag
2072   if (regs.b&0x80)  regs.cc |= 0x08;               // Set Negative flag
2073   regs.clock += 2;
2074 }
2075 static void OpC8(void)  // EORB #
2076       {
2077         regs.b ^= regs.RdMem(regs.pc++);
2078         regs.cc &= 0xFD;                            // CLV
2079         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2080         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2081         regs.clock += 2;
2082       }
2083 static void OpC9(void)  // ADCB #
2084 {
2085   tmp = regs.RdMem(regs.pc++);
2086   addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2087   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2088   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2089   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2090   regs.b = addr & 0xFF;                       // Set accumulator
2091   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2092   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2093   regs.clock += 2;
2094 }
2095 static void OpCA(void)  // ORB #
2096       {
2097         regs.b |= regs.RdMem(regs.pc++);
2098         regs.cc &= 0xFD;                            // CLV
2099         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2100         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2101         regs.clock += 2;
2102       }
2103 static void OpCB(void)  // ADDB #
2104 {
2105   tmp = regs.RdMem(regs.pc++);  addr = regs.b + tmp;
2106   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2107   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2108   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2109   regs.b = addr & 0xFF;                       // Set accumulator
2110   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2111   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2112   regs.clock += 2;
2113 }
2114 static void OpCC(void)  // LDD #
2115 {
2116   regs.a = regs.RdMem(regs.pc++);  regs.b = regs.RdMem(regs.pc++);
2117   regs.cc &= 0xFD;                                 // CLV
2118   ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2119   (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2120   regs.clock += 3;
2121 }
2122 static void OpCE(void)  // LDU #
2123 {
2124   regs.u = FetchW();
2125   regs.cc &= 0xFD;                              // CLV
2126   (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2127   (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2128   regs.clock += 3;
2129 }
2130 static void OpD0(void)  // SUBB DP
2131 {
2132   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t bs = regs.b;
2133   regs.b -= tmp;
2134   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2135   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2136   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2137   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2138   regs.clock += 4;
2139 }
2140 static void OpD1(void)  // CMPB DP
2141 {
2142   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2143   uint8_t db = regs.b - tmp;
2144   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2145   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2146   (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2147   ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2148   regs.clock += 4;
2149 }
2150 static void OpD2(void)  // SBCB DP
2151 {
2152   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8_t bs = regs.b;
2153   regs.b = regs.b - tmp - (regs.cc&0x01);
2154   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2155   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2156   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2157   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2158   regs.clock += 4;
2159 }
2160 static void OpD3(void)  // ADDD DP
2161 {
2162   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2163   uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2164   dr += adr2;
2165   (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2166   dr &= 0xFFFF;
2167   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2168   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2169   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2170   regs.a = dr>>8;  regs.b = dr&0xFF;
2171   regs.clock += 6;
2172 }
2173 static void OpD4(void)  // ANDB DP
2174       {
2175         regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2176         regs.cc &= 0xFD;                            // Clear oVerflow flag
2177         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2178         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2179         regs.clock += 4;
2180       }
2181 static void OpD5(void)  // BITB DP
2182       {
2183         tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2184         regs.cc &= 0xFD;                             // Clear oVerflow flag
2185         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2186         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2187         regs.clock += 4;
2188       }
2189 static void OpD6(void)  // LDB DP
2190 {
2191   regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2192   regs.cc &= 0xFD;                            // CLV
2193   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2194   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2195   regs.clock += 4;
2196 }
2197 static void OpD7(void)  // STB DP
2198       {
2199         regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
2200         regs.cc &= 0xFD;                            // CLV
2201         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2202         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2203         regs.clock += 4;
2204       }
2205 static void OpD8(void)  // EORB DP
2206       {
2207         regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2208         regs.cc &= 0xFD;                            // CLV
2209         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2210         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2211         regs.clock += 4;
2212       }
2213 static void OpD9(void)  // ADCB DP
2214 {
2215   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2216   addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2217   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2218   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2219   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2220   regs.b = addr;                              // Set accumulator
2221   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2222   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2223   regs.clock += 4;
2224 }
2225 static void OpDA(void)  // ORB DP
2226       {
2227         regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2228         regs.cc &= 0xFD;                            // CLV
2229         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2230         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2231         regs.clock += 4;
2232       }
2233 static void OpDB(void)  // ADDB DP
2234 {
2235   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
2236   addr = (uint16_t)regs.b + (uint16_t)tmp;
2237   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2238   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2239   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2240   regs.b = addr & 0xFF;                       // Set accumulator
2241   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2242   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2243   regs.clock += 4;
2244 }
2245 static void OpDC(void)  // LDD DP
2246 {
2247   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2248   regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
2249   regs.cc &= 0xFD;                                 // CLV
2250   ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2251   (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2252   regs.clock += 5;
2253 }
2254 static void OpDD(void)  // STD DP
2255 {
2256   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2257   regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
2258   regs.cc &= 0xFD;                                 // CLV
2259   ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2260   (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2261   regs.clock += 5;
2262 }
2263 static void OpDE(void)  // LDU DP
2264 {
2265   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2266   regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2267   regs.cc &= 0xFD;                              // CLV
2268   (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2269   (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2270   regs.clock += 5;
2271 }
2272 static void OpDF(void)  // STU DP
2273 {
2274   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2275   regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
2276   regs.cc &= 0xFD;                              // CLV
2277   (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2278   (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2279   regs.clock += 5;
2280 }
2281 static void OpE0(void)  // SUBB IDX
2282 {
2283   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t bs = regs.b;
2284   regs.b -= tmp;
2285   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2286   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2287   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2288   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2289   regs.clock += 4;
2290 }
2291 static void OpE1(void)  // CMPB IDX
2292 {
2293   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2294   uint8_t db = regs.b - tmp;
2295   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2296   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2297   (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2298   ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2299   regs.clock += 4;
2300 }
2301 static void OpE2(void)  // SBCB IDX
2302 {
2303   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8_t bs = regs.b;
2304   regs.b = regs.b - tmp - (regs.cc&0x01);
2305   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2306   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2307   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2308   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2309   regs.clock += 4;
2310 }
2311 static void OpE3(void)  // ADDD IDX
2312 {
2313   addr = DecodeIDX(regs.RdMem(regs.pc++));  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2314   uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2315   dr += adr2;
2316   (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2317   dr &= 0xFFFF;
2318   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2319   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2320   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2321   regs.a = dr>>8;  regs.b = dr&0xFF;
2322   regs.clock += 6;
2323 }
2324 static void OpE4(void)  // ANDB IDX
2325       {
2326         regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2327         regs.cc &= 0xFD;                            // Clear oVerflow flag
2328         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2329         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2330         regs.clock += 4;
2331       }
2332 static void OpE5(void)  // BITB IDX
2333       {
2334         tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2335         regs.cc &= 0xFD;                             // Clear oVerflow flag
2336         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2337         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2338         regs.clock += 4;
2339       }
2340 static void OpE6(void)  // LDB IDX
2341       {
2342         regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
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
2346         regs.clock += 4;
2347       }
2348 static void OpE7(void)  // STB IDX
2349 {
2350   regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
2351   regs.cc &= 0xF1;                            // CLV CLZ CLN
2352   if (regs.b == 0)  regs.cc |= 0x04;              // Adjust Zero flag
2353   if (regs.b&0x80)  regs.cc |= 0x08;              // Adjust Negative flag
2354   regs.clock += 4;
2355 }
2356 static void OpE8(void)  // EORB IDX
2357       {
2358         regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2359         regs.cc &= 0xFD;                            // CLV
2360         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2361         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2362         regs.clock += 4;
2363       }
2364 static void OpE9(void)  // ADCB IDX
2365 {
2366   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2367   addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2368   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2369   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2370   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2371   regs.b = addr;                              // Set accumulator
2372   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2373   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2374   regs.clock += 4;
2375 }
2376 static void OpEA(void)  // ORB IDX
2377       {
2378         regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2379         regs.cc &= 0xFD;                            // CLV
2380         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2381         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2382         regs.clock += 4;
2383       }
2384 static void OpEB(void)  // ADDB IDX
2385 {
2386   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
2387   addr = (uint16_t)regs.b + (uint16_t)tmp;
2388   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2389   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2390   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2391   regs.b = addr;                              // Set accumulator
2392   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2393   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2394   regs.clock += 4;
2395 }
2396 static void OpEC(void)  // LDD IDX
2397 {
2398   addr = DecodeIDX(regs.RdMem(regs.pc++));
2399   regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
2400   regs.cc &= 0xF1;                             // CLV CLZ CLN
2401   if (!(regs.a|regs.b))  regs.cc |= 0x04;              // Adjust Zero flag
2402   if (regs.a&0x80)   regs.cc |= 0x08;              // Adjust Negative flag
2403   regs.clock += 5;
2404 }
2405 static void OpED(void)  // STD IDX
2406 {
2407   addr = DecodeIDX(regs.RdMem(regs.pc++));
2408   regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
2409   regs.cc &= 0xF1;                             // CLV CLZ CLZ
2410   if (!(regs.a|regs.b))  regs.cc |= 0x04;              // Adjust Zero flag
2411   if (regs.a&0x80)   regs.cc |= 0x08;              // Adjust Negative flag
2412   regs.clock += 5;
2413 }
2414 static void OpEE(void)  // LDU IDX
2415 {
2416   addr = DecodeIDX(regs.RdMem(regs.pc++));
2417   regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2418   regs.cc &= 0xF1;                              // CLV CLZ CLN
2419   if (regs.u == 0)    regs.cc |= 0x04;              // Set Zero flag
2420   if (regs.u&0x8000)  regs.cc |= 0x08;              // Set Negative flag
2421   regs.clock += 5;
2422 }
2423 static void OpEF(void)  // STU IDX
2424 {
2425   addr = DecodeIDX(regs.RdMem(regs.pc++));
2426   regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
2427   regs.cc &= 0xF1;                              // CLV CLZ CLN
2428   if (regs.u == 0)    regs.cc |= 0x04;              // Set Zero flag
2429   if (regs.u&0x8000)  regs.cc |= 0x08;              // Set Negative flag
2430   regs.clock += 5;
2431 }
2432 static void OpF0(void)  // SUBB ABS
2433       {
2434         tmp = regs.RdMem(FetchW());  uint8_t bs = regs.b;
2435         regs.b -= tmp;
2436         (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2437         (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2438         (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2439         ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2440       }
2441 static void OpF1(void)  // CMPB ABS
2442       {
2443         tmp = regs.RdMem(FetchW());
2444         uint8_t db = regs.b - tmp;
2445         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2446         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2447         (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2448         ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2449         regs.clock += 5;
2450       }
2451 static void OpF2(void)  // SBCB ABS
2452 {
2453   tmp = regs.RdMem(FetchW());  uint8_t bs = regs.b;
2454   regs.b = regs.b - tmp - (regs.cc&0x01);
2455   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2456   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2457   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2458   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
2459   regs.clock += 5;
2460 }
2461 static void OpF3(void)  // ADDD ABS
2462 {
2463   addr = FetchW();  long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr;
2464   uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1);
2465   dr += adr2;
2466   (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2467   dr &= 0xFFFF;
2468   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2469   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2470   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2471   regs.a = dr>>8;  regs.b = dr&0xFF;
2472   regs.clock += 7;
2473 }
2474 static void OpF4(void)  // ANDB ABS
2475       {
2476         regs.b &= regs.RdMem(FetchW());
2477         regs.cc &= 0xFD;                            // Clear oVerflow flag
2478         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2479         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2480         regs.clock += 5;
2481       }
2482 static void OpF5(void)  // BITB ABS
2483       {
2484         tmp = regs.b & regs.RdMem(FetchW());
2485         regs.cc &= 0xFD;                             // Clear oVerflow flag
2486         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2487         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2488         regs.clock += 5;
2489       }
2490 static void OpF6(void)  // LDB ABS
2491       {
2492         regs.b = regs.RdMem(FetchW());
2493         regs.cc &= 0xFD;                            // CLV
2494         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2495         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2496         regs.clock += 5;
2497       }
2498 static void OpF7(void)  // STB ABS
2499       {
2500         regs.WrMem(FetchW(), regs.b);
2501         regs.cc &= 0xFD;                            // CLV
2502         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2503         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2504         regs.clock += 5;
2505       }
2506 static void OpF8(void)  // EORB ABS
2507       {
2508         regs.b ^= regs.RdMem(FetchW());
2509         regs.cc &= 0xFD;                            // CLV
2510         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2511         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2512         regs.clock += 5;
2513       }
2514 static void OpF9(void)  // ADCB ABS
2515 {
2516   tmp = regs.RdMem(FetchW());
2517   addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01);
2518   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2519   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2520   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2521   regs.b = addr & 0xFF;                       // Set accumulator
2522   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2523   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2524   regs.clock += 5;
2525 }
2526 static void OpFA(void)  // ORB ABS
2527       {
2528         regs.b |= regs.RdMem(FetchW());
2529         regs.cc &= 0xFD;                            // CLV
2530         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2531         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2532         regs.clock += 5;
2533       }
2534 static void OpFB(void)  // ADDB ABS
2535 {
2536   tmp = regs.RdMem(FetchW());
2537   addr = (uint16_t)regs.b + (uint16_t)tmp;
2538   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Set Carry flag
2539   ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
2540   ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
2541   regs.b = addr & 0xFF;                       // Set accumulator
2542   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
2543   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
2544   regs.clock += 5;
2545 }
2546 static void OpFC(void)  // LDD ABS
2547       {
2548         addr = FetchW();
2549         regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
2550         regs.cc &= 0xFD;                                 // CLV
2551         ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2552         (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2553         regs.clock += 6;
2554       }
2555 static void OpFD(void)  // STD ABS
2556       {
2557         addr = FetchW();
2558         regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
2559         regs.cc &= 0xFD;                                 // CLV
2560         ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2561         (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2562         regs.clock += 6;
2563       }
2564 static void OpFE(void)  // LDU ABS
2565       {
2566         addr = FetchW();
2567         regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
2568         regs.cc &= 0xFD;                              // CLV
2569         (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2570         (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2571         regs.clock += 6;
2572       }
2573 static void OpFF(void)  // STU ABS
2574       {
2575         addr = FetchW();
2576         regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
2577         regs.cc &= 0xFD;                              // CLV
2578         (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2579         (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2580         regs.clock += 6;
2581       }
2582
2583 //
2584 // Page one opcodes' execute code
2585 //
2586
2587 static void Op1021(void)                                                // LBRN
2588 {
2589         addr = FetchW();
2590
2591         regs.clock += 5;
2592 }
2593
2594 static void Op1022(void)                                                // LBHI
2595 {
2596         uint16_t word = FetchW();
2597
2598         if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
2599                 regs.pc += word;
2600
2601         regs.clock += 5;
2602 }
2603
2604 static void Op1023(void)                                                // LBLS
2605 {
2606         uint16_t word = FetchW();
2607
2608         if ((regs.cc & 0x01) | (regs.cc & 0x04))
2609                 regs.pc += word;
2610
2611         regs.clock += 5;
2612 }
2613
2614 static void Op1024(void)                                                // LBCC (LBHS)
2615 {
2616         uint16_t word = FetchW();
2617
2618         if (!(regs.cc & 0x01))
2619                 regs.pc += word;
2620
2621         regs.clock += 5;
2622 }
2623
2624 static void Op1025(void)                                                // LBCS (LBLO)
2625 {
2626         uint16_t word = FetchW();
2627
2628         if (regs.cc & 0x01)
2629                 regs.pc += word;
2630
2631         regs.clock += 5;
2632 }
2633
2634 static void Op1026(void)                                                // LBNE
2635 {
2636         uint16_t word = FetchW();
2637
2638         if (!(regs.cc & 0x04))
2639                 regs.pc += word;
2640
2641         regs.clock += 5;
2642 }
2643
2644 static void Op1027(void)                                                // LBEQ
2645 {
2646         uint16_t word = FetchW();
2647
2648         if (regs.cc & 0x04)
2649                 regs.pc += word;
2650
2651         regs.clock += 5;
2652 }
2653
2654 static void Op1028(void)                                                // LBVC
2655 {
2656         uint16_t word = FetchW();
2657
2658         if (!(regs.cc & 0x02))
2659                 regs.pc += word;
2660
2661         regs.clock += 5;
2662 }
2663
2664 static void Op1029(void)                                                // LBVS
2665 {
2666         uint16_t word = FetchW();
2667
2668         if (regs.cc & 0x02)
2669                 regs.pc += word;
2670
2671         regs.clock += 5;
2672 }
2673
2674 static void Op102A(void)                                                // LBPL
2675 {
2676         uint16_t word = FetchW();
2677
2678         if (!(regs.cc & 0x08))
2679                 regs.pc += word;
2680
2681         regs.clock += 5;
2682 }
2683
2684 static void Op102B(void)                                                // LBMI
2685 {
2686         uint16_t word = FetchW();
2687
2688         if (regs.cc & 0x08)
2689                 regs.pc += word;
2690
2691         regs.clock += 5;
2692 }
2693
2694 static void Op102C(void)                                                // LBGE
2695 {
2696         uint16_t word = FetchW();
2697
2698         if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2699                 regs.pc += word;
2700
2701         regs.clock += 5;
2702 }
2703
2704 static void Op102D(void)                                                // LBLT
2705 {
2706         uint16_t word = FetchW();
2707
2708         if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
2709                 regs.pc += word;
2710
2711         regs.clock += 5;
2712 }
2713
2714 static void Op102E(void)                                                // LBGT
2715 {
2716         uint16_t word = FetchW();
2717
2718         if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
2719                 regs.pc += word;
2720
2721         regs.clock += 5;
2722 }
2723
2724 static void Op102F(void)                                                // LBLE
2725 {
2726         uint16_t word = FetchW();
2727
2728         if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
2729                 regs.pc += word;
2730
2731         regs.clock += 5;
2732 }
2733
2734 static void Op103F(void)  // SWI2 (Not yet implemented)
2735 {
2736   regs.clock += 20;
2737 }
2738 static void Op1083(void)  // CMPD #
2739     {
2740       addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b;
2741       uint16_t dw = dr - addr;
2742       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2743       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2744       (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2745       ((dr^addr^dw^((uint16_t)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2746       regs.clock += 5;
2747     }
2748 static void Op108C(void)  // CMPY #
2749     {
2750       addr = FetchW();
2751       uint16_t dw = regs.y - addr;
2752       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2753       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2754       (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2755       ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2756       regs.clock += 5;
2757     }
2758 static void Op108E(void)  // LDY #
2759     {
2760       regs.y = FetchW();
2761       regs.cc &= 0xFD;                              // CLV
2762       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2763       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2764       regs.clock += 4;
2765     }
2766 static void Op1093(void)  // CMPD DP
2767     {
2768       uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
2769       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2770       uint16_t dw = dr - addr;
2771       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2772       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2773       (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2774       ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2775       regs.clock += 7;
2776     }
2777 static void Op109C(void)  // CMPY DP
2778     {
2779       uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2780       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2781       uint16_t dw = regs.y - addr;
2782       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2783       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2784       (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2785       ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2786       regs.clock += 7;
2787     }
2788
2789 static void Op109E(void)  // LDY DP
2790     {
2791       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2792       regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2793       regs.cc &= 0xFD;                              // CLV
2794       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2795       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2796       regs.clock += 6;
2797     }
2798
2799 static void Op109F(void)  // STY DP
2800     {
2801       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2802       regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
2803       regs.cc &= 0xFD;                              // CLV
2804       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2805       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2806       regs.clock += 6;
2807     }
2808 static void Op10A3(void)  // CMPD IDX
2809 {
2810   uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
2811   addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2812   uint16_t dw = dr - addr;
2813   regs.cc &= 0xF0;                              // CLC CLV CLZ CLN
2814   if (dr < addr)  regs.cc |= 0x01;              // Set Carry flag
2815   if ((dr^addr^dw^(regs.cc<<15))&0x8000)  regs.cc |= 0x02; // Set oVerflow
2816   if (dw == 0)    regs.cc |= 0x04;              // Set Zero flag
2817   if (dw&0x8000)  regs.cc |= 0x08;              // Set Negative flag
2818   regs.clock += 7;
2819 }
2820 static void Op10AC(void)  // CMPY IDX
2821     {
2822       uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++));
2823       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2824       uint16_t dw = regs.y - addr;
2825       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2826       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2827       (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2828       (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2829       regs.clock += 7;
2830     }
2831 static void Op10AE(void)  // LDY IDX
2832 {
2833   addr = DecodeIDX(regs.RdMem(regs.pc++));
2834   regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2835   regs.cc &= 0xF1;                              // CLV CLZ CLN
2836   if (regs.y == 0)    regs.cc |= 0x04;              // Adjust Zero flag
2837   if (regs.y&0x8000)  regs.cc |= 0x08;              // Adjust Negative flag
2838   regs.clock += 6;
2839 }
2840 static void Op10AF(void)  // STY IDX
2841     {
2842       addr = DecodeIDX(regs.RdMem(regs.pc++));
2843       regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
2844       regs.cc &= 0xFD;                              // CLV
2845       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2846       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2847       regs.clock += 6;
2848     }
2849 static void Op10B3(void)  // CMPD ABS
2850     {
2851       addr = FetchW();  uint16_t dr = (regs.a<<8)|regs.b;
2852       uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2853       uint16_t dw = dr - addr2;
2854       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2855       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2856       (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2857       (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2858       regs.clock += 8;
2859     }
2860 static void Op10BC(void)  // CMPY ABS
2861     {
2862       addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2863       uint16_t dw = regs.y - addr2;
2864       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2865       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2866       (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2867       (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2868       regs.clock += 8;
2869     }
2870 static void Op10BE(void)  // LDY ABS
2871     {
2872       addr = FetchW();
2873       regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2874       regs.cc &= 0xFD;                              // CLV
2875       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2876       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2877       regs.clock += 7;
2878     }
2879 static void Op10BF(void)  // STY ABS
2880     {
2881       addr = FetchW();
2882       regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
2883       regs.cc &= 0xFD;                              // CLV
2884       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2885       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2886       regs.clock += 7;
2887     }
2888 static void Op10CE(void)  // LDS #
2889     {
2890       regs.s = FetchW();
2891       regs.cc &= 0xFD;                              // CLV
2892       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2893       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2894       regs.clock += 4;
2895     }
2896 static void Op10DE(void)  // LDS DP
2897     {
2898       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2899       regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2900       regs.cc &= 0xFD;                              // CLV
2901       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2902       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2903       regs.clock += 6;
2904     }
2905 static void Op10DF(void)  // STS DP
2906     {
2907       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
2908       regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
2909       regs.cc &= 0xFD;                              // CLV
2910       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2911       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2912       regs.clock += 6;
2913     }
2914 static void Op10EE(void)  // LDS IDX
2915     {
2916       addr = DecodeIDX(regs.RdMem(regs.pc++));
2917       regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2918       regs.cc &= 0xFD;                              // CLV
2919       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2920       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2921       regs.clock += 6;
2922     }
2923 static void Op10EF(void)  // STS IDX
2924     {
2925       addr = DecodeIDX(regs.RdMem(regs.pc++));
2926       regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
2927       regs.cc &= 0xFD;                              // CLV
2928       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2929       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2930       regs.clock += 6;
2931     }
2932 static void Op10FE(void)  // LDS ABS
2933     {
2934       addr = FetchW();
2935       regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
2936       regs.cc &= 0xFD;                              // CLV
2937       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2938       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2939       regs.clock += 7;
2940     }
2941 static void Op10FF(void)  // STS ABS
2942 {
2943   addr = FetchW();
2944   regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
2945   regs.cc &= 0xFD;                              // CLV
2946   (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2947   (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2948   regs.clock += 7;
2949 }
2950
2951 //
2952 // Page two opcodes' execute code
2953 //
2954
2955 static void Op113F(void)  // SWI3
2956     {
2957       regs.clock += 20;
2958     }
2959 static void Op1183(void)  // CMPU #
2960     {
2961       addr = FetchW();
2962       uint16_t dw = regs.u - addr;
2963       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2964       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2965       (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2966       (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2967       regs.clock += 5;
2968     }
2969 static void Op118C(void)  // CMPS #
2970     {
2971       addr = FetchW();
2972       uint16_t dw = regs.s - addr;
2973       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2974       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2975       (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2976       (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2977       regs.clock += 5;
2978     }
2979 static void Op1193(void)  // CMPU DP
2980     {
2981       uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2982       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2983       uint16_t dw = regs.u - addr;
2984       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2985       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2986       (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2987       (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2988       regs.clock += 7;
2989     }
2990 static void Op119C(void)  // CMPS DP
2991     {
2992       uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
2993       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
2994       uint16_t dw = regs.s - addr;
2995       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
2996       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
2997       (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
2998       (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
2999       regs.clock += 7;
3000     }
3001 static void Op11A3(void)  // CMPU IDX
3002     {
3003       uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++));
3004       addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
3005       uint16_t dw = regs.u - addr;
3006       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3007       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3008       (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
3009       (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3010       regs.clock += 7;
3011     }
3012 static void Op11AC(void)  // CMPS IDX
3013     {
3014       uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++));
3015       addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
3016       uint16_t dw = regs.s - addr;
3017       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3018       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3019       (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
3020       (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3021       regs.clock += 7;
3022     }
3023 static void Op11B3(void)  // CMPU ABS
3024     {
3025       addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3026       uint16_t dw = regs.u - addr2;
3027       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3028       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3029       (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
3030       (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3031       regs.clock += 8;
3032     }
3033
3034 static void Op11BC(void)  // CMPS ABS
3035 {
3036         addr = FetchW();  uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
3037         uint16_t dw = regs.s - addr2;
3038         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3039         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3040         (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
3041         (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
3042         regs.clock += 8;
3043 }
3044
3045 //temp, for testing...
3046 #ifdef __DEBUG__
3047 static uint8_t backTrace[256];
3048 static uint16_t btPC[256];
3049 static int btPtr = 0;//*/
3050 #endif
3051 static void Op__(void)                                                                  // Illegal opcode
3052 {
3053         regs.clock++;
3054 //      illegal = true;
3055         regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3056 #ifdef __DEBUG__
3057 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3058 for(int i=0; i<256; i++)
3059 {
3060         Decode6809(btPC[(btPtr + i) & 0xFF]);
3061         WriteLog("\n");
3062 }//*/
3063 #endif
3064 }
3065
3066
3067 //
3068 // Internal "memcpy" (so we don't have to link with any external libraries!)
3069 //
3070 static void myMemcpy(void * dst, void * src, uint32_t size)
3071 {
3072         uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3073
3074         for(uint32_t i=0; i<size; i++)
3075                 d[i] = s[i];
3076 }
3077
3078 //
3079 // Function to execute 6809 instructions
3080 //
3081 //#define DEBUG_ILLEGAL
3082 #ifdef DEBUG_ILLEGAL
3083 #include "log.h"
3084 #include "dis6809.h"
3085 uint8_t btPtr = 0;
3086 uint8_t backTrace[256];
3087 V6809REGS btRegs[256];
3088 bool tripped = false;
3089 #endif
3090 #ifdef __DEBUG__
3091 //Here so this can be externally linked
3092 bool disasm = false;
3093 //bool disasm = true;
3094 #endif
3095 void Execute6809(V6809REGS * context, uint32_t cycles)
3096 {
3097         // If this is not in place, the clockOverrun calculations can cause the V6809 to get
3098         // stuck in an infinite loop.
3099         if (cycles == 0)                                                        // Nothing to do, so bail!
3100                 return;
3101
3102         myMemcpy(&regs, context, sizeof(V6809REGS));
3103
3104         // Execute here...
3105
3106         // Since we can't guarantee that we'll execute the number of cycles passed in
3107         // exactly, we have to keep track of how much we overran the number of cycles
3108         // the last time we executed. Since we already executed those cycles, this time
3109         // through we remove them from the cycles passed in in order to come out
3110         // approximately even. Over the long run, this unevenness in execution times
3111         // evens out.
3112         uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3113
3114         while (regs.clock < endCycles)
3115         {
3116 #ifdef DEBUG_ILLEGAL
3117 if (!tripped)
3118 {
3119         backTrace[btPtr] = regs.RdMem(regs.pc);
3120         btRegs[btPtr] = regs;
3121         btPtr = (btPtr + 1) & 0xFF;
3122
3123         if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3124         {
3125                 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3126                 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3127
3128                 for(uint16_t i=btPtr; i<btPtr+256; i++)
3129                 {
3130                         Decode6809(btRegs[i & 0xFF].pc);
3131 // Note that these values are *before* execution, so stale...
3132                         WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3133                                 btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
3134                 }
3135
3136                 tripped = true;
3137         }
3138 }
3139 #endif
3140 #ifdef __DEBUG__
3141 //Decode6809(regs.pc);
3142 if (disasm) Decode6809(regs);
3143 /*//if (regs.pc == 0x15BA)      disasm = true;
3144 //if (regs.pc == 0xFE76)        disasm = true;
3145 if (regs.x == 0xFED4)   disasm = true;
3146 if (disasm) Decode6809(regs.pc);
3147 //if (regs.pc == 0x164A)        disasm = false;//*/
3148
3149 //temp, for testing...
3150 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3151 btPC[btPtr] = regs.pc;
3152 btPtr = (btPtr + 1) & 0xFF;//*/
3153 #endif
3154                 exec_op0[regs.RdMem(regs.pc++)]();
3155
3156                 // Handle any pending interrupts
3157
3158 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3159 //              uint32_t flags = context->cpuFlags;
3160                 uint32_t flags = regs.cpuFlags;
3161
3162                 if (flags & V6809_ASSERT_LINE_RESET)                    // *** RESET handler ***
3163                 {
3164 #ifdef __DEBUG__
3165 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3166 #endif
3167                         regs.cc |= (FLAG_F | FLAG_I);                           // Set F, I
3168                         regs.dp = 0;                                                            // Reset direct page register
3169                         regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
3170                         context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3171                         regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3172                 }
3173                 else if (flags & V6809_ASSERT_LINE_NMI)                 // *** NMI handler ***
3174                 {
3175 #ifdef __DEBUG__
3176 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3177 #endif
3178                         regs.cc |= FLAG_E;                                                      // Set the Entire flag
3179
3180                         regs.WrMem(--regs.s, regs.pc & 0xFF);           // Save all regs...
3181                         regs.WrMem(--regs.s, regs.pc >> 8);
3182                         regs.WrMem(--regs.s, regs.u & 0xFF);
3183                         regs.WrMem(--regs.s, regs.u >> 8);
3184                         regs.WrMem(--regs.s, regs.y & 0xFF);
3185                         regs.WrMem(--regs.s, regs.y >> 8);
3186                         regs.WrMem(--regs.s, regs.x & 0xFF);
3187                         regs.WrMem(--regs.s, regs.x >> 8);
3188                         regs.WrMem(--regs.s, regs.dp);
3189                         regs.WrMem(--regs.s, regs.b);
3190                         regs.WrMem(--regs.s, regs.a);
3191                         regs.WrMem(--regs.s, regs.cc);
3192
3193                         regs.cc |= (FLAG_I | FLAG_F);                           // Set IRQ/FIRQ suppress flags
3194                         regs.pc = RdMemW(0xFFFC);                                       // And load PC with the NMI vector
3195                         regs.clock += 19;
3196 //                      context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3197 //                      regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI;        // Reset the asserted line (NMI)...
3198                 }
3199                 else if (flags & V6809_ASSERT_LINE_FIRQ)                // *** FIRQ handler ***
3200                 {
3201 #ifdef __DEBUG__
3202 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3203 #endif
3204                         if (!(regs.cc & FLAG_F))                                        // Is the FIRQ masked (F == 1)?
3205                         {
3206 #ifdef __DEBUG__
3207 if (disasm) WriteLog("       FIRQ taken...\n");
3208 #endif
3209                                 regs.cc &= ~FLAG_E;                                             // Clear the Entire flag
3210
3211                                 regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save PC, CC regs...
3212                                 regs.WrMem(--regs.s, regs.pc >> 8);
3213                                 regs.WrMem(--regs.s, regs.cc);
3214
3215                                 regs.cc |= (FLAG_I | FLAG_F);                   // Set IRQ/FIRQ suppress flags
3216                                 regs.pc = RdMemW(0xFFF6);                               // And load PC with the IRQ vector
3217                                 regs.clock += 10;
3218 //                              context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;   // Reset the asserted line (FIRQ)...
3219 //                              regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;       // Reset the asserted line (FIRQ)...
3220                         }
3221                 }
3222                 else if (flags & V6809_ASSERT_LINE_IRQ)                 // *** IRQ handler ***
3223                 {
3224 #ifdef __DEBUG__
3225 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3226 #endif
3227                         if (!(regs.cc & FLAG_I))                                        // Is the IRQ masked (I == 1)?
3228                         {
3229 #ifdef __DEBUG__
3230 if (disasm) WriteLog("       IRQ taken...\n");
3231 #endif
3232                                 regs.cc |= FLAG_E;                                              // Set the Entire flag
3233
3234                                 regs.WrMem(--regs.s, regs.pc & 0xFF);   // Save all regs...
3235                                 regs.WrMem(--regs.s, regs.pc >> 8);
3236                                 regs.WrMem(--regs.s, regs.u & 0xFF);
3237                                 regs.WrMem(--regs.s, regs.u >> 8);
3238                                 regs.WrMem(--regs.s, regs.y & 0xFF);
3239                                 regs.WrMem(--regs.s, regs.y >> 8);
3240                                 regs.WrMem(--regs.s, regs.x & 0xFF);
3241                                 regs.WrMem(--regs.s, regs.x >> 8);
3242                                 regs.WrMem(--regs.s, regs.dp);
3243                                 regs.WrMem(--regs.s, regs.b);
3244                                 regs.WrMem(--regs.s, regs.a);
3245                                 regs.WrMem(--regs.s, regs.cc);
3246
3247                                 regs.cc |= FLAG_I;                                              // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3248                                 regs.pc = RdMemW(0xFFF8);                               // And load PC with the IRQ vector
3249                                 regs.clock += 19;
3250 // Apparently, not done here!
3251 // Need to put IRQ handling in somewhere... It shouldn't be cleared here!
3252 //                              context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
3253 //                              regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
3254                         }
3255                 }
3256 #ifdef __DEBUG__
3257 if (disasm) WriteLog("\tCC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3258         (regs.cc & FLAG_E ? "E" : "-"), (regs.cc & FLAG_F ? "F" : "-"), (regs.cc & FLAG_H ? "H" : "-"),
3259         (regs.cc & FLAG_I ? "I" : "-"), (regs.cc & FLAG_N ? "N" : "-"), (regs.cc & FLAG_Z ? "Z" : "-"),
3260         (regs.cc & FLAG_V ? "V" : "-"), (regs.cc & FLAG_C ? "C" : "-"),
3261         regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3262 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3263         regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3264 #endif
3265         }
3266         // Keep track of how much we overran so we can adjust on the next run...
3267         regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3268
3269         myMemcpy(context, &regs, sizeof(V6809REGS));
3270
3271 #ifdef __DEBUG__
3272         if (disasm)
3273                 WriteLog("\n*** CONTEXT SWITCH ***\n\n");
3274 #endif
3275 }
3276
3277 //
3278 // Get the clock of the currently executing CPU
3279 //
3280 uint64_t GetCurrentV6809Clock(void)
3281 {
3282         return regs.clock;
3283 }
3284
3285 //
3286 // Get the PC of the currently executing CPU
3287 //
3288 uint16_t GetCurrentV6809PC(void)
3289 {
3290         return regs.pc;
3291 }
3292
3293 // Set a line of the currently executing CPU
3294 void SetLineOfCurrentV6809(uint32_t line)
3295 {
3296         regs.cpuFlags |= line;
3297 }
3298
3299 // Clear a line of the currently executing CPU
3300 void ClearLineOfCurrentV6809(uint32_t line)
3301 {
3302 #ifdef __DEBUG__
3303 if (disasm)
3304         WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
3305 #endif
3306         regs.cpuFlags &= ~line;
3307 }