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