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