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