]> Shamusworld >> Repos - stargem2/blob - src/v6809.cpp
Major refactoring of V6809 code--still not 100% at this point
[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 bool disasm = false;//so we can extern this shit
28 #endif
29
30 #define TEST_DONT_BRANCH_OPTIMIZATION
31
32 // Various macros
33
34 #define CLR_Z                           (flagZ = 0)
35 #define CLR_ZN                          (flagZ = flagN = 0)
36 #define CLR_ZNC                         (flagZ = flagN = flagC = 0)
37 #define CLR_V                           (flagV = 0)
38 #define CLR_N                           (flagN = 0)
39 #define SET_Z(r)                        (flagZ = ((r) == 0 ? 1 : 0))
40 #define SET_N(r)                        (flagN = ((r) & 0x80) >> 7)
41 #define SET_N16(r)                      (flagN = ((r) & 0x8000) >> 15)
42 #define SET_V(a,b,r)            (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
43 #define SET_V16(a,b,r)          (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
44
45 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
46 #define SET_C_ADD(a,b)          (flagC = ((uint8)(b) > (uint8)(~(a)) ? 1 : 0))
47 //#define SET_C_SUB(a,b)                (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
48 #define SET_C_CMP(a,b)          (flagC = ((uint8)(b) >= (uint8)(a) ? 1 : 0))
49 #define SET_ZN(r)                       SET_N(r); SET_Z(r)
50 #define SET_ZN16(r)                     SET_N16(r); SET_Z(r)
51 #define SET_ZNC_ADD(a,b,r)      SET_N(r); SET_Z(r); SET_C_ADD(a,b)
52 //#define SET_ZNC_SUB(a,b,r)    SET_N(r); SET_Z(r); SET_C_SUB(a,b)
53 #define SET_ZNC_CMP(a,b,r)      SET_N(r); SET_Z(r); SET_C_CMP(a,b)
54
55 //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
56 //Hmm, why not do like we did for READ_ABS*???
57 //Because the EA_* macros are usually used as an argument to a function call, that's why.
58 //Now, we CAN fix it using FetchMemW()!!! [DONE]
59 #define EA_IMM                          regs.pc++
60 #define EA_DP                           (regs.dp << 8) | regs.RdMem(regs.pc++)
61 #define EA_IDX                          DecodeIDX(regs.RdMem(regs.pc++))
62 #define EA_ABS                          FetchMemW(regs.pc)
63
64 #define READ_IMM                        regs.RdMem(EA_IMM)
65 #define READ_IMM16                      FetchMemW(regs.pc)
66 #define READ_DP                         regs.RdMem(EA_DP)
67 #define READ_DP16                       RdMemW(EA_DP)
68 #define READ_IDX                        regs.RdMem(EA_IDX)
69 #define READ_IDX16                      RdMemW(EA_IDX)
70 #define READ_ABS                        regs.RdMem(EA_ABS)
71 #define READ_ABS16                      RdMemW(EA_ABS)
72
73 #define READ_IMM_WB(v)          uint16 addr = EA_IMM;      v = regs.RdMem(addr)
74 #define READ_DP_WB(v)           uint16 addr = EA_DP;       v = regs.RdMem(addr)
75 #define READ_IDX_WB(v)          uint16 addr = EA_IDX;      v = regs.RdMem(addr)
76 #define READ_ABS_WB(v)          uint16 addr = EA_ABS;      v = regs.RdMem(addr)
77
78 #define WRITE_BACK(d)           regs.WrMem(addr, (d))
79
80 #define PULLS(r)                        r = regs.RdMem(regs.s++)
81 #define PUSHS(r)                        regs.WrMem(--regs.s, (r))
82 #define PULLS16(r)                      { r = RdMemW(regs.s); regs.s += 2; }
83 #define PUSHS16(r)                      { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
84 #define PULLU(r)                        r = regs.RdMem(regs.u++)
85 #define PUSHU(r)                        regs.WrMem(--regs.u, (r))
86 #define PULLU16(r)                      { r = RdMemW(regs.u); regs.u += 2; }
87 #define PUSHU16(r)                      { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
88
89 #define PACK_FLAGS                      ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
90 #define UNPACK_FLAGS            flagE = (regs.cc & FLAG_E) >> 7; \
91         flagF = (regs.cc & FLAG_F) >> 6; \
92         flagH = (regs.cc & FLAG_H) >> 5; \
93         flagI = (regs.cc & FLAG_I) >> 4; \
94         flagN = (regs.cc & FLAG_N) >> 3; \
95         flagZ = (regs.cc & FLAG_Z) >> 2; \
96         flagV = (regs.cc & FLAG_V) >> 1; \
97         flagC = (regs.cc & FLAG_C)
98
99 // Private global variables
100
101 static V6809REGS regs;
102 static uint8 flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
103
104 uint8 page0Cycles[256] = {
105         6,  1,  1,  6,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,          // $0x
106         1,  1,  2,  2,  1,  1,  5,  9,  1,  2,  3,  1,  3,  2,  8,  7,          // $1x
107         3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,          // $2x
108         4,  4,  4,  4,  5,  5,  5,  5,  1,  5,  3,  6, 21, 11,  0, 19,          // $3x
109         2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,          // $4x
110         2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  1,          // $5x
111         6,  1,  1,  6,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,          // $6x
112         7,  1,  1,  7,  7,  1,  7,  7,  7,  7,  7,  1,  7,  7,  3,  7,          // $7x
113         2,  2,  2,  4,  2,  2,  2,  1,  2,  2,  2,  2,  4,  7,  3,  1,          // $8x
114         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  6,  7,  5,  5,          // $9x
115         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  6,  7,  5,  5,          // $Ax
116         5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  7,  8,  6,  6,          // $Bx
117         2,  2,  2,  4,  2,  2,  2,  1,  2,  2,  2,  2,  3,  1,  3,  1,          // $Cx
118         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,          // $Dx
119         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,          // $Ex
120         5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6           // $Fx
121 };
122
123 uint8 page1Cycles[256] = {
124         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $0x
125         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $1x
126         1,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,          // $2x
127         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 20,          // $3x
128         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $4x
129         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $5x
130         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $6x
131         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $7x
132         1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  4,  1,          // $8x
133         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  6,  6,          // $9x
134         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  6,  6,          // $Ax
135         1,  1,  1,  8,  1,  1,  1,  1,  1,  1,  1,  1,  8,  1,  7,  7,          // $Bx
136         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  4,  1,          // $Cx
137         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,          // $Dx
138         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,          // $Ex
139         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  7,  7           // $Fx
140 };
141
142 uint8 page2Cycles[256] = {
143         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $0x
144         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $1x
145         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $2x
146         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 20,          // $3x
147         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $4x
148         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $5x
149         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $6x
150         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $7x
151         1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  1,  1,          // $8x
152         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  1,  1,          // $9x
153         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  1,  1,          // $Ax
154         1,  1,  1,  8,  1,  1,  1,  1,  1,  1,  1,  1,  8,  1,  1,  1,          // $Bx
155         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Cx
156         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Dx
157         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Ex
158         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1           // $Fx
159 };
160
161 // Private function prototypes
162
163 static uint16 RdMemW(uint16 addr);
164 static uint16 FetchMemW(uint16 addr);
165 static void WrMemW(uint16 addr, uint16 w);
166 static uint16 ReadEXG(uint8);                                   // Read TFR/EXG post byte
167 static void WriteEXG(uint8, uint16);                    // Set TFR/EXG data
168 static uint16 DecodeReg(uint8);                                 // Decode register data
169 static uint16 DecodeIDX(uint8);                                 // Decode IDX data
170
171 //
172 // Read word from memory function
173 //
174 static inline uint16 RdMemW(uint16 addr)
175 {
176         return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
177 }
178
179 //
180 // Fetch a word from memory function. Increments PC
181 //
182 static inline uint16 FetchMemW(uint16 addr)
183 {
184         regs.pc += 2;
185         return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
186 }
187
188 //
189 // Write word to memory function
190 //
191 static inline void WrMemW(uint16 addr, uint16 w)
192 {
193         regs.WrMem(addr + 0, w >> 8);
194         regs.WrMem(addr + 1, w & 0xFF);
195 }
196
197 //
198 // Function to read TFR/EXG post byte
199 //
200 uint16 ReadEXG(uint8 code)
201 {
202         uint16 retval;
203
204         switch (code)
205         {
206         case 0:
207                 retval = (regs.a << 8) | regs.b;
208                 break;
209         case 1:
210                 retval = regs.x;
211                 break;
212         case 2:
213                 retval = regs.y;
214                 break;
215         case 3:
216                 retval = regs.u;
217                 break;
218         case 4:
219                 retval = regs.s;
220                 break;
221         case 5:
222                 retval = regs.pc;
223                 break;
224         case 8:
225                 retval = regs.a;
226                 break;
227         case 9:
228                 retval = regs.b;
229                 break;
230         case 10:
231                 retval = regs.cc;
232                 break;
233         case 11:
234                 retval = regs.dp;
235                 break;
236         default:
237                 retval = 0xFF;
238         }
239
240         return retval;
241 }
242
243 //
244 // Function to set TFR/EXG data
245 //
246 void WriteEXG(uint8 code, uint16 data)
247 {
248         switch (code)
249         {
250         case 0:
251                 regs.a = data >> 8, regs.b = data & 0xFF;  break;
252         case 1:
253                 regs.x = data;  break;
254         case 2:
255                 regs.y = data;  break;
256         case 3:
257                 regs.u = data;  break;
258         case 4:
259                 regs.s = data;  break;
260         case 5:
261                 regs.pc = data;  break;
262         case 8:
263                 regs.a = data & 0xFF;  break;
264         case 9:
265                 regs.b = data & 0xFF;  break;
266         case 10:
267                 regs.cc = data & 0xFF;  break;
268         case 11:
269                 regs.dp = data & 0xFF;  break;
270         }
271 }
272
273 //
274 // Function to decode register data
275 //
276 uint16 DecodeReg(uint8 reg)
277 {
278         uint16 retval;
279
280         switch (reg)
281         {
282         case 0:
283         retval = regs.x;  break;
284         case 1:
285         retval = regs.y;  break;
286         case 2:
287         retval = regs.u;  break;
288         case 3:
289         retval = regs.s;  break;
290         }
291
292         return retval;
293 }
294
295 //
296 // Function to decode IDX data
297 //
298 uint16 DecodeIDX(uint8 code)
299 {
300         uint16 addr, woff;
301         uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
302
303         if (!(code & 0x80))                                                     // Hi bit unset? Then decode 4 bit offset
304                 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
305         else
306         {
307                 if (idxind)
308                 {
309                         switch (lo_nyb)
310                         {
311                         case 1:
312                                 woff = DecodeReg(reg);
313                                 addr = RdMemW(woff);
314                                 switch (reg)
315                                 {
316                                 case 0:  regs.x += 2;  break;
317                                 case 1:  regs.y += 2;  break;
318                                 case 2:  regs.u += 2;  break;
319                                 case 3:  regs.s += 2;  break;
320                                 }
321                                 break;
322                         case 3:
323                                 switch (reg)
324                                 {
325                                 case 0:  regs.x -= 2;  break;
326                                 case 1:  regs.y -= 2;  break;
327                                 case 2:  regs.u -= 2;  break;
328                                 case 3:  regs.s -= 2;  break;
329                                 }
330                                 woff = DecodeReg(reg);
331                                 addr = RdMemW(woff);
332                                 break;
333                         case 4:
334                                 woff = DecodeReg(reg);
335                                 addr = RdMemW(woff);
336                                 break;
337                         case 5:
338                                 woff = DecodeReg(reg) + (int16)(int8)regs.b;
339                                 addr = RdMemW(woff);
340                                 break;
341                         case 6:
342                                 woff = DecodeReg(reg) + (int16)(int8)regs.a;
343                                 addr = RdMemW(woff);
344                                 break;
345                         case 8:
346                                 woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);
347                                 addr = RdMemW(woff);
348                                 break;
349                         case 9:
350                                 woff = DecodeReg(reg) + FetchMemW(regs.pc);
351                                 addr = RdMemW(woff);
352                                 break;
353                         case 11:
354                                 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
355                                 addr = RdMemW(woff);
356                                 break;
357                         case 12:
358                                 woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);
359                                 addr = RdMemW(woff);
360                                 break;
361                         case 13:
362                                 woff = regs.pc + FetchMemW(regs.pc);
363                                 addr = RdMemW(woff);
364                                 break;
365                         case 15:
366                                 woff = FetchMemW(regs.pc);
367                                 addr = RdMemW(woff);
368                                 break;
369                         }
370                 }
371                 else
372                 {
373                         switch (lo_nyb)
374                         {
375                         case 0:
376                                 addr = DecodeReg(reg);
377                                 switch (reg)
378                                 {
379                                 case 0:  regs.x++;  break;
380                                 case 1:  regs.y++;  break;
381                                 case 2:  regs.u++;  break;
382                                 case 3:  regs.s++;  break;
383                                 }
384                                 break;
385                         case 1:
386                                 addr = DecodeReg(reg);
387                                 switch (reg)
388                                 {
389                                 case 0:  regs.x += 2;  break;
390                                 case 1:  regs.y += 2;  break;
391                                 case 2:  regs.u += 2;  break;
392                                 case 3:  regs.s += 2;  break;
393                                 }
394                                 break;
395         case 2:  { switch(reg)
396                    {
397                      case 0:  regs.x--;  break;
398                      case 1:  regs.y--;  break;
399                      case 2:  regs.u--;  break;
400                      case 3:  regs.s--;  break;
401                    }
402                    addr = DecodeReg(reg);  break; }
403         case 3:  { switch(reg)
404                    {
405                      case 0:  regs.x--;  regs.x--;  break;
406                      case 1:  regs.y--;  regs.y--;  break;
407                      case 2:  regs.u--;  regs.u--;  break;
408                      case 3:  regs.s--;  regs.s--;  break;
409                    }
410                    addr = DecodeReg(reg);  break; }
411         case 4:  { addr = DecodeReg(reg);  break; }
412         case 5:  { addr = DecodeReg(reg) + (int16)(int8)regs.b;  break; }
413         case 6:  { addr = DecodeReg(reg) + (int16)(int8)regs.a;  break; }
414         case 8:  { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);  break; }
415         case 9:  { addr = DecodeReg(reg) + FetchMemW(regs.pc);  break; }
416         case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);  break; }
417         case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);  break; }
418         case 13: { addr = regs.pc + FetchMemW(regs.pc);  break; }
419                         }
420                 }
421         }
422
423         return addr;
424 }
425
426 #if 1
427
428 //
429 // 6809 OPCODE IMPLEMENTATION
430 //
431 // NOTE: Lots of macros are used here to save a LOT of typing. Also
432 //       helps speed the debugging process. :-) Because of this, combining
433 //       certain lines may look like a good idea but would end in disaster.
434 //       You have been warned! ;-)
435 //
436
437 /*
438  +-----------------------------------------------------------------+
439  | Opcode     |             | Addressing   |               |       |
440  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
441  +------------+-------------+--------------+-------+-------+-------+
442  | 89    0137 | ADCA        | IMMEDIATE    |   2   |   2   | aaaaa |
443  | 99    0153 | ADCA        | DIRECT       |   4   |   2   | aaaaa |
444  | A9    0169 | ADCA        | INDEXED      |   4   |   2   | aaaaa |
445  | B9    0185 | ADCA        | EXTENDED     |   5   |   3   | aaaaa |
446  | C9    0201 | ADCB        | IMMEDIATE    |   2   |   2   | aaaaa |
447  | D9    0217 | ADCB        | DIRECT       |   4   |   2   | aaaaa |
448  | E9    0233 | ADCB        | INDEXED      |   4   |   2   | aaaaa |
449  | F9    0249 | ADCB        | EXTENDED     |   5   |   3   | aaaaa |
450 */
451
452 // ADC opcodes
453
454 #define OP_ADC_HANDLER(m, acc) \
455         uint16 sum = (uint16)acc + (m) + (uint16)flagC; \
456         flagC = (sum >> 8) & 0x01; \
457         flagH = (sum >> 4) & 0x01; \
458         SET_V(m, acc, sum); \
459         acc = sum & 0xFF; \
460         SET_ZN(acc)
461
462 /*
463 Old flag handling code:
464   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
465   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
466   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
467   regs.a = addr & 0xFF;                       // Set accumulator
468   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
469   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
470 */
471
472 static void Op89(void)                                                  // ADCA #
473 {
474         uint16 m = READ_IMM;
475         OP_ADC_HANDLER(m, regs.a);
476 }
477
478 static void Op99(void)                                                  // ADCA DP
479 {
480         uint16 m = READ_DP;
481         OP_ADC_HANDLER(m, regs.a);
482 }
483
484 static void OpA9(void)                                                  // ADCA IDX
485 {
486         uint16 m = READ_IDX;
487         OP_ADC_HANDLER(m, regs.a);
488 }
489
490 static void OpB9(void)                                                  // ADCA ABS
491 {
492         uint16 m = READ_ABS;
493         OP_ADC_HANDLER(m, regs.a);
494 }
495
496 static void OpC9(void)                                                  // ADCB #
497 {
498         uint16 m = READ_IMM;
499         OP_ADC_HANDLER(m, regs.b);
500 }
501
502 static void OpD9(void)                                                  // ADCB DP
503 {
504         uint16 m = READ_DP;
505         OP_ADC_HANDLER(m, regs.b);
506 }
507
508 static void OpE9(void)                                                  // ADCB IDX
509 {
510         uint16 m = READ_IDX;
511         OP_ADC_HANDLER(m, regs.b);
512 }
513
514 static void OpF9(void)                                                  // ADCB ABS
515 {
516         uint16 m = READ_ABS;
517         OP_ADC_HANDLER(m, regs.b);
518 }
519
520 /*
521  +-----------------------------------------------------------------+
522  | Opcode     |             | Addressing   |               |       |
523  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
524  +------------+-------------+--------------+-------+-------+-------+
525  | 3A    0058 | ABX         | INHERENT     |   3   |   1   | ----- |
526  | 8B    0139 | ADDA        | IMMEDIATE    |   2   |   2   | aaaaa |
527  | 9B    0155 | ADDA        | DIRECT       |   4   |   2   | aaaaa |
528  | AB    0171 | ADDA        | INDEXED      |   4   |   2   | aaaaa |
529  | BB    0187 | ADDA        | EXTENDED     |   5   |   3   | aaaaa |
530  | C3    0195 | ADDD        | IMMEDIATE    |   4   |   3   | -aaaa |
531  | CB    0203 | ADDB        | IMMEDIATE    |   2   |   2   | aaaaa |
532  | D3    0211 | ADDD        | DIRECT       |   6   |   2   | -aaaa |
533  | DB    0219 | ADDB        | DIRECT       |   4   |   2   | aaaaa |
534  | E3    0227 | ADDD        | INDEXED      |   6   |   2   | -aaaa |
535  | EB    0235 | ADDB        | INDEXED      |   4   |   2   | aaaaa |
536  | F3    0243 | ADDD        | EXTENDED     |   7   |   3   | -aaaa |
537  | FB    0251 | ADDB        | EXTENDED     |   5   |   3   | aaaaa |
538 */
539
540 // ADD opcodes
541
542 #define OP_ADD_HANDLER(m, acc) \
543         uint16 sum = (uint16)(acc) + (m); \
544         flagC = (sum >> 8) & 0x01; \
545         flagH = (sum >> 4) & 0x01; \
546         SET_V(m, acc, sum); \
547         (acc) = sum & 0xFF; \
548         SET_ZN(acc)
549
550 #define OP_ADD_HANDLER16(m, hireg, loreg) \
551         uint32 acc = (uint32)((hireg << 8) | loreg); \
552         uint32 sum = acc + (m); \
553         flagC = (sum >> 16) & 0x01; \
554         SET_V16(m, acc, sum); \
555         acc = sum & 0xFFFF; \
556         hireg = (acc >> 8) & 0xFF; \
557         loreg = acc & 0xFF; \
558         SET_ZN16(acc)
559
560 /*
561 Old flags:
562   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
563   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
564   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
565   regs.a = addr & 0xFF;                       // Set accumulator
566   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
567   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
568
569   dr += addr;
570   (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
571   dr &= 0xFFFF;
572   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
573   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
574   ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
575   regs.a = dr>>8;  regs.b = dr&0xFF;
576   regs.clock += 4;
577 */
578
579 static void Op3A(void)                                                  // ABX
580 {
581         regs.x += (uint16)regs.b;
582 }
583
584 static void Op8B(void)                                                  // ADDA #
585 {
586         uint16 m = READ_IMM;
587         OP_ADD_HANDLER(m, regs.a);
588 }
589
590 static void Op9B(void)                                                  // ADDA DP
591 {
592         uint16 m = READ_DP;
593         OP_ADD_HANDLER(m, regs.a);
594 }
595
596 static void OpAB(void)                                                  // ADDA IDX
597 {
598         uint16 m = READ_IDX;
599         OP_ADD_HANDLER(m, regs.a);
600 }
601
602 static void OpBB(void)                                                  // ADDA ABS
603 {
604         uint16 m = READ_ABS;
605         OP_ADD_HANDLER(m, regs.a);
606 }
607
608 static void OpC3(void)                                                  // ADDD #
609 {
610         uint32 m = READ_IMM16;
611         OP_ADD_HANDLER16(m, regs.a, regs.b);
612 }
613
614 static void OpCB(void)                                                  // ADDB #
615 {
616         uint16 m = READ_IMM;
617         OP_ADD_HANDLER(m, regs.b);
618 }
619
620 static void OpD3(void)                                                  // ADDD DP
621 {
622         uint32 m = READ_DP16;
623         OP_ADD_HANDLER16(m, regs.a, regs.b);
624 }
625
626 static void OpDB(void)                                                  // ADDB DP
627 {
628         uint16 m = READ_DP;
629         OP_ADD_HANDLER(m, regs.b);
630 }
631
632 static void OpE3(void)                                                  // ADDD IDX
633 {
634         uint32 m = READ_IDX16;
635         OP_ADD_HANDLER16(m, regs.a, regs.b);
636 }
637
638 static void OpEB(void)                                                  // ADDB IDX
639 {
640         uint16 m = READ_IDX;
641         OP_ADD_HANDLER(m, regs.b);
642 }
643
644 static void OpF3(void)                                                  // ADDD ABS
645 {
646         uint32 m = READ_ABS16;
647         OP_ADD_HANDLER16(m, regs.a, regs.b);
648 }
649
650 static void OpFB(void)                                                  // ADDB ABS
651 {
652         uint16 m = READ_ABS;
653         OP_ADD_HANDLER(m, regs.b);
654 }
655
656 /*
657  +-----------------------------------------------------------------+
658  | Opcode     |             | Addressing   |               |       |
659  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
660  +------------+-------------+--------------+-------+-------+-------+
661  | 84    0132 | ANDA        | IMMEDIATE    |   2   |   2   | -aa0- |
662  | 94    0148 | ANDA        | DIRECT       |   4   |   2   | -aa0- |
663  | A4    0164 | ANDA        | INDEXED      |   4   |   2   | -aa0- |
664  | B4    0180 | ANDA        | EXTENDED     |   5   |   3   | -aa0- |
665  | C4    0196 | ANDB        | IMMEDIATE    |   2   |   2   | -aa0- |
666  | D4    0212 | ANDB        | DIRECT       |   4   |   2   | -aa0- |
667  | E4    0228 | ANDB        | INDEXED      |   4   |   2   | -aa0- |
668  | F4    0244 | ANDB        | EXTENDED     |   5   |   3   | -aa0- |
669 */
670
671 // AND opcodes
672
673 #define OP_AND_HANDLER(m, acc) \
674         acc &= m; \
675         SET_ZN(acc); \
676         CLR_V
677
678 static void Op84(void)                                                  // ANDA #
679 {
680         uint16 m = READ_IMM;
681         OP_AND_HANDLER(m, regs.a);
682 }
683
684 static void Op94(void)                                                  // ANDA DP
685 {
686         uint16 m = READ_DP;
687         OP_AND_HANDLER(m, regs.a);
688 }
689
690 static void OpA4(void)                                                  // ANDA IDX
691 {
692         uint16 m = READ_IDX;
693         OP_AND_HANDLER(m, regs.a);
694 }
695
696 static void OpB4(void)                                                  // ANDA ABS
697 {
698         uint16 m = READ_ABS;
699         OP_AND_HANDLER(m, regs.a);
700 }
701
702 static void OpC4(void)                                                  // ANDB #
703 {
704         uint16 m = READ_IMM;
705         OP_AND_HANDLER(m, regs.b);
706 }
707
708 static void OpD4(void)                                                  // ANDB DP
709 {
710         uint16 m = READ_DP;
711         OP_AND_HANDLER(m, regs.b);
712 }
713
714 static void OpE4(void)                                                  // ANDB IDX
715 {
716         uint16 m = READ_IDX;
717         OP_AND_HANDLER(m, regs.b);
718 }
719
720 static void OpF4(void)                                                  // ANDB ABS
721 {
722         uint16 m = READ_ABS;
723         OP_AND_HANDLER(m, regs.b);
724 }
725
726 /*
727  +-----------------------------------------------------------------+
728  | Opcode     |             | Addressing   |               |       |
729  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
730  +------------+-------------+--------------+-------+-------+-------+
731  | 08    0008 | LSL/ASL     | DIRECT       |   6   |   2   | naaas |
732  | 48    0072 | LSLA/ASLA   | INHERENT     |   2   |   1   | naaas |
733  | 58    0088 | LSLB/ASLB   | INHERENT     |   2   |   1   | naaas |
734  | 68    0104 | LSL/ASL     | INDEXED      |   6   |   2   | naaas |
735  | 78    0120 | LSL/ASL     | EXTENDED     |   7   |   3   | naaas |
736 */
737
738 // ASL opcodes
739
740 #define OP_ASL_HANDLER(m) \
741         uint16 res = m << 1; \
742         SET_V(m, m, res); \
743         flagC = (res >> 8) & 0x01; \
744         m = res & 0xFF; \
745         SET_ZN(m)
746
747 static void Op08(void)                                                  // ASL DP
748 {
749         uint8 m;
750         READ_DP_WB(m);
751         OP_ASL_HANDLER(m);
752         WRITE_BACK(m);
753 }
754
755 static void Op48(void)                                                  // ASLA
756 {
757         OP_ASL_HANDLER(regs.a);
758 }
759
760 static void Op58(void)                                                  // ASLB
761 {
762         OP_ASL_HANDLER(regs.b);
763 }
764
765 static void Op68(void)                                                  // ASL IDX
766 {
767         uint8 m;
768         READ_IDX_WB(m);
769         OP_ASL_HANDLER(m);
770         WRITE_BACK(m);
771 }
772
773 static void Op78(void)                                                  // ASL ABS
774 {
775         uint8 m;
776         READ_ABS_WB(m);
777         OP_ASL_HANDLER(m);
778         WRITE_BACK(m);
779 }
780
781 /*
782  +-----------------------------------------------------------------+
783  | Opcode     |             | Addressing   |               |       |
784  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
785  +------------+-------------+--------------+-------+-------+-------+
786  | 07    0007 | ASR         | DIRECT       |   6   |   2   | uaa-s |
787  | 47    0071 | ASRA        | INHERENT     |   2   |   1   | uaa-s |
788  | 57    0087 | ASRB        | INHERENT     |   2   |   1   | uaa-s |
789  | 67    0103 | ASR         | INDEXED      |   6   |   2   | uaa-s |
790  | 77    0119 | ASR         | EXTENDED     |   7   |   3   | uaa-s |
791 */
792
793 // ASR opcodes (arithmetic, so preserves the sign)
794
795 #define OP_ASR_HANDLER(m) \
796         uint8 res = (m & 0x80) | (m >> 1); \
797         SET_ZN(res); \
798         flagC = m & 0x01; \
799         m = res
800
801 static void Op07(void)                                                  // ASR DP
802 {
803         uint8 m;
804         READ_DP_WB(m);
805         OP_ASR_HANDLER(m);
806         WRITE_BACK(m);
807 }
808
809 static void Op47(void)                                                  // ASRA
810 {
811         OP_ASR_HANDLER(regs.a);
812 }
813
814 static void Op57(void)                                                  // ASRB
815 {
816         OP_ASR_HANDLER(regs.b);
817 }
818
819 static void Op67(void)                                                  // ASR IDX
820 {
821         uint8 m;
822         READ_IDX_WB(m);
823         OP_ASR_HANDLER(m);
824         WRITE_BACK(m);
825 }
826
827 static void Op77(void)                                                  // ASR ABS
828 {
829         uint8 m;
830         READ_ABS_WB(m);
831         OP_ASR_HANDLER(m);
832         WRITE_BACK(m);
833 }
834
835 /*
836  +-----------------------------------------------------------------+
837  | Opcode     |             | Addressing   |               |       |
838  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
839  +------------+-------------+--------------+-------+-------+-------+
840  | 16    0022 | LBRA        | RELATIVE     |   5   |   3   | ----- |
841  | 20    0032 | BRA         | RELATIVE     |   3   |   2   | ----- |
842  | 21    0033 | BRN         | RELATIVE     |   3   |   2   | ----- |
843  | 22    0034 | BHI         | RELATIVE     |   3   |   2   | ----- |
844  | 23    0035 | BLS         | RELATIVE     |   3   |   2   | ----- |
845  | 24    0036 | BHS/BCC     | RELATIVE     |   3   |   2   | ----- |
846  | 25    0037 | BLO/BCS     | RELATIVE     |   3   |   2   | ----- |
847  | 26    0038 | BNE         | RELATIVE     |   3   |   2   | ----- |
848  | 27    0039 | BEQ         | RELATIVE     |   3   |   2   | ----- |
849  | 28    0040 | BVC         | RELATIVE     |   3   |   2   | ----- |
850  | 29    0041 | BVS         | RELATIVE     |   3   |   2   | ----- |
851  | 2A    0042 | BPL         | RELATIVE     |   3   |   2   | ----- |
852  | 2B    0043 | BMI         | RELATIVE     |   3   |   2   | ----- |
853  | 2C    0044 | BGE         | RELATIVE     |   3   |   2   | ----- |
854  | 2D    0045 | BLT         | RELATIVE     |   3   |   2   | ----- |
855  | 2E    0046 | BGT         | RELATIVE     |   3   |   2   | ----- |
856  | 2F    0047 | BLE         | RELATIVE     |   3   |   2   | ----- |
857  | 1021  4129 | LBRN        | RELATIVE     | 5(6)  |   4   | ----- |
858  | 1022  4130 | LBHI        | RELATIVE     | 5(6)  |   4   | ----- |
859  | 1023  4131 | LBLS        | RELATIVE     | 5(6)  |   4   | ----- |
860  | 1024  4132 | LBHS/LBCC   | RELATIVE     | 5(6)  |   4   | ----- |
861  | 1025  4133 | LBLO/LBCS   | RELATIVE     | 5(6)  |   4   | ----- |
862  | 1026  4134 | LBNE        | RELATIVE     | 5(6)  |   4   | ----- |
863  | 1027  4135 | LBEQ        | RELATIVE     | 5(6)  |   4   | ----- |
864  | 1028  4136 | LBVC        | RELATIVE     | 5(6)  |   4   | ----- |
865  | 1029  4137 | LBVS        | RELATIVE     | 5(6)  |   4   | ----- |
866  | 102A  4138 | LBPL        | RELATIVE     | 5(6)  |   4   | ----- |
867  | 102B  4139 | LBMI        | RELATIVE     | 5(6)  |   4   | ----- |
868  | 102C  4140 | LBGE        | RELATIVE     | 5(6)  |   4   | ----- |
869  | 102D  4141 | LBLT        | RELATIVE     | 5(6)  |   4   | ----- |
870  | 102E  4142 | LBGT        | RELATIVE     | 5(6)  |   4   | ----- |
871  | 102F  4143 | LBLE        | RELATIVE     | 5(6)  |   4   | ----- |
872 */
873
874 // Branch opcodes
875
876 static void Op16(void)                                                  // LBRA
877 {
878         uint16 offset = READ_IMM16;
879         regs.pc += offset;
880 }
881
882 static void Op20(void)                                                  // BRA
883 {
884         int16 offset = (int16)(int8)READ_IMM;
885         regs.pc += offset;
886 }
887
888 static void Op21(void)                                                  // BRN
889 {
890         // This is basically a 2 byte NOP
891         int16 offset = (int16)(int8)READ_IMM;
892 }
893
894 static void Op22(void)                                                  // BHI
895 {
896         // !C && !Z
897         int16 offset = (int16)(int8)READ_IMM;
898
899 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
900 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
901         regs.pc += offset * ((flagZ | flagC) ^ 0x01);
902 #else
903         if (!(flagZ || flagC))
904                 regs.pc += offset;
905 #endif
906 }
907
908 static void Op23(void)                                                  // BLS
909 {
910         // C || Z
911         int16 offset = (int16)(int8)READ_IMM;
912
913 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
914         regs.pc += offset * (flagZ | flagC);
915 #else
916         if (flagZ || flagC)
917                 regs.pc += offset;
918 #endif
919 }
920
921 static void Op24(void)                                                  // BHS/CC
922 {
923         // !C
924         int16 offset = (int16)(int8)READ_IMM;
925
926 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
927         regs.pc += offset * (flagC ^ 0x01);
928 #else
929         if (!flagC)
930                 regs.pc += offset;
931 #endif
932 }
933
934 static void Op25(void)                                                  // BLO/CS
935 {
936         // C
937         int16 offset = (int16)(int8)READ_IMM;
938 //if (disasm)
939 //      WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
940
941 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
942         regs.pc += offset * flagC;
943 #else
944         if (flagC)
945                 regs.pc += offset;
946 #endif
947 }
948
949 static void Op26(void)                                                  // BNE
950 {
951         // !Z
952         int16 offset = (int16)(int8)READ_IMM;
953
954 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
955         regs.pc += offset * (flagZ ^ 0x01);
956 #else
957         if (!flagZ)
958                 regs.pc += offset;
959 #endif
960 }
961
962 static void Op27(void)                                                  // BEQ
963 {
964         // Z
965         int16 offset = (int16)(int8)READ_IMM;
966
967 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
968         regs.pc += offset * flagZ;
969 #else
970         if (flagZ)
971                 regs.pc += offset;
972 #endif
973 }
974
975 static void Op28(void)                                                  // BVC
976 {
977         // !V
978         int16 offset = (int16)(int8)READ_IMM;
979
980 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
981         regs.pc += offset * (flagV ^ 0x01);
982 #else
983         if (!flagV)
984                 regs.pc += offset;
985 #endif
986 }
987
988 static void Op29(void)                                                  // BVS
989 {
990         // V
991         int16 offset = (int16)(int8)READ_IMM;
992
993 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
994         regs.pc += offset * flagV;
995 #else
996         if (flagV)
997                 regs.pc += offset;
998 #endif
999 }
1000
1001 static void Op2A(void)                                                  // BPL
1002 {
1003         // !N
1004         int16 offset = (int16)(int8)READ_IMM;
1005
1006 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1007         regs.pc += offset * (flagN ^ 0x01);
1008 #else
1009         if (!flagN)
1010                 regs.pc += offset;
1011 #endif
1012 }
1013
1014 static void Op2B(void)                                                  // BMI
1015 {
1016         // N
1017         int16 offset = (int16)(int8)READ_IMM;
1018
1019 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1020         regs.pc += offset * flagN;
1021 #else
1022         if (flagN)
1023                 regs.pc += offset;
1024 #endif
1025 }
1026
1027 static void Op2C(void)                                                  // BGE
1028 {
1029         // (N && V) || (!N && !V)
1030         int16 offset = (int16)(int8)READ_IMM;
1031
1032 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1033         regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1034 #else
1035         if ((flagN && flagV) || (!flagN && !flagV))
1036                 regs.pc += offset;
1037 #endif
1038 }
1039
1040 static void Op2D(void)                                                  // BLT
1041 {
1042         // (N && !V) || (!N && V)
1043         int16 offset = (int16)(int8)READ_IMM;
1044
1045 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1046         regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1047 #else
1048         if ((flagN && !flagV) || (!flagN && flagV))
1049                 regs.pc += offset;
1050 #endif
1051 }
1052
1053 static void Op2E(void)                                                  // BGT
1054 {
1055         // (N && V && !Z) || (!N && !V && !Z)
1056         int16 offset = (int16)(int8)READ_IMM;
1057
1058 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1059         regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1060 #else
1061         if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1062                 regs.pc += offset;
1063 #endif
1064 }
1065
1066 static void Op2F(void)                                                  // BLE
1067 {
1068         // Z || (N && !V) || (!N && V)
1069         int16 offset = (int16)(int8)READ_IMM;
1070
1071 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1072         regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1073 #else
1074         if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1075                 regs.pc += offset;
1076 #endif
1077 }
1078
1079 static void Op1021(void)                                                // LBRN
1080 {
1081         // This is basically a 4 byte NOP
1082         uint16 offset = READ_IMM16;
1083 }
1084
1085 static void Op1022(void)                                                // LBHI
1086 {
1087         // !C && !Z
1088         uint16 offset = READ_IMM16;
1089
1090 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1091 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1092         regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1093 #else
1094         if (!(flagZ || flagC))
1095                 regs.pc += offset;
1096 #endif
1097 }
1098
1099 static void Op1023(void)                                                // LBLS
1100 {
1101         // C || Z
1102         uint16 offset = READ_IMM16;
1103
1104 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1105         regs.pc += offset * (flagZ | flagC);
1106 #else
1107         if (flagZ || flagC)
1108                 regs.pc += offset;
1109 #endif
1110 }
1111
1112 static void Op1024(void)                                                // LBHS/CC
1113 {
1114         // !C
1115         uint16 offset = READ_IMM16;
1116
1117 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1118         regs.pc += offset * (flagC ^ 0x01);
1119 #else
1120         if (!flagC)
1121                 regs.pc += offset;
1122 #endif
1123 }
1124
1125 static void Op1025(void)                                                // LBLO/CS
1126 {
1127         // C
1128         uint16 offset = READ_IMM16;
1129
1130 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1131         regs.pc += offset * flagC;
1132 #else
1133         if (flagC)
1134                 regs.pc += offset;
1135 #endif
1136 }
1137
1138 static void Op1026(void)                                                // LBNE
1139 {
1140         // !Z
1141         uint16 offset = READ_IMM16;
1142
1143 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1144         regs.pc += offset * (flagZ ^ 0x01);
1145 #else
1146         if (!flagZ)
1147                 regs.pc += offset;
1148 #endif
1149 }
1150
1151 static void Op1027(void)                                                // LBEQ
1152 {
1153         // Z
1154         uint16 offset = READ_IMM16;
1155
1156 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1157         regs.pc += offset * flagZ;
1158 #else
1159         if (flagZ)
1160                 regs.pc += offset;
1161 #endif
1162 }
1163
1164 static void Op1028(void)                                                // LBVC
1165 {
1166         // !V
1167         uint16 offset = READ_IMM16;
1168
1169 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1170         regs.pc += offset * (flagV ^ 0x01);
1171 #else
1172         if (!flagV)
1173                 regs.pc += offset;
1174 #endif
1175 }
1176
1177 static void Op1029(void)                                                // LBVS
1178 {
1179         // V
1180         uint16 offset = READ_IMM16;
1181
1182 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1183         regs.pc += offset * flagV;
1184 #else
1185         if (flagV)
1186                 regs.pc += offset;
1187 #endif
1188 }
1189
1190 static void Op102A(void)                                                // LBPL
1191 {
1192         // !N
1193         uint16 offset = READ_IMM16;
1194
1195 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1196         regs.pc += offset * (flagN ^ 0x01);
1197 #else
1198         if (!flagN)
1199                 regs.pc += offset;
1200 #endif
1201 }
1202
1203 static void Op102B(void)                                                // LBMI
1204 {
1205         // N
1206         uint16 offset = READ_IMM16;
1207
1208 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1209         regs.pc += offset * flagN;
1210 #else
1211         if (flagN)
1212                 regs.pc += offset;
1213 #endif
1214 }
1215
1216 static void Op102C(void)                                                // LBGE
1217 {
1218         // (N && V) || (!N && !V)
1219         uint16 offset = READ_IMM16;
1220
1221 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1222         regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1223 #else
1224         if ((flagN && flagV) || (!flagN && !flagV))
1225                 regs.pc += offset;
1226 #endif
1227 }
1228
1229 static void Op102D(void)                                                // LBLT
1230 {
1231         // (N && !V) || (!N && V)
1232         uint16 offset = READ_IMM16;
1233
1234 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1235         regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1236 #else
1237         if ((flagN && !flagV) || (!flagN && flagV))
1238                 regs.pc += offset;
1239 #endif
1240 }
1241
1242 static void Op102E(void)                                                // LBGT
1243 {
1244         // (N && V && !Z) || (!N && !V && !Z)
1245         uint16 offset = READ_IMM16;
1246
1247 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1248         regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1249 #else
1250         if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1251                 regs.pc += offset;
1252 #endif
1253 }
1254
1255 static void Op102F(void)                                                // LBLE
1256 {
1257         // Z || (N && !V) || (!N && V)
1258         uint16 offset = READ_IMM16;
1259
1260 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1261         regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1262 #else
1263         if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1264                 regs.pc += offset;
1265 #endif
1266 }
1267
1268 /*
1269  +-----------------------------------------------------------------+
1270  | Opcode     |             | Addressing   |               |       |
1271  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1272  +------------+-------------+--------------+-------+-------+-------+
1273  | 85    0133 | BITA        | IMMEDIATE    |   2   |   2   | -aa0- |
1274  | 95    0149 | BITA        | DIRECT       |   4   |   2   | -aa0- |
1275  | A5    0165 | BITA        | INDEXED      |   4   |   2   | -aa0- |
1276  | B5    0181 | BITA        | EXTENDED     |   5   |   3   | -aa0- |
1277  | C5    0197 | BITB        | IMMEDIATE    |   2   |   2   | -aa0- |
1278  | D5    0213 | BITB        | DIRECT       |   4   |   2   | -aa0- |
1279  | E5    0229 | BITB        | INDEXED      |   4   |   2   | -aa0- |
1280  | F5    0245 | BITB        | EXTENDED     |   5   |   3   | -aa0- |
1281 */
1282
1283 // BIT opcodes
1284
1285 #define OP_BIT_HANDLER(m, acc) \
1286         uint8 result = acc & (m); \
1287         SET_ZN(result); \
1288         CLR_V
1289
1290 static void Op85(void)                                                  // BITA #
1291 {
1292         uint8 m = READ_IMM;
1293         OP_BIT_HANDLER(m, regs.a);
1294 }
1295
1296 static void Op95(void)                                                  // BITA DP
1297 {
1298         uint8 m = READ_DP;
1299         OP_BIT_HANDLER(m, regs.a);
1300 }
1301
1302 static void OpA5(void)                                                  // BITA IDX
1303 {
1304         uint8 m = READ_IDX;
1305         OP_BIT_HANDLER(m, regs.a);
1306 }
1307
1308 static void OpB5(void)                                                  // BITA ABS
1309 {
1310         uint8 m = READ_ABS;
1311         OP_BIT_HANDLER(m, regs.a);
1312 }
1313
1314 static void OpC5(void)                                                  // BITB #
1315 {
1316         uint8 m = READ_IMM;
1317         OP_BIT_HANDLER(m, regs.b);
1318 }
1319
1320 static void OpD5(void)                                                  // BITB DP
1321 {
1322         uint8 m = READ_DP;
1323         OP_BIT_HANDLER(m, regs.b);
1324 }
1325
1326 static void OpE5(void)                                                  // BITB IDX
1327 {
1328         uint8 m = READ_IDX;
1329         OP_BIT_HANDLER(m, regs.b);
1330 }
1331
1332 static void OpF5(void)                                                  // BITB ABS
1333 {
1334         uint8 m = READ_ABS;
1335         OP_BIT_HANDLER(m, regs.b);
1336 }
1337
1338 /*
1339  +-----------------------------------------------------------------+
1340  | Opcode     |             | Addressing   |               |       |
1341  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1342  +------------+-------------+--------------+-------+-------+-------+
1343  | 0F    0015 | CLR         | DIRECT       |   6   |   2   | -0100 |
1344  | 4F    0079 | CLRA        | INHERENT     |   2   |   1   | -0100 |
1345  | 5F    0095 | CLRB        | INHERENT     |   2   |   1   | -0100 |
1346  | 6F    0111 | CLR         | INDEXED      |   6   |   2   | -0100 |
1347  | 7F    0127 | CLR         | EXTENDED     |   7   |   3   | -0100 |
1348 */
1349
1350 // CLR opcodes
1351
1352 #define OP_CLR_HANDLER(m) \
1353         flagN = flagV = flagC = 0; \
1354         flagZ = 1; \
1355         m = 0
1356
1357 static void Op0F(void)                                                  // CLR DP
1358 {
1359         uint8 m;
1360         READ_DP_WB(m);
1361         OP_CLR_HANDLER(m);
1362         WRITE_BACK(m);
1363 }
1364
1365 static void Op4F(void)                                                  // CLRA
1366 {
1367         OP_CLR_HANDLER(regs.a);
1368 }
1369
1370 static void Op5F(void)                                                  // CLRB
1371 {
1372         OP_CLR_HANDLER(regs.b);
1373 }
1374
1375 static void Op6F(void)                                                  // CLR IDX
1376 {
1377         uint8 m;
1378         READ_IDX_WB(m);
1379         OP_CLR_HANDLER(m);
1380         WRITE_BACK(m);
1381 }
1382
1383 static void Op7F(void)                                                  // CLR ABS
1384 {
1385         uint8 m;
1386         READ_ABS_WB(m);
1387         OP_CLR_HANDLER(m);
1388         WRITE_BACK(m);
1389 }
1390
1391 /*
1392  +-----------------------------------------------------------------+
1393  | Opcode     |             | Addressing   |               |       |
1394  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1395  +------------+-------------+--------------+-------+-------+-------+
1396  | 81    0129 | CMPA        | IMMEDIATE    |   2   |   2   | uaaaa |
1397  | 8C    0140 | CMPX        | IMMEDIATE    |   4   |   3   | -aaaa |
1398  | 91    0145 | CMPA        | DIRECT       |   4   |   2   | uaaaa |
1399  | 9C    0156 | CMPX        | DIRECT       |   6   |   2   | -aaaa |
1400  | A1    0161 | CMPA        | INDEXED      |   4   |   2   | uaaaa |
1401  | AC    0172 | CMPX        | INDEXED      |   6   |   2   | -aaaa |
1402  | B1    0177 | CMPA        | EXTENDED     |   5   |   3   | uaaaa |
1403  | BC    0188 | CMPX        | EXTENDED     |   7   |   3   | -aaaa |
1404  | C1    0193 | CMPB        | IMMEDIATE    |   2   |   2   | uaaaa |
1405  | D1    0209 | CMPB        | DIRECT       |   4   |   2   | uaaaa |
1406  | E1    0225 | CMPB        | INDEXED      |   4   |   2   | uaaaa |
1407  | F1    0241 | CMPB        | EXTENDED     |   5   |   3   | uaaaa |
1408  | 1083  4227 | CMPD        | IMMEDIATE    |   5   |   4   | -aaaa |
1409  | 108C  4236 | CMPY        | IMMEDIATE    |   5   |   4   | -aaaa |
1410  | 1093  4243 | CMPD        | DIRECT       |   7   |   3   | -aaaa |
1411  | 109C  4252 | CMPY        | DIRECT       |   7   |   3   | -aaaa |
1412  | 10A3  4259 | CMPD        | INDEXED      |   7   |   3   | -aaaa |
1413  | 10AC  4268 | CMPY        | INDEXED      |   7   |   3   | -aaaa |
1414  | 10B3  4275 | CMPD        | EXTENDED     |   8   |   4   | -aaaa |
1415  | 10BC  4284 | CMPY        | EXTENDED     |   8   |   4   | -aaaa |
1416  | 1183  4438 | CMPU        | IMMEDIATE    |   5   |   4   | -aaaa |
1417  | 118C  4492 | CMPS        | IMMEDIATE    |   5   |   4   | -aaaa |
1418  | 1193  4499 | CMPU        | DIRECT       |   7   |   3   | -aaaa |
1419  | 119C  4508 | CMPS        | DIRECT       |   7   |   3   | -aaaa |
1420  | 11A3  4515 | CMPU        | INDEXED      |   7   |   3   | -aaaa |
1421  | 11AC  4524 | CMPS        | INDEXED      |   7   |   3   | -aaaa |
1422  | 11B3  4531 | CMPU        | EXTENDED     |   8   |   4   | -aaaa |
1423  | 11BC  4540 | CMPS        | EXTENDED     |   8   |   4   | -aaaa |
1424 */
1425
1426 // CMP opcodes
1427
1428 #define OP_CMP_HANDLER(m, acc) \
1429         uint16 sum = (uint16)(acc) - (m); \
1430         flagC = (sum >> 8) & 0x01; \
1431         SET_V(m, acc, sum); \
1432         SET_ZN(sum)
1433
1434 #define OP_CMP_HANDLER16(m, acc) \
1435         uint32 sum = (uint32)(acc) - (m); \
1436         flagC = (sum >> 16) & 0x01; \
1437         SET_V16(m, acc, sum); \
1438         SET_ZN16(sum)
1439
1440 static void Op81(void)                                                  // CMPA #
1441 {
1442         uint8 m = READ_IMM;
1443         OP_CMP_HANDLER(m, regs.a);
1444 }
1445
1446 static void Op8C(void)                                                  // CMPX #
1447 {
1448         uint16 m = READ_IMM16;
1449         OP_CMP_HANDLER16(m, regs.x);
1450 }
1451
1452 static void Op91(void)                                                  // CMPA DP
1453 {
1454         uint8 m = READ_DP;
1455         OP_CMP_HANDLER(m, regs.a);
1456 }
1457
1458 static void Op9C(void)                                                  // CMPX DP
1459 {
1460         uint16 m = READ_DP16;
1461         OP_CMP_HANDLER16(m, regs.x);
1462 }
1463
1464 static void OpA1(void)                                                  // CMPA IDX
1465 {
1466         uint8 m = READ_IDX;
1467         OP_CMP_HANDLER(m, regs.a);
1468 }
1469
1470 static void OpAC(void)                                                  // CMPX IDX
1471 {
1472         uint16 m = READ_IDX16;
1473         OP_CMP_HANDLER16(m, regs.x);
1474 }
1475
1476 static void OpB1(void)                                                  // CMPA ABS
1477 {
1478         uint8 m = READ_ABS;
1479         OP_CMP_HANDLER(m, regs.a);
1480 }
1481
1482 static void OpBC(void)                                                  // CMPX ABS
1483 {
1484         uint16 m = READ_ABS16;
1485         OP_CMP_HANDLER16(m, regs.x);
1486 }
1487
1488 static void OpC1(void)                                                  // CMPB #
1489 {
1490         uint8 m = READ_IMM;
1491         OP_CMP_HANDLER(m, regs.b);
1492 }
1493
1494 static void OpD1(void)                                                  // CMPB DP
1495 {
1496         uint8 m = READ_DP;
1497         OP_CMP_HANDLER(m, regs.b);
1498 }
1499
1500 static void OpE1(void)                                                  // CMPB IDX
1501 {
1502         uint8 m = READ_IDX;
1503         OP_CMP_HANDLER(m, regs.b);
1504 }
1505
1506 static void OpF1(void)                                                  // CMPB ABS
1507 {
1508         uint8 m = READ_ABS;
1509         OP_CMP_HANDLER(m, regs.b);
1510 }
1511
1512 static void Op1083(void)                                                // CMPD #
1513 {
1514         uint16 m = READ_IMM16;
1515         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1516 }
1517
1518 static void Op108C(void)                                                // CMPY #
1519 {
1520         uint16 m = READ_IMM16;
1521         OP_CMP_HANDLER16(m, regs.y);
1522 }
1523
1524 static void Op1093(void)                                                // CMPD DP
1525 {
1526         uint16 m = READ_DP16;
1527         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1528 }
1529
1530 static void Op109C(void)                                                // CMPY DP
1531 {
1532         uint16 m = READ_DP16;
1533         OP_CMP_HANDLER16(m, regs.y);
1534 }
1535
1536 static void Op10A3(void)                                                // CMPD IDX
1537 {
1538         uint16 m = READ_IDX16;
1539         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1540 }
1541
1542 static void Op10AC(void)                                                // CMPY IDX
1543 {
1544         uint16 m = READ_IDX16;
1545         OP_CMP_HANDLER16(m, regs.y);
1546 }
1547
1548 static void Op10B3(void)                                                // CMPD ABS
1549 {
1550         uint16 m = READ_ABS16;
1551         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1552 }
1553
1554 static void Op10BC(void)                                                // CMPY ABS
1555 {
1556         uint16 m = READ_ABS16;
1557         OP_CMP_HANDLER16(m, regs.y);
1558 }
1559
1560 static void Op1183(void)                                                // CMPU #
1561 {
1562         uint16 m = READ_IMM16;
1563         OP_CMP_HANDLER16(m, regs.u);
1564 }
1565
1566 static void Op118C(void)                                                // CMPS #
1567 {
1568         uint16 m = READ_IMM16;
1569         OP_CMP_HANDLER16(m, regs.s);
1570 }
1571
1572 static void Op1193(void)                                                // CMPU DP
1573 {
1574         uint16 m = READ_DP16;
1575         OP_CMP_HANDLER16(m, regs.u);
1576 }
1577
1578 static void Op119C(void)                                                // CMPS DP
1579 {
1580         uint16 m = READ_DP16;
1581         OP_CMP_HANDLER16(m, regs.s);
1582 }
1583
1584 static void Op11A3(void)                                                // CMPU IDX
1585 {
1586         uint16 m = READ_IDX16;
1587         OP_CMP_HANDLER16(m, regs.u);
1588 }
1589
1590 static void Op11AC(void)                                                // CMPS IDX
1591 {
1592         uint16 m = READ_IDX16;
1593         OP_CMP_HANDLER16(m, regs.s);
1594 }
1595
1596 static void Op11B3(void)                                                // CMPU ABS
1597 {
1598         uint16 m = READ_ABS16;
1599         OP_CMP_HANDLER16(m, regs.u);
1600 }
1601
1602 static void Op11BC(void)                                                // CMPS ABS
1603 {
1604         uint16 m = READ_ABS16;
1605         OP_CMP_HANDLER16(m, regs.s);
1606 }
1607
1608 /*
1609  +-----------------------------------------------------------------+
1610  | Opcode     |             | Addressing   |               |       |
1611  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1612  +------------+-------------+--------------+-------+-------+-------+
1613  | 03    0003 | COM         | DIRECT       |   6   |   2   | -aa01 |
1614  | 43    0067 | COMA        | INHERENT     |   2   |   1   | -aa01 |
1615  | 53    0083 | COMB        | INHERENT     |   2   |   1   | -aa01 |
1616  | 63    0099 | COM         | INDEXED      |   6   |   2   | -aa01 |
1617  | 73    0115 | COM         | EXTENDED     |   7   |   3   | -aa01 |
1618 */
1619
1620 // COM opcodes
1621
1622 #define OP_COM_HANDLER(m) \
1623         m = ~m; \
1624         SET_ZN(m); \
1625         flagC = 1; \
1626         flagV = 0
1627
1628 static void Op03(void)                                                  // COM DP
1629 {
1630         uint8 m;
1631         READ_DP_WB(m);
1632         OP_COM_HANDLER(m);
1633         WRITE_BACK(m);
1634 }
1635
1636 static void Op43(void)                                                  // COMA
1637 {
1638         OP_COM_HANDLER(regs.a);
1639 }
1640
1641 static void Op53(void)                                                  // COMB
1642 {
1643         OP_COM_HANDLER(regs.b);
1644 }
1645
1646 static void Op63(void)                                                  // COM IDX
1647 {
1648         uint8 m;
1649         READ_IDX_WB(m);
1650         OP_COM_HANDLER(m);
1651         WRITE_BACK(m);
1652 }
1653
1654 static void Op73(void)                                                  // COM ABS
1655 {
1656         uint8 m;
1657         READ_ABS_WB(m);
1658         OP_COM_HANDLER(m);
1659         WRITE_BACK(m);
1660 }
1661
1662 /*
1663  +-----------------------------------------------------------------+
1664  | Opcode     |             | Addressing   |               |       |
1665  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1666  +------------+-------------+--------------+-------+-------+-------+
1667  | 13    0019 | SYNC        | INHERENT     |   2   |   1   | ----- |
1668  | 3C    0060 | CWAI        | INHERENT     |  21   |   2   | ddddd |
1669  | 3E    0062 | RESET*      | INHERENT     |   *   |   1   | ***** |
1670  | 3F    0063 | SWI         | INHERENT     |  19   |   1   | ----- |
1671  | 103F  4159 | SWI2        | INHERENT     |  20   |   2   | ----- |
1672  | 113F  4415 | SWI3        | INHERENT     |  20   |   2   | ----- |
1673 */
1674
1675 static void Op13(void)                                                  // SYNC
1676 {
1677 #warning "!!! SYNC not implemented !!!"
1678 #if 0
1679         /* SYNC stops processing instructions until an interrupt request happens. */
1680         /* This doesn't require the corresponding interrupt to be enabled: if it */
1681         /* is disabled, execution continues with the next instruction. */
1682         m68_state->int_state |= M6809_SYNC;      /* HJB 990227 */
1683         check_irq_lines(m68_state);
1684         /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1685      * stop execution until the interrupt lines change. */
1686         if( m68_state->int_state & M6809_SYNC )
1687                 if (m68_state->icount > 0) m68_state->icount = 0;
1688 #endif
1689 }
1690
1691 static void Op3C(void)                                                  // CWAI
1692 {
1693 #warning "!!! CWAI not implemented !!!"
1694 #if 0
1695         UINT8 t;
1696         IMMBYTE(t);
1697         CC &= t;
1698         /*
1699      * CWAI stacks the entire machine state on the hardware stack,
1700      * then waits for an interrupt; when the interrupt is taken
1701      * later, the state is *not* saved again after CWAI.
1702      */
1703         CC |= CC_E;             /* HJB 990225: save entire state */
1704         PUSHWORD(pPC);
1705         PUSHWORD(pU);
1706         PUSHWORD(pY);
1707         PUSHWORD(pX);
1708         PUSHBYTE(DP);
1709         PUSHBYTE(B);
1710         PUSHBYTE(A);
1711         PUSHBYTE(CC);
1712         m68_state->int_state |= M6809_CWAI;      /* HJB 990228 */
1713         check_irq_lines(m68_state);    /* HJB 990116 */
1714         if( m68_state->int_state & M6809_CWAI )
1715                 if( m68_state->icount > 0 )
1716                         m68_state->icount = 0;
1717 #endif
1718 }
1719
1720 static void Op3E(void)                                                  // RESET
1721 {
1722         regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
1723 }
1724
1725 static void Op3F(void)                                                  // SWI
1726 {
1727         flagE = 1;
1728         regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
1729         PUSHS16(regs.pc);
1730         PUSHS16(regs.u);
1731         PUSHS16(regs.y);
1732         PUSHS16(regs.x);
1733         PUSHS(regs.dp);
1734         PUSHS(regs.b);
1735         PUSHS(regs.a);
1736         PUSHS(regs.cc);
1737         flagF = flagI = 1;
1738         regs.pc = RdMemW(0xFFFA);
1739 }
1740
1741 static void Op103F(void)                                                // SWI2
1742 {
1743         flagE = 1;
1744         regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
1745         PUSHS16(regs.pc);
1746         PUSHS16(regs.u);
1747         PUSHS16(regs.y);
1748         PUSHS16(regs.x);
1749         PUSHS(regs.dp);
1750         PUSHS(regs.b);
1751         PUSHS(regs.a);
1752         PUSHS(regs.cc);
1753         regs.pc = RdMemW(0xFFF4);
1754 }
1755
1756 static void Op113F(void)                                                // SWI3
1757 {
1758         flagE = 1;
1759         regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
1760         PUSHS16(regs.pc);
1761         PUSHS16(regs.u);
1762         PUSHS16(regs.y);
1763         PUSHS16(regs.x);
1764         PUSHS(regs.dp);
1765         PUSHS(regs.b);
1766         PUSHS(regs.a);
1767         PUSHS(regs.cc);
1768         regs.pc = RdMemW(0xFFF2);
1769 }
1770
1771 /*
1772  +-----------------------------------------------------------------+
1773  | Opcode     |             | Addressing   |               |       |
1774  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1775  +------------+-------------+--------------+-------+-------+-------+
1776  | 12    0018 | NOP         | INHERENT     |   2   |   1   | ----- |
1777  | 19    0025 | DAA         | INHERENT     |   2   |   1   | -aa0a |
1778  | 1A    0026 | ORCC        | IMMEDIATE    |   3   |   2   | ddddd |
1779  | 1C    0028 | ANDCC       | IMMEDIATE    |   3   |   2   | ddddd |
1780  | 1D    0029 | SEX         | INHERENT     |   2   |   1   | -aa0- |
1781 */
1782
1783 static void Op12()                                                              // NOP
1784 {
1785 }
1786
1787 static void Op19()                                                              // DAA
1788 {
1789         uint16 result = (uint16)regs.a;
1790
1791         if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
1792                 result += 0x06;
1793
1794         if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1795                 result += 0x60;
1796
1797         regs.a = (uint8)result;
1798         SET_ZN(result);
1799         CLR_V;
1800         flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
1801 }
1802
1803 static void Op1A()                                                              // ORCC
1804 {
1805         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
1806         regs.cc |= READ_IMM;
1807         UNPACK_FLAGS;                                                           // & unmash 'em
1808 }
1809
1810 static void Op1C()                                                              // ANDCC
1811 {
1812         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
1813         regs.cc &= READ_IMM;
1814         UNPACK_FLAGS;                                                           // & unmash 'em
1815 }
1816
1817 static void Op1D()                                                              // SEX
1818 {
1819         regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1820         SET_ZN16((regs.a << 8) | regs.b);
1821         CLR_V;
1822 }
1823
1824 /*
1825  +-----------------------------------------------------------------+
1826  | Opcode     |             | Addressing   |               |       |
1827  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1828  +------------+-------------+--------------+-------+-------+-------+
1829  | 0A    0010 | DEC         | DIRECT       |   6   |   2   | -aaa- |
1830  | 4A    0074 | DECA        | INHERENT     |   2   |   1   | -aaa- |
1831  | 5A    0090 | DECB        | INHERENT     |   2   |   1   | -aaa- |
1832  | 6A    0106 | DEC         | INDEXED      |   6   |   2   | -aaa- |
1833  | 7A    0122 | DEC         | EXTENDED     |   7   |   3   | -aaa- |
1834 */
1835
1836 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1837
1838 #define OP_DEC_HANDLER(m) \
1839         m--; \
1840         SET_ZN(m); \
1841         flagV = (m == 0x7F ? 1 : 0)
1842
1843 static void Op0A(void)                                                  // DEC DP
1844 {
1845         uint8 m;
1846         READ_DP_WB(m);
1847         OP_DEC_HANDLER(m);
1848         WRITE_BACK(m);
1849 }
1850
1851 static void Op4A(void)                                                  // DECA
1852 {
1853         OP_DEC_HANDLER(regs.a);
1854 }
1855
1856 static void Op5A(void)                                                  // DECB
1857 {
1858         OP_DEC_HANDLER(regs.b);
1859 }
1860
1861 static void Op6A(void)                                                  // DEC IDX
1862 {
1863         uint8 m;
1864         READ_IDX_WB(m);
1865         OP_DEC_HANDLER(m);
1866         WRITE_BACK(m);
1867 }
1868
1869 static void Op7A(void)                                                  // DEC ABS
1870 {
1871         uint8 m;
1872         READ_ABS_WB(m);
1873         OP_DEC_HANDLER(m);
1874         WRITE_BACK(m);
1875 }
1876
1877 /*
1878  +-----------------------------------------------------------------+
1879  | Opcode     |             | Addressing   |               |       |
1880  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1881  +------------+-------------+--------------+-------+-------+-------+
1882  | 88    0136 | EORA        | IMMEDIATE    |   2   |   2   | -aa0- |
1883  | 98    0152 | EORA        | DIRECT       |   4   |   2   | -aa0- |
1884  | A8    0168 | EORA        | INDEXED      |   4   |   2   | -aa0- |
1885  | B8    0184 | EORA        | EXTENDED     |   5   |   3   | -aa0- |
1886  | C8    0200 | EORB        | IMMEDIATE    |   2   |   2   | -aa0- |
1887  | D8    0216 | EORB        | DIRECT       |   4   |   2   | -aa0- |
1888  | E8    0232 | EORB        | INDEXED      |   4   |   2   | -aa0- |
1889  | F8    0248 | EORB        | EXTENDED     |   5   |   3   | -aa0- |
1890 */
1891
1892 // EOR opcodes
1893
1894 #define OP_EOR_HANDLER(m, acc) \
1895         acc ^= (m); \
1896         SET_ZN(acc); \
1897         CLR_V
1898
1899 static void Op88(void)                                                  // EORA #
1900 {
1901         uint8 m = READ_IMM;
1902         OP_EOR_HANDLER(m, regs.a);
1903 }
1904
1905 static void Op98(void)                                                  // EORA DP
1906 {
1907         uint8 m = READ_DP;
1908         OP_EOR_HANDLER(m, regs.a);
1909 }
1910
1911 static void OpA8(void)                                                  // EORA IDX
1912 {
1913         uint8 m = READ_IDX;
1914         OP_EOR_HANDLER(m, regs.a);
1915 }
1916
1917 static void OpB8(void)                                                  // EORA ABS
1918 {
1919         uint8 m = READ_ABS;
1920         OP_EOR_HANDLER(m, regs.a);
1921 }
1922
1923 static void OpC8(void)                                                  // EORB #
1924 {
1925         uint8 m = READ_IMM;
1926         OP_EOR_HANDLER(m, regs.b);
1927 }
1928
1929 static void OpD8(void)                                                  // EORB DP
1930 {
1931         uint8 m = READ_DP;
1932         OP_EOR_HANDLER(m, regs.b);
1933 }
1934
1935 static void OpE8(void)                                                  // EORB IDX
1936 {
1937         uint8 m = READ_IDX;
1938         OP_EOR_HANDLER(m, regs.b);
1939 }
1940
1941 static void OpF8(void)                                                  // EORB ABS
1942 {
1943         uint8 m = READ_ABS;
1944         OP_EOR_HANDLER(m, regs.b);
1945 }
1946
1947 /*
1948  +-----------------------------------------------------------------+
1949  | Opcode     |             | Addressing   |               |       |
1950  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1951  +------------+-------------+--------------+-------+-------+-------+
1952  | 0C    0012 | INC         | DIRECT       |   6   |   2   | -aaa- |
1953  | 4C    0076 | INCA        | INHERENT     |   2   |   1   | -aaa- |
1954  | 5C    0092 | INCB        | INHERENT     |   2   |   1   | -aaa- |
1955  | 6C    0108 | INC         | INDEXED      |   6   |   2   | -aaa- |
1956  | 7C    0124 | INC         | EXTENDED     |   7   |   3   | -aaa- |
1957 */
1958
1959 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1960
1961 #define OP_INC_HANDLER(m) \
1962         m++; \
1963         SET_ZN(m); \
1964         flagV = (m == 0x80 ? 1 : 0)
1965
1966 static void Op0C(void)                                                  // INC DP
1967 {
1968         uint8 m;
1969         READ_DP_WB(m);
1970         OP_INC_HANDLER(m);
1971         WRITE_BACK(m);
1972 }
1973
1974 static void Op4C(void)                                                  // INCA
1975 {
1976         OP_INC_HANDLER(regs.a);
1977 }
1978
1979 static void Op5C(void)                                                  // INCB
1980 {
1981         OP_INC_HANDLER(regs.b);
1982 }
1983
1984 static void Op6C(void)                                                  // INC IDX
1985 {
1986         uint8 m;
1987         READ_IDX_WB(m);
1988         OP_INC_HANDLER(m);
1989         WRITE_BACK(m);
1990 }
1991
1992 static void Op7C(void)                                                  // INC ABS
1993 {
1994         uint8 m;
1995         READ_ABS_WB(m);
1996         OP_INC_HANDLER(m);
1997         WRITE_BACK(m);
1998 }
1999
2000 /*
2001  +-----------------------------------------------------------------+
2002  | Opcode     |             | Addressing   |               |       |
2003  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2004  +------------+-------------+--------------+-------+-------+-------+
2005  | 0E    0014 | JMP         | DIRECT       |   3   |   2   | ----- |
2006  | 17    0023 | LBSR        | RELATIVE     |   9   |   3   | ----- |
2007  | 39    0057 | RTS         | INHERENT     |   5   |   1   | ----- |
2008  | 3B    0059 | RTI         | INHERENT     | 6/15  |   1   | ----- |
2009  | 6E    0110 | JMP         | INDEXED      |   3   |   2   | ----- |
2010  | 7E    0126 | JMP         | EXTENDED     |   3   |   3   | ----- |
2011  | 8D    0141 | BSR         | RELATIVE     |   7   |   2   | ----- |
2012  | 9D    0157 | JSR         | DIRECT       |   7   |   2   | ----- |
2013  | AD    0173 | JSR         | INDEXED      |   7   |   2   | ----- |
2014  | BD    0189 | JSR         | EXTENDED     |   8   |   3   | ----- |
2015 */
2016
2017 static void Op0E(void)                                                  // JMP DP
2018 {
2019         regs.pc = EA_DP;
2020 }
2021
2022 static void Op17(void)                                                  // LBSR
2023 {
2024         uint16 word = FetchMemW(regs.pc);
2025         PUSHS16(regs.pc);
2026         regs.pc += word;
2027 }
2028
2029 static void Op39(void)                                                  // RTS
2030 {
2031         PULLS16(regs.pc);
2032 }
2033
2034 static void Op3B(void)                                                  // RTI
2035 {
2036         PULLS(regs.cc);
2037         UNPACK_FLAGS;
2038
2039         // If E flag set, pull all regs
2040         if (flagE)
2041         {
2042                 PULLS(regs.a);
2043                 PULLS(regs.b);
2044                 PULLS(regs.dp);
2045                 PULLS16(regs.x);
2046                 PULLS16(regs.y);
2047                 PULLS16(regs.u);
2048                 regs.clock += 9;
2049         }
2050
2051         PULLS16(regs.pc);
2052 }
2053
2054 static void Op6E(void)                                                  // JMP IDX
2055 {
2056         regs.pc = EA_IDX;
2057 }
2058
2059 static void Op7E(void)                                                  // JMP ABS
2060 {
2061         regs.pc = EA_ABS;
2062 }
2063
2064 static void Op8D(void)                                                  // BSR
2065 {
2066         uint16 word = (int16)(int8)READ_IMM;
2067         PUSHS16(regs.pc);
2068         regs.pc += word;
2069 }
2070
2071 static void Op9D(void)                                                  // JSR DP
2072 {
2073         uint16 word = EA_DP;
2074         PUSHS16(regs.pc);
2075         regs.pc = word;
2076 }
2077
2078 static void OpAD(void)                                                  // JSR IDX
2079 {
2080         uint16 word = EA_IDX;
2081         PUSHS16(regs.pc);
2082         regs.pc = word;
2083 }
2084
2085 static void OpBD(void)                                                  // JSR ABS
2086 {
2087         uint16 word = EA_ABS;
2088         PUSHS16(regs.pc);
2089         regs.pc = word;
2090 }
2091
2092 /*
2093  +-----------------------------------------------------------------+
2094  | Opcode     |             | Addressing   |               |       |
2095  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2096  +------------+-------------+--------------+-------+-------+-------+
2097  | 1E    0030 | EXG         | INHERENT     |   8   |   2   | ccccc |
2098  | 1F    0031 | TFR         | INHERENT     |   7   |   2   | ccccc |
2099 */
2100
2101 static void Op1E(void)                                                  // EXG
2102 {
2103         uint8 m = READ_IMM;
2104         uint8 reg1 = m >> 4, reg2 = m & 0x0F;
2105         uint16 acc = ReadEXG(reg1);
2106         WriteEXG(reg1, ReadEXG(reg2));
2107         WriteEXG(reg2, acc);
2108 }
2109
2110 static void Op1F(void)                                                  // TFR
2111 {
2112         uint8 m = READ_IMM;
2113         WriteEXG(m & 0x0F, ReadEXG(m >> 4));
2114 }
2115
2116 /*
2117  +-----------------------------------------------------------------+
2118  | Opcode     |             | Addressing   |               |       |
2119  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2120  +------------+-------------+--------------+-------+-------+-------+
2121  | 86    0134 | LDA         | IMMEDIATE    |   2   |   2   | -aa0- |
2122  | 8E    0142 | LDX         | IMMEDIATE    |   3   |   3   | -aa0- |
2123  | 96    0150 | LDA         | DIRECT       |   4   |   2   | -aa0- |
2124  | 9E    0158 | LDX         | DIRECT       |   5   |   2   | -aa0- |
2125  | A6    0166 | LDA         | INDEXED      |   4   |   2   | -aa0- |
2126  | AE    0174 | LDX         | INDEXED      |   5   |   2   | -aa0- |
2127  | B6    0182 | LDA         | EXTENDED     |   5   |   3   | -aa0- |
2128  | BE    0190 | LDX         | EXTENDED     |   6   |   3   | -aa0- |
2129  | C6    0198 | LDB         | IMMEDIATE    |   2   |   2   | -aa0- |
2130  | CC    0204 | LDD         | IMMEDIATE    |   3   |   3   | -aa0- |
2131  | CE    0206 | LDU         | IMMEDIATE    |   3   |   3   | -aa0- |
2132  | D6    0214 | LDB         | DIRECT       |   4   |   2   | -aa0- |
2133  | DC    0220 | LDD         | DIRECT       |   5   |   2   | -aa0- |
2134  | DE    0222 | LDU         | DIRECT       |   5   |   2   | -aa0- |
2135  | E6    0230 | LDB         | INDEXED      |   4   |   2   | -aa0- |
2136  | EC    0236 | LDD         | INDEXED      |   5   |   2   | -aa0- |
2137  | EE    0238 | LDU         | INDEXED      |   5   |   2   | -aa0- |
2138  | F6    0246 | LDB         | EXTENDED     |   5   |   3   | -aa0- |
2139  | FC    0252 | LDD         | EXTENDED     |   6   |   3   | -aa0- |
2140  | FE    0254 | LDU         | EXTENDED     |   6   |   3   | -aa0- |
2141  | 108E  4238 | LDY         | IMMEDIATE    |   4   |   4   | -aa0- |
2142  | 109E  4254 | LDY         | DIRECT       |   6   |   3   | -aa0- |
2143  | 10AE  4270 | LDY         | INDEXED      |   6   |   3   | -aa0- |
2144  | 10BE  4286 | LDY         | EXTENDED     |   7   |   4   | -aa0- |
2145  | 10CE  4302 | LDS         | IMMEDIATE    |   4   |   4   | -aa0- |
2146  | 10DE  4318 | LDS         | DIRECT       |   6   |   3   | -aa0- |
2147  | 10EE  4334 | LDS         | INDEXED      |   6   |   3   | -aa0- |
2148  | 10FE  4350 | LDS         | EXTENDED     |   7   |   4   | -aa0- |
2149 */
2150
2151 // LDA opcodes
2152
2153 #define OP_LDA_HANDLER(m, acc) \
2154         acc = m; \
2155         CLR_V; \
2156         SET_ZN(acc)
2157
2158 #define OP_LDA_HANDLER16(m, acc) \
2159         acc = m; \
2160         CLR_V; \
2161         SET_ZN16(acc)
2162
2163 #define OP_LDA_HANDLER16D(m) \
2164         regs.a = (m >> 8); \
2165         regs.b = m & 0xFF; \
2166         CLR_V; \
2167         SET_ZN16(m)
2168
2169 static void Op86(void)                                                  // LDA #
2170 {
2171         uint8 m = READ_IMM;
2172         OP_LDA_HANDLER(m, regs.a);
2173 }
2174
2175 static void Op8E(void)                                                  // LDX #
2176 {
2177         uint16 m = READ_IMM16;
2178         OP_LDA_HANDLER16(m, regs.x);
2179 }
2180
2181 static void Op96(void)                                                  // LDA DP
2182 {
2183         uint8 m = READ_DP;
2184         OP_LDA_HANDLER(m, regs.a);
2185 }
2186
2187 static void Op9E(void)                                                  // LDX DP
2188 {
2189         uint16 m = READ_DP16;
2190         OP_LDA_HANDLER16(m, regs.x);
2191 }
2192
2193 static void OpA6(void)                                                  // LDA IDX
2194 {
2195         uint8 m = READ_IDX;
2196         OP_LDA_HANDLER(m, regs.a);
2197 }
2198
2199 static void OpAE(void)                                                  // LDX IDX
2200 {
2201         uint16 m = READ_IDX16;
2202         OP_LDA_HANDLER16(m, regs.x);
2203 }
2204
2205 static void OpB6(void)                                                  // LDA ABS
2206 {
2207         uint8 m = READ_ABS;
2208         OP_LDA_HANDLER(m, regs.a);
2209 }
2210
2211 static void OpBE(void)                                                  // LDX ABS
2212 {
2213         uint16 m = READ_ABS16;
2214         OP_LDA_HANDLER16(m, regs.x);
2215 }
2216
2217 static void OpC6(void)                                                  // LDB #
2218 {
2219         uint8 m = READ_IMM;
2220         OP_LDA_HANDLER(m, regs.b);
2221 }
2222
2223 static void OpCC(void)                                                  // LDD #
2224 {
2225         uint16 m = READ_IMM16;
2226         OP_LDA_HANDLER16D(m);
2227 }
2228
2229 static void OpCE(void)                                                  // LDU #
2230 {
2231         uint16 m = READ_IMM16;
2232         OP_LDA_HANDLER16(m, regs.u);
2233 }
2234
2235 static void OpD6(void)                                                  // LDB DP
2236 {
2237         uint8 m = READ_DP;
2238         OP_LDA_HANDLER(m, regs.b);
2239 }
2240
2241 static void OpDC(void)                                                  // LDD DP
2242 {
2243         uint16 m = READ_DP16;
2244         OP_LDA_HANDLER16D(m);
2245 }
2246
2247 static void OpDE(void)                                                  // LDU DP
2248 {
2249         uint16 m = READ_DP16;
2250         OP_LDA_HANDLER16(m, regs.u);
2251 }
2252
2253 static void OpE6(void)                                                  // LDB IDX
2254 {
2255         uint8 m = READ_IDX;
2256         OP_LDA_HANDLER(m, regs.b);
2257 }
2258
2259 static void OpEC(void)                                                  // LDD IDX
2260 {
2261         uint16 m = READ_IDX16;
2262         OP_LDA_HANDLER16D(m);
2263 }
2264
2265 static void OpEE(void)                                                  // LDU IDX
2266 {
2267         uint16 m = READ_IDX16;
2268         OP_LDA_HANDLER16(m, regs.u);
2269 }
2270
2271 static void OpF6(void)                                                  // LDB ABS
2272 {
2273         uint8 m = READ_ABS;
2274         OP_LDA_HANDLER(m, regs.b);
2275 }
2276
2277 static void OpFC(void)                                                  // LDD ABS
2278 {
2279         uint16 m = READ_ABS16;
2280         OP_LDA_HANDLER16D(m);
2281 }
2282
2283 static void OpFE(void)                                                  // LDU ABS
2284 {
2285         uint16 m = READ_ABS16;
2286         OP_LDA_HANDLER16(m, regs.u);
2287 }
2288
2289 static void Op108E(void)                                                // LDY #
2290 {
2291         uint16 m = READ_IMM16;
2292         OP_LDA_HANDLER16(m, regs.y);
2293 }
2294
2295 static void Op109E(void)                                                // LDY DP
2296 {
2297         uint16 m = READ_DP16;
2298         OP_LDA_HANDLER16(m, regs.y);
2299 }
2300
2301 static void Op10AE(void)                                                // LDY IDX
2302 {
2303         uint16 m = READ_IDX16;
2304         OP_LDA_HANDLER16(m, regs.y);
2305 }
2306
2307 static void Op10BE(void)                                                // LDY ABS
2308 {
2309         uint16 m = READ_ABS16;
2310         OP_LDA_HANDLER16(m, regs.y);
2311 }
2312
2313 static void Op10CE(void)                                                // LDS #
2314 {
2315         uint16 m = READ_IMM16;
2316         OP_LDA_HANDLER16(m, regs.s);
2317 }
2318
2319 static void Op10DE(void)                                                // LDS DP
2320 {
2321         uint16 m = READ_DP16;
2322         OP_LDA_HANDLER16(m, regs.s);
2323 }
2324
2325 static void Op10EE(void)                                                // LDS IDX
2326 {
2327         uint16 m = READ_IDX16;
2328         OP_LDA_HANDLER16(m, regs.s);
2329 }
2330
2331 static void Op10FE(void)                                                // LDS ABS
2332 {
2333         uint16 m = READ_ABS16;
2334         OP_LDA_HANDLER16(m, regs.s);
2335 }
2336
2337 /*
2338  +-----------------------------------------------------------------+
2339  | Opcode     |             | Addressing   |               |       |
2340  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2341  +------------+-------------+--------------+-------+-------+-------+
2342  | 30    0048 | LEAX        | INDEXED      |   4   |   2   | --a-- |
2343  | 31    0049 | LEAY        | INDEXED      |   4   |   2   | --a-- |
2344  | 32    0050 | LEAS        | INDEXED      |   4   |   2   | ----- |
2345  | 33    0051 | LEAU        | INDEXED      |   4   |   2   | ----- |
2346 */
2347
2348 static void Op30(void)                                                  // LEAX
2349 {
2350         regs.x = EA_IDX;
2351         SET_Z(regs.x);
2352 }
2353
2354 static void Op31(void)                                                  // LEAY
2355 {
2356         regs.y = EA_IDX;
2357         SET_Z(regs.y);
2358 }
2359
2360 static void Op32(void)                                                  // LEAS
2361 {
2362         regs.s = EA_IDX;
2363 }
2364
2365 static void Op33(void)                                                  // LEAU
2366 {
2367         regs.u = EA_IDX;
2368 }
2369
2370 /*
2371  +-----------------------------------------------------------------+
2372  | Opcode     |             | Addressing   |               |       |
2373  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2374  +------------+-------------+--------------+-------+-------+-------+
2375  | 04    0004 | LSR         | DIRECT       |   6   |   2   | -0a-s |
2376  | 44    0068 | LSRA        | INHERENT     |   2   |   1   | -0a-s |
2377  | 54    0084 | LSRB        | INHERENT     |   2   |   1   | -0a-s |
2378  | 64    0100 | LSR         | INDEXED      |   6   |   2   | -0a-s |
2379  | 74    0116 | LSR         | EXTENDED     |   7   |   3   | -0a-s |
2380 */
2381
2382 // LSR opcodes
2383
2384 #define OP_LSR_HANDLER(m) \
2385         flagC = m & 0x01; \
2386         m >>= 1; \
2387         SET_ZN(m)
2388
2389 static void Op04(void)                                                  // LSR DP
2390 {
2391         uint8 m;
2392         READ_DP_WB(m);
2393         OP_LSR_HANDLER(m);
2394         WRITE_BACK(m);
2395 }
2396
2397 static void Op44(void)                                                  // LSRA
2398 {
2399         OP_LSR_HANDLER(regs.a);
2400 }
2401
2402 static void Op54(void)                                                  // LSRB
2403 {
2404         OP_LSR_HANDLER(regs.b);
2405 }
2406
2407 static void Op64(void)                                                  // LSR IDX
2408 {
2409         uint8 m;
2410         READ_IDX_WB(m);
2411         OP_LSR_HANDLER(m);
2412         WRITE_BACK(m);
2413 }
2414
2415 static void Op74(void)                                                  // LSR ABS
2416 {
2417         uint8 m;
2418         READ_ABS_WB(m);
2419         OP_LSR_HANDLER(m);
2420         WRITE_BACK(m);
2421 }
2422
2423 /*
2424  +-----------------------------------------------------------------+
2425  | Opcode     |             | Addressing   |               |       |
2426  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2427  +------------+-------------+--------------+-------+-------+-------+
2428  | 3D    0061 | MUL         | INHERENT     |  11   |   1   | --a-a |
2429 */
2430
2431 static void Op3D(void)                                                  // MUL
2432 {
2433         uint16 prod = regs.a * regs.b;
2434         regs.a = prod >> 8;
2435         regs.b = prod & 0xFF;
2436         SET_Z(prod);
2437 //      flagC = (prod & 0x0080 ? 1 : 0);
2438         flagC = (prod >> 7) & 0x01;
2439 }
2440
2441 /*
2442  +-----------------------------------------------------------------+
2443  | Opcode     |             | Addressing   |               |       |
2444  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2445  +------------+-------------+--------------+-------+-------+-------+
2446  | 00    0000 | NEG         | DIRECT       |   6   |   2   | uaaaa |
2447  | 40    0064 | NEGA        | INHERENT     |   2   |   1   | uaaaa |
2448  | 50    0080 | NEGB        | INHERENT     |   2   |   1   | uaaaa |
2449  | 60    0096 | NEG         | INDEXED      |   6   |   2   | uaaaa |
2450  | 70    0112 | NEG         | EXTENDED     |   7   |   3   | uaaaa |
2451 */
2452
2453 // NEG opcodes
2454
2455 #define OP_NEG_HANDLER(m) \
2456         uint8 res = -m; \
2457         SET_ZN(res); \
2458         SET_V(0, m, res); \
2459         flagC = (res >= 0x80 ? 1 : 0); \
2460         m = res
2461
2462 /*
2463         UINT16 r,t;
2464         DIRBYTE(t);
2465         r = -t;
2466         CLR_NZVC;
2467         SET_FLAGS8(0,t,r);
2468         WM(EAD,r);
2469 #define SET_FLAGS8(a,b,r)       {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
2470 #define SET_C8(a)               CC|=((a&0x100)>>8)
2471 */
2472 static void Op00(void)                                                  // NEG DP
2473 {
2474         uint8 m;
2475         READ_DP_WB(m);
2476         OP_NEG_HANDLER(m);
2477         WRITE_BACK(m);
2478 }
2479
2480 static void Op40(void)                                                  // NEGA
2481 {
2482         OP_NEG_HANDLER(regs.a);
2483 }
2484
2485 static void Op50(void)                                                  // NEGB
2486 {
2487         OP_NEG_HANDLER(regs.b);
2488 }
2489
2490 static void Op60(void)                                                  // NEG IDX
2491 {
2492         uint8 m;
2493         READ_IDX_WB(m);
2494         OP_NEG_HANDLER(m);
2495         WRITE_BACK(m);
2496 }
2497
2498 static void Op70(void)                                                  // NEG ABS
2499 {
2500         uint8 m;
2501         READ_ABS_WB(m);
2502         OP_NEG_HANDLER(m);
2503         WRITE_BACK(m);
2504 }
2505
2506 /*
2507  +-----------------------------------------------------------------+
2508  | Opcode     |             | Addressing   |               |       |
2509  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2510  +------------+-------------+--------------+-------+-------+-------+
2511  | 8A    0138 | ORA         | IMMEDIATE    |   2   |   2   | -aa0- |
2512  | 9A    0154 | ORA         | DIRECT       |   4   |   2   | -aa0- |
2513  | AA    0170 | ORA         | INDEXED      |   4   |   2   | -aa0- |
2514  | BA    0186 | ORA         | EXTENDED     |   5   |   3   | -aa0- |
2515  | CA    0202 | ORB         | IMMEDIATE    |   2   |   2   | -aa0- |
2516  | DA    0218 | ORB         | DIRECT       |   4   |   2   | -aa0- |
2517  | EA    0234 | ORB         | INDEXED      |   4   |   2   | -aa0- |
2518  | FA    0250 | ORB         | EXTENDED     |   5   |   3   | -aa0- |
2519 */
2520
2521 // ORA opcodes
2522
2523 #define OP_OR_HANDLER(m, acc) \
2524         acc |= (m); \
2525         SET_ZN(acc); \
2526         CLR_V
2527
2528 static void Op8A(void)                                                  // ORA #
2529 {
2530         uint8 m = READ_IMM;
2531         OP_OR_HANDLER(m, regs.a);
2532 }
2533
2534 static void Op9A(void)                                                  // ORA DP
2535 {
2536         uint8 m = READ_DP;
2537         OP_OR_HANDLER(m, regs.a);
2538 }
2539
2540 static void OpAA(void)                                                  // ORA IDX
2541 {
2542         uint8 m = READ_IDX;
2543         OP_OR_HANDLER(m, regs.a);
2544 }
2545
2546 static void OpBA(void)                                                  // ORA ABS
2547 {
2548         uint8 m = READ_ABS;
2549         OP_OR_HANDLER(m, regs.a);
2550 }
2551
2552 static void OpCA(void)                                                  // ORB #
2553 {
2554         uint8 m = READ_IMM;
2555         OP_OR_HANDLER(m, regs.b);
2556 }
2557
2558 static void OpDA(void)                                                  // ORB DP
2559 {
2560         uint8 m = READ_DP;
2561         OP_OR_HANDLER(m, regs.b);
2562 }
2563
2564 static void OpEA(void)                                                  // ORB IDX
2565 {
2566         uint8 m = READ_IDX;
2567         OP_OR_HANDLER(m, regs.b);
2568 }
2569
2570 static void OpFA(void)                                                  // ORB ABS
2571 {
2572         uint8 m = READ_ABS;
2573         OP_OR_HANDLER(m, regs.b);
2574 }
2575
2576 /*
2577  +-----------------------------------------------------------------+
2578  | Opcode     |             | Addressing   |               |       |
2579  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2580  +------------+-------------+--------------+-------+-------+-------+
2581  | 34    0052 | PSHS        | INHERENT     |   5   |   2   | ----- |
2582  | 35    0053 | PULS        | INHERENT     |   5   |   2   | ccccc |
2583  | 36    0054 | PSHU        | INHERENT     |   5   |   2   | ----- |
2584  | 37    0055 | PULU        | INHERENT     |   5   |   2   | ccccc |
2585 */
2586
2587 static void Op34(void)                                                  // PSHS
2588 {
2589         uint8 m = READ_IMM;
2590
2591         if (m & 0x80)
2592                 PUSHS16(regs.pc);
2593         if (m & 0x40)
2594                 PUSHS16(regs.u);
2595         if (m & 0x20)
2596                 PUSHS16(regs.y);
2597         if (m & 0x10)
2598                 PUSHS16(regs.x);
2599         if (m & 0x08)
2600                 PUSHS(regs.dp);
2601         if (m & 0x04)
2602                 PUSHS(regs.b);
2603         if (m & 0x02)
2604                 PUSHS(regs.a);
2605         if (m & 0x01)
2606         {
2607                 regs.cc = PACK_FLAGS;
2608                 PUSHS(regs.cc);
2609         }
2610 }
2611
2612 static void Op35(void)                                                  // PULS
2613 {
2614         uint8 m = READ_IMM;
2615
2616         if (m & 0x01)
2617         {
2618                 PULLS(regs.cc);
2619                 UNPACK_FLAGS;
2620         }
2621         if (m & 0x02)
2622                 PULLS(regs.a);
2623         if (m & 0x04)
2624                 PULLS(regs.b);
2625         if (m & 0x08)
2626                 PULLS(regs.dp);
2627         if (m & 0x10)
2628                 PULLS16(regs.x);
2629         if (m & 0x20)
2630                 PULLS16(regs.y);
2631         if (m & 0x40)
2632                 PULLS16(regs.u);
2633         if (m & 0x80)
2634                 PULLS16(regs.pc);
2635 }
2636
2637 static void Op36(void)                                                  // PHSU
2638 {
2639         uint8 m = READ_IMM;
2640
2641         if (m & 0x80)
2642                 PUSHU16(regs.pc);
2643         if (m & 0x40)
2644                 PUSHU16(regs.s);
2645         if (m & 0x20)
2646                 PUSHU16(regs.y);
2647         if (m & 0x10)
2648                 PUSHU16(regs.x);
2649         if (m & 0x08)
2650                 PUSHU(regs.dp);
2651         if (m & 0x04)
2652                 PUSHU(regs.b);
2653         if (m & 0x02)
2654                 PUSHU(regs.a);
2655         if (m & 0x01)
2656         {
2657                 regs.cc = PACK_FLAGS;
2658                 PUSHU(regs.cc);
2659         }
2660 }
2661
2662 static void Op37(void)                                                  // PULU
2663 {
2664         uint8 m = READ_IMM;
2665
2666         if (m & 0x01)
2667         {
2668                 PULLU(regs.cc);
2669                 UNPACK_FLAGS;
2670         }
2671         if (m & 0x02)
2672                 PULLU(regs.a);
2673         if (m & 0x04)
2674                 PULLU(regs.b);
2675         if (m & 0x08)
2676                 PULLU(regs.dp);
2677         if (m & 0x10)
2678                 PULLU16(regs.x);
2679         if (m & 0x20)
2680                 PULLU16(regs.y);
2681         if (m & 0x40)
2682                 PULLU16(regs.s);
2683         if (m & 0x80)
2684                 PULLU16(regs.pc);
2685 }
2686
2687 /*
2688  +-----------------------------------------------------------------+
2689  | Opcode     |             | Addressing   |               |       |
2690  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2691  +------------+-------------+--------------+-------+-------+-------+
2692  | 09    0009 | ROL         | DIRECT       |   6   |   2   | -aaas |
2693  | 49    0073 | ROLA        | INHERENT     |   2   |   1   | -aaas |
2694  | 59    0089 | ROLB        | INHERENT     |   2   |   1   | -aaas |
2695  | 69    0105 | ROL         | INDEXED      |   6   |   2   | -aaas |
2696  | 79    0121 | ROL         | EXTENDED     |   7   |   3   | -aaas |
2697 */
2698
2699 // ROL opcodes
2700
2701 #define OP_ROL_HANDLER(m) \
2702         uint8 res = (m << 1) | flagC; \
2703         SET_ZN(res); \
2704         SET_V(m, m, res); \
2705         flagC = (m >> 7) & 0x01; \
2706         m = res
2707
2708 /*
2709         UINT16 t,r;
2710         DIRBYTE(t);
2711         r = (CC & CC_C) | (t << 1);
2712         CLR_NZVC;
2713         SET_FLAGS8(t,t,r);
2714         WM(EAD,r);
2715 */
2716 static void Op09(void)                                                  // ROL DP
2717 {
2718         uint8 m;
2719         READ_DP_WB(m);
2720         OP_ROL_HANDLER(m);
2721         WRITE_BACK(m);
2722 }
2723
2724 static void Op49(void)                                                  // ROLA
2725 {
2726         OP_ROL_HANDLER(regs.a);
2727 }
2728
2729 static void Op59(void)                                                  // ROLB
2730 {
2731         OP_ROL_HANDLER(regs.b);
2732 }
2733
2734 static void Op69(void)                                                  // ROL IDX
2735 {
2736         uint8 m;
2737         READ_IDX_WB(m);
2738         OP_ROL_HANDLER(m);
2739         WRITE_BACK(m);
2740 }
2741
2742 static void Op79(void)                                                  // ROL ABS
2743 {
2744         uint8 m;
2745         READ_ABS_WB(m);
2746         OP_ROL_HANDLER(m);
2747         WRITE_BACK(m);
2748 }
2749
2750 /*
2751  +-----------------------------------------------------------------+
2752  | Opcode     |             | Addressing   |               |       |
2753  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2754  +------------+-------------+--------------+-------+-------+-------+
2755  | 06    0006 | ROR         | DIRECT       |   6   |   2   | -aa-s |
2756  | 46    0070 | RORA        | INHERENT     |   2   |   1   | -aa-s |
2757  | 56    0086 | RORB        | INHERENT     |   2   |   1   | -aa-s |
2758  | 66    0102 | ROR         | INDEXED      |   6   |   2   | -aa-s |
2759  | 76    0118 | ROR         | EXTENDED     |   7   |   3   | -aa-s |
2760 */
2761
2762 // ROR opcodes
2763
2764 #define OP_ROR_HANDLER(m) \
2765         uint8 res = (flagC << 7) | (m >> 1); \
2766         SET_ZN(res); \
2767         SET_V(m, m, res); \
2768         flagC = m & 0x01; \
2769         m = res
2770
2771 static void Op06(void)                                                  // ROR DP
2772 {
2773         uint8 m;
2774         READ_DP_WB(m);
2775         OP_ROR_HANDLER(m);
2776         WRITE_BACK(m);
2777 }
2778
2779 static void Op46(void)                                                  // RORA
2780 {
2781         OP_ROR_HANDLER(regs.a);
2782 }
2783
2784 static void Op56(void)                                                  // RORB
2785 {
2786         OP_ROR_HANDLER(regs.b);
2787 }
2788
2789 static void Op66(void)                                                  // ROR IDX
2790 {
2791         uint8 m;
2792         READ_IDX_WB(m);
2793         OP_ROR_HANDLER(m);
2794         WRITE_BACK(m);
2795 }
2796
2797 static void Op76(void)                                                  // ROR ABS
2798 {
2799         uint8 m;
2800         READ_ABS_WB(m);
2801         OP_ROR_HANDLER(m);
2802         WRITE_BACK(m);
2803 }
2804
2805 /*
2806  +-----------------------------------------------------------------+
2807  | Opcode     |             | Addressing   |               |       |
2808  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2809  +------------+-------------+--------------+-------+-------+-------+
2810  | 82    0130 | SBCA        | IMMEDIATE    |   2   |   2   | uaaaa |
2811  | 92    0146 | SBCA        | DIRECT       |   4   |   2   | uaaaa |
2812  | A2    0162 | SBCA        | INDEXED      |   4   |   2   | uaaaa |
2813  | B2    0178 | SBCA        | EXTENDED     |   5   |   3   | uaaaa |
2814  | C2    0194 | SBCB        | IMMEDIATE    |   2   |   2   | uaaaa |
2815  | D2    0210 | SBCB        | DIRECT       |   4   |   2   | uaaaa |
2816  | E2    0226 | SBCB        | INDEXED      |   4   |   2   | uaaaa |
2817  | F2    0242 | SBCB        | EXTENDED     |   5   |   3   | uaaaa |
2818 */
2819
2820 // SBC opcodes
2821
2822 #define OP_SBC_HANDLER(m, acc) \
2823         uint16 sum = (uint16)acc - (m) - (uint16)flagC; \
2824         flagC = (sum >> 8) & 0x01; \
2825         SET_V(m, acc, sum); \
2826         acc = (uint8)sum; \
2827         SET_ZN(acc)
2828
2829 static void Op82(void)                                                  // SBCA #
2830 {
2831         uint8 m = READ_IMM;
2832         OP_SBC_HANDLER(m, regs.a);
2833 }
2834
2835 static void Op92(void)                                                  // SBCA DP
2836 {
2837         uint8 m = READ_DP;
2838         OP_SBC_HANDLER(m, regs.a);
2839 }
2840
2841 static void OpA2(void)                                                  // SBCA IDX
2842 {
2843         uint8 m = READ_IDX;
2844         OP_SBC_HANDLER(m, regs.a);
2845 }
2846
2847 static void OpB2(void)                                                  // SBCA ABS
2848 {
2849         uint8 m = READ_ABS;
2850         OP_SBC_HANDLER(m, regs.a);
2851 }
2852
2853 static void OpC2(void)                                                  // SBCB #
2854 {
2855         uint8 m = READ_IMM;
2856         OP_SBC_HANDLER(m, regs.b);
2857 }
2858
2859 static void OpD2(void)                                                  // SBCB DP
2860 {
2861         uint8 m = READ_DP;
2862         OP_SBC_HANDLER(m, regs.b);
2863 }
2864
2865 static void OpE2(void)                                                  // SBCB IDX
2866 {
2867         uint8 m = READ_IDX;
2868         OP_SBC_HANDLER(m, regs.b);
2869 }
2870
2871 static void OpF2(void)                                                  // SBCB ABS
2872 {
2873         uint8 m = READ_ABS;
2874         OP_SBC_HANDLER(m, regs.b);
2875 }
2876
2877 /*
2878  +-----------------------------------------------------------------+
2879  | Opcode     |             | Addressing   |               |       |
2880  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2881  +------------+-------------+--------------+-------+-------+-------+
2882  | 97    0151 | STA         | DIRECT       |   4   |   2   | -aa0- |
2883  | 9F    0159 | STX         | DIRECT       |   5   |   2   | -aa0- |
2884  | A7    0167 | STA         | INDEXED      |   4   |   2   | -aa0- |
2885  | AF    0175 | STX         | INDEXED      |   5   |   2   | -aa0- |
2886  | B7    0183 | STA         | EXTENDED     |   5   |   3   | -aa0- |
2887  | BF    0191 | STX         | EXTENDED     |   6   |   3   | -aa0- |
2888  | D7    0215 | STB         | DIRECT       |   4   |   2   | -aa0- |
2889  | DD    0221 | STD         | DIRECT       |   5   |   2   | -aa0- |
2890  | DF    0223 | STU         | DIRECT       |   5   |   2   | -aa0- |
2891  | E7    0231 | STB         | INDEXED      |   4   |   2   | -aa0- |
2892  | ED    0237 | STD         | INDEXED      |   5   |   2   | -aa0- |
2893  | EF    0239 | STU         | INDEXED      |   5   |   2   | -aa0- |
2894  | F7    0247 | STB         | EXTENDED     |   5   |   3   | -aa0- |
2895  | FD    0253 | STD         | EXTENDED     |   6   |   3   | -aa0- |
2896  | FF    0255 | STU         | EXTENDED     |   6   |   3   | -aa0- |
2897  | 109F  4255 | STY         | DIRECT       |   6   |   3   | -aa0- |
2898  | 10AF  4271 | STY         | INDEXED      |   6   |   3   | -aa0- |
2899  | 10BF  4287 | STY         | EXTENDED     |   7   |   4   | -aa0- |
2900  | 10DF  4319 | STS         | DIRECT       |   6   |   3   | -aa0- |
2901  | 10EF  4335 | STS         | INDEXED      |   6   |   3   | -aa0- |
2902  | 10FF  4351 | STS         | EXTENDED     |   7   |   4   | -aa0- |
2903 */
2904
2905 // STA opcodes
2906
2907 #define OP_STA_HANDLER(m, acc) \
2908         regs.WrMem(m, acc); \
2909         CLR_V; \
2910         SET_ZN(acc)
2911
2912 #define OP_STA_HANDLER16(m, acc) \
2913         WrMemW(m, acc); \
2914         CLR_V; \
2915         SET_ZN16(acc)
2916
2917 static void Op97(void)                                                  // STA DP
2918 {
2919         uint16 addr = EA_DP;
2920         OP_STA_HANDLER(addr, regs.a);
2921 }
2922
2923 static void Op9F(void)                                                  // STX DP
2924 {
2925         uint16 addr = EA_DP;
2926         OP_STA_HANDLER16(addr, regs.x);
2927 }
2928
2929 static void OpA7(void)                                                  // STA IDX
2930 {
2931         uint16 addr = EA_IDX;
2932         OP_STA_HANDLER(addr, regs.a);
2933 }
2934
2935 static void OpAF(void)                                                  // STX IDX
2936 {
2937         uint16 addr = EA_IDX;
2938         OP_STA_HANDLER16(addr, regs.x);
2939 }
2940
2941 static void OpB7(void)                                                  // STA ABS
2942 {
2943         uint16 addr = EA_ABS;
2944         OP_STA_HANDLER(addr, regs.a);
2945 }
2946
2947 static void OpBF(void)                                                  // STX ABS
2948 {
2949         uint16 addr = EA_ABS;
2950         OP_STA_HANDLER16(addr, regs.x);
2951 }
2952
2953 static void OpD7(void)                                                  // STB DP
2954 {
2955         uint16 addr = EA_DP;
2956         OP_STA_HANDLER(addr, regs.b);
2957 }
2958
2959 static void OpDD(void)                                                  // STD DP
2960 {
2961         uint16 addr = EA_DP;
2962         OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2963 }
2964
2965 static void OpDF(void)                                                  // STU DP
2966 {
2967         uint16 addr = EA_DP;
2968         OP_STA_HANDLER16(addr, regs.u);
2969 }
2970
2971 static void OpE7(void)                                                  // STB IDX
2972 {
2973         uint16 addr = EA_IDX;
2974         OP_STA_HANDLER(addr, regs.b);
2975 }
2976
2977 static void OpED(void)                                                  // STD IDX
2978 {
2979         uint16 addr = EA_IDX;
2980         OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2981 }
2982
2983 static void OpEF(void)                                                  // STU IDX
2984 {
2985         uint16 addr = EA_IDX;
2986         OP_STA_HANDLER16(addr, regs.u);
2987 }
2988
2989 static void OpF7(void)                                                  // STB ABS
2990 {
2991         uint16 addr = EA_ABS;
2992         OP_STA_HANDLER(addr, regs.b);
2993 }
2994
2995 static void OpFD(void)                                                  // STD ABS
2996 {
2997         uint16 addr = EA_ABS;
2998         OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2999 }
3000
3001 static void OpFF(void)                                                  // STU ABS
3002 {
3003         uint16 addr = EA_ABS;
3004         OP_STA_HANDLER16(addr, regs.u);
3005 }
3006
3007 static void Op109F(void)                                                // STY DP
3008 {
3009         uint16 addr = EA_DP;
3010         OP_STA_HANDLER16(addr, regs.y);
3011 }
3012
3013 static void Op10AF(void)                                                // STY IDX
3014 {
3015         uint16 addr = EA_IDX;
3016         OP_STA_HANDLER16(addr, regs.y);
3017 }
3018
3019 static void Op10BF(void)                                                // STY ABS
3020 {
3021         uint16 addr = EA_ABS;
3022         OP_STA_HANDLER16(addr, regs.y);
3023 }
3024
3025 static void Op10DF(void)                                                // STS DP
3026 {
3027         uint16 addr = EA_DP;
3028         OP_STA_HANDLER16(addr, regs.s);
3029 }
3030
3031 static void Op10EF(void)                                                // STS IDX
3032 {
3033         uint16 addr = EA_IDX;
3034         OP_STA_HANDLER16(addr, regs.s);
3035 }
3036
3037 static void Op10FF(void)                                                // STS ABS
3038 {
3039         uint16 addr = EA_ABS;
3040         OP_STA_HANDLER16(addr, regs.s);
3041 }
3042
3043 /*
3044  +-----------------------------------------------------------------+
3045  | Opcode     |             | Addressing   |               |       |
3046  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
3047  +------------+-------------+--------------+-------+-------+-------+
3048  | 80    0128 | SUBA        | IMMEDIATE    |   2   |   2   | uaaaa |
3049  | 83    0131 | SUBD        | IMMEDIATE    |   4   |   3   | -aaaa |
3050  | 90    0144 | SUBA        | DIRECT       |   4   |   2   | uaaaa |
3051  | 93    0147 | SUBD        | DIRECT       |   6   |   2   | -aaaa |
3052  | A0    0160 | SUBA        | INDEXED      |   4   |   2   | uaaaa |
3053  | A3    0163 | SUBD        | INDEXED      |   6   |   2   | -aaaa |
3054  | B0    0176 | SUBA        | EXTENDED     |   5   |   3   | uaaaa |
3055  | B3    0179 | SUBD        | EXTENDED     |   7   |   3   | -aaaa |
3056  | C0    0192 | SUBB        | IMMEDIATE    |   2   |   2   | uaaaa |
3057  | D0    0208 | SUBB        | DIRECT       |   4   |   2   | uaaaa |
3058  | E0    0224 | SUBB        | INDEXED      |   4   |   2   | uaaaa |
3059  | F0    0240 | SUBB        | EXTENDED     |   5   |   3   | uaaaa |
3060 */
3061
3062 // SUB opcodes
3063
3064 #define OP_SUB_HANDLER(m, acc) \
3065         uint16 sum = (uint16)acc - (m); \
3066         flagC = (sum >> 8) & 0x01; \
3067         SET_V(m, acc, sum); \
3068         acc = (uint8)sum; \
3069         SET_ZN(acc)
3070
3071 #define OP_SUB_HANDLER16D(m) \
3072         uint32 acc = (uint32)((regs.a << 8) | regs.b); \
3073         uint32 sum = acc - (m); \
3074         flagC = (sum >> 16) & 0x01; \
3075         SET_V16(m, acc, sum); \
3076         acc = sum & 0xFFFF; \
3077         regs.a = (acc >> 8) & 0xFF; \
3078         regs.b = acc & 0xFF; \
3079         SET_ZN16(acc)
3080
3081 static void Op80(void)                                                  // SUBA #
3082 {
3083         uint8 m = READ_IMM;
3084         OP_SUB_HANDLER(m, regs.a);
3085 }
3086
3087 static void Op83(void)                                                  // SUBD #
3088 {
3089         uint16 m = READ_IMM16;
3090         OP_SUB_HANDLER16D(m);
3091 }
3092
3093 static void Op90(void)                                                  // SUBA DP
3094 {
3095         uint8 m = READ_DP;
3096         OP_SUB_HANDLER(m, regs.a);
3097 }
3098
3099 static void Op93(void)                                                  // SUBD DP
3100 {
3101         uint16 m = READ_DP16;
3102         OP_SUB_HANDLER16D(m);
3103 }
3104
3105 static void OpA0(void)                                                  // SUBA IDX
3106 {
3107         uint8 m = READ_IDX;
3108         OP_SUB_HANDLER(m, regs.a);
3109 }
3110
3111 static void OpA3(void)                                                  // SUBD IDX
3112 {
3113         uint16 m = READ_IDX16;
3114         OP_SUB_HANDLER16D(m);
3115 }
3116
3117 static void OpB0(void)                                                  // SUBA ABS
3118 {
3119         uint8 m = READ_ABS;
3120         OP_SUB_HANDLER(m, regs.a);
3121 }
3122
3123 static void OpB3(void)                                                  // SUBD ABS
3124 {
3125         uint16 m = READ_ABS16;
3126         OP_SUB_HANDLER16D(m);
3127 }
3128
3129 static void OpC0(void)                                                  // SUBB #
3130 {
3131         uint8 m = READ_IMM;
3132         OP_SUB_HANDLER(m, regs.b);
3133 }
3134
3135 static void OpD0(void)                                                  // SUBB DP
3136 {
3137         uint8 m = READ_DP;
3138         OP_SUB_HANDLER(m, regs.b);
3139 }
3140
3141 static void OpE0(void)                                                  // SUBB IDX
3142 {
3143         uint8 m = READ_IDX;
3144         OP_SUB_HANDLER(m, regs.b);
3145 }
3146
3147 static void OpF0(void)                                                  // SUBB ABS
3148 {
3149         uint8 m = READ_ABS;
3150         OP_SUB_HANDLER(m, regs.b);
3151 }
3152
3153 /*
3154  +-----------------------------------------------------------------+
3155  | Opcode     |             | Addressing   |               |       |
3156  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
3157  +------------+-------------+--------------+-------+-------+-------+
3158  | 0D    0013 | TST         | DIRECT       |   6   |   2   | -aa0- |
3159  | 4D    0077 | TSTA        | INHERENT     |   2   |   1   | -aa0- |
3160  | 5D    0093 | TSTB        | INHERENT     |   2   |   1   | -aa0- |
3161  | 6D    0109 | TST         | INDEXED      |   6   |   2   | -aa0- |
3162  | 7D    0125 | TST         | EXTENDED     |   7   |   3   | -aa0- |
3163 */
3164
3165 // TST opcodes
3166
3167 #define OP_TST_HANDLER(m) \
3168         SET_ZN(m); \
3169         CLR_V
3170
3171 static void Op0D(void)                                                  // TST DP
3172 {
3173         uint8 m = READ_DP;
3174         OP_TST_HANDLER(m);
3175 }
3176
3177 static void Op4D(void)                                                  // TSTA
3178 {
3179         OP_TST_HANDLER(regs.a);
3180 }
3181
3182 static void Op5D(void)                                                  // TSTB
3183 {
3184         OP_TST_HANDLER(regs.b);
3185 }
3186
3187 static void Op6D(void)                                                  // TST IDX
3188 {
3189         uint8 m = READ_IDX;
3190         OP_TST_HANDLER(m);
3191 }
3192
3193 static void Op7D(void)                                                  // TST ABS
3194 {
3195         uint8 m = READ_ABS;
3196         OP_TST_HANDLER(m);
3197 }
3198
3199 // Undocumented Opcodes
3200
3201 static void Op01(void)
3202 {
3203         Op00();                                                                         // NEG DP
3204 }
3205
3206 #else
3207
3208 //
3209 // Page zero instructions...
3210 //
3211
3212 static void Op00(void)                                                                  // NEG DP
3213 {
3214         addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
3215         tmp = 256 - regs.RdMem(addr);
3216         regs.WrMem(addr, tmp);
3217
3218         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD);      // oVerflow
3219         (tmp == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);      // Adjust Zero flag
3220         (tmp & 0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);      // Adjust Negative flag
3221         (tmp > 0x7F  ? regs.cc |= 0x01 : regs.cc &= 0xFE);      // Adjust carry
3222
3223         regs.clock += 6;
3224 }
3225
3226 static void Op01(void)                                                                  // NEG DP (Undocumented)
3227 {
3228         Op00();
3229 }
3230
3231 static void Op03(void)                                                                  // COM DP
3232 {
3233         addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
3234         tmp = 0xFF ^ regs.RdMem(addr);
3235         regs.WrMem(addr, tmp);
3236
3237         regs.cc &= 0xFD;  regs.cc |= 0x01;                                      // CLV SEC
3238         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);         // Adjust Zero flag
3239         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);         // Adjust Negative flag
3240
3241         regs.clock += 6;
3242 }
3243
3244 static void Op04(void)  // LSR DP
3245 {
3246   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
3247   tmp = regs.RdMem(addr);
3248   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
3249   tmp >>= 1;  regs.WrMem(addr, tmp);
3250   regs.cc &= 0xF7;                             // CLN
3251   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3252   regs.clock += 6;
3253 }
3254 static void Op06(void)  // ROR DP
3255 {
3256   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  uint8 tmp2 = regs.RdMem(addr);
3257   tmp = (tmp2>>1) + (regs.cc&0x01)*128;
3258   regs.WrMem(addr, tmp);
3259   (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3260   (tmp == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3261   (tmp&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3262   regs.clock += 6;
3263 }
3264 static void Op07(void)  // ASR DP
3265 {
3266   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  tmp = regs.RdMem(addr);
3267   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
3268   tmp >>= 1;
3269   if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
3270   regs.WrMem(addr, tmp);
3271   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3272   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3273   regs.clock += 6;
3274 }
3275 static void Op08(void)  // LSL DP
3276 {
3277   addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
3278   tmp = regs.RdMem(addr);
3279   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
3280   tmp <<= 1;
3281   regs.WrMem(addr, tmp);
3282   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3283   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3284   regs.clock += 6;
3285 }
3286 static void Op09(void)  // ROL DP
3287 {
3288   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);  uint8 tmp2 = regs.RdMem(addr);
3289   tmp = (tmp2<<1) + (regs.cc&0x01);
3290   regs.WrMem(addr, tmp);
3291   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3292   ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3293   (tmp == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3294   (tmp&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3295   regs.clock += 6;
3296 }
3297 static void Op0A(void)  // DEC DP
3298 {
3299   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
3300   tmp = regs.RdMem(addr) - 1;
3301   regs.WrMem(addr, tmp);
3302   (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3303   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3304   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3305   regs.clock += 6;
3306 }
3307 static void Op0C(void)  // INC DP
3308 {
3309   addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
3310   tmp = regs.RdMem(addr) + 1;
3311   regs.WrMem(addr, tmp);
3312   (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3313   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3314   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3315   regs.clock += 6;
3316 }
3317 static void Op0D(void)  // TST DP
3318 {
3319   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
3320   regs.cc &= 0xFD;                              // CLV
3321   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
3322   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
3323   regs.clock += 6;
3324 }
3325 static void Op0E(void)  // JMP DP
3326 {
3327   regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
3328   regs.clock += 3;
3329 }
3330 static void Op0F(void)  // CLR DP
3331 {
3332   regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
3333   regs.cc &= 0xF0;  regs.cc |= 0x04;                // CLN, SEZ, CLV, CLC
3334   regs.clock += 6;
3335 }
3336
3337 static void Op12(void)                                                  // NOP
3338 {
3339         regs.clock += 2;
3340 }
3341
3342 static void Op13(void)                                                  // SYNC
3343 {
3344         // Fix this so it does the right thing (software interrupt!)
3345         regs.clock += 2;
3346 }
3347
3348 static void Op16(void)                                                  // LBRA
3349 {
3350 //      regs.pc += SignedW(FetchW());
3351         regs.pc += FetchW();                                            // No need to make signed, both are 16 bit quantities
3352
3353         regs.clock += 5;
3354 }
3355
3356 static void Op17(void)                                                  // LBSR
3357 {
3358         uint16 word = FetchW();
3359         regs.WrMem(--regs.s, regs.pc & 0xFF);
3360         regs.WrMem(--regs.s, regs.pc >> 8);
3361 //      regs.pc += SignedW(addr);
3362         regs.pc += word;                                                        // No need to make signed, both are 16 bit
3363
3364         regs.clock += 9;
3365 }
3366
3367 static void Op19(void)  // DAA
3368 {
3369 #if 0
3370         uint8 result = regs.a;
3371
3372         if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09))    // H set or lo nyb too big?
3373         {
3374 //              regs.a += 0x06;
3375                 result += 0x06;
3376                 regs.cc |= 0x20;              // Then adjust & set half carry
3377         }
3378
3379         if ((regs.cc&0x01) || (regs.a > 0x9F))           // C set or hi nyb too big?
3380         {
3381 //              regs.a += 0x60;
3382                 result += 0x60;
3383                 regs.cc |= 0x01;              // Then adjust & set carry
3384         }
3385
3386         regs.a = result;
3387
3388         regs.cc &= 0xF1;                             // CL NZV
3389         if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
3390         if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
3391 #else
3392         uint16 result = (uint16)regs.a;
3393
3394         if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
3395                 result += 0x06;
3396
3397         if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
3398                 result += 0x60;
3399
3400         regs.a = (uint8)result;
3401 //      SET_ZN(result);
3402 //      CLR_V;                                                                          // Not sure this is correct...
3403         regs.cc &= 0xF1;                             // CL NZV
3404         if (regs.a == 0)  regs.cc |= 0x04;               // Adjust Zero flag
3405         if (regs.a&0x80)  regs.cc |= 0x08;               // Adjust Negative flag
3406 //      flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
3407         regs.cc |= (result & 0x100) > 8;
3408 #endif
3409         regs.clock += 2;
3410 }
3411
3412 static void Op1A(void)                                                                  // ORCC #
3413 {
3414         regs.cc |= regs.RdMem(regs.pc++);
3415
3416         regs.clock += 3;
3417 }
3418
3419 static void Op1C(void)                                                                  // ANDCC #
3420 {
3421         regs.cc &= regs.RdMem(regs.pc++);
3422
3423         regs.clock += 3;
3424 }
3425
3426 static void Op1D(void)                                                  // SEX
3427 {
3428         (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
3429
3430         ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
3431         (regs.a & 0x80          ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
3432
3433         regs.clock += 2;
3434 }
3435
3436 static void Op1E(void)                                                  // EXG
3437 {
3438         tmp = regs.RdMem(regs.pc++);
3439         addr = ReadEXG(tmp >> 4);
3440         WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
3441         WriteEXG(tmp & 0xF, addr);
3442
3443         regs.clock += 8;
3444 }
3445
3446 static void Op1F(void)  // TFR
3447 {
3448   tmp = regs.RdMem(regs.pc++);
3449   WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
3450   regs.clock += 7;
3451 }
3452
3453 static void Op20(void)                                                  // BRA
3454 {
3455 //      regs.pc += SignedB(regs.RdMem(regs.pc++));  // Branch always
3456         regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1;        // Branch always
3457
3458         regs.clock += 3;
3459 }
3460
3461 static void Op21(void)                                                  // BRN
3462 {
3463         regs.RdMem(regs.pc++);
3464
3465         regs.clock += 3;
3466 }
3467
3468 static void Op22(void)                                                  // BHI
3469 {
3470         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3471
3472         if (!(regs.cc & 0x05))
3473                 regs.pc += word;
3474
3475         regs.clock += 3;
3476 }
3477
3478 static void Op23(void)                                                  // BLS
3479 {
3480         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3481
3482         if (regs.cc & 0x05)
3483                 regs.pc += word;
3484
3485         regs.clock += 3;
3486 }
3487
3488 static void Op24(void)                                                  // BCC (BHS)
3489 {
3490         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3491
3492         if (!(regs.cc & 0x01))
3493                 regs.pc += word;
3494
3495         regs.clock += 3;
3496 }
3497
3498 static void Op25(void)                                                  // BCS (BLO)
3499 {
3500         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3501
3502         if (regs.cc & 0x01)
3503                 regs.pc += word;
3504
3505         regs.clock += 3;
3506 }
3507
3508 static void Op26(void)                                                  // BNE
3509 {
3510         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3511
3512         if (!(regs.cc & 0x04))
3513                 regs.pc += word;
3514
3515         regs.clock += 3;
3516 }
3517
3518 static void Op27(void)                                                  // BEQ
3519 {
3520         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3521
3522         if (regs.cc & 0x04)
3523                 regs.pc += word;
3524
3525         regs.clock += 3;
3526 }
3527
3528 static void Op28(void)                                                  // BVC
3529 {
3530         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3531
3532         if (!(regs.cc & 0x02))
3533                 regs.pc += word;
3534
3535         regs.clock += 3;
3536 }
3537
3538 static void Op29(void)                                                  // BVS
3539 {
3540         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3541
3542         if (regs.cc & 0x02)
3543                 regs.pc += word;
3544
3545         regs.clock += 3;
3546 }
3547
3548 static void Op2A(void)                                                  // BPL
3549 {
3550         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3551
3552         if (!(regs.cc & 0x08))
3553                 regs.pc += word;
3554
3555         regs.clock += 3;
3556 }
3557
3558 static void Op2B(void)                                                  // BMI
3559 {
3560         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3561
3562         if (regs.cc & 0x08)
3563                 regs.pc += word;
3564
3565         regs.clock += 3;
3566 }
3567
3568 static void Op2C(void)                                                  // BGE
3569 {
3570         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3571
3572         if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
3573                 regs.pc += word;
3574
3575         regs.clock += 3;
3576 }
3577
3578 static void Op2D(void)                                                  // BLT
3579 {
3580         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3581
3582         if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
3583                 regs.pc += word;
3584
3585         regs.clock += 3;
3586 }
3587
3588 static void Op2E(void)                                                  // BGT
3589 {
3590         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3591
3592         if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
3593                 regs.pc += word;
3594
3595         regs.clock += 3;
3596 }
3597
3598 static void Op2F(void)                                                  // BLE
3599 {
3600         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3601
3602         if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
3603                 regs.pc += word;
3604
3605         regs.clock += 3;
3606 }
3607
3608 static void Op30(void)  // LEAX
3609 {
3610   regs.x = DecodeIDX(regs.RdMem(regs.pc++));
3611   (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3612   regs.clock += 4;
3613 }
3614 static void Op31(void)  // LEAY
3615 {
3616   regs.y = DecodeIDX(regs.RdMem(regs.pc++));
3617   (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3618   regs.clock += 4;
3619 }
3620 static void Op32(void)  // LEAS
3621 {
3622   regs.s = DecodeIDX(regs.RdMem(regs.pc++));
3623   (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3624   regs.clock += 4;
3625 }
3626 static void Op33(void)  // LEAU
3627 {
3628   regs.u = DecodeIDX(regs.RdMem(regs.pc++));
3629   (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3630   regs.clock += 4;
3631 }
3632 static void Op34(void)  // PSHS
3633 {
3634   tmp = regs.RdMem(regs.pc++);
3635   if (tmp&0x80)  { regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8); }
3636   if (tmp&0x40)  { regs.WrMem(--regs.s, regs.u&0xFF);  regs.WrMem(--regs.s, regs.u>>8); }
3637   if (tmp&0x20)  { regs.WrMem(--regs.s, regs.y&0xFF);  regs.WrMem(--regs.s, regs.y>>8); }
3638   if (tmp&0x10)  { regs.WrMem(--regs.s, regs.x&0xFF);  regs.WrMem(--regs.s, regs.x>>8); }
3639   if (tmp&0x08)  regs.WrMem(--regs.s, regs.dp);
3640   if (tmp&0x04)  regs.WrMem(--regs.s, regs.b);
3641   if (tmp&0x02)  regs.WrMem(--regs.s, regs.a);
3642   if (tmp&0x01)  regs.WrMem(--regs.s, regs.cc);
3643   regs.clock += 5;
3644 }
3645 static void Op35(void)  // PULS
3646 {
3647   tmp = regs.RdMem(regs.pc++);
3648   if (tmp&0x01)  regs.cc = regs.RdMem(regs.s++);
3649   if (tmp&0x02)  regs.a  = regs.RdMem(regs.s++);
3650   if (tmp&0x04)  regs.b  = regs.RdMem(regs.s++);
3651   if (tmp&0x08)  regs.dp = regs.RdMem(regs.s++);
3652   if (tmp&0x10)  regs.x  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3653   if (tmp&0x20)  regs.y  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3654   if (tmp&0x40)  regs.u  = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3655   if (tmp&0x80)  regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3656   regs.clock += 5;
3657 }
3658
3659 static void Op36(void)  // PSHU
3660 {
3661         tmp = regs.RdMem(regs.pc++);
3662
3663         if (tmp & 0x80)  { regs.WrMem(--regs.u, regs.pc & 0xFF);  regs.WrMem(--regs.u, regs.pc >> 8); }
3664         if (tmp & 0x40)  { regs.WrMem(--regs.u, regs.s & 0xFF);  regs.WrMem(--regs.u, regs.s >> 8); }
3665         if (tmp & 0x20)  { regs.WrMem(--regs.u, regs.y & 0xFF);  regs.WrMem(--regs.u, regs.y >> 8); }
3666         if (tmp & 0x10)  { regs.WrMem(--regs.u, regs.x & 0xFF);  regs.WrMem(--regs.u, regs.x >> 8); }
3667         if (tmp & 0x08)  regs.WrMem(--regs.u, regs.dp);
3668         if (tmp & 0x04)  regs.WrMem(--regs.u, regs.b);
3669         if (tmp & 0x02)  regs.WrMem(--regs.u, regs.a);
3670         if (tmp & 0x01)  regs.WrMem(--regs.u, regs.cc);
3671
3672   regs.clock += 5;
3673 }
3674
3675 static void Op37(void)  // PULU
3676 {
3677   tmp = regs.RdMem(regs.pc++);
3678   if (tmp&0x01)  regs.cc = regs.RdMem(regs.u++);
3679   if (tmp&0x02)  regs.a  = regs.RdMem(regs.u++);
3680   if (tmp&0x04)  regs.b  = regs.RdMem(regs.u++);
3681   if (tmp&0x08)  regs.dp = regs.RdMem(regs.u++);
3682   if (tmp&0x10)  regs.x  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3683   if (tmp&0x20)  regs.y  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3684   if (tmp&0x40)  regs.s  = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3685   if (tmp&0x80)  regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3686   regs.clock += 5;
3687 }
3688 static void Op39(void)  // RTS
3689 {
3690   regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3691   regs.clock += 5;
3692 }
3693 static void Op3B(void)  // RTI
3694 {
3695   regs.cc = regs.RdMem(regs.s++);
3696   if (regs.cc&0x80)      // If E flag set, pull all regs
3697   {
3698     regs.a = regs.RdMem(regs.s++);  regs.b = regs.RdMem(regs.s++);  regs.dp = regs.RdMem(regs.s++);
3699     regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3700     regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3701     regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3702     regs.clock += 15;
3703   }
3704   else
3705   {
3706     regs.clock += 6;
3707   }
3708   regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3709 }
3710 static void Op3C(void)  // CWAI
3711 {
3712   regs.cc &= regs.RdMem(regs.pc++);  regs.cc |= 0x80;
3713   regs.clock += 1000000;             // Force interrupt
3714 }
3715 static void Op3D(void)  // MUL
3716 {
3717   addr = regs.a * regs.b;  regs.a = addr>>8;  regs.b = addr&0xFF;
3718   (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
3719   (regs.b&0x80   ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
3720   regs.clock += 11;
3721 }
3722 static void Op3E(void)  // RESET
3723 {
3724 }
3725 static void Op3F(void)  // SWI
3726 {
3727 }
3728 static void Op40(void)  // NEGA
3729 {
3730   regs.a = 256 - regs.a;
3731   (regs.a > 0x7F  ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3732   (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3733   (regs.a == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3734   (regs.a&0x80    ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3735   regs.clock += 2;
3736 }
3737 static void Op43(void)  // COMA
3738 {
3739   regs.a ^= 0xFF;
3740   regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
3741   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3742   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3743   regs.clock += 2;
3744 }
3745 static void Op44(void)  // LSRA
3746 {
3747   (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
3748   regs.a >>= 1;
3749   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3750   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3751   regs.clock += 2;
3752 }
3753 static void Op46(void)  // RORA
3754 {
3755   tmp = regs.a;  regs.a = (tmp>>1) + (regs.cc&0x01)*128;
3756   (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3757   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3758   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3759   regs.clock += 2;
3760 }
3761 static void Op47(void)  // ASRA
3762 {
3763   (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
3764   regs.a >>= 1;                               // Do the shift
3765   if (regs.a&0x40)  regs.a |= 0x80;               // Set neg if it was set
3766   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3767   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3768   regs.clock += 2;
3769 }
3770 static void Op48(void)  // LSLA  [Keep checking from here...]
3771 {
3772   (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
3773   regs.a <<= 1;
3774   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3775   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3776   regs.clock += 2;
3777 }
3778 static void Op49(void)  // ROLA
3779 {
3780   tmp = regs.a;  regs.a = (tmp<<1) + (regs.cc&0x01);
3781   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3782   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3783   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3784   regs.clock += 2;
3785 }
3786 static void Op4A(void)  // DECA
3787 {
3788   regs.a--;
3789   (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3790   (regs.a == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3791   (regs.a&0x80    ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3792   regs.clock += 2;
3793 }
3794 static void Op4C(void)  // INCA
3795       {
3796         regs.a++;
3797         (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3798         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3799         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3800         regs.clock += 2;
3801       }
3802 static void Op4D(void)  // TSTA
3803       {
3804         regs.cc &= 0xFD;                            // Clear oVerflow flag
3805         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3806         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3807         regs.clock += 2;
3808       }
3809 static void Op4F(void)  // CLRA
3810 {
3811   regs.a = 0;
3812   regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
3813   regs.clock += 2;
3814 }
3815 static void Op50(void)  // NEGB
3816       {
3817         regs.b = 256 - regs.b;
3818 //        ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
3819         (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3820         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
3821         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
3822         (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3823         regs.clock += 2;
3824       }
3825 static void Op53(void)  // COMB
3826       {
3827         regs.b ^= 0xFF;
3828         regs.cc &= 0xFD;  regs.cc |= 0x01;              // CLV, SEC
3829         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3830         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3831         regs.clock += 2;
3832       }
3833 static void Op54(void)  // LSRB
3834       {
3835         (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
3836         regs.b >>= 1;
3837         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3838         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3839         regs.clock += 2;
3840       }
3841 static void Op56(void)  // RORB
3842       {
3843         tmp = regs.b;  regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
3844         (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE);  // Shift bit into carry
3845         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3846         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3847         regs.clock += 2;
3848       }
3849 static void Op57(void)  // ASRB
3850       {
3851         (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
3852         regs.b >>= 1;                               // Do the shift
3853         if (regs.b&0x40)  regs.b |= 0x80;               // Set neg if it was set
3854         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3855         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3856         regs.clock += 2;
3857       }
3858 static void Op58(void)  // LSLB
3859       {
3860         (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
3861         regs.b <<= 1;
3862         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3863         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3864         regs.clock += 2;
3865       }
3866 static void Op59(void)  // ROLB
3867 {
3868   tmp = regs.b;
3869   regs.b = (tmp<<1) + (regs.cc&0x01);
3870   (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3871   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3872   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3873   regs.clock += 2;
3874 }
3875 static void Op5A(void)  // DECB
3876       {
3877         regs.b--;
3878         (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3879         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3880         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3881         regs.clock += 2;
3882       }
3883 static void Op5C(void)  // INCB
3884       {
3885         regs.b++;
3886         (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3887         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3888         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3889         regs.clock += 2;
3890       }
3891 static void Op5D(void)  // TSTB
3892       {
3893         regs.cc &= 0xFD;                            // Clear oVerflow flag
3894         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3895         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3896         regs.clock += 2;
3897       }
3898 static void Op5F(void)  // CLRB
3899       {
3900         regs.b = 0;
3901         regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
3902         regs.clock += 2;
3903       }
3904 static void Op60(void)  // NEG IDX
3905       {
3906         addr = DecodeIDX(regs.RdMem(regs.pc++));
3907         tmp = regs.RdMem(addr);  uint8 res = 256 - tmp;
3908         regs.WrMem(addr, res);
3909 //        ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
3910         (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3911         (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
3912         (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
3913         (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3914         regs.clock += 6;
3915       }
3916 static void Op63(void)  // COM IDX
3917       {
3918         addr = DecodeIDX(regs.RdMem(regs.pc++));
3919         tmp = regs.RdMem(addr) ^ 0xFF;
3920         regs.WrMem(addr, tmp);
3921         regs.cc &= 0xFD;  regs.cc |= 0x01;               // CLV, SEC
3922         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3923         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3924         regs.clock += 6;
3925       }
3926 static void Op64(void)  // LSR IDX
3927       {
3928         addr = DecodeIDX(regs.RdMem(regs.pc++));
3929         tmp = regs.RdMem(addr);
3930         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
3931         tmp >>= 1;  regs.WrMem(addr, tmp);
3932         regs.cc &= 0xF7;                             // CLN
3933         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3934         regs.clock += 6;
3935       }
3936 static void Op66(void)  // ROR IDX
3937       {
3938         addr = DecodeIDX(regs.RdMem(regs.pc++));
3939         tmp = regs.RdMem(addr);  uint8 tmp2 = tmp;
3940         tmp = (tmp >> 1) + (regs.cc&0x01)*128;
3941         regs.WrMem(addr, tmp);
3942         (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3943         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3944         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3945         regs.clock += 6;
3946       }
3947 static void Op67(void)  // ASR IDX
3948       {
3949         addr = DecodeIDX(regs.RdMem(regs.pc++));
3950         tmp = regs.RdMem(addr);
3951         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
3952         tmp >>= 1;
3953         if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
3954         regs.WrMem(addr, tmp);
3955         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3956         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3957         regs.clock += 6;
3958       }
3959 static void Op68(void)  // LSL IDX
3960       {
3961         addr = DecodeIDX(regs.RdMem(regs.pc++));
3962         tmp = regs.RdMem(addr);
3963         (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
3964         tmp <<= 1;
3965         regs.WrMem(addr, tmp);
3966         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3967         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3968         regs.clock += 6;
3969       }
3970 static void Op69(void)  // ROL IDX
3971 {
3972   uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
3973   tmp = (tmp2<<1) + (regs.cc&0x01);
3974   regs.WrMem(addr, tmp);
3975   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3976   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
3977   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
3978   regs.clock += 6;
3979 }
3980 static void Op6A(void)  // DEC IDX
3981       {
3982   uint8 tmp;  uint16 addr;
3983         addr = DecodeIDX(regs.RdMem(regs.pc++));
3984         tmp = regs.RdMem(addr) - 1;
3985         regs.WrMem(addr, tmp);
3986         (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3987         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3988         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3989         regs.clock += 6;
3990       }
3991 static void Op6C(void)  // INC IDX
3992       {
3993         addr = DecodeIDX(regs.RdMem(regs.pc++));
3994         tmp = regs.RdMem(addr) + 1;
3995         regs.WrMem(addr, tmp);
3996         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3997         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
3998         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
3999         regs.clock += 6;
4000       }
4001 static void Op6D(void)  // TST IDX
4002       {
4003         tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4004         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
4005         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
4006         regs.clock += 6;
4007       }
4008 static void Op6E(void)  // JMP IDX
4009 {
4010   regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
4011   regs.clock += 3;
4012 }
4013 static void Op6F(void)  // CLR IDX
4014 {
4015   addr = DecodeIDX(regs.RdMem(regs.pc++));
4016   regs.WrMem(addr, 0);
4017   regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
4018   regs.clock += 6;
4019 }
4020 static void Op70(void)  // NEG ABS
4021       {
4022         addr = FetchW();
4023         tmp = regs.RdMem(addr);  uint8 res = 256 - tmp;
4024         regs.WrMem(addr, res);
4025         (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4026         (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
4027         (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
4028         (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
4029         regs.clock += 7;
4030       }
4031 static void Op73(void)  // COM ABS
4032       {
4033         addr = FetchW();
4034         tmp = regs.RdMem(addr) ^ 0xFF;
4035         regs.WrMem(addr, tmp);
4036         regs.cc &= 0xFD;  regs.cc |= 0x01;               // CLV, SEC
4037         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4038         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4039         regs.clock += 7;
4040       }
4041 static void Op74(void)  // LSR ABS
4042       {
4043         addr = FetchW();
4044         tmp = regs.RdMem(addr);
4045         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift low bit into carry
4046         tmp >>= 1;  regs.WrMem(addr, tmp);
4047         regs.cc &= 0xF7;                             // CLN
4048         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4049         regs.clock += 7;
4050       }
4051 static void Op76(void)  // ROR ABS
4052       {
4053   uint8 tmp;  uint16 addr;
4054         addr = FetchW();
4055         tmp = regs.RdMem(addr);  uint8 tmp2 = tmp;
4056         tmp = (tmp >> 1) + (regs.cc&0x01)*128;
4057         regs.WrMem(addr, tmp);
4058         (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
4059         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4060         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4061         regs.clock += 7;
4062       }
4063 static void Op77(void)  // ASR ABS
4064       {
4065   uint8 tmp;  uint16 addr;
4066         addr = FetchW();
4067         tmp = regs.RdMem(addr);
4068         (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift bit into carry
4069         tmp >>= 1;
4070         if (tmp&0x40)  tmp |= 0x80;              // Set Neg if it was set
4071         regs.WrMem(addr, tmp);
4072         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4073         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4074         regs.clock += 7;
4075       }
4076 static void Op78(void)  // LSL ABS
4077       {
4078   uint8 tmp;  uint16 addr;
4079         addr = FetchW();
4080         tmp = regs.RdMem(addr);
4081         (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Shift hi bit into carry
4082         tmp <<= 1;
4083         regs.WrMem(addr, tmp);
4084         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4085         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4086         regs.clock += 7;
4087       }
4088 static void Op79(void)  // ROL ABS
4089 {
4090   uint8 tmp2 = regs.RdMem(FetchW());
4091   tmp = (tmp2<<1) + (regs.cc&0x01);
4092   regs.WrMem(addr, tmp);
4093   (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
4094   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4095   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4096   regs.clock += 7;
4097 }
4098 static void Op7A(void)  // DEC ABS
4099       {
4100   uint8 tmp;  uint16 addr;
4101         addr = FetchW();
4102         tmp = regs.RdMem(addr) - 1;
4103         regs.WrMem(addr, tmp);
4104         (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
4105         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
4106         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
4107         regs.clock += 7;
4108       }
4109 static void Op7C(void)  // INC ABS
4110       {
4111   uint8 tmp;  uint16 addr;
4112         addr = FetchW();
4113         tmp = regs.RdMem(addr) + 1;
4114         regs.WrMem(addr, tmp);
4115         (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
4116         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
4117         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
4118         regs.clock += 7;
4119       }
4120
4121 static void Op7D(void)  // TST ABS
4122 {
4123         uint8 tmp = regs.RdMem(FetchW());
4124
4125         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);   // Adjust Zero flag
4126         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);   // Adjust Negative flag
4127
4128         regs.clock += 7;
4129 }
4130
4131 static void Op7E(void)  // JMP ABS
4132 {
4133   regs.pc = FetchW();
4134   regs.clock += 3;
4135 }
4136 static void Op7F(void)  // CLR ABS
4137       {
4138         regs.WrMem(FetchW(), 0);
4139         regs.cc &= 0xF0;  regs.cc |= 0x04;                // Set NZVC
4140         regs.clock += 7;
4141       }
4142 static void Op80(void)  // SUBA #
4143 {
4144   uint8 tmp = regs.RdMem(regs.pc++);  uint8 as = regs.a;
4145   regs.a -= tmp;
4146   (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4147   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4148   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4149   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4150   regs.clock += 2;
4151 }
4152 static void Op81(void)  // CMPA #
4153 {
4154   tmp = regs.RdMem(regs.pc++);
4155   uint8 db = regs.a - tmp;
4156   (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4157   ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4158   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4159   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4160   regs.clock += 2;
4161 }
4162 static void Op82(void)  // SBCA #
4163 {
4164   tmp = regs.RdMem(regs.pc++);  uint8 as = regs.a;
4165   regs.a = regs.a - tmp - (regs.cc&0x01);
4166   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4167   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4168   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4169   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4170   regs.clock += 2;
4171 }
4172 static void Op83(void)  // SUBD #
4173 {
4174   addr = FetchW();  uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4175   dr -= addr;
4176   (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4177   ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4178   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4179   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4180   regs.a = dr>>8;  regs.b = dr&0xFF;
4181   regs.clock += 4;
4182 }
4183 static void Op85(void)  // BITA #
4184       {
4185         tmp = regs.a & regs.RdMem(regs.pc++);
4186         regs.cc &= 0xFD;                             // Clear oVerflow flag
4187         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4188         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4189         regs.clock += 2;
4190       }
4191 static void Op86(void)  // LDA #
4192       {
4193         regs.a = regs.RdMem(regs.pc++);
4194         regs.cc &= 0xFD;                            // CLV
4195         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4196         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4197         regs.clock += 2;
4198       }
4199 static void Op88(void)  // EORA #
4200       {
4201         regs.a ^= regs.RdMem(regs.pc++);
4202         regs.cc &= 0xFD;                            // CLV
4203         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4204         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4205         regs.clock += 2;
4206       }
4207 static void Op8A(void)  // ORA #
4208       {
4209         regs.a |= regs.RdMem(regs.pc++);
4210         regs.cc &= 0xFD;                            // CLV
4211         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4212         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4213         regs.clock += 2;
4214       }
4215 static void Op8C(void)  // CMPX #
4216 {
4217         addr = FetchW();
4218         uint16 dw = regs.x - addr;
4219         (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4220         ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
4221         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4222         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4223         regs.clock += 4;
4224 }
4225
4226 static void Op8D(void)                                                  // Bregs.s
4227 {
4228         uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
4229         regs.WrMem(--regs.s, regs.pc & 0xFF);
4230         regs.WrMem(--regs.s, regs.pc >> 8);
4231         regs.pc += word;
4232
4233         regs.clock += 7;
4234 }
4235
4236 static void Op8E(void)  // LDX #
4237       {
4238         regs.x = FetchW();
4239         regs.cc &= 0xFD;                              // CLV
4240         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4241         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4242         regs.clock += 3;
4243       }
4244 static void Op90(void)  // SUBA DP
4245       {
4246         tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8 as = regs.a;
4247         regs.a -= tmp;
4248         (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4249         (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4250         (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4251         ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4252         regs.clock += 4;
4253       }
4254 static void Op91(void)  // CMPA DP
4255       {
4256         tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4257         uint8 db = regs.a - tmp;
4258         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4259         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4260         (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4261         ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4262         regs.clock += 4;
4263       }
4264 static void Op92(void)  // SBCA DP
4265 {
4266   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8 as = regs.a;
4267   regs.a = regs.a - tmp - (regs.cc&0x01);
4268   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4269   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4270   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4271   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4272   regs.clock += 4;
4273 }
4274 static void Op93(void)  // SUBD DP
4275 {
4276   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);  uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4277   uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4278   dr -= adr2;
4279   (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4280   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4281   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4282   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4283   regs.a = dr>>8;  regs.b = dr&0xFF;
4284   regs.clock += 6;
4285 }
4286 static void Op84(void)  // ANDA #
4287       {
4288         regs.a &= regs.RdMem(regs.pc++);
4289         regs.cc &= 0xFD;                            // Clear oVerflow flag
4290         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4291         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4292         regs.clock += 2;
4293       }
4294 static void Op94(void)  // ANDA DP
4295 {
4296   regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4297   regs.cc &= 0xF1;                   // CLV CLZ CLN
4298   if (regs.a == 0)  regs.cc |= 0x04;     // Adjust Zero flag
4299   if (regs.a&0x80)  regs.cc |= 0x08;     // Adjust Negative flag
4300   regs.clock += 4;
4301 }
4302 static void Op95(void)  // BITA DP
4303       {
4304         tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4305         regs.cc &= 0xFD;                             // Clear oVerflow flag
4306         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4307         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4308         regs.clock += 4;
4309       }
4310 static void Op96(void)  // LDA DP
4311 {
4312   regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4313   regs.cc &= 0xF1;                            // CLN CLZ CLV
4314   if (regs.a == 0)  regs.cc |= 0x04;              // Set Zero flag
4315   if (regs.a&0x80)  regs.cc |= 0x08;              // Set Negative flag
4316   regs.clock += 4;
4317 }
4318 static void Op97(void)  // STA DP
4319       {
4320         regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
4321         regs.cc &= 0xFD;                            // CLV
4322         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4323         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4324         regs.clock += 4;
4325       }
4326 static void Op98(void)  // EORA DP
4327       {
4328         regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4329         regs.cc &= 0xFD;                            // CLV
4330         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4331         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4332         regs.clock += 4;
4333       }
4334 static void Op9A(void)  // ORA DP
4335       {
4336         regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4337         regs.cc &= 0xFD;                            // CLV
4338         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4339         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4340         regs.clock += 4;
4341       }
4342 static void Op9C(void)  // CMPX DP
4343       {
4344         addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4345         uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4346         uint16 dw = regs.x - adr2;
4347         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4348         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4349         (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4350         ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
4351         regs.clock += 6;
4352       }
4353 static void Op9D(void)  // JSR DP
4354       {
4355         addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
4356         regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
4357         regs.pc = addr;      // JSR to DP location...
4358         regs.clock += 7;
4359       }
4360 static void Op9E(void)  // LDX DP
4361       {
4362         addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
4363         regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4364         regs.cc &= 0xFD;                              // CLV
4365         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4366         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4367         regs.clock += 5;
4368       }
4369 static void Op9F(void)  // STX DP
4370       {
4371         addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
4372         regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
4373         regs.cc &= 0xFD;                              // CLV
4374         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4375         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4376         regs.clock += 5;
4377       }
4378 static void OpA0(void)  // SUBA IDX
4379       {
4380         tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 as = regs.a;
4381         regs.a -= tmp;
4382         (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4383         (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4384         (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4385         ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4386         regs.clock += 4;
4387       }
4388 static void OpA1(void)  // CMPA IDX
4389       {
4390         tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4391         uint8 db = regs.a - tmp;
4392         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4393         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4394         (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4395         ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4396         regs.clock += 4;
4397       }
4398 static void OpA2(void)  // SBCA IDX
4399 {
4400   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 as = regs.a;
4401   regs.a = regs.a - tmp - (regs.cc&0x01);
4402   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4403   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4404   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4405   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4406   regs.clock += 4;
4407 }
4408 static void OpA3(void)  // SUBD IDX
4409 {
4410   addr = DecodeIDX(regs.RdMem(regs.pc++));  uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4411   uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4412   dr -= adr2;
4413   (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4414   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4415   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4416   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4417   regs.a = dr>>8;  regs.b = dr&0xFF;
4418   regs.clock += 6;
4419 }
4420 static void OpA4(void)  // ANDA IDX
4421       {
4422         regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4423         regs.cc &= 0xFD;                            // Clear oVerflow flag
4424         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4425         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4426         regs.clock += 4;
4427       }
4428 static void OpA5(void)  // BITA IDX
4429       {
4430         tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4431         regs.cc &= 0xFD;                             // Clear oVerflow flag
4432         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4433         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4434         regs.clock += 4;
4435       }
4436 static void OpA6(void)  // LDA IDX
4437 {
4438   regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4439   regs.cc &= 0xF1;                        // CLV CLZ CLN
4440   if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
4441   if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
4442   regs.clock += 4;
4443 }
4444 static void OpA7(void)  // STA IDX
4445 {
4446   regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
4447   regs.cc &= 0xF1;                        // CLV CLZ CLN
4448   if (regs.a == 0)  regs.cc |= 0x04;          // Set Zero flag
4449   if (regs.a&0x80)  regs.cc |= 0x08;          // Set Negative flag
4450   regs.clock += 4;
4451 }
4452 static void OpA8(void)  // EORA IDX
4453       {
4454         regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4455         regs.cc &= 0xFD;                            // CLV
4456         (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4457         (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4458         regs.clock += 4;
4459       }
4460 static void OpAA(void)  // ORA IDX
4461 {
4462   regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4463   regs.cc &= 0xFD;                            // CLV
4464   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4465   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4466   regs.clock += 4;
4467 }
4468 static void OpAC(void)  // CMPX IDX
4469 {
4470   addr = DecodeIDX(regs.RdMem(regs.pc++));
4471   uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4472   uint16 dw = regs.x - addr2;
4473   (dw == 0    ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4474   (dw&0x8000  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4475   (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4476   ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4477   regs.clock += 6;
4478 }
4479 static void OpAD(void)  // JSR IDX
4480 {
4481   addr = DecodeIDX(regs.RdMem(regs.pc++));
4482   regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
4483   regs.pc = addr;                               // Jregs.s directly to IDX ptr
4484   regs.clock += 7;
4485 }
4486 static void OpAE(void)  // LDX IDX
4487 {
4488   addr = DecodeIDX(regs.RdMem(regs.pc++));
4489   regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4490   regs.cc &= 0xFD;                              // CLV
4491   (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4492   (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4493   regs.clock += 5;
4494 }
4495 static void OpAF(void)  // STX IDX
4496 {
4497   addr = DecodeIDX(regs.RdMem(regs.pc++));
4498   regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
4499   regs.cc &= 0xF1;                              // CLV CLZ CLN
4500   if (regs.x == 0)    regs.cc |= 0x04;              // Set Zero flag
4501   if (regs.x&0x8000)  regs.cc |= 0x08;              // Set Negative flag
4502   regs.clock += 5;
4503 }
4504 static void OpB0(void)  // SUBA ABS
4505       {
4506         tmp = regs.RdMem(FetchW());  uint8 as = regs.a;
4507         regs.a -= tmp;
4508         (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4509         (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4510         (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4511         ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4512         regs.clock += 5;
4513       }
4514 static void OpB1(void)  // CMPA ABS
4515       {
4516         tmp = regs.RdMem(FetchW());
4517         uint8 db = regs.a - tmp;
4518         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4519         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4520         (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4521         ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4522         regs.clock += 5;
4523       }
4524 static void OpB2(void)  // SBCA ABS
4525 {
4526   tmp = regs.RdMem(FetchW());  uint8 as = regs.a;
4527   regs.a = regs.a - tmp - (regs.cc&0x01);
4528   (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4529   ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4530   (regs.a == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4531   (regs.a&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4532   regs.clock += 5;
4533 }
4534 static void OpB3(void)  // SUBD ABS
4535 {
4536   addr = FetchW();  uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4537   uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4538   dr -= adr2;
4539   (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4540   ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
4541   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4542   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4543   regs.a = dr>>8;  regs.b = dr&0xFF;
4544   regs.clock += 7;
4545 }
4546 static void OpB4(void)  // ANDA ABS
4547 {
4548   regs.a &= regs.RdMem(FetchW());
4549   regs.cc &= 0xFD;                            // Clear oVerflow flag
4550   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4551   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4552   regs.clock += 5;
4553 }
4554 static void OpB5(void)  // BITA ABS
4555 {
4556   tmp = regs.a & regs.RdMem(FetchW());
4557   regs.cc &= 0xFD;                             // Clear oVerflow flag
4558   (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4559   (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4560   regs.clock += 5;
4561 }
4562 static void OpB6(void)  // LDA ABS
4563 {
4564   regs.a = regs.RdMem(FetchW());
4565   regs.cc &= 0xFD;                            // CLV
4566   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4567   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4568   regs.clock += 5;
4569 }
4570 static void OpB7(void)  // STA ABS
4571 {
4572   regs.WrMem(FetchW(), regs.a);
4573   regs.cc &= 0xFD;                            // CLV
4574   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4575   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4576   regs.clock += 5;
4577 }
4578 static void OpB8(void)  // EORA ABS
4579 {
4580   regs.a ^= regs.RdMem(FetchW());
4581   regs.cc &= 0xFD;                            // CLV
4582   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4583   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4584   regs.clock += 5;
4585 }
4586 static void OpBA(void)  // ORA ABS
4587 {
4588   regs.a |= regs.RdMem(FetchW());
4589   regs.cc &= 0xFD;                            // CLV
4590   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4591   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4592   regs.clock += 5;
4593 }
4594 static void OpBC(void)  // CMPX ABS
4595 {
4596   addr = FetchW();  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4597   uint16 dw = regs.x - addr2;
4598   (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4599   (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4600   (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4601   ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4602   regs.clock += 7;
4603 }
4604 static void OpBD(void)  // JSR ABS
4605 {
4606   addr = FetchW();
4607   regs.WrMem(--regs.s, regs.pc&0xFF);  regs.WrMem(--regs.s, regs.pc>>8);
4608   regs.pc = addr;                          // Go to absolute address (Not indir)
4609   regs.clock += 8;
4610 }
4611
4612 static void OpBE(void)                                                                  // LDX ABS
4613 {
4614 //      addr = FetchW();
4615 //      regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4616         regs.x = RdMemW(FetchW());
4617
4618         regs.cc &= 0xFD;                                                                        // CLV
4619         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
4620         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
4621
4622         regs.clock += 6;
4623 }
4624
4625 static void OpBF(void)                                                                  // STX ABS
4626 {
4627 //      addr = FetchW();
4628 //      regs.WrMem(addr, regs.x>>8);  regs.WrMem(addr+1, regs.x&0xFF);
4629         WrMemW(FetchW(), regs.x);
4630
4631         regs.cc &= 0xFD;                                                                        // CLV
4632         (regs.x == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);    // Adjust Zero flag
4633         (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);    // Adjust Negative flag
4634
4635         regs.clock += 6;
4636 }
4637
4638 static void OpC0(void)  // SUBB #
4639       {
4640         tmp = regs.RdMem(regs.pc++);  uint8 bs = regs.b;
4641         regs.b -= tmp;
4642         (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4643         (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4644         (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4645         ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4646         regs.clock += 2;
4647       }
4648 static void OpC1(void)  // CMPB #
4649       {
4650         tmp = regs.RdMem(regs.pc++);
4651         uint8 db = regs.b - tmp;
4652         (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4653         ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4654         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4655         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4656         regs.clock += 2;
4657       }
4658 static void OpC2(void)  // SBCB #
4659 {
4660   tmp = regs.RdMem(regs.pc++);  uint8 bs = regs.b;
4661   regs.b = regs.b - tmp - (regs.cc&0x01);
4662   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4663   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4664   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4665   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4666   regs.clock += 2;
4667 }
4668 static void OpC4(void)  // ANDB #
4669       {
4670         regs.b &= regs.RdMem(regs.pc++);
4671         regs.cc &= 0xFD;                            // Clear oVerflow flag
4672         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4673         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4674         regs.clock += 2;
4675       }
4676 static void OpC5(void)  // BITB #
4677 {
4678   tmp = regs.b & regs.RdMem(regs.pc++);
4679   regs.cc &= 0xF1;                             // CLV CLZ CLN
4680   if (tmp == 0)  regs.cc |= 0x04;              // Set Zero flag
4681   if (tmp&0x80)  regs.cc |= 0x08;              // Set Negative flag
4682   regs.clock += 2;
4683 }
4684 static void OpC6(void)  // LDB #
4685 {
4686   regs.b = regs.RdMem(regs.pc++);
4687   regs.cc &= 0xF1;                             // CLV CLZ CLN
4688   if (regs.b == 0)  regs.cc |= 0x04;               // Set Zero flag
4689   if (regs.b&0x80)  regs.cc |= 0x08;               // Set Negative flag
4690   regs.clock += 2;
4691 }
4692 static void OpC8(void)  // EORB #
4693       {
4694         regs.b ^= regs.RdMem(regs.pc++);
4695         regs.cc &= 0xFD;                            // CLV
4696         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4697         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4698         regs.clock += 2;
4699       }
4700 static void OpCA(void)  // ORB #
4701       {
4702         regs.b |= regs.RdMem(regs.pc++);
4703         regs.cc &= 0xFD;                            // CLV
4704         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4705         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4706         regs.clock += 2;
4707       }
4708 static void OpCC(void)  // LDD #
4709 {
4710   regs.a = regs.RdMem(regs.pc++);  regs.b = regs.RdMem(regs.pc++);
4711   regs.cc &= 0xFD;                                 // CLV
4712   ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4713   (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4714   regs.clock += 3;
4715 }
4716 static void OpCE(void)  // LDU #
4717 {
4718   regs.u = FetchW();
4719   regs.cc &= 0xFD;                              // CLV
4720   (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4721   (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4722   regs.clock += 3;
4723 }
4724 static void OpD0(void)  // SUBB DP
4725 {
4726   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8 bs = regs.b;
4727   regs.b -= tmp;
4728   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4729   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4730   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4731   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4732   regs.clock += 4;
4733 }
4734 static void OpD1(void)  // CMPB DP
4735 {
4736   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4737   uint8 db = regs.b - tmp;
4738   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4739   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4740   (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4741   ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4742   regs.clock += 4;
4743 }
4744 static void OpD2(void)  // SBCB DP
4745 {
4746   tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));  uint8 bs = regs.b;
4747   regs.b = regs.b - tmp - (regs.cc&0x01);
4748   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4749   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4750   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4751   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4752   regs.clock += 4;
4753 }
4754 static void OpD4(void)  // ANDB DP
4755       {
4756         regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4757         regs.cc &= 0xFD;                            // Clear oVerflow flag
4758         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4759         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4760         regs.clock += 4;
4761       }
4762 static void OpD5(void)  // BITB DP
4763       {
4764         tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4765         regs.cc &= 0xFD;                             // Clear oVerflow flag
4766         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4767         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4768         regs.clock += 4;
4769       }
4770 static void OpD6(void)  // LDB DP
4771 {
4772   regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4773   regs.cc &= 0xFD;                            // CLV
4774   (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4775   (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4776   regs.clock += 4;
4777 }
4778 static void OpD7(void)  // STB DP
4779       {
4780         regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
4781         regs.cc &= 0xFD;                            // CLV
4782         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4783         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4784         regs.clock += 4;
4785       }
4786 static void OpD8(void)  // EORB DP
4787       {
4788         regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4789         regs.cc &= 0xFD;                            // CLV
4790         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4791         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4792         regs.clock += 4;
4793       }
4794 static void OpDA(void)  // ORB DP
4795       {
4796         regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4797         regs.cc &= 0xFD;                            // CLV
4798         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4799         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4800         regs.clock += 4;
4801       }
4802 static void OpDC(void)  // LDD DP
4803 {
4804   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4805   regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
4806   regs.cc &= 0xFD;                                 // CLV
4807   ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4808   (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4809   regs.clock += 5;
4810 }
4811 static void OpDD(void)  // STD DP
4812 {
4813   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4814   regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
4815   regs.cc &= 0xFD;                                 // CLV
4816   ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4817   (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4818   regs.clock += 5;
4819 }
4820 static void OpDE(void)  // LDU DP
4821 {
4822   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4823   regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4824   regs.cc &= 0xFD;                              // CLV
4825   (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4826   (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4827   regs.clock += 5;
4828 }
4829 static void OpDF(void)  // STU DP
4830 {
4831   addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4832   regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
4833   regs.cc &= 0xFD;                              // CLV
4834   (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4835   (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4836   regs.clock += 5;
4837 }
4838 static void OpE0(void)  // SUBB IDX
4839 {
4840   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 bs = regs.b;
4841   regs.b -= tmp;
4842   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4843   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4844   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4845   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4846   regs.clock += 4;
4847 }
4848 static void OpE1(void)  // CMPB IDX
4849 {
4850   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4851   uint8 db = regs.b - tmp;
4852   (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4853   (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4854   (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4855   ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4856   regs.clock += 4;
4857 }
4858 static void OpE2(void)  // SBCB IDX
4859 {
4860   tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));  uint8 bs = regs.b;
4861   regs.b = regs.b - tmp - (regs.cc&0x01);
4862   (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4863   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4864   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4865   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4866   regs.clock += 4;
4867 }
4868 static void OpE4(void)  // ANDB IDX
4869       {
4870         regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4871         regs.cc &= 0xFD;                            // Clear oVerflow flag
4872         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4873         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4874         regs.clock += 4;
4875       }
4876 static void OpE5(void)  // BITB IDX
4877       {
4878         tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4879         regs.cc &= 0xFD;                             // Clear oVerflow flag
4880         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4881         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4882         regs.clock += 4;
4883       }
4884 static void OpE6(void)  // LDB IDX
4885       {
4886         regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4887         regs.cc &= 0xFD;                            // CLV
4888         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4889         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4890         regs.clock += 4;
4891       }
4892 static void OpE7(void)  // STB IDX
4893 {
4894   regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
4895   regs.cc &= 0xF1;                            // CLV CLZ CLN
4896   if (regs.b == 0)  regs.cc |= 0x04;              // Adjust Zero flag
4897   if (regs.b&0x80)  regs.cc |= 0x08;              // Adjust Negative flag
4898   regs.clock += 4;
4899 }
4900 static void OpE8(void)  // EORB IDX
4901       {
4902         regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4903         regs.cc &= 0xFD;                            // CLV
4904         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4905         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4906         regs.clock += 4;
4907       }
4908 static void OpEA(void)  // ORB IDX
4909       {
4910         regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4911         regs.cc &= 0xFD;                            // CLV
4912         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4913         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4914         regs.clock += 4;
4915       }
4916 static void OpEC(void)  // LDD IDX
4917 {
4918   addr = DecodeIDX(regs.RdMem(regs.pc++));
4919   regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
4920   regs.cc &= 0xF1;                             // CLV CLZ CLN
4921   if (!(regs.a|regs.b))  regs.cc |= 0x04;              // Adjust Zero flag
4922   if (regs.a&0x80)   regs.cc |= 0x08;              // Adjust Negative flag
4923   regs.clock += 5;
4924 }
4925 static void OpED(void)  // STD IDX
4926 {
4927   addr = DecodeIDX(regs.RdMem(regs.pc++));
4928   regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
4929   regs.cc &= 0xF1;                             // CLV CLZ CLZ
4930   if (!(regs.a|regs.b))  regs.cc |= 0x04;              // Adjust Zero flag
4931   if (regs.a&0x80)   regs.cc |= 0x08;              // Adjust Negative flag
4932   regs.clock += 5;
4933 }
4934 static void OpEE(void)  // LDU IDX
4935 {
4936   addr = DecodeIDX(regs.RdMem(regs.pc++));
4937   regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4938   regs.cc &= 0xF1;                              // CLV CLZ CLN
4939   if (regs.u == 0)    regs.cc |= 0x04;              // Set Zero flag
4940   if (regs.u&0x8000)  regs.cc |= 0x08;              // Set Negative flag
4941   regs.clock += 5;
4942 }
4943 static void OpEF(void)  // STU IDX
4944 {
4945   addr = DecodeIDX(regs.RdMem(regs.pc++));
4946   regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
4947   regs.cc &= 0xF1;                              // CLV CLZ CLN
4948   if (regs.u == 0)    regs.cc |= 0x04;              // Set Zero flag
4949   if (regs.u&0x8000)  regs.cc |= 0x08;              // Set Negative flag
4950   regs.clock += 5;
4951 }
4952 static void OpF0(void)  // SUBB ABS
4953       {
4954         tmp = regs.RdMem(FetchW());  uint8 bs = regs.b;
4955         regs.b -= tmp;
4956         (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4957         (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4958         (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4959         ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4960       }
4961 static void OpF1(void)  // CMPB ABS
4962       {
4963         tmp = regs.RdMem(FetchW());
4964         uint8 db = regs.b - tmp;
4965         (db == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4966         (db&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4967         (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4968         ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4969         regs.clock += 5;
4970       }
4971 static void OpF2(void)  // SBCB ABS
4972 {
4973   tmp = regs.RdMem(FetchW());  uint8 bs = regs.b;
4974   regs.b = regs.b - tmp - (regs.cc&0x01);
4975   (regs.b == 0  ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4976   (regs.b&0x80  ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4977   (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
4978   ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4979   regs.clock += 5;
4980 }
4981 static void OpF4(void)  // ANDB ABS
4982       {
4983         regs.b &= regs.RdMem(FetchW());
4984         regs.cc &= 0xFD;                            // Clear oVerflow flag
4985         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4986         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4987         regs.clock += 5;
4988       }
4989 static void OpF5(void)  // BITB ABS
4990       {
4991         tmp = regs.b & regs.RdMem(FetchW());
4992         regs.cc &= 0xFD;                             // Clear oVerflow flag
4993         (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
4994         (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
4995         regs.clock += 5;
4996       }
4997 static void OpF6(void)  // LDB ABS
4998       {
4999         regs.b = regs.RdMem(FetchW());
5000         regs.cc &= 0xFD;                            // CLV
5001         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5002         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5003         regs.clock += 5;
5004       }
5005 static void OpF7(void)  // STB ABS
5006       {
5007         regs.WrMem(FetchW(), regs.b);
5008         regs.cc &= 0xFD;                            // CLV
5009         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5010         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5011         regs.clock += 5;
5012       }
5013 static void OpF8(void)  // EORB ABS
5014       {
5015         regs.b ^= regs.RdMem(FetchW());
5016         regs.cc &= 0xFD;                            // CLV
5017         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5018         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5019         regs.clock += 5;
5020       }
5021 static void OpFA(void)  // ORB ABS
5022       {
5023         regs.b |= regs.RdMem(FetchW());
5024         regs.cc &= 0xFD;                            // CLV
5025         (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5026         (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5027         regs.clock += 5;
5028       }
5029 static void OpFC(void)  // LDD ABS
5030       {
5031         addr = FetchW();
5032         regs.a = regs.RdMem(addr);  regs.b = regs.RdMem(addr+1);
5033         regs.cc &= 0xFD;                                 // CLV
5034         ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5035         (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5036         regs.clock += 6;
5037       }
5038 static void OpFD(void)  // STD ABS
5039       {
5040         addr = FetchW();
5041         regs.WrMem(addr, regs.a);  regs.WrMem(addr+1, regs.b);
5042         regs.cc &= 0xFD;                                 // CLV
5043         ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5044         (regs.a&0x80      ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5045         regs.clock += 6;
5046       }
5047 static void OpFE(void)  // LDU ABS
5048       {
5049         addr = FetchW();
5050         regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
5051         regs.cc &= 0xFD;                              // CLV
5052         (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5053         (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5054         regs.clock += 6;
5055       }
5056 static void OpFF(void)  // STU ABS
5057       {
5058         addr = FetchW();
5059         regs.WrMem(addr, regs.u>>8);  regs.WrMem(addr+1, regs.u&0xFF);
5060         regs.cc &= 0xFD;                              // CLV
5061         (regs.u == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5062         (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5063         regs.clock += 6;
5064       }
5065
5066 //
5067 // Page one opcodes' execute code
5068 //
5069
5070 static void Op1021(void)                                                // LBRN
5071 {
5072         addr = FetchW();
5073
5074         regs.clock += 5;
5075 }
5076
5077 static void Op1022(void)                                                // LBHI
5078 {
5079         uint16 word = FetchW();
5080
5081         if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
5082                 regs.pc += word;
5083
5084         regs.clock += 5;
5085 }
5086
5087 static void Op1023(void)                                                // LBLS
5088 {
5089         uint16 word = FetchW();
5090
5091         if ((regs.cc & 0x01) | (regs.cc & 0x04))
5092                 regs.pc += word;
5093
5094         regs.clock += 5;
5095 }
5096
5097 static void Op1024(void)                                                // LBCC (LBHS)
5098 {
5099         uint16 word = FetchW();
5100
5101         if (!(regs.cc & 0x01))
5102                 regs.pc += word;
5103
5104         regs.clock += 5;
5105 }
5106
5107 static void Op1025(void)                                                // LBCS (LBLO)
5108 {
5109         uint16 word = FetchW();
5110
5111         if (regs.cc & 0x01)
5112                 regs.pc += word;
5113
5114         regs.clock += 5;
5115 }
5116
5117 static void Op1026(void)                                                // LBNE
5118 {
5119         uint16 word = FetchW();
5120
5121         if (!(regs.cc & 0x04))
5122                 regs.pc += word;
5123
5124         regs.clock += 5;
5125 }
5126
5127 static void Op1027(void)                                                // LBEQ
5128 {
5129         uint16 word = FetchW();
5130
5131         if (regs.cc & 0x04)
5132                 regs.pc += word;
5133
5134         regs.clock += 5;
5135 }
5136
5137 static void Op1028(void)                                                // LBVC
5138 {
5139         uint16 word = FetchW();
5140
5141         if (!(regs.cc & 0x02))
5142                 regs.pc += word;
5143
5144         regs.clock += 5;
5145 }
5146
5147 static void Op1029(void)                                                // LBVS
5148 {
5149         uint16 word = FetchW();
5150
5151         if (regs.cc & 0x02)
5152                 regs.pc += word;
5153
5154         regs.clock += 5;
5155 }
5156
5157 static void Op102A(void)                                                // LBPL
5158 {
5159         uint16 word = FetchW();
5160
5161         if (!(regs.cc & 0x08))
5162                 regs.pc += word;
5163
5164         regs.clock += 5;
5165 }
5166
5167 static void Op102B(void)                                                // LBMI
5168 {
5169         uint16 word = FetchW();
5170
5171         if (regs.cc & 0x08)
5172                 regs.pc += word;
5173
5174         regs.clock += 5;
5175 }
5176
5177 static void Op102C(void)                                                // LBGE
5178 {
5179         uint16 word = FetchW();
5180
5181         if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
5182                 regs.pc += word;
5183
5184         regs.clock += 5;
5185 }
5186
5187 static void Op102D(void)                                                // LBLT
5188 {
5189         uint16 word = FetchW();
5190
5191         if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
5192                 regs.pc += word;
5193
5194         regs.clock += 5;
5195 }
5196
5197 static void Op102E(void)                                                // LBGT
5198 {
5199         uint16 word = FetchW();
5200
5201         if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
5202                 regs.pc += word;
5203
5204         regs.clock += 5;
5205 }
5206
5207 static void Op102F(void)                                                // LBLE
5208 {
5209         uint16 word = FetchW();
5210
5211         if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
5212                 regs.pc += word;
5213
5214         regs.clock += 5;
5215 }
5216
5217 static void Op103F(void)  // SWI2 (Not yet implemented)
5218 {
5219   regs.clock += 20;
5220 }
5221 static void Op1083(void)  // CMPD #
5222     {
5223       addr = FetchW();  uint16 dr = (regs.a<<8)|regs.b;
5224       uint16 dw = dr - addr;
5225       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5226       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5227       (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5228       ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5229       regs.clock += 5;
5230     }
5231 static void Op108C(void)  // CMPY #
5232     {
5233       addr = FetchW();
5234       uint16 dw = regs.y - addr;
5235       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5236       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5237       (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5238       ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5239       regs.clock += 5;
5240     }
5241 static void Op108E(void)  // LDY #
5242     {
5243       regs.y = FetchW();
5244       regs.cc &= 0xFD;                              // CLV
5245       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5246       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5247       regs.clock += 4;
5248     }
5249 static void Op1093(void)  // CMPD DP
5250     {
5251       uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
5252       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5253       uint16 dw = dr - addr;
5254       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5255       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5256       (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5257       ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5258       regs.clock += 7;
5259     }
5260 static void Op109C(void)  // CMPY DP
5261     {
5262       uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
5263       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5264       uint16 dw = regs.y - addr;
5265       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5266       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5267       (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5268       ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5269       regs.clock += 7;
5270     }
5271
5272 static void Op109E(void)  // LDY DP
5273     {
5274       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5275       regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5276       regs.cc &= 0xFD;                              // CLV
5277       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5278       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5279       regs.clock += 6;
5280     }
5281
5282 static void Op109F(void)  // STY DP
5283     {
5284       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5285       regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
5286       regs.cc &= 0xFD;                              // CLV
5287       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5288       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5289       regs.clock += 6;
5290     }
5291 static void Op10A3(void)  // CMPD IDX
5292 {
5293   uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
5294   addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5295   uint16 dw = dr - addr;
5296   regs.cc &= 0xF0;                              // CLC CLV CLZ CLN
5297   if (dr < addr)  regs.cc |= 0x01;              // Set Carry flag
5298   if ((dr^addr^dw^(regs.cc<<15))&0x8000)  regs.cc |= 0x02; // Set oVerflow
5299   if (dw == 0)    regs.cc |= 0x04;              // Set Zero flag
5300   if (dw&0x8000)  regs.cc |= 0x08;              // Set Negative flag
5301   regs.clock += 7;
5302 }
5303 static void Op10AC(void)  // CMPY IDX
5304     {
5305       uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
5306       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5307       uint16 dw = regs.y - addr;
5308       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5309       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5310       (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5311       (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5312       regs.clock += 7;
5313     }
5314 static void Op10AE(void)  // LDY IDX
5315 {
5316   addr = DecodeIDX(regs.RdMem(regs.pc++));
5317   regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5318   regs.cc &= 0xF1;                              // CLV CLZ CLN
5319   if (regs.y == 0)    regs.cc |= 0x04;              // Adjust Zero flag
5320   if (regs.y&0x8000)  regs.cc |= 0x08;              // Adjust Negative flag
5321   regs.clock += 6;
5322 }
5323 static void Op10AF(void)  // STY IDX
5324     {
5325       addr = DecodeIDX(regs.RdMem(regs.pc++));
5326       regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
5327       regs.cc &= 0xFD;                              // CLV
5328       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5329       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5330       regs.clock += 6;
5331     }
5332 static void Op10B3(void)  // CMPD ABS
5333     {
5334       addr = FetchW();  uint16 dr = (regs.a<<8)|regs.b;
5335       uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5336       uint16 dw = dr - addr2;
5337       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5338       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5339       (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5340       (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5341       regs.clock += 8;
5342     }
5343 static void Op10BC(void)  // CMPY ABS
5344     {
5345       addr = FetchW();  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5346       uint16 dw = regs.y - addr2;
5347       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5348       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5349       (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5350       (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5351       regs.clock += 8;
5352     }
5353 static void Op10BE(void)  // LDY ABS
5354     {
5355       addr = FetchW();
5356       regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5357       regs.cc &= 0xFD;                              // CLV
5358       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5359       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5360       regs.clock += 7;
5361     }
5362 static void Op10BF(void)  // STY ABS
5363     {
5364       addr = FetchW();
5365       regs.WrMem(addr, regs.y>>8);  regs.WrMem(addr+1, regs.y&0xFF);
5366       regs.cc &= 0xFD;                              // CLV
5367       (regs.y == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5368       (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5369       regs.clock += 7;
5370     }
5371 static void Op10CE(void)  // LDS #
5372     {
5373       regs.s = FetchW();
5374       regs.cc &= 0xFD;                              // CLV
5375       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5376       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5377       regs.clock += 4;
5378     }
5379 static void Op10DE(void)  // LDS DP
5380     {
5381       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5382       regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5383       regs.cc &= 0xFD;                              // CLV
5384       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5385       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5386       regs.clock += 6;
5387     }
5388 static void Op10DF(void)  // STS DP
5389     {
5390       addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5391       regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
5392       regs.cc &= 0xFD;                              // CLV
5393       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5394       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5395       regs.clock += 6;
5396     }
5397 static void Op10EE(void)  // LDS IDX
5398     {
5399       addr = DecodeIDX(regs.RdMem(regs.pc++));
5400       regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5401       regs.cc &= 0xFD;                              // CLV
5402       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5403       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5404       regs.clock += 6;
5405     }
5406 static void Op10EF(void)  // STS IDX
5407     {
5408       addr = DecodeIDX(regs.RdMem(regs.pc++));
5409       regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
5410       regs.cc &= 0xFD;                              // CLV
5411       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5412       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5413       regs.clock += 6;
5414     }
5415 static void Op10FE(void)  // LDS ABS
5416     {
5417       addr = FetchW();
5418       regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5419       regs.cc &= 0xFD;                              // CLV
5420       (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5421       (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5422       regs.clock += 7;
5423     }
5424 static void Op10FF(void)  // STS ABS
5425 {
5426   addr = FetchW();
5427   regs.WrMem(addr, regs.s>>8);  regs.WrMem(addr+1, regs.s&0xFF);
5428   regs.cc &= 0xFD;                              // CLV
5429   (regs.s == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5430   (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5431   regs.clock += 7;
5432 }
5433
5434 //
5435 // Page two opcodes' execute code
5436 //
5437
5438 static void Op113F(void)  // SWI3
5439     {
5440       regs.clock += 20;
5441     }
5442 static void Op1183(void)  // CMPU #
5443     {
5444       addr = FetchW();
5445       uint16 dw = regs.u - addr;
5446       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5447       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5448       (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5449       (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5450       regs.clock += 5;
5451     }
5452 static void Op118C(void)  // CMPS #
5453     {
5454       addr = FetchW();
5455       uint16 dw = regs.s - addr;
5456       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5457       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5458       (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5459       (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5460       regs.clock += 5;
5461     }
5462 static void Op1193(void)  // CMPU DP
5463     {
5464       uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
5465       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5466       uint16 dw = regs.u - addr;
5467       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5468       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5469       (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5470       (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5471       regs.clock += 7;
5472     }
5473 static void Op119C(void)  // CMPS DP
5474     {
5475       uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
5476       addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5477       uint16 dw = regs.s - addr;
5478       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5479       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5480       (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5481       (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5482       regs.clock += 7;
5483     }
5484 static void Op11A3(void)  // CMPU IDX
5485     {
5486       uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
5487       addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
5488       uint16 dw = regs.u - addr;
5489       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5490       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5491       (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5492       (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5493       regs.clock += 7;
5494     }
5495 static void Op11AC(void)  // CMPS IDX
5496     {
5497       uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
5498       addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
5499       uint16 dw = regs.s - addr;
5500       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5501       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5502       (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5503       (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5504       regs.clock += 7;
5505     }
5506 static void Op11B3(void)  // CMPU ABS
5507     {
5508       addr = FetchW();  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5509       uint16 dw = regs.u - addr2;
5510       (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5511       (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5512       (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5513       (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5514       regs.clock += 8;
5515     }
5516
5517 static void Op11BC(void)  // CMPS ABS
5518 {
5519         addr = FetchW();  uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5520         uint16 dw = regs.s - addr2;
5521         (dw == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
5522         (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
5523         (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
5524         (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5525         regs.clock += 8;
5526 }
5527 #endif
5528
5529
5530 //temp, for testing...
5531 #ifdef __DEBUG__
5532 static uint8 backTrace[256];
5533 static uint16 btPC[256];
5534 static int btPtr = 0;//*/
5535 #endif
5536 static void Op__(void)                                                                  // Illegal opcode
5537 {
5538         regs.clock++;
5539 //      illegal = true;
5540         regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
5541 #ifdef __DEBUG__
5542 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
5543 for(int i=0; i<256; i++)
5544 {
5545         Decode6809(btPC[(btPtr + i) & 0xFF]);
5546         WriteLog("\n");
5547 }//*/
5548 #endif
5549 }
5550
5551 //
5552 // Function arrays
5553 //
5554
5555 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
5556 static void Op10(void);
5557 static void Op11(void);
5558
5559 // Array of page zero opcode functions...
5560
5561 static void (* exec_op0[256])() = {
5562         Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
5563         Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
5564         Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
5565         Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
5566         Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
5567         Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
5568         Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
5569         Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
5570         Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
5571         Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
5572         OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
5573         OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
5574         OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
5575         OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
5576         OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
5577         OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
5578 };
5579
5580 // Array of page one opcode functions...
5581 static void (* exec_op1[256])() = {
5582         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5583         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5584         Op__,   Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
5585         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op103F,
5586         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5587         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5588         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5589         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5590         Op__,   Op__,   Op__,   Op1083, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op108C, Op__,   Op108E, Op__,
5591         Op__,   Op__,   Op__,   Op1093, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op109C, Op__,   Op109E, Op109F,
5592         Op__,   Op__,   Op__,   Op10A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10AC, Op__,   Op10AE, Op10AF,
5593         Op__,   Op__,   Op__,   Op10B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10BC, Op__,   Op10BE, Op10BF,
5594         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10CE, Op__,
5595         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10DE, Op10DF,
5596         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10EE, Op10EF,
5597         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10FE, Op10FF
5598 };
5599
5600 // Array of page two opcode functions...
5601 static void (* exec_op2[256])() = {
5602         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5603         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5604         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5605         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op113F,
5606         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5607         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5608         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5609         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5610         Op__,   Op__,   Op__,   Op1183, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op118C, Op__,   Op__,   Op__,
5611         Op__,   Op__,   Op__,   Op1193, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op119C, Op__,   Op__,   Op__,
5612         Op__,   Op__,   Op__,   Op11A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11AC, Op__,   Op__,   Op__,
5613         Op__,   Op__,   Op__,   Op11B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11BC, Op__,   Op__,   Op__,
5614         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5615         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5616         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
5617         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__
5618 };
5619
5620 // These are here to save typing a ton of forward declarations...
5621
5622 // Page 1 opcode
5623 static void Op10(void)
5624 {
5625 //      exec_op1[regs.RdMem(regs.pc++)]();
5626         uint8 opcode = regs.RdMem(regs.pc++);
5627         exec_op1[opcode]();
5628         regs.clock += page1Cycles[opcode];
5629 }
5630
5631 // Page 2 opcode
5632 static void Op11(void)
5633 {
5634 //      exec_op2[regs.RdMem(regs.pc++)]();
5635         uint8 opcode = regs.RdMem(regs.pc++);
5636         exec_op2[opcode]();
5637         regs.clock += page2Cycles[opcode];
5638 }
5639
5640
5641 //
5642 // Internal "memcpy" (so we don't have to link with any external libraries!)
5643 //
5644 static void myMemcpy(void * dst, void * src, uint32 size)
5645 {
5646         uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
5647
5648         for(uint32 i=0; i<size; i++)
5649                 d[i] = s[i];
5650 }
5651
5652 //
5653 // Function to execute 6809 instructions
5654 //
5655 //#define DEBUG_ILLEGAL
5656 #ifdef DEBUG_ILLEGAL
5657 #include "log.h"
5658 #include "dis6809.h"
5659 uint8 btPtr = 0;
5660 uint8 backTrace[256];
5661 V6809REGS btRegs[256];
5662 bool tripped = false;
5663 #endif
5664 void Execute6809(V6809REGS * context, uint32 cycles)
5665 {
5666         // If this is not in place, the clockOverrun calculations can cause the V6809 to get
5667         // stuck in an infinite loop.
5668         if (cycles == 0)                                                        // Nothing to do, so bail!
5669                 return;
5670
5671         myMemcpy(&regs, context, sizeof(V6809REGS));
5672         UNPACK_FLAGS;                                                           // Explode flags register into individual uint8s
5673
5674         // Execute here...
5675
5676         // Since we can't guarantee that we'll execute the number of cycles passed in
5677         // exactly, we have to keep track of how much we overran the number of cycles
5678         // the last time we executed. Since we already executed those cycles, this time
5679         // through we remove them from the cycles passed in in order to come out
5680         // approximately even. Over the long run, this unevenness in execution times
5681         // evens out.
5682         uint64 endCycles = regs.clock + (uint64)(cycles - regs.clockOverrun);
5683
5684         while (regs.clock < endCycles)
5685         {
5686 #ifdef DEBUG_ILLEGAL
5687 if (!tripped)
5688 {
5689         backTrace[btPtr] = regs.RdMem(regs.pc);
5690         btRegs[btPtr] = regs;
5691         btPtr = (btPtr + 1) & 0xFF;
5692
5693         if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
5694         {
5695                 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
5696                 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
5697
5698                 for(uint16 i=btPtr; i<btPtr+256; i++)
5699                 {
5700                         Decode6809(btRegs[i & 0xFF].pc);
5701 // Note that these values are *before* execution, so stale...
5702                         WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
5703                                 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);//*/
5704                 }
5705
5706                 tripped = true;
5707         }
5708 }
5709 #endif
5710 #ifdef __DEBUG__
5711 if (disasm)
5712 {
5713         Decode6809(regs.pc);
5714 //      WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC);
5715 }
5716 #if 0 //we solved this...
5717 if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
5718         WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
5719 #endif
5720 //static bool disasm = false;
5721 /*//if (regs.pc == 0x15BA)      disasm = true;
5722 //if (regs.pc == 0xFE76)        disasm = true;
5723 if (regs.x == 0xFED4)   disasm = true;
5724 if (disasm) Decode6809(regs.pc);
5725 //if (regs.pc == 0x164A)        disasm = false;//*/
5726
5727 //temp, for testing...
5728 /*backTrace[btPtr] = regs.RdMem(regs.pc);
5729 btPC[btPtr] = regs.pc;
5730 btPtr = (btPtr + 1) & 0xFF;//*/
5731 #endif
5732 //              exec_op0[regs.RdMem(regs.pc++)]();
5733                 uint8 opcode = regs.RdMem(regs.pc++);
5734                 exec_op0[opcode]();
5735                 regs.clock += page0Cycles[opcode];
5736
5737                 // Handle any pending interrupts
5738
5739 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
5740 //              uint32 flags = context->cpuFlags;
5741                 uint32 flags = regs.cpuFlags;
5742
5743                 if (flags & V6809_ASSERT_LINE_RESET)                    // *** RESET handler ***
5744                 {
5745 #ifdef __DEBUG__
5746 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
5747 #endif
5748                         flagF = flagI = 1;                                                      // Set F, I
5749                         regs.dp = 0;                                                            // Reset direct page register
5750                         regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
5751                         context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
5752                         regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
5753                 }
5754                 else if (flags & V6809_ASSERT_LINE_NMI)                 // *** NMI handler ***
5755                 {
5756 #ifdef __DEBUG__
5757 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
5758 #endif
5759                         flagE = 1;                                                                      // Set Entire flag
5760                         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
5761
5762                         PUSHS16(regs.pc);                                                       // Save all regs...
5763                         PUSHS16(regs.u);
5764                         PUSHS16(regs.y);
5765                         PUSHS16(regs.x);
5766                         PUSHS(regs.dp);
5767                         PUSHS(regs.b);
5768                         PUSHS(regs.a);
5769                         PUSHS(regs.cc);
5770
5771                         flagI = flagF = 1;                                                      // Set IRQ/FIRQ suppress flags
5772                         regs.pc = RdMemW(0xFFFC);                                       // And load PC with the NMI vector
5773                         regs.clock += 19;
5774 //                      context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
5775 //                      regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI;        // Reset the asserted line (NMI)...
5776                 }
5777                 else if (flags & V6809_ASSERT_LINE_FIRQ)                // *** FIRQ handler ***
5778                 {
5779 #ifdef __DEBUG__
5780 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
5781 #endif
5782                         if (!flagF)                                                                     // Is the FIRQ masked (F == 1)?
5783                         {
5784 #ifdef __DEBUG__
5785 if (disasm) WriteLog("       FIRQ taken...\n");
5786 #endif
5787                                 flagE = 0;                                                              // Clear Entire flag
5788                                 regs.cc = PACK_FLAGS;                                   // Mash flags back into the CC register
5789
5790                                 PUSHS16(regs.pc);
5791                                 PUSHS(regs.cc);
5792
5793                                 flagI = flagF = 1;                                              // Set IRQ/FIRQ suppress flags
5794                                 regs.pc = RdMemW(0xFFF6);                               // And load PC with the IRQ vector
5795                                 regs.clock += 10;
5796 //                              context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;   // Reset the asserted line (FIRQ)...
5797 //                              regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;       // Reset the asserted line (FIRQ)...
5798                         }
5799                 }
5800                 else if (flags & V6809_ASSERT_LINE_IRQ)                 // *** IRQ handler ***
5801                 {
5802 #ifdef __DEBUG__
5803 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
5804 #endif
5805                         if (!flagI)                                                                     // Is the IRQ masked (I == 1)?
5806                         {
5807 #ifdef __DEBUG__
5808 if (disasm) WriteLog("       IRQ taken...\n");
5809 #endif
5810                                 flagE = 1;                                                              // Set the Entire flag
5811                                 regs.cc = PACK_FLAGS;                                   // Mash flags back into the CC register
5812
5813                                 PUSHS16(regs.pc);
5814                                 PUSHS16(regs.u);
5815                                 PUSHS16(regs.y);
5816                                 PUSHS16(regs.x);
5817                                 PUSHS(regs.dp);
5818                                 PUSHS(regs.b);
5819                                 PUSHS(regs.a);
5820                                 PUSHS(regs.cc);
5821
5822                                 flagI = 1;                                                              // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
5823                                 regs.pc = RdMemW(0xFFF8);                               // And load PC with the IRQ vector
5824                                 regs.clock += 19;
5825 // Apparently, not done here!
5826 //                              context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
5827 //                              regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
5828                         }
5829                 }
5830 #ifdef __DEBUG__
5831 if (disasm) WriteLog("\tCC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
5832         (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
5833         (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
5834         regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
5835 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
5836         regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
5837 #endif
5838         }
5839
5840         // Keep track of how much we overran so we can adjust on the next run...
5841         regs.clockOverrun = (uint32)(regs.clock - endCycles);
5842
5843         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
5844         myMemcpy(context, &regs, sizeof(V6809REGS));
5845 }
5846
5847 //
5848 // Get the clock of the currently executing CPU
5849 //
5850 uint64 GetCurrentV6809Clock(void)
5851 {
5852         return regs.clock;
5853 }
5854
5855 //
5856 // Get the PC of the currently executing CPU
5857 //
5858 uint16 GetCurrentV6809PC(void)
5859 {
5860         return regs.pc;
5861 }
5862
5863 // Set a line of the currently executing CPU
5864 void SetLineOfCurrentV6809(uint32 line)
5865 {
5866         regs.cpuFlags |= line;
5867 }
5868
5869 // Clear a line of the currently executing CPU
5870 void ClearLineOfCurrentV6809(uint32 line)
5871 {
5872 #ifdef __DEBUG__
5873 if (disasm)
5874         WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
5875 #endif
5876         regs.cpuFlags &= ~line;
5877 }
5878
5879 #if 0
5880 FE54: 27 6A          BEQ   $FEC0        CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
5881 E S=BFFF U=0000 PC=FEC0
5882 FEC0: 6E A4          JMP   ,Y   CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
5883  U=0000 PC=F51E
5884 F51E: 86 34          LDA   #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
5885  U=0000 PC=F520
5886 F520: B7 C8 0D       STA   $C80D        CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523
5887 F523: B7 C8 0F       STA   $C80F        CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526
5888 F526: 7F C8 0E       CLR   $C80EV6809: Clearing line IRQ...     CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529
5889 F529: 86 9C          LDA   #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
5890 F52B: 1F 8B          TFR   A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D
5891 F52D: 10 CE BF FF    LDS   #$BFFF       CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531
5892 F531: BD 13 BD       JSR   $13BD        CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD
5893 13BD: 34 76          PSHS  A B X Y U    CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF
5894 13BF: CE 9C 00       LDU   #$9C00       CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2
5895 13C2: 8E 00 00       LDX   #$0000       CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5
5896 13C5: 1F 12          TFR   X,Y  CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7
5897 13C7: 1F 10          TFR   X,D  CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9
5898 13C9: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB
5899 13CB: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD
5900 13CD: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF
5901 13CF: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1
5902 13D1: 36 36          PSHU  A B X Y      CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3
5903 13D3: 36 10          PSHU  X    CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5
5904 13D5: 11 83 00 00    CMPU  #$0000       CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000
5905 #endif