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