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