]> Shamusworld >> Repos - stargem2/blob - src/v6809.cpp
Converted to SDL 2, added fullscreen support (F12 to toggle).
[stargem2] / src / v6809.cpp
1 //
2 // Virtual 6809 v1.4
3 //
4 // by James L. Hammons
5 // (c) 1997, 2009 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 // JLH  09/29/2009  Converted V6809 to macro implementation!
15 //
16
17 #define __DEBUG__
18
19 #include "v6809.h"
20
21 #ifdef __DEBUG__
22 #include "dis6809.h"    // Temporary...
23 #include "log.h"                // Temporary...
24 bool disasm = false;//so we can extern this shit
25 #endif
26
27 #define TEST_DONT_BRANCH_OPTIMIZATION
28
29 // Various macros
30
31 #define CLR_Z                           (flagZ = 0)
32 #define CLR_ZN                          (flagZ = flagN = 0)
33 #define CLR_ZNC                         (flagZ = flagN = flagC = 0)
34 #define CLR_V                           (flagV = 0)
35 #define CLR_N                           (flagN = 0)
36 #define SET_Z(r)                        (flagZ = ((r) == 0 ? 1 : 0))
37 #define SET_N(r)                        (flagN = ((r) & 0x80) >> 7)
38 #define SET_N16(r)                      (flagN = ((r) & 0x8000) >> 15)
39 #define SET_V(a,b,r)            (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
40 #define SET_V16(a,b,r)          (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
41 #define SET_H(a,b,r)            (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4)
42
43 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
44 //#define SET_C_ADD(a,b)                (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0))
45 //#define SET_C_SUB(a,b)                (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
46 //#define SET_C_CMP(a,b)                (flagC = ((uint8_t)(b) >= (uint8_t)(a) ? 1 : 0))
47 #define SET_ZN(r)                       SET_N(r); SET_Z(r)
48 #define SET_ZN16(r)                     SET_N16(r); SET_Z(r)
49 //#define SET_ZNC_ADD(a,b,r)    SET_N(r); SET_Z(r); SET_C_ADD(a,b)
50 //#define SET_ZNC_SUB(a,b,r)    SET_N(r); SET_Z(r); SET_C_SUB(a,b)
51 //#define SET_ZNC_CMP(a,b,r)    SET_N(r); SET_Z(r); SET_C_CMP(a,b)
52
53 #define EA_IMM                          regs.pc++
54 #define EA_DP                           (regs.dp << 8) | regs.RdMem(regs.pc++)
55 #define EA_IDX                          DecodeIDX(regs.RdMem(regs.pc++))
56 #define EA_ABS                          FetchMemW(regs.pc)
57
58 #define READ_IMM                        regs.RdMem(EA_IMM)
59 #define READ_IMM16                      FetchMemW(regs.pc)
60 #define READ_DP                         regs.RdMem(EA_DP)
61 #define READ_DP16                       RdMemW(EA_DP)
62 #define READ_IDX                        regs.RdMem(EA_IDX)
63 #define READ_IDX16                      RdMemW(EA_IDX)
64 #define READ_ABS                        regs.RdMem(EA_ABS)
65 #define READ_ABS16                      RdMemW(EA_ABS)
66
67 #define READ_IMM_WB(v)          uint16_t addr = EA_IMM;      v = regs.RdMem(addr)
68 #define READ_DP_WB(v)           uint16_t addr = EA_DP;       v = regs.RdMem(addr)
69 #define READ_IDX_WB(v)          uint16_t addr = EA_IDX;      v = regs.RdMem(addr)
70 #define READ_ABS_WB(v)          uint16_t addr = EA_ABS;      v = regs.RdMem(addr)
71
72 #define WRITE_BACK(d)           regs.WrMem(addr, (d))
73
74 #define PULLS(r)                        r = regs.RdMem(regs.s++)
75 #define PUSHS(r)                        regs.WrMem(--regs.s, (r))
76 #define PULLS16(r)                      { r = RdMemW(regs.s); regs.s += 2; }
77 #define PUSHS16(r)                      { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
78 #define PULLU(r)                        r = regs.RdMem(regs.u++)
79 #define PUSHU(r)                        regs.WrMem(--regs.u, (r))
80 #define PULLU16(r)                      { r = RdMemW(regs.u); regs.u += 2; }
81 #define PUSHU16(r)                      { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
82
83 #define PACK_FLAGS                      ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
84 #define UNPACK_FLAGS            flagE = (regs.cc & FLAG_E) >> 7; \
85         flagF = (regs.cc & FLAG_F) >> 6; \
86         flagH = (regs.cc & FLAG_H) >> 5; \
87         flagI = (regs.cc & FLAG_I) >> 4; \
88         flagN = (regs.cc & FLAG_N) >> 3; \
89         flagZ = (regs.cc & FLAG_Z) >> 2; \
90         flagV = (regs.cc & FLAG_V) >> 1; \
91         flagC = (regs.cc & FLAG_C)
92
93 // Private global variables
94
95 static V6809REGS regs;
96 static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
97
98 uint8_t page0Cycles[256] = {
99         6,  1,  1,  6,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,          // $0x
100         1,  1,  2,  2,  1,  1,  5,  9,  1,  2,  3,  1,  3,  2,  8,  7,          // $1x
101         3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,          // $2x
102         4,  4,  4,  4,  5,  5,  5,  5,  1,  5,  3,  6, 21, 11,  0, 19,          // $3x
103         2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  2,          // $4x
104         2,  1,  1,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  1,  1,          // $5x
105         6,  1,  1,  6,  6,  1,  6,  6,  6,  6,  6,  1,  6,  6,  3,  6,          // $6x
106         7,  1,  1,  7,  7,  1,  7,  7,  7,  7,  7,  1,  7,  7,  3,  7,          // $7x
107         2,  2,  2,  4,  2,  2,  2,  1,  2,  2,  2,  2,  4,  7,  3,  1,          // $8x
108         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  6,  7,  5,  5,          // $9x
109         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  6,  7,  5,  5,          // $Ax
110         5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  7,  8,  6,  6,          // $Bx
111         2,  2,  2,  4,  2,  2,  2,  1,  2,  2,  2,  2,  3,  1,  3,  1,          // $Cx
112         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,          // $Dx
113         4,  4,  4,  6,  4,  4,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,          // $Ex
114         5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6           // $Fx
115 };
116
117 uint8_t page1Cycles[256] = {
118         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $0x
119         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $1x
120         1,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,          // $2x
121         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 20,          // $3x
122         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $4x
123         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $5x
124         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $6x
125         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $7x
126         1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  4,  1,          // $8x
127         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  6,  6,          // $9x
128         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  6,  6,          // $Ax
129         1,  1,  1,  8,  1,  1,  1,  1,  1,  1,  1,  1,  8,  1,  7,  7,          // $Bx
130         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  4,  1,          // $Cx
131         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,          // $Dx
132         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,          // $Ex
133         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  7,  7           // $Fx
134 };
135
136 uint8_t page2Cycles[256] = {
137         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $0x
138         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $1x
139         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $2x
140         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 20,          // $3x
141         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $4x
142         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $5x
143         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $6x
144         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $7x
145         1,  1,  1,  5,  1,  1,  1,  1,  1,  1,  1,  1,  5,  1,  1,  1,          // $8x
146         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  1,  1,          // $9x
147         1,  1,  1,  7,  1,  1,  1,  1,  1,  1,  1,  1,  7,  1,  1,  1,          // $Ax
148         1,  1,  1,  8,  1,  1,  1,  1,  1,  1,  1,  1,  8,  1,  1,  1,          // $Bx
149         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Cx
150         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Dx
151         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,          // $Ex
152         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1           // $Fx
153 };
154
155 // Private function prototypes
156
157 static uint16_t RdMemW(uint16_t addr);
158 static uint16_t FetchMemW(uint16_t addr);
159 static void WrMemW(uint16_t addr, uint16_t w);
160 static uint16_t ReadEXG(uint8_t);                                       // Read TFR/EXG post byte
161 static void WriteEXG(uint8_t, uint16_t);                        // Set TFR/EXG data
162 static uint16_t DecodeReg(uint8_t);                                     // Decode register data
163 static uint16_t DecodeIDX(uint8_t);                                     // Decode IDX data
164
165 //
166 // Read word from memory function
167 //
168 static inline uint16_t RdMemW(uint16_t addr)
169 {
170         return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
171 }
172
173 //
174 // Fetch a word from memory function. Increments PC
175 //
176 static inline uint16_t FetchMemW(uint16_t addr)
177 {
178         regs.pc += 2;
179         return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
180 }
181
182 //
183 // Write word to memory function
184 //
185 static inline void WrMemW(uint16_t addr, uint16_t w)
186 {
187         regs.WrMem(addr + 0, w >> 8);
188         regs.WrMem(addr + 1, w & 0xFF);
189 }
190
191 //
192 // Function to read TFR/EXG post byte
193 //
194 uint16_t ReadEXG(uint8_t code)
195 {
196         uint16_t retval;
197
198         switch (code)
199         {
200         case 0:
201                 retval = (regs.a << 8) | regs.b;
202                 break;
203         case 1:
204                 retval = regs.x;
205                 break;
206         case 2:
207                 retval = regs.y;
208                 break;
209         case 3:
210                 retval = regs.u;
211                 break;
212         case 4:
213                 retval = regs.s;
214                 break;
215         case 5:
216                 retval = regs.pc;
217                 break;
218         case 8:
219                 retval = regs.a;
220                 break;
221         case 9:
222                 retval = regs.b;
223                 break;
224         case 10:
225                 PACK_FLAGS;
226                 retval = regs.cc;
227                 break;
228         case 11:
229                 retval = regs.dp;
230                 break;
231         default:
232                 retval = 0xFF;
233         }
234
235         return retval;
236 }
237
238 //
239 // Function to set TFR/EXG data
240 //
241 void WriteEXG(uint8_t code, uint16_t data)
242 {
243         switch (code)
244         {
245         case 0:
246                 regs.a = data >> 8, regs.b = data & 0xFF;  break;
247         case 1:
248                 regs.x = data;  break;
249         case 2:
250                 regs.y = data;  break;
251         case 3:
252                 regs.u = data;  break;
253         case 4:
254                 regs.s = data;  break;
255         case 5:
256                 regs.pc = data;  break;
257         case 8:
258                 regs.a = data & 0xFF;  break;
259         case 9:
260                 regs.b = data & 0xFF;  break;
261         case 10:
262                 regs.cc = data & 0xFF;  UNPACK_FLAGS;  break;
263         case 11:
264                 regs.dp = data & 0xFF;  break;
265         }
266 }
267
268 //
269 // Function to decode register data
270 //
271 uint16_t DecodeReg(uint8_t reg)
272 {
273         uint16_t retval;
274
275         switch (reg)
276         {
277         case 0:
278         retval = regs.x;  break;
279         case 1:
280         retval = regs.y;  break;
281         case 2:
282         retval = regs.u;  break;
283         case 3:
284         retval = regs.s;  break;
285         }
286
287         return retval;
288 }
289
290 //
291 // Function to decode IDX data
292 //
293 uint16_t DecodeIDX(uint8_t code)
294 {
295         uint16_t addr, woff;
296         uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
297
298         if (!(code & 0x80))                                                     // Hi bit unset? Then decode 4 bit offset
299                 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
300         else
301         {
302                 if (idxind)
303                 {
304                         switch (lo_nyb)
305                         {
306                         case 1:
307                                 woff = DecodeReg(reg);
308                                 addr = RdMemW(woff);
309                                 switch (reg)
310                                 {
311                                 case 0:  regs.x += 2;  break;
312                                 case 1:  regs.y += 2;  break;
313                                 case 2:  regs.u += 2;  break;
314                                 case 3:  regs.s += 2;  break;
315                                 }
316                                 break;
317                         case 3:
318                                 switch (reg)
319                                 {
320                                 case 0:  regs.x -= 2;  break;
321                                 case 1:  regs.y -= 2;  break;
322                                 case 2:  regs.u -= 2;  break;
323                                 case 3:  regs.s -= 2;  break;
324                                 }
325                                 woff = DecodeReg(reg);
326                                 addr = RdMemW(woff);
327                                 break;
328                         case 4:
329                                 woff = DecodeReg(reg);
330                                 addr = RdMemW(woff);
331                                 break;
332                         case 5:
333                                 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
334                                 addr = RdMemW(woff);
335                                 break;
336                         case 6:
337                                 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
338                                 addr = RdMemW(woff);
339                                 break;
340                         case 8:
341                                 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
342                                 addr = RdMemW(woff);
343                                 break;
344                         case 9:
345                                 woff = DecodeReg(reg) + FetchMemW(regs.pc);
346                                 addr = RdMemW(woff);
347                                 break;
348                         case 11:
349                                 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
350                                 addr = RdMemW(woff);
351                                 break;
352                         case 12:
353                                 woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
354                                 addr = RdMemW(woff);
355                                 break;
356                         case 13:
357                                 woff = regs.pc + FetchMemW(regs.pc);
358                                 addr = RdMemW(woff);
359                                 break;
360                         case 15:
361                                 woff = FetchMemW(regs.pc);
362                                 addr = RdMemW(woff);
363                                 break;
364                         }
365                 }
366                 else
367                 {
368                         switch (lo_nyb)
369                         {
370                         case 0:
371                                 addr = DecodeReg(reg);
372                                 switch (reg)
373                                 {
374                                 case 0:  regs.x++;  break;
375                                 case 1:  regs.y++;  break;
376                                 case 2:  regs.u++;  break;
377                                 case 3:  regs.s++;  break;
378                                 }
379                                 break;
380                         case 1:
381                                 addr = DecodeReg(reg);
382                                 switch (reg)
383                                 {
384                                 case 0:  regs.x += 2;  break;
385                                 case 1:  regs.y += 2;  break;
386                                 case 2:  regs.u += 2;  break;
387                                 case 3:  regs.s += 2;  break;
388                                 }
389                                 break;
390         case 2:  { switch(reg)
391                    {
392                      case 0:  regs.x--;  break;
393                      case 1:  regs.y--;  break;
394                      case 2:  regs.u--;  break;
395                      case 3:  regs.s--;  break;
396                    }
397                    addr = DecodeReg(reg);  break; }
398         case 3:  { switch(reg)
399                    {
400                      case 0:  regs.x--;  regs.x--;  break;
401                      case 1:  regs.y--;  regs.y--;  break;
402                      case 2:  regs.u--;  regs.u--;  break;
403                      case 3:  regs.s--;  regs.s--;  break;
404                    }
405                    addr = DecodeReg(reg);  break; }
406         case 4:  { addr = DecodeReg(reg);  break; }
407         case 5:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b;  break; }
408         case 6:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a;  break; }
409         case 8:  { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
410         case 9:  { addr = DecodeReg(reg) + FetchMemW(regs.pc);  break; }
411         case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);  break; }
412         case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);  break; }
413         case 13: { addr = regs.pc + FetchMemW(regs.pc);  break; }
414                         }
415                 }
416         }
417
418         return addr;
419 }
420
421 //
422 // 6809 OPCODE IMPLEMENTATION
423 //
424 // NOTE: Lots of macros are used here to save a LOT of typing. Also
425 //       helps speed the debugging process. :-) Because of this, combining
426 //       certain lines may look like a good idea but would end in disaster.
427 //       You have been warned! ;-)
428 //
429
430 /*
431  +-----------------------------------------------------------------+
432  | Opcode     |             | Addressing   |               |       |
433  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
434  +------------+-------------+--------------+-------+-------+-------+
435  | 89    0137 | ADCA        | IMMEDIATE    |   2   |   2   | aaaaa |
436  | 99    0153 | ADCA        | DIRECT       |   4   |   2   | aaaaa |
437  | A9    0169 | ADCA        | INDEXED      |   4   |   2   | aaaaa |
438  | B9    0185 | ADCA        | EXTENDED     |   5   |   3   | aaaaa |
439  | C9    0201 | ADCB        | IMMEDIATE    |   2   |   2   | aaaaa |
440  | D9    0217 | ADCB        | DIRECT       |   4   |   2   | aaaaa |
441  | E9    0233 | ADCB        | INDEXED      |   4   |   2   | aaaaa |
442  | F9    0249 | ADCB        | EXTENDED     |   5   |   3   | aaaaa |
443 */
444
445 // ADC opcodes
446
447 #define OP_ADC_HANDLER(m, acc) \
448         uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
449         flagC = (sum >> 8) & 0x01; \
450         SET_H(m, acc, sum); \
451         SET_V(m, acc, sum); \
452         acc = sum & 0xFF; \
453         SET_ZN(acc)
454
455 /*
456 Old flag handling code:
457   (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry
458   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
459   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
460   regs.a = addr & 0xFF;                       // Set accumulator
461   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero
462   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative
463 */
464
465 static void Op89(void)                                                  // ADCA #
466 {
467         uint16_t m = READ_IMM;
468         OP_ADC_HANDLER(m, regs.a);
469 }
470
471 static void Op99(void)                                                  // ADCA DP
472 {
473         uint16_t m = READ_DP;
474         OP_ADC_HANDLER(m, regs.a);
475 }
476
477 static void OpA9(void)                                                  // ADCA IDX
478 {
479         uint16_t m = READ_IDX;
480         OP_ADC_HANDLER(m, regs.a);
481 }
482
483 static void OpB9(void)                                                  // ADCA ABS
484 {
485         uint16_t m = READ_ABS;
486         OP_ADC_HANDLER(m, regs.a);
487 }
488
489 static void OpC9(void)                                                  // ADCB #
490 {
491         uint16_t m = READ_IMM;
492         OP_ADC_HANDLER(m, regs.b);
493 }
494
495 static void OpD9(void)                                                  // ADCB DP
496 {
497         uint16_t m = READ_DP;
498         OP_ADC_HANDLER(m, regs.b);
499 }
500
501 static void OpE9(void)                                                  // ADCB IDX
502 {
503         uint16_t m = READ_IDX;
504         OP_ADC_HANDLER(m, regs.b);
505 }
506
507 static void OpF9(void)                                                  // ADCB ABS
508 {
509         uint16_t m = READ_ABS;
510         OP_ADC_HANDLER(m, regs.b);
511 }
512
513 /*
514  +-----------------------------------------------------------------+
515  | Opcode     |             | Addressing   |               |       |
516  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
517  +------------+-------------+--------------+-------+-------+-------+
518  | 3A    0058 | ABX         | INHERENT     |   3   |   1   | ----- |
519  | 8B    0139 | ADDA        | IMMEDIATE    |   2   |   2   | aaaaa |
520  | 9B    0155 | ADDA        | DIRECT       |   4   |   2   | aaaaa |
521  | AB    0171 | ADDA        | INDEXED      |   4   |   2   | aaaaa |
522  | BB    0187 | ADDA        | EXTENDED     |   5   |   3   | aaaaa |
523  | C3    0195 | ADDD        | IMMEDIATE    |   4   |   3   | -aaaa |
524  | CB    0203 | ADDB        | IMMEDIATE    |   2   |   2   | aaaaa |
525  | D3    0211 | ADDD        | DIRECT       |   6   |   2   | -aaaa |
526  | DB    0219 | ADDB        | DIRECT       |   4   |   2   | aaaaa |
527  | E3    0227 | ADDD        | INDEXED      |   6   |   2   | -aaaa |
528  | EB    0235 | ADDB        | INDEXED      |   4   |   2   | aaaaa |
529  | F3    0243 | ADDD        | EXTENDED     |   7   |   3   | -aaaa |
530  | FB    0251 | ADDB        | EXTENDED     |   5   |   3   | aaaaa |
531 */
532
533 // ADD opcodes
534
535 #define OP_ADD_HANDLER(m, acc) \
536         uint16_t sum = (uint16_t)(acc) + (m); \
537         flagC = (sum >> 8) & 0x01; \
538         SET_H(m, acc, sum); \
539         SET_V(m, acc, sum); \
540         (acc) = sum & 0xFF; \
541         SET_ZN(acc)
542
543 #define OP_ADD_HANDLER16(m, hireg, loreg) \
544         uint32_t acc = (uint32_t)((hireg << 8) | loreg); \
545         uint32_t sum = acc + (m); \
546         flagC = (sum >> 16) & 0x01; \
547         SET_V16(m, acc, sum); \
548         acc = sum & 0xFFFF; \
549         hireg = (acc >> 8) & 0xFF; \
550         loreg = acc & 0xFF; \
551         SET_ZN16(acc)
552
553 /*
554 Old flags:
555   (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
556   ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF);  // Set Half carry
557   ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
558   regs.a = addr & 0xFF;                       // Set accumulator
559   (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Set Zero flag
560   (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Set Negative flag
561
562   dr += addr;
563   (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE);  // Adjust Carry flag
564   dr &= 0xFFFF;
565   (dr == 0   ? regs.cc |= 0x04 : regs.cc &= 0xFB);  // Adjust Zero flag
566   (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7);  // Adjust Negative flag
567   ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
568   regs.a = dr>>8;  regs.b = dr&0xFF;
569   regs.clock += 4;
570 */
571
572 static void Op3A(void)                                                  // ABX
573 {
574         regs.x += (uint16_t)regs.b;
575 }
576
577 static void Op8B(void)                                                  // ADDA #
578 {
579         uint16_t m = READ_IMM;
580         OP_ADD_HANDLER(m, regs.a);
581 }
582
583 static void Op9B(void)                                                  // ADDA DP
584 {
585         uint16_t m = READ_DP;
586         OP_ADD_HANDLER(m, regs.a);
587 }
588
589 static void OpAB(void)                                                  // ADDA IDX
590 {
591         uint16_t m = READ_IDX;
592         OP_ADD_HANDLER(m, regs.a);
593 }
594
595 static void OpBB(void)                                                  // ADDA ABS
596 {
597         uint16_t m = READ_ABS;
598         OP_ADD_HANDLER(m, regs.a);
599 }
600
601 static void OpC3(void)                                                  // ADDD #
602 {
603         uint32_t m = READ_IMM16;
604         OP_ADD_HANDLER16(m, regs.a, regs.b);
605 }
606
607 static void OpCB(void)                                                  // ADDB #
608 {
609         uint16_t m = READ_IMM;
610         OP_ADD_HANDLER(m, regs.b);
611 }
612
613 static void OpD3(void)                                                  // ADDD DP
614 {
615         uint32_t m = READ_DP16;
616         OP_ADD_HANDLER16(m, regs.a, regs.b);
617 }
618
619 static void OpDB(void)                                                  // ADDB DP
620 {
621         uint16_t m = READ_DP;
622         OP_ADD_HANDLER(m, regs.b);
623 }
624
625 static void OpE3(void)                                                  // ADDD IDX
626 {
627         uint32_t m = READ_IDX16;
628         OP_ADD_HANDLER16(m, regs.a, regs.b);
629 }
630
631 static void OpEB(void)                                                  // ADDB IDX
632 {
633         uint16_t m = READ_IDX;
634         OP_ADD_HANDLER(m, regs.b);
635 }
636
637 static void OpF3(void)                                                  // ADDD ABS
638 {
639         uint32_t m = READ_ABS16;
640         OP_ADD_HANDLER16(m, regs.a, regs.b);
641 }
642
643 static void OpFB(void)                                                  // ADDB ABS
644 {
645         uint16_t m = READ_ABS;
646         OP_ADD_HANDLER(m, regs.b);
647 }
648
649 /*
650  +-----------------------------------------------------------------+
651  | Opcode     |             | Addressing   |               |       |
652  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
653  +------------+-------------+--------------+-------+-------+-------+
654  | 84    0132 | ANDA        | IMMEDIATE    |   2   |   2   | -aa0- |
655  | 94    0148 | ANDA        | DIRECT       |   4   |   2   | -aa0- |
656  | A4    0164 | ANDA        | INDEXED      |   4   |   2   | -aa0- |
657  | B4    0180 | ANDA        | EXTENDED     |   5   |   3   | -aa0- |
658  | C4    0196 | ANDB        | IMMEDIATE    |   2   |   2   | -aa0- |
659  | D4    0212 | ANDB        | DIRECT       |   4   |   2   | -aa0- |
660  | E4    0228 | ANDB        | INDEXED      |   4   |   2   | -aa0- |
661  | F4    0244 | ANDB        | EXTENDED     |   5   |   3   | -aa0- |
662 */
663
664 // AND opcodes
665
666 #define OP_AND_HANDLER(m, acc) \
667         acc &= m; \
668         SET_ZN(acc); \
669         CLR_V
670
671 static void Op84(void)                                                  // ANDA #
672 {
673         uint16_t m = READ_IMM;
674         OP_AND_HANDLER(m, regs.a);
675 }
676
677 static void Op94(void)                                                  // ANDA DP
678 {
679         uint16_t m = READ_DP;
680         OP_AND_HANDLER(m, regs.a);
681 }
682
683 static void OpA4(void)                                                  // ANDA IDX
684 {
685         uint16_t m = READ_IDX;
686         OP_AND_HANDLER(m, regs.a);
687 }
688
689 static void OpB4(void)                                                  // ANDA ABS
690 {
691         uint16_t m = READ_ABS;
692         OP_AND_HANDLER(m, regs.a);
693 }
694
695 static void OpC4(void)                                                  // ANDB #
696 {
697         uint16_t m = READ_IMM;
698         OP_AND_HANDLER(m, regs.b);
699 }
700
701 static void OpD4(void)                                                  // ANDB DP
702 {
703         uint16_t m = READ_DP;
704         OP_AND_HANDLER(m, regs.b);
705 }
706
707 static void OpE4(void)                                                  // ANDB IDX
708 {
709         uint16_t m = READ_IDX;
710         OP_AND_HANDLER(m, regs.b);
711 }
712
713 static void OpF4(void)                                                  // ANDB ABS
714 {
715         uint16_t m = READ_ABS;
716         OP_AND_HANDLER(m, regs.b);
717 }
718
719 /*
720  +-----------------------------------------------------------------+
721  | Opcode     |             | Addressing   |               |       |
722  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
723  +------------+-------------+--------------+-------+-------+-------+
724  | 08    0008 | LSL/ASL     | DIRECT       |   6   |   2   | naaas |
725  | 48    0072 | LSLA/ASLA   | INHERENT     |   2   |   1   | naaas |
726  | 58    0088 | LSLB/ASLB   | INHERENT     |   2   |   1   | naaas |
727  | 68    0104 | LSL/ASL     | INDEXED      |   6   |   2   | naaas |
728  | 78    0120 | LSL/ASL     | EXTENDED     |   7   |   3   | naaas |
729 */
730
731 // ASL opcodes
732
733 #define OP_ASL_HANDLER(m) \
734         uint16_t res = m << 1; \
735         SET_V(m, m, res); \
736         flagC = (res >> 8) & 0x01; \
737         m = res & 0xFF; \
738         SET_ZN(m)
739
740 static void Op08(void)                                                  // ASL DP
741 {
742         uint8_t m;
743         READ_DP_WB(m);
744         OP_ASL_HANDLER(m);
745         WRITE_BACK(m);
746 }
747
748 static void Op48(void)                                                  // ASLA
749 {
750         OP_ASL_HANDLER(regs.a);
751 }
752
753 static void Op58(void)                                                  // ASLB
754 {
755         OP_ASL_HANDLER(regs.b);
756 }
757
758 static void Op68(void)                                                  // ASL IDX
759 {
760         uint8_t m;
761         READ_IDX_WB(m);
762         OP_ASL_HANDLER(m);
763         WRITE_BACK(m);
764 }
765
766 static void Op78(void)                                                  // ASL ABS
767 {
768         uint8_t m;
769         READ_ABS_WB(m);
770         OP_ASL_HANDLER(m);
771         WRITE_BACK(m);
772 }
773
774 /*
775  +-----------------------------------------------------------------+
776  | Opcode     |             | Addressing   |               |       |
777  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
778  +------------+-------------+--------------+-------+-------+-------+
779  | 07    0007 | ASR         | DIRECT       |   6   |   2   | uaa-s |
780  | 47    0071 | ASRA        | INHERENT     |   2   |   1   | uaa-s |
781  | 57    0087 | ASRB        | INHERENT     |   2   |   1   | uaa-s |
782  | 67    0103 | ASR         | INDEXED      |   6   |   2   | uaa-s |
783  | 77    0119 | ASR         | EXTENDED     |   7   |   3   | uaa-s |
784 */
785
786 // ASR opcodes (arithmetic, so preserves the sign)
787
788 #define OP_ASR_HANDLER(m) \
789         uint8_t res = (m & 0x80) | (m >> 1); \
790         SET_ZN(res); \
791         flagC = m & 0x01; \
792         m = res
793
794 static void Op07(void)                                                  // ASR DP
795 {
796         uint8_t m;
797         READ_DP_WB(m);
798         OP_ASR_HANDLER(m);
799         WRITE_BACK(m);
800 }
801
802 static void Op47(void)                                                  // ASRA
803 {
804         OP_ASR_HANDLER(regs.a);
805 }
806
807 static void Op57(void)                                                  // ASRB
808 {
809         OP_ASR_HANDLER(regs.b);
810 }
811
812 static void Op67(void)                                                  // ASR IDX
813 {
814         uint8_t m;
815         READ_IDX_WB(m);
816         OP_ASR_HANDLER(m);
817         WRITE_BACK(m);
818 }
819
820 static void Op77(void)                                                  // ASR ABS
821 {
822         uint8_t m;
823         READ_ABS_WB(m);
824         OP_ASR_HANDLER(m);
825         WRITE_BACK(m);
826 }
827
828 /*
829  +-----------------------------------------------------------------+
830  | Opcode     |             | Addressing   |               |       |
831  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
832  +------------+-------------+--------------+-------+-------+-------+
833  | 16    0022 | LBRA        | RELATIVE     |   5   |   3   | ----- |
834  | 20    0032 | BRA         | RELATIVE     |   3   |   2   | ----- |
835  | 21    0033 | BRN         | RELATIVE     |   3   |   2   | ----- |
836  | 22    0034 | BHI         | RELATIVE     |   3   |   2   | ----- |
837  | 23    0035 | BLS         | RELATIVE     |   3   |   2   | ----- |
838  | 24    0036 | BHS/BCC     | RELATIVE     |   3   |   2   | ----- |
839  | 25    0037 | BLO/BCS     | RELATIVE     |   3   |   2   | ----- |
840  | 26    0038 | BNE         | RELATIVE     |   3   |   2   | ----- |
841  | 27    0039 | BEQ         | RELATIVE     |   3   |   2   | ----- |
842  | 28    0040 | BVC         | RELATIVE     |   3   |   2   | ----- |
843  | 29    0041 | BVS         | RELATIVE     |   3   |   2   | ----- |
844  | 2A    0042 | BPL         | RELATIVE     |   3   |   2   | ----- |
845  | 2B    0043 | BMI         | RELATIVE     |   3   |   2   | ----- |
846  | 2C    0044 | BGE         | RELATIVE     |   3   |   2   | ----- |
847  | 2D    0045 | BLT         | RELATIVE     |   3   |   2   | ----- |
848  | 2E    0046 | BGT         | RELATIVE     |   3   |   2   | ----- |
849  | 2F    0047 | BLE         | RELATIVE     |   3   |   2   | ----- |
850  | 1021  4129 | LBRN        | RELATIVE     | 5(6)  |   4   | ----- |
851  | 1022  4130 | LBHI        | RELATIVE     | 5(6)  |   4   | ----- |
852  | 1023  4131 | LBLS        | RELATIVE     | 5(6)  |   4   | ----- |
853  | 1024  4132 | LBHS/LBCC   | RELATIVE     | 5(6)  |   4   | ----- |
854  | 1025  4133 | LBLO/LBCS   | RELATIVE     | 5(6)  |   4   | ----- |
855  | 1026  4134 | LBNE        | RELATIVE     | 5(6)  |   4   | ----- |
856  | 1027  4135 | LBEQ        | RELATIVE     | 5(6)  |   4   | ----- |
857  | 1028  4136 | LBVC        | RELATIVE     | 5(6)  |   4   | ----- |
858  | 1029  4137 | LBVS        | RELATIVE     | 5(6)  |   4   | ----- |
859  | 102A  4138 | LBPL        | RELATIVE     | 5(6)  |   4   | ----- |
860  | 102B  4139 | LBMI        | RELATIVE     | 5(6)  |   4   | ----- |
861  | 102C  4140 | LBGE        | RELATIVE     | 5(6)  |   4   | ----- |
862  | 102D  4141 | LBLT        | RELATIVE     | 5(6)  |   4   | ----- |
863  | 102E  4142 | LBGT        | RELATIVE     | 5(6)  |   4   | ----- |
864  | 102F  4143 | LBLE        | RELATIVE     | 5(6)  |   4   | ----- |
865 */
866
867 // Branch opcodes
868
869 static void Op16(void)                                                  // LBRA
870 {
871         uint16_t offset = READ_IMM16;
872         regs.pc += offset;
873 }
874
875 static void Op20(void)                                                  // BRA
876 {
877         int16_t offset = (int16_t)(int8_t)READ_IMM;
878         regs.pc += offset;
879 }
880
881 static void Op21(void)                                                  // BRN
882 {
883         // This is basically a 2 byte NOP
884         int16_t offset = (int16_t)(int8_t)READ_IMM;
885 }
886
887 static void Op22(void)                                                  // BHI
888 {
889         // !C && !Z
890         int16_t offset = (int16_t)(int8_t)READ_IMM;
891
892 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
893 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
894         regs.pc += offset * ((flagZ | flagC) ^ 0x01);
895 #else
896         if (!(flagZ || flagC))
897                 regs.pc += offset;
898 #endif
899 }
900
901 static void Op23(void)                                                  // BLS
902 {
903         // C || Z
904         int16_t offset = (int16_t)(int8_t)READ_IMM;
905
906 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
907         regs.pc += offset * (flagZ | flagC);
908 #else
909         if (flagZ || flagC)
910                 regs.pc += offset;
911 #endif
912 }
913
914 static void Op24(void)                                                  // BHS/CC
915 {
916         // !C
917         int16_t offset = (int16_t)(int8_t)READ_IMM;
918
919 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
920         regs.pc += offset * (flagC ^ 0x01);
921 #else
922         if (!flagC)
923                 regs.pc += offset;
924 #endif
925 }
926
927 static void Op25(void)                                                  // BLO/CS
928 {
929         // C
930         int16_t offset = (int16_t)(int8_t)READ_IMM;
931 //if (disasm)
932 //      WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
933
934 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
935         regs.pc += offset * flagC;
936 #else
937         if (flagC)
938                 regs.pc += offset;
939 #endif
940 }
941
942 static void Op26(void)                                                  // BNE
943 {
944         // !Z
945         int16_t offset = (int16_t)(int8_t)READ_IMM;
946
947 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
948         regs.pc += offset * (flagZ ^ 0x01);
949 #else
950         if (!flagZ)
951                 regs.pc += offset;
952 #endif
953 }
954
955 static void Op27(void)                                                  // BEQ
956 {
957         // Z
958         int16_t offset = (int16_t)(int8_t)READ_IMM;
959
960 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
961         regs.pc += offset * flagZ;
962 #else
963         if (flagZ)
964                 regs.pc += offset;
965 #endif
966 }
967
968 static void Op28(void)                                                  // BVC
969 {
970         // !V
971         int16_t offset = (int16_t)(int8_t)READ_IMM;
972
973 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
974         regs.pc += offset * (flagV ^ 0x01);
975 #else
976         if (!flagV)
977                 regs.pc += offset;
978 #endif
979 }
980
981 static void Op29(void)                                                  // BVS
982 {
983         // V
984         int16_t offset = (int16_t)(int8_t)READ_IMM;
985
986 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
987         regs.pc += offset * flagV;
988 #else
989         if (flagV)
990                 regs.pc += offset;
991 #endif
992 }
993
994 static void Op2A(void)                                                  // BPL
995 {
996         // !N
997         int16_t offset = (int16_t)(int8_t)READ_IMM;
998
999 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1000         regs.pc += offset * (flagN ^ 0x01);
1001 #else
1002         if (!flagN)
1003                 regs.pc += offset;
1004 #endif
1005 }
1006
1007 static void Op2B(void)                                                  // BMI
1008 {
1009         // N
1010         int16_t offset = (int16_t)(int8_t)READ_IMM;
1011
1012 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1013         regs.pc += offset * flagN;
1014 #else
1015         if (flagN)
1016                 regs.pc += offset;
1017 #endif
1018 }
1019
1020 static void Op2C(void)                                                  // BGE
1021 {
1022         // (N && V) || (!N && !V)
1023         int16_t offset = (int16_t)(int8_t)READ_IMM;
1024
1025 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1026         regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1027 #else
1028         if ((flagN && flagV) || (!flagN && !flagV))
1029                 regs.pc += offset;
1030 #endif
1031 }
1032
1033 static void Op2D(void)                                                  // BLT
1034 {
1035         // (N && !V) || (!N && V)
1036         int16_t offset = (int16_t)(int8_t)READ_IMM;
1037
1038 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1039         regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1040 #else
1041         if ((flagN && !flagV) || (!flagN && flagV))
1042                 regs.pc += offset;
1043 #endif
1044 }
1045
1046 static void Op2E(void)                                                  // BGT
1047 {
1048         // (N && V && !Z) || (!N && !V && !Z)
1049         int16_t offset = (int16_t)(int8_t)READ_IMM;
1050
1051 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1052         regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1053 #else
1054         if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1055                 regs.pc += offset;
1056 #endif
1057 }
1058
1059 static void Op2F(void)                                                  // BLE
1060 {
1061         // Z || (N && !V) || (!N && V)
1062         int16_t offset = (int16_t)(int8_t)READ_IMM;
1063
1064 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1065         regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1066 #else
1067         if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1068                 regs.pc += offset;
1069 #endif
1070 }
1071
1072 static void Op1021(void)                                                // LBRN
1073 {
1074         // This is basically a 4 byte NOP
1075         uint16_t offset = READ_IMM16;
1076 }
1077
1078 static void Op1022(void)                                                // LBHI
1079 {
1080         // !C && !Z
1081         uint16_t offset = READ_IMM16;
1082
1083 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1084 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1085         regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1086 #else
1087         if (!(flagZ || flagC))
1088                 regs.pc += offset;
1089 #endif
1090 }
1091
1092 static void Op1023(void)                                                // LBLS
1093 {
1094         // C || Z
1095         uint16_t offset = READ_IMM16;
1096
1097 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1098         regs.pc += offset * (flagZ | flagC);
1099 #else
1100         if (flagZ || flagC)
1101                 regs.pc += offset;
1102 #endif
1103 }
1104
1105 static void Op1024(void)                                                // LBHS/CC
1106 {
1107         // !C
1108         uint16_t offset = READ_IMM16;
1109
1110 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1111         regs.pc += offset * (flagC ^ 0x01);
1112 #else
1113         if (!flagC)
1114                 regs.pc += offset;
1115 #endif
1116 }
1117
1118 static void Op1025(void)                                                // LBLO/CS
1119 {
1120         // C
1121         uint16_t offset = READ_IMM16;
1122
1123 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1124         regs.pc += offset * flagC;
1125 #else
1126         if (flagC)
1127                 regs.pc += offset;
1128 #endif
1129 }
1130
1131 static void Op1026(void)                                                // LBNE
1132 {
1133         // !Z
1134         uint16_t offset = READ_IMM16;
1135
1136 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1137         regs.pc += offset * (flagZ ^ 0x01);
1138 #else
1139         if (!flagZ)
1140                 regs.pc += offset;
1141 #endif
1142 }
1143
1144 static void Op1027(void)                                                // LBEQ
1145 {
1146         // Z
1147         uint16_t offset = READ_IMM16;
1148
1149 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1150         regs.pc += offset * flagZ;
1151 #else
1152         if (flagZ)
1153                 regs.pc += offset;
1154 #endif
1155 }
1156
1157 static void Op1028(void)                                                // LBVC
1158 {
1159         // !V
1160         uint16_t offset = READ_IMM16;
1161
1162 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1163         regs.pc += offset * (flagV ^ 0x01);
1164 #else
1165         if (!flagV)
1166                 regs.pc += offset;
1167 #endif
1168 }
1169
1170 static void Op1029(void)                                                // LBVS
1171 {
1172         // V
1173         uint16_t offset = READ_IMM16;
1174
1175 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1176         regs.pc += offset * flagV;
1177 #else
1178         if (flagV)
1179                 regs.pc += offset;
1180 #endif
1181 }
1182
1183 static void Op102A(void)                                                // LBPL
1184 {
1185         // !N
1186         uint16_t offset = READ_IMM16;
1187
1188 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1189         regs.pc += offset * (flagN ^ 0x01);
1190 #else
1191         if (!flagN)
1192                 regs.pc += offset;
1193 #endif
1194 }
1195
1196 static void Op102B(void)                                                // LBMI
1197 {
1198         // N
1199         uint16_t offset = READ_IMM16;
1200
1201 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1202         regs.pc += offset * flagN;
1203 #else
1204         if (flagN)
1205                 regs.pc += offset;
1206 #endif
1207 }
1208
1209 static void Op102C(void)                                                // LBGE
1210 {
1211         // (N && V) || (!N && !V)
1212         uint16_t offset = READ_IMM16;
1213
1214 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1215         regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1216 #else
1217         if ((flagN && flagV) || (!flagN && !flagV))
1218                 regs.pc += offset;
1219 #endif
1220 }
1221
1222 static void Op102D(void)                                                // LBLT
1223 {
1224         // (N && !V) || (!N && V)
1225         uint16_t offset = READ_IMM16;
1226
1227 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1228         regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1229 #else
1230         if ((flagN && !flagV) || (!flagN && flagV))
1231                 regs.pc += offset;
1232 #endif
1233 }
1234
1235 static void Op102E(void)                                                // LBGT
1236 {
1237         // (N && V && !Z) || (!N && !V && !Z)
1238         uint16_t offset = READ_IMM16;
1239
1240 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1241         regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1242 #else
1243         if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1244                 regs.pc += offset;
1245 #endif
1246 }
1247
1248 static void Op102F(void)                                                // LBLE
1249 {
1250         // Z || (N && !V) || (!N && V)
1251         uint16_t offset = READ_IMM16;
1252
1253 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1254         regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1255 #else
1256         if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1257                 regs.pc += offset;
1258 #endif
1259 }
1260
1261 /*
1262  +-----------------------------------------------------------------+
1263  | Opcode     |             | Addressing   |               |       |
1264  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1265  +------------+-------------+--------------+-------+-------+-------+
1266  | 85    0133 | BITA        | IMMEDIATE    |   2   |   2   | -aa0- |
1267  | 95    0149 | BITA        | DIRECT       |   4   |   2   | -aa0- |
1268  | A5    0165 | BITA        | INDEXED      |   4   |   2   | -aa0- |
1269  | B5    0181 | BITA        | EXTENDED     |   5   |   3   | -aa0- |
1270  | C5    0197 | BITB        | IMMEDIATE    |   2   |   2   | -aa0- |
1271  | D5    0213 | BITB        | DIRECT       |   4   |   2   | -aa0- |
1272  | E5    0229 | BITB        | INDEXED      |   4   |   2   | -aa0- |
1273  | F5    0245 | BITB        | EXTENDED     |   5   |   3   | -aa0- |
1274 */
1275
1276 // BIT opcodes
1277
1278 #define OP_BIT_HANDLER(m, acc) \
1279         uint8_t result = acc & (m); \
1280         SET_ZN(result); \
1281         CLR_V
1282
1283 static void Op85(void)                                                  // BITA #
1284 {
1285         uint8_t m = READ_IMM;
1286         OP_BIT_HANDLER(m, regs.a);
1287 }
1288
1289 static void Op95(void)                                                  // BITA DP
1290 {
1291         uint8_t m = READ_DP;
1292         OP_BIT_HANDLER(m, regs.a);
1293 }
1294
1295 static void OpA5(void)                                                  // BITA IDX
1296 {
1297         uint8_t m = READ_IDX;
1298         OP_BIT_HANDLER(m, regs.a);
1299 }
1300
1301 static void OpB5(void)                                                  // BITA ABS
1302 {
1303         uint8_t m = READ_ABS;
1304         OP_BIT_HANDLER(m, regs.a);
1305 }
1306
1307 static void OpC5(void)                                                  // BITB #
1308 {
1309         uint8_t m = READ_IMM;
1310         OP_BIT_HANDLER(m, regs.b);
1311 }
1312
1313 static void OpD5(void)                                                  // BITB DP
1314 {
1315         uint8_t m = READ_DP;
1316         OP_BIT_HANDLER(m, regs.b);
1317 }
1318
1319 static void OpE5(void)                                                  // BITB IDX
1320 {
1321         uint8_t m = READ_IDX;
1322         OP_BIT_HANDLER(m, regs.b);
1323 }
1324
1325 static void OpF5(void)                                                  // BITB ABS
1326 {
1327         uint8_t m = READ_ABS;
1328         OP_BIT_HANDLER(m, regs.b);
1329 }
1330
1331 /*
1332  +-----------------------------------------------------------------+
1333  | Opcode     |             | Addressing   |               |       |
1334  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1335  +------------+-------------+--------------+-------+-------+-------+
1336  | 0F    0015 | CLR         | DIRECT       |   6   |   2   | -0100 |
1337  | 4F    0079 | CLRA        | INHERENT     |   2   |   1   | -0100 |
1338  | 5F    0095 | CLRB        | INHERENT     |   2   |   1   | -0100 |
1339  | 6F    0111 | CLR         | INDEXED      |   6   |   2   | -0100 |
1340  | 7F    0127 | CLR         | EXTENDED     |   7   |   3   | -0100 |
1341 */
1342
1343 // CLR opcodes
1344
1345 #define OP_CLR_HANDLER(m) \
1346         flagN = flagV = flagC = 0; \
1347         flagZ = 1; \
1348         m = 0
1349
1350 static void Op0F(void)                                                  // CLR DP
1351 {
1352         uint8_t m;
1353         READ_DP_WB(m);
1354         OP_CLR_HANDLER(m);
1355         WRITE_BACK(m);
1356 }
1357
1358 static void Op4F(void)                                                  // CLRA
1359 {
1360         OP_CLR_HANDLER(regs.a);
1361 }
1362
1363 static void Op5F(void)                                                  // CLRB
1364 {
1365         OP_CLR_HANDLER(regs.b);
1366 }
1367
1368 static void Op6F(void)                                                  // CLR IDX
1369 {
1370         uint8_t m;
1371         READ_IDX_WB(m);
1372         OP_CLR_HANDLER(m);
1373         WRITE_BACK(m);
1374 }
1375
1376 static void Op7F(void)                                                  // CLR ABS
1377 {
1378         uint8_t m;
1379         READ_ABS_WB(m);
1380         OP_CLR_HANDLER(m);
1381         WRITE_BACK(m);
1382 }
1383
1384 /*
1385  +-----------------------------------------------------------------+
1386  | Opcode     |             | Addressing   |               |       |
1387  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1388  +------------+-------------+--------------+-------+-------+-------+
1389  | 81    0129 | CMPA        | IMMEDIATE    |   2   |   2   | uaaaa |
1390  | 8C    0140 | CMPX        | IMMEDIATE    |   4   |   3   | -aaaa |
1391  | 91    0145 | CMPA        | DIRECT       |   4   |   2   | uaaaa |
1392  | 9C    0156 | CMPX        | DIRECT       |   6   |   2   | -aaaa |
1393  | A1    0161 | CMPA        | INDEXED      |   4   |   2   | uaaaa |
1394  | AC    0172 | CMPX        | INDEXED      |   6   |   2   | -aaaa |
1395  | B1    0177 | CMPA        | EXTENDED     |   5   |   3   | uaaaa |
1396  | BC    0188 | CMPX        | EXTENDED     |   7   |   3   | -aaaa |
1397  | C1    0193 | CMPB        | IMMEDIATE    |   2   |   2   | uaaaa |
1398  | D1    0209 | CMPB        | DIRECT       |   4   |   2   | uaaaa |
1399  | E1    0225 | CMPB        | INDEXED      |   4   |   2   | uaaaa |
1400  | F1    0241 | CMPB        | EXTENDED     |   5   |   3   | uaaaa |
1401  | 1083  4227 | CMPD        | IMMEDIATE    |   5   |   4   | -aaaa |
1402  | 108C  4236 | CMPY        | IMMEDIATE    |   5   |   4   | -aaaa |
1403  | 1093  4243 | CMPD        | DIRECT       |   7   |   3   | -aaaa |
1404  | 109C  4252 | CMPY        | DIRECT       |   7   |   3   | -aaaa |
1405  | 10A3  4259 | CMPD        | INDEXED      |   7   |   3   | -aaaa |
1406  | 10AC  4268 | CMPY        | INDEXED      |   7   |   3   | -aaaa |
1407  | 10B3  4275 | CMPD        | EXTENDED     |   8   |   4   | -aaaa |
1408  | 10BC  4284 | CMPY        | EXTENDED     |   8   |   4   | -aaaa |
1409  | 1183  4438 | CMPU        | IMMEDIATE    |   5   |   4   | -aaaa |
1410  | 118C  4492 | CMPS        | IMMEDIATE    |   5   |   4   | -aaaa |
1411  | 1193  4499 | CMPU        | DIRECT       |   7   |   3   | -aaaa |
1412  | 119C  4508 | CMPS        | DIRECT       |   7   |   3   | -aaaa |
1413  | 11A3  4515 | CMPU        | INDEXED      |   7   |   3   | -aaaa |
1414  | 11AC  4524 | CMPS        | INDEXED      |   7   |   3   | -aaaa |
1415  | 11B3  4531 | CMPU        | EXTENDED     |   8   |   4   | -aaaa |
1416  | 11BC  4540 | CMPS        | EXTENDED     |   8   |   4   | -aaaa |
1417 */
1418
1419 // CMP opcodes
1420
1421 #define OP_CMP_HANDLER(m, acc) \
1422         uint16_t sum = (uint16_t)(acc) - (m); \
1423         flagC = (sum >> 8) & 0x01; \
1424         SET_V(m, acc, sum); \
1425         SET_ZN(sum)
1426
1427 #define OP_CMP_HANDLER16(m, acc) \
1428         uint32_t sum = (uint32_t)(acc) - (m); \
1429         flagC = (sum >> 16) & 0x01; \
1430         SET_V16(m, acc, sum); \
1431         SET_ZN16(sum)
1432
1433 static void Op81(void)                                                  // CMPA #
1434 {
1435         uint8_t m = READ_IMM;
1436         OP_CMP_HANDLER(m, regs.a);
1437 }
1438
1439 static void Op8C(void)                                                  // CMPX #
1440 {
1441         uint16_t m = READ_IMM16;
1442         OP_CMP_HANDLER16(m, regs.x);
1443 }
1444
1445 static void Op91(void)                                                  // CMPA DP
1446 {
1447         uint8_t m = READ_DP;
1448         OP_CMP_HANDLER(m, regs.a);
1449 }
1450
1451 static void Op9C(void)                                                  // CMPX DP
1452 {
1453         uint16_t m = READ_DP16;
1454         OP_CMP_HANDLER16(m, regs.x);
1455 }
1456
1457 static void OpA1(void)                                                  // CMPA IDX
1458 {
1459         uint8_t m = READ_IDX;
1460         OP_CMP_HANDLER(m, regs.a);
1461 }
1462
1463 static void OpAC(void)                                                  // CMPX IDX
1464 {
1465         uint16_t m = READ_IDX16;
1466         OP_CMP_HANDLER16(m, regs.x);
1467 }
1468
1469 static void OpB1(void)                                                  // CMPA ABS
1470 {
1471         uint8_t m = READ_ABS;
1472         OP_CMP_HANDLER(m, regs.a);
1473 }
1474
1475 static void OpBC(void)                                                  // CMPX ABS
1476 {
1477         uint16_t m = READ_ABS16;
1478         OP_CMP_HANDLER16(m, regs.x);
1479 }
1480
1481 static void OpC1(void)                                                  // CMPB #
1482 {
1483         uint8_t m = READ_IMM;
1484         OP_CMP_HANDLER(m, regs.b);
1485 }
1486
1487 static void OpD1(void)                                                  // CMPB DP
1488 {
1489         uint8_t m = READ_DP;
1490         OP_CMP_HANDLER(m, regs.b);
1491 }
1492
1493 static void OpE1(void)                                                  // CMPB IDX
1494 {
1495         uint8_t m = READ_IDX;
1496         OP_CMP_HANDLER(m, regs.b);
1497 }
1498
1499 static void OpF1(void)                                                  // CMPB ABS
1500 {
1501         uint8_t m = READ_ABS;
1502         OP_CMP_HANDLER(m, regs.b);
1503 }
1504
1505 static void Op1083(void)                                                // CMPD #
1506 {
1507         uint16_t m = READ_IMM16;
1508         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1509 }
1510
1511 static void Op108C(void)                                                // CMPY #
1512 {
1513         uint16_t m = READ_IMM16;
1514         OP_CMP_HANDLER16(m, regs.y);
1515 }
1516
1517 static void Op1093(void)                                                // CMPD DP
1518 {
1519         uint16_t m = READ_DP16;
1520         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1521 }
1522
1523 static void Op109C(void)                                                // CMPY DP
1524 {
1525         uint16_t m = READ_DP16;
1526         OP_CMP_HANDLER16(m, regs.y);
1527 }
1528
1529 static void Op10A3(void)                                                // CMPD IDX
1530 {
1531         uint16_t m = READ_IDX16;
1532         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1533 }
1534
1535 static void Op10AC(void)                                                // CMPY IDX
1536 {
1537         uint16_t m = READ_IDX16;
1538         OP_CMP_HANDLER16(m, regs.y);
1539 }
1540
1541 static void Op10B3(void)                                                // CMPD ABS
1542 {
1543         uint16_t m = READ_ABS16;
1544         OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1545 }
1546
1547 static void Op10BC(void)                                                // CMPY ABS
1548 {
1549         uint16_t m = READ_ABS16;
1550         OP_CMP_HANDLER16(m, regs.y);
1551 }
1552
1553 static void Op1183(void)                                                // CMPU #
1554 {
1555         uint16_t m = READ_IMM16;
1556         OP_CMP_HANDLER16(m, regs.u);
1557 }
1558
1559 static void Op118C(void)                                                // CMPS #
1560 {
1561         uint16_t m = READ_IMM16;
1562         OP_CMP_HANDLER16(m, regs.s);
1563 }
1564
1565 static void Op1193(void)                                                // CMPU DP
1566 {
1567         uint16_t m = READ_DP16;
1568         OP_CMP_HANDLER16(m, regs.u);
1569 }
1570
1571 static void Op119C(void)                                                // CMPS DP
1572 {
1573         uint16_t m = READ_DP16;
1574         OP_CMP_HANDLER16(m, regs.s);
1575 }
1576
1577 static void Op11A3(void)                                                // CMPU IDX
1578 {
1579         uint16_t m = READ_IDX16;
1580         OP_CMP_HANDLER16(m, regs.u);
1581 }
1582
1583 static void Op11AC(void)                                                // CMPS IDX
1584 {
1585         uint16_t m = READ_IDX16;
1586         OP_CMP_HANDLER16(m, regs.s);
1587 }
1588
1589 static void Op11B3(void)                                                // CMPU ABS
1590 {
1591         uint16_t m = READ_ABS16;
1592         OP_CMP_HANDLER16(m, regs.u);
1593 }
1594
1595 static void Op11BC(void)                                                // CMPS ABS
1596 {
1597         uint16_t m = READ_ABS16;
1598         OP_CMP_HANDLER16(m, regs.s);
1599 }
1600
1601 /*
1602  +-----------------------------------------------------------------+
1603  | Opcode     |             | Addressing   |               |       |
1604  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1605  +------------+-------------+--------------+-------+-------+-------+
1606  | 03    0003 | COM         | DIRECT       |   6   |   2   | -aa01 |
1607  | 43    0067 | COMA        | INHERENT     |   2   |   1   | -aa01 |
1608  | 53    0083 | COMB        | INHERENT     |   2   |   1   | -aa01 |
1609  | 63    0099 | COM         | INDEXED      |   6   |   2   | -aa01 |
1610  | 73    0115 | COM         | EXTENDED     |   7   |   3   | -aa01 |
1611 */
1612
1613 // COM opcodes
1614
1615 #define OP_COM_HANDLER(m) \
1616         m = ~m; \
1617         SET_ZN(m); \
1618         flagC = 1; \
1619         flagV = 0
1620
1621 static void Op03(void)                                                  // COM DP
1622 {
1623         uint8_t m;
1624         READ_DP_WB(m);
1625         OP_COM_HANDLER(m);
1626         WRITE_BACK(m);
1627 }
1628
1629 static void Op43(void)                                                  // COMA
1630 {
1631         OP_COM_HANDLER(regs.a);
1632 }
1633
1634 static void Op53(void)                                                  // COMB
1635 {
1636         OP_COM_HANDLER(regs.b);
1637 }
1638
1639 static void Op63(void)                                                  // COM IDX
1640 {
1641         uint8_t m;
1642         READ_IDX_WB(m);
1643         OP_COM_HANDLER(m);
1644         WRITE_BACK(m);
1645 }
1646
1647 static void Op73(void)                                                  // COM ABS
1648 {
1649         uint8_t m;
1650         READ_ABS_WB(m);
1651         OP_COM_HANDLER(m);
1652         WRITE_BACK(m);
1653 }
1654
1655 /*
1656  +-----------------------------------------------------------------+
1657  | Opcode     |             | Addressing   |               |       |
1658  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1659  +------------+-------------+--------------+-------+-------+-------+
1660  | 13    0019 | SYNC        | INHERENT     |   2   |   1   | ----- |
1661  | 3C    0060 | CWAI        | INHERENT     |  21   |   2   | ddddd |
1662  | 3E    0062 | RESET*      | INHERENT     |   *   |   1   | ***** |
1663  | 3F    0063 | SWI         | INHERENT     |  19   |   1   | ----- |
1664  | 103F  4159 | SWI2        | INHERENT     |  20   |   2   | ----- |
1665  | 113F  4415 | SWI3        | INHERENT     |  20   |   2   | ----- |
1666 */
1667
1668 static void Op13(void)                                                  // SYNC
1669 {
1670 #warning "!!! SYNC not implemented !!!"
1671 #if 0
1672         /* SYNC stops processing instructions until an interrupt request happens. */
1673         /* This doesn't require the corresponding interrupt to be enabled: if it */
1674         /* is disabled, execution continues with the next instruction. */
1675         m68_state->int_state |= M6809_SYNC;      /* HJB 990227 */
1676         check_irq_lines(m68_state);
1677         /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1678      * stop execution until the interrupt lines change. */
1679         if( m68_state->int_state & M6809_SYNC )
1680                 if (m68_state->icount > 0) m68_state->icount = 0;
1681 #endif
1682 }
1683
1684 static void Op3C(void)                                                  // CWAI
1685 {
1686 #warning "!!! CWAI not implemented !!!"
1687 #if 0
1688         UINT8 t;
1689         IMMBYTE(t);
1690         CC &= t;
1691         /*
1692      * CWAI stacks the entire machine state on the hardware stack,
1693      * then waits for an interrupt; when the interrupt is taken
1694      * later, the state is *not* saved again after CWAI.
1695      */
1696         CC |= CC_E;             /* HJB 990225: save entire state */
1697         PUSHWORD(pPC);
1698         PUSHWORD(pU);
1699         PUSHWORD(pY);
1700         PUSHWORD(pX);
1701         PUSHBYTE(DP);
1702         PUSHBYTE(B);
1703         PUSHBYTE(A);
1704         PUSHBYTE(CC);
1705         m68_state->int_state |= M6809_CWAI;      /* HJB 990228 */
1706         check_irq_lines(m68_state);    /* HJB 990116 */
1707         if( m68_state->int_state & M6809_CWAI )
1708                 if( m68_state->icount > 0 )
1709                         m68_state->icount = 0;
1710 #endif
1711 }
1712
1713 static void Op3E(void)                                                  // RESET
1714 {
1715         regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
1716 }
1717
1718 static void Op3F(void)                                                  // SWI
1719 {
1720         flagE = 1;
1721         regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
1722         PUSHS16(regs.pc);
1723         PUSHS16(regs.u);
1724         PUSHS16(regs.y);
1725         PUSHS16(regs.x);
1726         PUSHS(regs.dp);
1727         PUSHS(regs.b);
1728         PUSHS(regs.a);
1729         PUSHS(regs.cc);
1730         flagF = flagI = 1;
1731         regs.pc = RdMemW(0xFFFA);
1732 }
1733
1734 static void Op103F(void)                                                // SWI2
1735 {
1736         flagE = 1;
1737         regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
1738         PUSHS16(regs.pc);
1739         PUSHS16(regs.u);
1740         PUSHS16(regs.y);
1741         PUSHS16(regs.x);
1742         PUSHS(regs.dp);
1743         PUSHS(regs.b);
1744         PUSHS(regs.a);
1745         PUSHS(regs.cc);
1746         regs.pc = RdMemW(0xFFF4);
1747 }
1748
1749 static void Op113F(void)                                                // SWI3
1750 {
1751         flagE = 1;
1752         regs.cc = PACK_FLAGS;                                           // Mash flags into CC byte
1753         PUSHS16(regs.pc);
1754         PUSHS16(regs.u);
1755         PUSHS16(regs.y);
1756         PUSHS16(regs.x);
1757         PUSHS(regs.dp);
1758         PUSHS(regs.b);
1759         PUSHS(regs.a);
1760         PUSHS(regs.cc);
1761         regs.pc = RdMemW(0xFFF2);
1762 }
1763
1764 /*
1765  +-----------------------------------------------------------------+
1766  | Opcode     |             | Addressing   |               |       |
1767  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1768  +------------+-------------+--------------+-------+-------+-------+
1769  | 12    0018 | NOP         | INHERENT     |   2   |   1   | ----- |
1770  | 19    0025 | DAA         | INHERENT     |   2   |   1   | -aa0a |
1771  | 1A    0026 | ORCC        | IMMEDIATE    |   3   |   2   | ddddd |
1772  | 1C    0028 | ANDCC       | IMMEDIATE    |   3   |   2   | ddddd |
1773  | 1D    0029 | SEX         | INHERENT     |   2   |   1   | -aa0- |
1774 */
1775
1776 static void Op12()                                                              // NOP
1777 {
1778 }
1779
1780 /*
1781 D3F8: A6 47       LDA   (7),U      CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA
1782 D3FA: 8B 01       ADDA  #$01       CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC
1783 D3FC: 19          DAA              CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD
1784 */
1785
1786 static void Op19()                                                              // DAA
1787 {
1788         uint16_t result = (uint16_t)regs.a;
1789
1790 //      if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
1791         if ((regs.a & 0x0F) > 0x09 || flagH)
1792                 result += 0x06;
1793
1794 //      if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1795         if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1796                 result += 0x60;
1797
1798         regs.a = (uint8_t)result;
1799         SET_ZN(result);
1800         CLR_V;
1801         flagC |= (result & 0x100) >> 8;                         // Overwrite carry if it was 0, otherwise, ignore
1802 }
1803
1804 static void Op1A()                                                              // ORCC
1805 {
1806         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
1807         regs.cc |= READ_IMM;
1808         UNPACK_FLAGS;                                                           // & unmash 'em
1809 }
1810
1811 static void Op1C()                                                              // ANDCC
1812 {
1813         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
1814         regs.cc &= READ_IMM;
1815         UNPACK_FLAGS;                                                           // & unmash 'em
1816 }
1817
1818 static void Op1D()                                                              // SEX
1819 {
1820         regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1821         SET_ZN16((regs.a << 8) | regs.b);
1822         CLR_V;
1823 }
1824
1825 /*
1826  +-----------------------------------------------------------------+
1827  | Opcode     |             | Addressing   |               |       |
1828  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1829  +------------+-------------+--------------+-------+-------+-------+
1830  | 0A    0010 | DEC         | DIRECT       |   6   |   2   | -aaa- |
1831  | 4A    0074 | DECA        | INHERENT     |   2   |   1   | -aaa- |
1832  | 5A    0090 | DECB        | INHERENT     |   2   |   1   | -aaa- |
1833  | 6A    0106 | DEC         | INDEXED      |   6   |   2   | -aaa- |
1834  | 7A    0122 | DEC         | EXTENDED     |   7   |   3   | -aaa- |
1835 */
1836
1837 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1838
1839 #define OP_DEC_HANDLER(m) \
1840         m--; \
1841         SET_ZN(m); \
1842         flagV = (m == 0x7F ? 1 : 0)
1843
1844 static void Op0A(void)                                                  // DEC DP
1845 {
1846         uint8_t m;
1847         READ_DP_WB(m);
1848         OP_DEC_HANDLER(m);
1849         WRITE_BACK(m);
1850 }
1851
1852 static void Op4A(void)                                                  // DECA
1853 {
1854         OP_DEC_HANDLER(regs.a);
1855 }
1856
1857 static void Op5A(void)                                                  // DECB
1858 {
1859         OP_DEC_HANDLER(regs.b);
1860 }
1861
1862 static void Op6A(void)                                                  // DEC IDX
1863 {
1864         uint8_t m;
1865         READ_IDX_WB(m);
1866         OP_DEC_HANDLER(m);
1867         WRITE_BACK(m);
1868 }
1869
1870 static void Op7A(void)                                                  // DEC ABS
1871 {
1872         uint8_t m;
1873         READ_ABS_WB(m);
1874         OP_DEC_HANDLER(m);
1875         WRITE_BACK(m);
1876 }
1877
1878 /*
1879  +-----------------------------------------------------------------+
1880  | Opcode     |             | Addressing   |               |       |
1881  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1882  +------------+-------------+--------------+-------+-------+-------+
1883  | 88    0136 | EORA        | IMMEDIATE    |   2   |   2   | -aa0- |
1884  | 98    0152 | EORA        | DIRECT       |   4   |   2   | -aa0- |
1885  | A8    0168 | EORA        | INDEXED      |   4   |   2   | -aa0- |
1886  | B8    0184 | EORA        | EXTENDED     |   5   |   3   | -aa0- |
1887  | C8    0200 | EORB        | IMMEDIATE    |   2   |   2   | -aa0- |
1888  | D8    0216 | EORB        | DIRECT       |   4   |   2   | -aa0- |
1889  | E8    0232 | EORB        | INDEXED      |   4   |   2   | -aa0- |
1890  | F8    0248 | EORB        | EXTENDED     |   5   |   3   | -aa0- |
1891 */
1892
1893 // EOR opcodes
1894
1895 #define OP_EOR_HANDLER(m, acc) \
1896         acc ^= (m); \
1897         SET_ZN(acc); \
1898         CLR_V
1899
1900 static void Op88(void)                                                  // EORA #
1901 {
1902         uint8_t m = READ_IMM;
1903         OP_EOR_HANDLER(m, regs.a);
1904 }
1905
1906 static void Op98(void)                                                  // EORA DP
1907 {
1908         uint8_t m = READ_DP;
1909         OP_EOR_HANDLER(m, regs.a);
1910 }
1911
1912 static void OpA8(void)                                                  // EORA IDX
1913 {
1914         uint8_t m = READ_IDX;
1915         OP_EOR_HANDLER(m, regs.a);
1916 }
1917
1918 static void OpB8(void)                                                  // EORA ABS
1919 {
1920         uint8_t m = READ_ABS;
1921         OP_EOR_HANDLER(m, regs.a);
1922 }
1923
1924 static void OpC8(void)                                                  // EORB #
1925 {
1926         uint8_t m = READ_IMM;
1927         OP_EOR_HANDLER(m, regs.b);
1928 }
1929
1930 static void OpD8(void)                                                  // EORB DP
1931 {
1932         uint8_t m = READ_DP;
1933         OP_EOR_HANDLER(m, regs.b);
1934 }
1935
1936 static void OpE8(void)                                                  // EORB IDX
1937 {
1938         uint8_t m = READ_IDX;
1939         OP_EOR_HANDLER(m, regs.b);
1940 }
1941
1942 static void OpF8(void)                                                  // EORB ABS
1943 {
1944         uint8_t m = READ_ABS;
1945         OP_EOR_HANDLER(m, regs.b);
1946 }
1947
1948 /*
1949  +-----------------------------------------------------------------+
1950  | Opcode     |             | Addressing   |               |       |
1951  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
1952  +------------+-------------+--------------+-------+-------+-------+
1953  | 0C    0012 | INC         | DIRECT       |   6   |   2   | -aaa- |
1954  | 4C    0076 | INCA        | INHERENT     |   2   |   1   | -aaa- |
1955  | 5C    0092 | INCB        | INHERENT     |   2   |   1   | -aaa- |
1956  | 6C    0108 | INC         | INDEXED      |   6   |   2   | -aaa- |
1957  | 7C    0124 | INC         | EXTENDED     |   7   |   3   | -aaa- |
1958 */
1959
1960 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1961
1962 #define OP_INC_HANDLER(m) \
1963         m++; \
1964         SET_ZN(m); \
1965         flagV = (m == 0x80 ? 1 : 0)
1966
1967 static void Op0C(void)                                                  // INC DP
1968 {
1969         uint8_t m;
1970         READ_DP_WB(m);
1971         OP_INC_HANDLER(m);
1972         WRITE_BACK(m);
1973 }
1974
1975 static void Op4C(void)                                                  // INCA
1976 {
1977         OP_INC_HANDLER(regs.a);
1978 }
1979
1980 static void Op5C(void)                                                  // INCB
1981 {
1982         OP_INC_HANDLER(regs.b);
1983 }
1984
1985 static void Op6C(void)                                                  // INC IDX
1986 {
1987         uint8_t m;
1988         READ_IDX_WB(m);
1989         OP_INC_HANDLER(m);
1990         WRITE_BACK(m);
1991 }
1992
1993 static void Op7C(void)                                                  // INC ABS
1994 {
1995         uint8_t m;
1996         READ_ABS_WB(m);
1997         OP_INC_HANDLER(m);
1998         WRITE_BACK(m);
1999 }
2000
2001 /*
2002  +-----------------------------------------------------------------+
2003  | Opcode     |             | Addressing   |               |       |
2004  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2005  +------------+-------------+--------------+-------+-------+-------+
2006  | 0E    0014 | JMP         | DIRECT       |   3   |   2   | ----- |
2007  | 17    0023 | LBSR        | RELATIVE     |   9   |   3   | ----- |
2008  | 39    0057 | RTS         | INHERENT     |   5   |   1   | ----- |
2009  | 3B    0059 | RTI         | INHERENT     | 6/15  |   1   | ----- |
2010  | 6E    0110 | JMP         | INDEXED      |   3   |   2   | ----- |
2011  | 7E    0126 | JMP         | EXTENDED     |   3   |   3   | ----- |
2012  | 8D    0141 | BSR         | RELATIVE     |   7   |   2   | ----- |
2013  | 9D    0157 | JSR         | DIRECT       |   7   |   2   | ----- |
2014  | AD    0173 | JSR         | INDEXED      |   7   |   2   | ----- |
2015  | BD    0189 | JSR         | EXTENDED     |   8   |   3   | ----- |
2016 */
2017
2018 static void Op0E(void)                                                  // JMP DP
2019 {
2020         regs.pc = EA_DP;
2021 }
2022
2023 static void Op17(void)                                                  // LBSR
2024 {
2025         uint16_t word = FetchMemW(regs.pc);
2026         PUSHS16(regs.pc);
2027         regs.pc += word;
2028 }
2029
2030 static void Op39(void)                                                  // RTS
2031 {
2032         PULLS16(regs.pc);
2033 }
2034
2035 static void Op3B(void)                                                  // RTI
2036 {
2037         PULLS(regs.cc);
2038         UNPACK_FLAGS;
2039
2040         // If E flag set, pull all regs
2041         if (flagE)
2042         {
2043                 PULLS(regs.a);
2044                 PULLS(regs.b);
2045                 PULLS(regs.dp);
2046                 PULLS16(regs.x);
2047                 PULLS16(regs.y);
2048                 PULLS16(regs.u);
2049                 regs.clock += 9;
2050         }
2051
2052         PULLS16(regs.pc);
2053 }
2054
2055 static void Op6E(void)                                                  // JMP IDX
2056 {
2057         regs.pc = EA_IDX;
2058 }
2059
2060 static void Op7E(void)                                                  // JMP ABS
2061 {
2062         regs.pc = EA_ABS;
2063 }
2064
2065 static void Op8D(void)                                                  // BSR
2066 {
2067         uint16_t word = (int16_t)(int8_t)READ_IMM;
2068         PUSHS16(regs.pc);
2069         regs.pc += word;
2070 }
2071
2072 static void Op9D(void)                                                  // JSR DP
2073 {
2074         uint16_t word = EA_DP;
2075         PUSHS16(regs.pc);
2076         regs.pc = word;
2077 }
2078
2079 static void OpAD(void)                                                  // JSR IDX
2080 {
2081         uint16_t word = EA_IDX;
2082         PUSHS16(regs.pc);
2083         regs.pc = word;
2084 }
2085
2086 static void OpBD(void)                                                  // JSR ABS
2087 {
2088         uint16_t word = EA_ABS;
2089         PUSHS16(regs.pc);
2090         regs.pc = word;
2091 }
2092
2093 /*
2094  +-----------------------------------------------------------------+
2095  | Opcode     |             | Addressing   |               |       |
2096  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2097  +------------+-------------+--------------+-------+-------+-------+
2098  | 1E    0030 | EXG         | INHERENT     |   8   |   2   | ccccc |
2099  | 1F    0031 | TFR         | INHERENT     |   7   |   2   | ccccc |
2100 */
2101
2102 static void Op1E(void)                                                  // EXG
2103 {
2104         // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2105
2106         uint8_t m = READ_IMM;
2107         uint8_t reg1 = m >> 4, reg2 = m & 0x0F;
2108         uint16_t acc1 = ReadEXG(reg1);
2109         uint16_t acc2 = ReadEXG(reg2);
2110
2111         // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2112         if (((m >> 4) ^ m) & 0x08)
2113                 acc1 = acc2 = 0xFF;
2114
2115         WriteEXG(reg1, acc2);
2116         WriteEXG(reg2, acc1);
2117 }
2118
2119 static void Op1F(void)                                                  // TFR
2120 {
2121         uint8_t m = READ_IMM;
2122         uint16_t acc = ReadEXG(m >> 4);
2123
2124         // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2125         if (((m >> 4) ^ m) & 0x08)
2126                 acc = 0xFF;
2127
2128         WriteEXG(m & 0x0F, acc);
2129 }
2130
2131 /*
2132  +-----------------------------------------------------------------+
2133  | Opcode     |             | Addressing   |               |       |
2134  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2135  +------------+-------------+--------------+-------+-------+-------+
2136  | 86    0134 | LDA         | IMMEDIATE    |   2   |   2   | -aa0- |
2137  | 8E    0142 | LDX         | IMMEDIATE    |   3   |   3   | -aa0- |
2138  | 96    0150 | LDA         | DIRECT       |   4   |   2   | -aa0- |
2139  | 9E    0158 | LDX         | DIRECT       |   5   |   2   | -aa0- |
2140  | A6    0166 | LDA         | INDEXED      |   4   |   2   | -aa0- |
2141  | AE    0174 | LDX         | INDEXED      |   5   |   2   | -aa0- |
2142  | B6    0182 | LDA         | EXTENDED     |   5   |   3   | -aa0- |
2143  | BE    0190 | LDX         | EXTENDED     |   6   |   3   | -aa0- |
2144  | C6    0198 | LDB         | IMMEDIATE    |   2   |   2   | -aa0- |
2145  | CC    0204 | LDD         | IMMEDIATE    |   3   |   3   | -aa0- |
2146  | CE    0206 | LDU         | IMMEDIATE    |   3   |   3   | -aa0- |
2147  | D6    0214 | LDB         | DIRECT       |   4   |   2   | -aa0- |
2148  | DC    0220 | LDD         | DIRECT       |   5   |   2   | -aa0- |
2149  | DE    0222 | LDU         | DIRECT       |   5   |   2   | -aa0- |
2150  | E6    0230 | LDB         | INDEXED      |   4   |   2   | -aa0- |
2151  | EC    0236 | LDD         | INDEXED      |   5   |   2   | -aa0- |
2152  | EE    0238 | LDU         | INDEXED      |   5   |   2   | -aa0- |
2153  | F6    0246 | LDB         | EXTENDED     |   5   |   3   | -aa0- |
2154  | FC    0252 | LDD         | EXTENDED     |   6   |   3   | -aa0- |
2155  | FE    0254 | LDU         | EXTENDED     |   6   |   3   | -aa0- |
2156  | 108E  4238 | LDY         | IMMEDIATE    |   4   |   4   | -aa0- |
2157  | 109E  4254 | LDY         | DIRECT       |   6   |   3   | -aa0- |
2158  | 10AE  4270 | LDY         | INDEXED      |   6   |   3   | -aa0- |
2159  | 10BE  4286 | LDY         | EXTENDED     |   7   |   4   | -aa0- |
2160  | 10CE  4302 | LDS         | IMMEDIATE    |   4   |   4   | -aa0- |
2161  | 10DE  4318 | LDS         | DIRECT       |   6   |   3   | -aa0- |
2162  | 10EE  4334 | LDS         | INDEXED      |   6   |   3   | -aa0- |
2163  | 10FE  4350 | LDS         | EXTENDED     |   7   |   4   | -aa0- |
2164 */
2165
2166 // LDA opcodes
2167
2168 #define OP_LDA_HANDLER(m, acc) \
2169         acc = m; \
2170         CLR_V; \
2171         SET_ZN(acc)
2172
2173 #define OP_LDA_HANDLER16(m, acc) \
2174         acc = m; \
2175         CLR_V; \
2176         SET_ZN16(acc)
2177
2178 #define OP_LDA_HANDLER16D(m) \
2179         regs.a = (m >> 8); \
2180         regs.b = m & 0xFF; \
2181         CLR_V; \
2182         SET_ZN16(m)
2183
2184 static void Op86(void)                                                  // LDA #
2185 {
2186         uint8_t m = READ_IMM;
2187         OP_LDA_HANDLER(m, regs.a);
2188 }
2189
2190 static void Op8E(void)                                                  // LDX #
2191 {
2192         uint16_t m = READ_IMM16;
2193         OP_LDA_HANDLER16(m, regs.x);
2194 }
2195
2196 static void Op96(void)                                                  // LDA DP
2197 {
2198         uint8_t m = READ_DP;
2199         OP_LDA_HANDLER(m, regs.a);
2200 }
2201
2202 static void Op9E(void)                                                  // LDX DP
2203 {
2204         uint16_t m = READ_DP16;
2205         OP_LDA_HANDLER16(m, regs.x);
2206 }
2207
2208 static void OpA6(void)                                                  // LDA IDX
2209 {
2210         uint8_t m = READ_IDX;
2211         OP_LDA_HANDLER(m, regs.a);
2212 }
2213
2214 static void OpAE(void)                                                  // LDX IDX
2215 {
2216         uint16_t m = READ_IDX16;
2217         OP_LDA_HANDLER16(m, regs.x);
2218 }
2219
2220 static void OpB6(void)                                                  // LDA ABS
2221 {
2222         uint8_t m = READ_ABS;
2223         OP_LDA_HANDLER(m, regs.a);
2224 }
2225
2226 static void OpBE(void)                                                  // LDX ABS
2227 {
2228         uint16_t m = READ_ABS16;
2229         OP_LDA_HANDLER16(m, regs.x);
2230 }
2231
2232 static void OpC6(void)                                                  // LDB #
2233 {
2234         uint8_t m = READ_IMM;
2235         OP_LDA_HANDLER(m, regs.b);
2236 }
2237
2238 static void OpCC(void)                                                  // LDD #
2239 {
2240         uint16_t m = READ_IMM16;
2241         OP_LDA_HANDLER16D(m);
2242 }
2243
2244 static void OpCE(void)                                                  // LDU #
2245 {
2246         uint16_t m = READ_IMM16;
2247         OP_LDA_HANDLER16(m, regs.u);
2248 }
2249
2250 static void OpD6(void)                                                  // LDB DP
2251 {
2252         uint8_t m = READ_DP;
2253         OP_LDA_HANDLER(m, regs.b);
2254 }
2255
2256 static void OpDC(void)                                                  // LDD DP
2257 {
2258         uint16_t m = READ_DP16;
2259         OP_LDA_HANDLER16D(m);
2260 }
2261
2262 static void OpDE(void)                                                  // LDU DP
2263 {
2264         uint16_t m = READ_DP16;
2265         OP_LDA_HANDLER16(m, regs.u);
2266 }
2267
2268 static void OpE6(void)                                                  // LDB IDX
2269 {
2270         uint8_t m = READ_IDX;
2271         OP_LDA_HANDLER(m, regs.b);
2272 }
2273
2274 static void OpEC(void)                                                  // LDD IDX
2275 {
2276         uint16_t m = READ_IDX16;
2277         OP_LDA_HANDLER16D(m);
2278 }
2279
2280 static void OpEE(void)                                                  // LDU IDX
2281 {
2282         uint16_t m = READ_IDX16;
2283         OP_LDA_HANDLER16(m, regs.u);
2284 }
2285
2286 static void OpF6(void)                                                  // LDB ABS
2287 {
2288         uint8_t m = READ_ABS;
2289         OP_LDA_HANDLER(m, regs.b);
2290 }
2291
2292 static void OpFC(void)                                                  // LDD ABS
2293 {
2294         uint16_t m = READ_ABS16;
2295         OP_LDA_HANDLER16D(m);
2296 }
2297
2298 static void OpFE(void)                                                  // LDU ABS
2299 {
2300         uint16_t m = READ_ABS16;
2301         OP_LDA_HANDLER16(m, regs.u);
2302 }
2303
2304 static void Op108E(void)                                                // LDY #
2305 {
2306         uint16_t m = READ_IMM16;
2307         OP_LDA_HANDLER16(m, regs.y);
2308 }
2309
2310 static void Op109E(void)                                                // LDY DP
2311 {
2312         uint16_t m = READ_DP16;
2313         OP_LDA_HANDLER16(m, regs.y);
2314 }
2315
2316 static void Op10AE(void)                                                // LDY IDX
2317 {
2318         uint16_t m = READ_IDX16;
2319         OP_LDA_HANDLER16(m, regs.y);
2320 }
2321
2322 static void Op10BE(void)                                                // LDY ABS
2323 {
2324         uint16_t m = READ_ABS16;
2325         OP_LDA_HANDLER16(m, regs.y);
2326 }
2327
2328 static void Op10CE(void)                                                // LDS #
2329 {
2330         uint16_t m = READ_IMM16;
2331         OP_LDA_HANDLER16(m, regs.s);
2332 }
2333
2334 static void Op10DE(void)                                                // LDS DP
2335 {
2336         uint16_t m = READ_DP16;
2337         OP_LDA_HANDLER16(m, regs.s);
2338 }
2339
2340 static void Op10EE(void)                                                // LDS IDX
2341 {
2342         uint16_t m = READ_IDX16;
2343         OP_LDA_HANDLER16(m, regs.s);
2344 }
2345
2346 static void Op10FE(void)                                                // LDS ABS
2347 {
2348         uint16_t m = READ_ABS16;
2349         OP_LDA_HANDLER16(m, regs.s);
2350 }
2351
2352 /*
2353  +-----------------------------------------------------------------+
2354  | Opcode     |             | Addressing   |               |       |
2355  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2356  +------------+-------------+--------------+-------+-------+-------+
2357  | 30    0048 | LEAX        | INDEXED      |   4   |   2   | --a-- |
2358  | 31    0049 | LEAY        | INDEXED      |   4   |   2   | --a-- |
2359  | 32    0050 | LEAS        | INDEXED      |   4   |   2   | ----- |
2360  | 33    0051 | LEAU        | INDEXED      |   4   |   2   | ----- |
2361 */
2362
2363 static void Op30(void)                                                  // LEAX
2364 {
2365         regs.x = EA_IDX;
2366         SET_Z(regs.x);
2367 }
2368
2369 static void Op31(void)                                                  // LEAY
2370 {
2371         regs.y = EA_IDX;
2372         SET_Z(regs.y);
2373 }
2374
2375 static void Op32(void)                                                  // LEAS
2376 {
2377         regs.s = EA_IDX;
2378 }
2379
2380 static void Op33(void)                                                  // LEAU
2381 {
2382         regs.u = EA_IDX;
2383 }
2384
2385 /*
2386  +-----------------------------------------------------------------+
2387  | Opcode     |             | Addressing   |               |       |
2388  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2389  +------------+-------------+--------------+-------+-------+-------+
2390  | 04    0004 | LSR         | DIRECT       |   6   |   2   | -0a-s |
2391  | 44    0068 | LSRA        | INHERENT     |   2   |   1   | -0a-s |
2392  | 54    0084 | LSRB        | INHERENT     |   2   |   1   | -0a-s |
2393  | 64    0100 | LSR         | INDEXED      |   6   |   2   | -0a-s |
2394  | 74    0116 | LSR         | EXTENDED     |   7   |   3   | -0a-s |
2395 */
2396
2397 // LSR opcodes
2398
2399 #define OP_LSR_HANDLER(m) \
2400         flagC = m & 0x01; \
2401         m >>= 1; \
2402         SET_ZN(m)
2403
2404 static void Op04(void)                                                  // LSR DP
2405 {
2406         uint8_t m;
2407         READ_DP_WB(m);
2408         OP_LSR_HANDLER(m);
2409         WRITE_BACK(m);
2410 }
2411
2412 static void Op44(void)                                                  // LSRA
2413 {
2414         OP_LSR_HANDLER(regs.a);
2415 }
2416
2417 static void Op54(void)                                                  // LSRB
2418 {
2419         OP_LSR_HANDLER(regs.b);
2420 }
2421
2422 static void Op64(void)                                                  // LSR IDX
2423 {
2424         uint8_t m;
2425         READ_IDX_WB(m);
2426         OP_LSR_HANDLER(m);
2427         WRITE_BACK(m);
2428 }
2429
2430 static void Op74(void)                                                  // LSR ABS
2431 {
2432         uint8_t m;
2433         READ_ABS_WB(m);
2434         OP_LSR_HANDLER(m);
2435         WRITE_BACK(m);
2436 }
2437
2438 /*
2439  +-----------------------------------------------------------------+
2440  | Opcode     |             | Addressing   |               |       |
2441  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2442  +------------+-------------+--------------+-------+-------+-------+
2443  | 3D    0061 | MUL         | INHERENT     |  11   |   1   | --a-a |
2444 */
2445
2446 static void Op3D(void)                                                  // MUL
2447 {
2448         uint16_t prod = regs.a * regs.b;
2449         regs.a = prod >> 8;
2450         regs.b = prod & 0xFF;
2451         SET_Z(prod);
2452 //      flagC = (prod & 0x0080 ? 1 : 0);
2453         flagC = (prod >> 7) & 0x01;
2454 }
2455
2456 /*
2457  +-----------------------------------------------------------------+
2458  | Opcode     |             | Addressing   |               |       |
2459  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2460  +------------+-------------+--------------+-------+-------+-------+
2461  | 00    0000 | NEG         | DIRECT       |   6   |   2   | uaaaa |
2462  | 40    0064 | NEGA        | INHERENT     |   2   |   1   | uaaaa |
2463  | 50    0080 | NEGB        | INHERENT     |   2   |   1   | uaaaa |
2464  | 60    0096 | NEG         | INDEXED      |   6   |   2   | uaaaa |
2465  | 70    0112 | NEG         | EXTENDED     |   7   |   3   | uaaaa |
2466 */
2467
2468 // NEG opcodes
2469
2470 #define OP_NEG_HANDLER(m) \
2471         uint8_t res = -m; \
2472         SET_ZN(res); \
2473         SET_V(0, m, res); \
2474         flagC = (res >= 0x80 ? 1 : 0); \
2475         m = res
2476
2477 /*
2478         UINT16 r,t;
2479         DIRBYTE(t);
2480         r = -t;
2481         CLR_NZVC;
2482         SET_FLAGS8(0,t,r);
2483         WM(EAD,r);
2484 #define SET_FLAGS8(a,b,r)       {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
2485 #define SET_C8(a)               CC|=((a&0x100)>>8)
2486 */
2487 static void Op00(void)                                                  // NEG DP
2488 {
2489         uint8_t m;
2490         READ_DP_WB(m);
2491         OP_NEG_HANDLER(m);
2492         WRITE_BACK(m);
2493 }
2494
2495 static void Op40(void)                                                  // NEGA
2496 {
2497         OP_NEG_HANDLER(regs.a);
2498 }
2499
2500 static void Op50(void)                                                  // NEGB
2501 {
2502         OP_NEG_HANDLER(regs.b);
2503 }
2504
2505 static void Op60(void)                                                  // NEG IDX
2506 {
2507         uint8_t m;
2508         READ_IDX_WB(m);
2509         OP_NEG_HANDLER(m);
2510         WRITE_BACK(m);
2511 }
2512
2513 static void Op70(void)                                                  // NEG ABS
2514 {
2515         uint8_t m;
2516         READ_ABS_WB(m);
2517         OP_NEG_HANDLER(m);
2518         WRITE_BACK(m);
2519 }
2520
2521 /*
2522  +-----------------------------------------------------------------+
2523  | Opcode     |             | Addressing   |               |       |
2524  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2525  +------------+-------------+--------------+-------+-------+-------+
2526  | 8A    0138 | ORA         | IMMEDIATE    |   2   |   2   | -aa0- |
2527  | 9A    0154 | ORA         | DIRECT       |   4   |   2   | -aa0- |
2528  | AA    0170 | ORA         | INDEXED      |   4   |   2   | -aa0- |
2529  | BA    0186 | ORA         | EXTENDED     |   5   |   3   | -aa0- |
2530  | CA    0202 | ORB         | IMMEDIATE    |   2   |   2   | -aa0- |
2531  | DA    0218 | ORB         | DIRECT       |   4   |   2   | -aa0- |
2532  | EA    0234 | ORB         | INDEXED      |   4   |   2   | -aa0- |
2533  | FA    0250 | ORB         | EXTENDED     |   5   |   3   | -aa0- |
2534 */
2535
2536 // ORA opcodes
2537
2538 #define OP_OR_HANDLER(m, acc) \
2539         acc |= (m); \
2540         SET_ZN(acc); \
2541         CLR_V
2542
2543 static void Op8A(void)                                                  // ORA #
2544 {
2545         uint8_t m = READ_IMM;
2546         OP_OR_HANDLER(m, regs.a);
2547 }
2548
2549 static void Op9A(void)                                                  // ORA DP
2550 {
2551         uint8_t m = READ_DP;
2552         OP_OR_HANDLER(m, regs.a);
2553 }
2554
2555 static void OpAA(void)                                                  // ORA IDX
2556 {
2557         uint8_t m = READ_IDX;
2558         OP_OR_HANDLER(m, regs.a);
2559 }
2560
2561 static void OpBA(void)                                                  // ORA ABS
2562 {
2563         uint8_t m = READ_ABS;
2564         OP_OR_HANDLER(m, regs.a);
2565 }
2566
2567 static void OpCA(void)                                                  // ORB #
2568 {
2569         uint8_t m = READ_IMM;
2570         OP_OR_HANDLER(m, regs.b);
2571 }
2572
2573 static void OpDA(void)                                                  // ORB DP
2574 {
2575         uint8_t m = READ_DP;
2576         OP_OR_HANDLER(m, regs.b);
2577 }
2578
2579 static void OpEA(void)                                                  // ORB IDX
2580 {
2581         uint8_t m = READ_IDX;
2582         OP_OR_HANDLER(m, regs.b);
2583 }
2584
2585 static void OpFA(void)                                                  // ORB ABS
2586 {
2587         uint8_t m = READ_ABS;
2588         OP_OR_HANDLER(m, regs.b);
2589 }
2590
2591 /*
2592  +-----------------------------------------------------------------+
2593  | Opcode     |             | Addressing   |               |       |
2594  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2595  +------------+-------------+--------------+-------+-------+-------+
2596  | 34    0052 | PSHS        | INHERENT     |   5   |   2   | ----- |
2597  | 35    0053 | PULS        | INHERENT     |   5   |   2   | ccccc |
2598  | 36    0054 | PSHU        | INHERENT     |   5   |   2   | ----- |
2599  | 37    0055 | PULU        | INHERENT     |   5   |   2   | ccccc |
2600 */
2601
2602 static void Op34(void)                                                  // PSHS
2603 {
2604         uint8_t m = READ_IMM;
2605
2606         if (m & 0x80)
2607                 PUSHS16(regs.pc);
2608         if (m & 0x40)
2609                 PUSHS16(regs.u);
2610         if (m & 0x20)
2611                 PUSHS16(regs.y);
2612         if (m & 0x10)
2613                 PUSHS16(regs.x);
2614         if (m & 0x08)
2615                 PUSHS(regs.dp);
2616         if (m & 0x04)
2617                 PUSHS(regs.b);
2618         if (m & 0x02)
2619                 PUSHS(regs.a);
2620         if (m & 0x01)
2621         {
2622                 regs.cc = PACK_FLAGS;
2623                 PUSHS(regs.cc);
2624         }
2625
2626         // Count bits in each nybble to come up with correct cycle counts...
2627         uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2628         regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2629 }
2630
2631 static void Op35(void)                                                  // PULS
2632 {
2633         uint8_t m = READ_IMM;
2634
2635         if (m & 0x01)
2636         {
2637                 PULLS(regs.cc);
2638                 UNPACK_FLAGS;
2639         }
2640         if (m & 0x02)
2641                 PULLS(regs.a);
2642         if (m & 0x04)
2643                 PULLS(regs.b);
2644         if (m & 0x08)
2645                 PULLS(regs.dp);
2646         if (m & 0x10)
2647                 PULLS16(regs.x);
2648         if (m & 0x20)
2649                 PULLS16(regs.y);
2650         if (m & 0x40)
2651                 PULLS16(regs.u);
2652         if (m & 0x80)
2653                 PULLS16(regs.pc);
2654
2655         // Count bits in each nybble to come up with correct cycle counts...
2656         uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2657         regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2658 }
2659
2660 static void Op36(void)                                                  // PHSU
2661 {
2662         uint8_t m = READ_IMM;
2663
2664         if (m & 0x80)
2665                 PUSHU16(regs.pc);
2666         if (m & 0x40)
2667                 PUSHU16(regs.s);
2668         if (m & 0x20)
2669                 PUSHU16(regs.y);
2670         if (m & 0x10)
2671                 PUSHU16(regs.x);
2672         if (m & 0x08)
2673                 PUSHU(regs.dp);
2674         if (m & 0x04)
2675                 PUSHU(regs.b);
2676         if (m & 0x02)
2677                 PUSHU(regs.a);
2678         if (m & 0x01)
2679         {
2680                 regs.cc = PACK_FLAGS;
2681                 PUSHU(regs.cc);
2682         }
2683
2684         // Count bits in each nybble to come up with correct cycle counts...
2685         uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2686         regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2687 }
2688
2689 static void Op37(void)                                                  // PULU
2690 {
2691         uint8_t m = READ_IMM;
2692
2693         if (m & 0x01)
2694         {
2695                 PULLU(regs.cc);
2696                 UNPACK_FLAGS;
2697         }
2698         if (m & 0x02)
2699                 PULLU(regs.a);
2700         if (m & 0x04)
2701                 PULLU(regs.b);
2702         if (m & 0x08)
2703                 PULLU(regs.dp);
2704         if (m & 0x10)
2705                 PULLU16(regs.x);
2706         if (m & 0x20)
2707                 PULLU16(regs.y);
2708         if (m & 0x40)
2709                 PULLU16(regs.s);
2710         if (m & 0x80)
2711                 PULLU16(regs.pc);
2712
2713         // Count bits in each nybble to come up with correct cycle counts...
2714         uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2715         regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2716 }
2717
2718 /*
2719  +-----------------------------------------------------------------+
2720  | Opcode     |             | Addressing   |               |       |
2721  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2722  +------------+-------------+--------------+-------+-------+-------+
2723  | 09    0009 | ROL         | DIRECT       |   6   |   2   | -aaas |
2724  | 49    0073 | ROLA        | INHERENT     |   2   |   1   | -aaas |
2725  | 59    0089 | ROLB        | INHERENT     |   2   |   1   | -aaas |
2726  | 69    0105 | ROL         | INDEXED      |   6   |   2   | -aaas |
2727  | 79    0121 | ROL         | EXTENDED     |   7   |   3   | -aaas |
2728 */
2729
2730 // ROL opcodes
2731
2732 #define OP_ROL_HANDLER(m) \
2733         uint8_t res = (m << 1) | flagC; \
2734         SET_ZN(res); \
2735         SET_V(m, m, res); \
2736         flagC = (m >> 7) & 0x01; \
2737         m = res
2738
2739 /*
2740         UINT16 t,r;
2741         DIRBYTE(t);
2742         r = (CC & CC_C) | (t << 1);
2743         CLR_NZVC;
2744         SET_FLAGS8(t,t,r);
2745         WM(EAD,r);
2746 */
2747 static void Op09(void)                                                  // ROL DP
2748 {
2749         uint8_t m;
2750         READ_DP_WB(m);
2751         OP_ROL_HANDLER(m);
2752         WRITE_BACK(m);
2753 }
2754
2755 static void Op49(void)                                                  // ROLA
2756 {
2757         OP_ROL_HANDLER(regs.a);
2758 }
2759
2760 static void Op59(void)                                                  // ROLB
2761 {
2762         OP_ROL_HANDLER(regs.b);
2763 }
2764
2765 static void Op69(void)                                                  // ROL IDX
2766 {
2767         uint8_t m;
2768         READ_IDX_WB(m);
2769         OP_ROL_HANDLER(m);
2770         WRITE_BACK(m);
2771 }
2772
2773 static void Op79(void)                                                  // ROL ABS
2774 {
2775         uint8_t m;
2776         READ_ABS_WB(m);
2777         OP_ROL_HANDLER(m);
2778         WRITE_BACK(m);
2779 }
2780
2781 /*
2782  +-----------------------------------------------------------------+
2783  | Opcode     |             | Addressing   |               |       |
2784  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2785  +------------+-------------+--------------+-------+-------+-------+
2786  | 06    0006 | ROR         | DIRECT       |   6   |   2   | -aa-s |
2787  | 46    0070 | RORA        | INHERENT     |   2   |   1   | -aa-s |
2788  | 56    0086 | RORB        | INHERENT     |   2   |   1   | -aa-s |
2789  | 66    0102 | ROR         | INDEXED      |   6   |   2   | -aa-s |
2790  | 76    0118 | ROR         | EXTENDED     |   7   |   3   | -aa-s |
2791 */
2792
2793 // ROR opcodes
2794
2795 #define OP_ROR_HANDLER(m) \
2796         uint8_t res = (flagC << 7) | (m >> 1); \
2797         SET_ZN(res); \
2798         SET_V(m, m, res); \
2799         flagC = m & 0x01; \
2800         m = res
2801
2802 static void Op06(void)                                                  // ROR DP
2803 {
2804         uint8_t m;
2805         READ_DP_WB(m);
2806         OP_ROR_HANDLER(m);
2807         WRITE_BACK(m);
2808 }
2809
2810 static void Op46(void)                                                  // RORA
2811 {
2812         OP_ROR_HANDLER(regs.a);
2813 }
2814
2815 static void Op56(void)                                                  // RORB
2816 {
2817         OP_ROR_HANDLER(regs.b);
2818 }
2819
2820 static void Op66(void)                                                  // ROR IDX
2821 {
2822         uint8_t m;
2823         READ_IDX_WB(m);
2824         OP_ROR_HANDLER(m);
2825         WRITE_BACK(m);
2826 }
2827
2828 static void Op76(void)                                                  // ROR ABS
2829 {
2830         uint8_t m;
2831         READ_ABS_WB(m);
2832         OP_ROR_HANDLER(m);
2833         WRITE_BACK(m);
2834 }
2835
2836 /*
2837  +-----------------------------------------------------------------+
2838  | Opcode     |             | Addressing   |               |       |
2839  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2840  +------------+-------------+--------------+-------+-------+-------+
2841  | 82    0130 | SBCA        | IMMEDIATE    |   2   |   2   | uaaaa |
2842  | 92    0146 | SBCA        | DIRECT       |   4   |   2   | uaaaa |
2843  | A2    0162 | SBCA        | INDEXED      |   4   |   2   | uaaaa |
2844  | B2    0178 | SBCA        | EXTENDED     |   5   |   3   | uaaaa |
2845  | C2    0194 | SBCB        | IMMEDIATE    |   2   |   2   | uaaaa |
2846  | D2    0210 | SBCB        | DIRECT       |   4   |   2   | uaaaa |
2847  | E2    0226 | SBCB        | INDEXED      |   4   |   2   | uaaaa |
2848  | F2    0242 | SBCB        | EXTENDED     |   5   |   3   | uaaaa |
2849 */
2850
2851 // SBC opcodes
2852
2853 #define OP_SBC_HANDLER(m, acc) \
2854         uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
2855         flagC = (sum >> 8) & 0x01; \
2856         SET_V(m, acc, sum); \
2857         acc = (uint8_t)sum; \
2858         SET_ZN(acc)
2859
2860 static void Op82(void)                                                  // SBCA #
2861 {
2862         uint8_t m = READ_IMM;
2863         OP_SBC_HANDLER(m, regs.a);
2864 }
2865
2866 static void Op92(void)                                                  // SBCA DP
2867 {
2868         uint8_t m = READ_DP;
2869         OP_SBC_HANDLER(m, regs.a);
2870 }
2871
2872 static void OpA2(void)                                                  // SBCA IDX
2873 {
2874         uint8_t m = READ_IDX;
2875         OP_SBC_HANDLER(m, regs.a);
2876 }
2877
2878 static void OpB2(void)                                                  // SBCA ABS
2879 {
2880         uint8_t m = READ_ABS;
2881         OP_SBC_HANDLER(m, regs.a);
2882 }
2883
2884 static void OpC2(void)                                                  // SBCB #
2885 {
2886         uint8_t m = READ_IMM;
2887         OP_SBC_HANDLER(m, regs.b);
2888 }
2889
2890 static void OpD2(void)                                                  // SBCB DP
2891 {
2892         uint8_t m = READ_DP;
2893         OP_SBC_HANDLER(m, regs.b);
2894 }
2895
2896 static void OpE2(void)                                                  // SBCB IDX
2897 {
2898         uint8_t m = READ_IDX;
2899         OP_SBC_HANDLER(m, regs.b);
2900 }
2901
2902 static void OpF2(void)                                                  // SBCB ABS
2903 {
2904         uint8_t m = READ_ABS;
2905         OP_SBC_HANDLER(m, regs.b);
2906 }
2907
2908 /*
2909  +-----------------------------------------------------------------+
2910  | Opcode     |             | Addressing   |               |       |
2911  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
2912  +------------+-------------+--------------+-------+-------+-------+
2913  | 97    0151 | STA         | DIRECT       |   4   |   2   | -aa0- |
2914  | 9F    0159 | STX         | DIRECT       |   5   |   2   | -aa0- |
2915  | A7    0167 | STA         | INDEXED      |   4   |   2   | -aa0- |
2916  | AF    0175 | STX         | INDEXED      |   5   |   2   | -aa0- |
2917  | B7    0183 | STA         | EXTENDED     |   5   |   3   | -aa0- |
2918  | BF    0191 | STX         | EXTENDED     |   6   |   3   | -aa0- |
2919  | D7    0215 | STB         | DIRECT       |   4   |   2   | -aa0- |
2920  | DD    0221 | STD         | DIRECT       |   5   |   2   | -aa0- |
2921  | DF    0223 | STU         | DIRECT       |   5   |   2   | -aa0- |
2922  | E7    0231 | STB         | INDEXED      |   4   |   2   | -aa0- |
2923  | ED    0237 | STD         | INDEXED      |   5   |   2   | -aa0- |
2924  | EF    0239 | STU         | INDEXED      |   5   |   2   | -aa0- |
2925  | F7    0247 | STB         | EXTENDED     |   5   |   3   | -aa0- |
2926  | FD    0253 | STD         | EXTENDED     |   6   |   3   | -aa0- |
2927  | FF    0255 | STU         | EXTENDED     |   6   |   3   | -aa0- |
2928  | 109F  4255 | STY         | DIRECT       |   6   |   3   | -aa0- |
2929  | 10AF  4271 | STY         | INDEXED      |   6   |   3   | -aa0- |
2930  | 10BF  4287 | STY         | EXTENDED     |   7   |   4   | -aa0- |
2931  | 10DF  4319 | STS         | DIRECT       |   6   |   3   | -aa0- |
2932  | 10EF  4335 | STS         | INDEXED      |   6   |   3   | -aa0- |
2933  | 10FF  4351 | STS         | EXTENDED     |   7   |   4   | -aa0- |
2934 */
2935
2936 // STA opcodes
2937
2938 #define OP_STA_HANDLER(m, acc) \
2939         regs.WrMem(m, acc); \
2940         CLR_V; \
2941         SET_ZN(acc)
2942
2943 #define OP_STA_HANDLER16(m, acc) \
2944         WrMemW(m, acc); \
2945         CLR_V; \
2946         SET_ZN16(acc)
2947
2948 static void Op97(void)                                                  // STA DP
2949 {
2950         uint16_t addr = EA_DP;
2951         OP_STA_HANDLER(addr, regs.a);
2952 }
2953
2954 static void Op9F(void)                                                  // STX DP
2955 {
2956         uint16_t addr = EA_DP;
2957         OP_STA_HANDLER16(addr, regs.x);
2958 }
2959
2960 static void OpA7(void)                                                  // STA IDX
2961 {
2962         uint16_t addr = EA_IDX;
2963         OP_STA_HANDLER(addr, regs.a);
2964 }
2965
2966 static void OpAF(void)                                                  // STX IDX
2967 {
2968         uint16_t addr = EA_IDX;
2969         OP_STA_HANDLER16(addr, regs.x);
2970 }
2971
2972 static void OpB7(void)                                                  // STA ABS
2973 {
2974         uint16_t addr = EA_ABS;
2975         OP_STA_HANDLER(addr, regs.a);
2976 }
2977
2978 static void OpBF(void)                                                  // STX ABS
2979 {
2980         uint16_t addr = EA_ABS;
2981         OP_STA_HANDLER16(addr, regs.x);
2982 }
2983
2984 static void OpD7(void)                                                  // STB DP
2985 {
2986         uint16_t addr = EA_DP;
2987         OP_STA_HANDLER(addr, regs.b);
2988 }
2989
2990 static void OpDD(void)                                                  // STD DP
2991 {
2992         uint16_t addr = EA_DP;
2993         OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2994 }
2995
2996 static void OpDF(void)                                                  // STU DP
2997 {
2998         uint16_t addr = EA_DP;
2999         OP_STA_HANDLER16(addr, regs.u);
3000 }
3001
3002 static void OpE7(void)                                                  // STB IDX
3003 {
3004         uint16_t addr = EA_IDX;
3005         OP_STA_HANDLER(addr, regs.b);
3006 }
3007
3008 static void OpED(void)                                                  // STD IDX
3009 {
3010         uint16_t addr = EA_IDX;
3011         OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3012 }
3013
3014 static void OpEF(void)                                                  // STU IDX
3015 {
3016         uint16_t addr = EA_IDX;
3017         OP_STA_HANDLER16(addr, regs.u);
3018 }
3019
3020 static void OpF7(void)                                                  // STB ABS
3021 {
3022         uint16_t addr = EA_ABS;
3023         OP_STA_HANDLER(addr, regs.b);
3024 }
3025
3026 static void OpFD(void)                                                  // STD ABS
3027 {
3028         uint16_t addr = EA_ABS;
3029         OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3030 }
3031
3032 static void OpFF(void)                                                  // STU ABS
3033 {
3034         uint16_t addr = EA_ABS;
3035         OP_STA_HANDLER16(addr, regs.u);
3036 }
3037
3038 static void Op109F(void)                                                // STY DP
3039 {
3040         uint16_t addr = EA_DP;
3041         OP_STA_HANDLER16(addr, regs.y);
3042 }
3043
3044 static void Op10AF(void)                                                // STY IDX
3045 {
3046         uint16_t addr = EA_IDX;
3047         OP_STA_HANDLER16(addr, regs.y);
3048 }
3049
3050 static void Op10BF(void)                                                // STY ABS
3051 {
3052         uint16_t addr = EA_ABS;
3053         OP_STA_HANDLER16(addr, regs.y);
3054 }
3055
3056 static void Op10DF(void)                                                // STS DP
3057 {
3058         uint16_t addr = EA_DP;
3059         OP_STA_HANDLER16(addr, regs.s);
3060 }
3061
3062 static void Op10EF(void)                                                // STS IDX
3063 {
3064         uint16_t addr = EA_IDX;
3065         OP_STA_HANDLER16(addr, regs.s);
3066 }
3067
3068 static void Op10FF(void)                                                // STS ABS
3069 {
3070         uint16_t addr = EA_ABS;
3071         OP_STA_HANDLER16(addr, regs.s);
3072 }
3073
3074 /*
3075  +-----------------------------------------------------------------+
3076  | Opcode     |             | Addressing   |               |       |
3077  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
3078  +------------+-------------+--------------+-------+-------+-------+
3079  | 80    0128 | SUBA        | IMMEDIATE    |   2   |   2   | uaaaa |
3080  | 83    0131 | SUBD        | IMMEDIATE    |   4   |   3   | -aaaa |
3081  | 90    0144 | SUBA        | DIRECT       |   4   |   2   | uaaaa |
3082  | 93    0147 | SUBD        | DIRECT       |   6   |   2   | -aaaa |
3083  | A0    0160 | SUBA        | INDEXED      |   4   |   2   | uaaaa |
3084  | A3    0163 | SUBD        | INDEXED      |   6   |   2   | -aaaa |
3085  | B0    0176 | SUBA        | EXTENDED     |   5   |   3   | uaaaa |
3086  | B3    0179 | SUBD        | EXTENDED     |   7   |   3   | -aaaa |
3087  | C0    0192 | SUBB        | IMMEDIATE    |   2   |   2   | uaaaa |
3088  | D0    0208 | SUBB        | DIRECT       |   4   |   2   | uaaaa |
3089  | E0    0224 | SUBB        | INDEXED      |   4   |   2   | uaaaa |
3090  | F0    0240 | SUBB        | EXTENDED     |   5   |   3   | uaaaa |
3091 */
3092
3093 // SUB opcodes
3094
3095 #define OP_SUB_HANDLER(m, acc) \
3096         uint16_t sum = (uint16_t)acc - (m); \
3097         flagC = (sum >> 8) & 0x01; \
3098         SET_V(m, acc, sum); \
3099         acc = (uint8_t)sum; \
3100         SET_ZN(acc)
3101
3102 #define OP_SUB_HANDLER16D(m) \
3103         uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \
3104         uint32_t sum = acc - (m); \
3105         flagC = (sum >> 16) & 0x01; \
3106         SET_V16(m, acc, sum); \
3107         acc = sum & 0xFFFF; \
3108         regs.a = (acc >> 8) & 0xFF; \
3109         regs.b = acc & 0xFF; \
3110         SET_ZN16(acc)
3111
3112 static void Op80(void)                                                  // SUBA #
3113 {
3114         uint8_t m = READ_IMM;
3115         OP_SUB_HANDLER(m, regs.a);
3116 }
3117
3118 static void Op83(void)                                                  // SUBD #
3119 {
3120         uint16_t m = READ_IMM16;
3121         OP_SUB_HANDLER16D(m);
3122 }
3123
3124 static void Op90(void)                                                  // SUBA DP
3125 {
3126         uint8_t m = READ_DP;
3127         OP_SUB_HANDLER(m, regs.a);
3128 }
3129
3130 static void Op93(void)                                                  // SUBD DP
3131 {
3132         uint16_t m = READ_DP16;
3133         OP_SUB_HANDLER16D(m);
3134 }
3135
3136 static void OpA0(void)                                                  // SUBA IDX
3137 {
3138         uint8_t m = READ_IDX;
3139         OP_SUB_HANDLER(m, regs.a);
3140 }
3141
3142 static void OpA3(void)                                                  // SUBD IDX
3143 {
3144         uint16_t m = READ_IDX16;
3145         OP_SUB_HANDLER16D(m);
3146 }
3147
3148 static void OpB0(void)                                                  // SUBA ABS
3149 {
3150         uint8_t m = READ_ABS;
3151         OP_SUB_HANDLER(m, regs.a);
3152 }
3153
3154 static void OpB3(void)                                                  // SUBD ABS
3155 {
3156         uint16_t m = READ_ABS16;
3157         OP_SUB_HANDLER16D(m);
3158 }
3159
3160 static void OpC0(void)                                                  // SUBB #
3161 {
3162         uint8_t m = READ_IMM;
3163         OP_SUB_HANDLER(m, regs.b);
3164 }
3165
3166 static void OpD0(void)                                                  // SUBB DP
3167 {
3168         uint8_t m = READ_DP;
3169         OP_SUB_HANDLER(m, regs.b);
3170 }
3171
3172 static void OpE0(void)                                                  // SUBB IDX
3173 {
3174         uint8_t m = READ_IDX;
3175         OP_SUB_HANDLER(m, regs.b);
3176 }
3177
3178 static void OpF0(void)                                                  // SUBB ABS
3179 {
3180         uint8_t m = READ_ABS;
3181         OP_SUB_HANDLER(m, regs.b);
3182 }
3183
3184 /*
3185  +-----------------------------------------------------------------+
3186  | Opcode     |             | Addressing   |               |       |
3187  | Hex   Dec  | Instruction | Mode         | Cycles  Bytes | HNZVC |
3188  +------------+-------------+--------------+-------+-------+-------+
3189  | 0D    0013 | TST         | DIRECT       |   6   |   2   | -aa0- |
3190  | 4D    0077 | TSTA        | INHERENT     |   2   |   1   | -aa0- |
3191  | 5D    0093 | TSTB        | INHERENT     |   2   |   1   | -aa0- |
3192  | 6D    0109 | TST         | INDEXED      |   6   |   2   | -aa0- |
3193  | 7D    0125 | TST         | EXTENDED     |   7   |   3   | -aa0- |
3194 */
3195
3196 // TST opcodes
3197
3198 #define OP_TST_HANDLER(m) \
3199         SET_ZN(m); \
3200         CLR_V
3201
3202 static void Op0D(void)                                                  // TST DP
3203 {
3204         uint8_t m = READ_DP;
3205         OP_TST_HANDLER(m);
3206 }
3207
3208 static void Op4D(void)                                                  // TSTA
3209 {
3210         OP_TST_HANDLER(regs.a);
3211 }
3212
3213 static void Op5D(void)                                                  // TSTB
3214 {
3215         OP_TST_HANDLER(regs.b);
3216 }
3217
3218 static void Op6D(void)                                                  // TST IDX
3219 {
3220         uint8_t m = READ_IDX;
3221         OP_TST_HANDLER(m);
3222 }
3223
3224 static void Op7D(void)                                                  // TST ABS
3225 {
3226         uint8_t m = READ_ABS;
3227         OP_TST_HANDLER(m);
3228 }
3229
3230 // Undocumented Opcodes
3231
3232 static void Op01(void)
3233 {
3234         Op00();                                                                         // NEG DP
3235 }
3236
3237
3238 //temp, for testing...
3239 #ifdef __DEBUG__
3240 static uint8_t backTrace[256];
3241 static uint16_t btPC[256];
3242 static int btPtr = 0;//*/
3243 #endif
3244 static void Op__(void)                                                                  // Illegal opcode
3245 {
3246         regs.clock++;
3247 //      illegal = true;
3248         regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3249 #ifdef __DEBUG__
3250 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3251 for(int i=0; i<256; i++)
3252 {
3253         Decode6809(btPC[(btPtr + i) & 0xFF]);
3254         WriteLog("\n");
3255 }//*/
3256 #endif
3257 }
3258
3259 //
3260 // Function arrays
3261 //
3262
3263 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
3264 static void Op10(void);
3265 static void Op11(void);
3266
3267 // Array of page zero opcode functions...
3268
3269 static void (* exec_op0[256])() = {
3270         Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
3271         Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
3272         Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
3273         Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
3274         Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
3275         Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
3276         Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
3277         Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
3278         Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
3279         Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
3280         OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
3281         OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
3282         OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
3283         OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
3284         OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
3285         OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
3286 };
3287
3288 // Array of page one opcode functions...
3289 static void (* exec_op1[256])() = {
3290         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3291         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3292         Op__,   Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
3293         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op103F,
3294         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3295         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3296         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3297         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3298         Op__,   Op__,   Op__,   Op1083, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op108C, Op__,   Op108E, Op__,
3299         Op__,   Op__,   Op__,   Op1093, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op109C, Op__,   Op109E, Op109F,
3300         Op__,   Op__,   Op__,   Op10A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10AC, Op__,   Op10AE, Op10AF,
3301         Op__,   Op__,   Op__,   Op10B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10BC, Op__,   Op10BE, Op10BF,
3302         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10CE, Op__,
3303         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10DE, Op10DF,
3304         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10EE, Op10EF,
3305         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op10FE, Op10FF
3306 };
3307
3308 // Array of page two opcode functions...
3309 static void (* exec_op2[256])() = {
3310         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3311         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3312         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3313         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op113F,
3314         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3315         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3316         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3317         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3318         Op__,   Op__,   Op__,   Op1183, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op118C, Op__,   Op__,   Op__,
3319         Op__,   Op__,   Op__,   Op1193, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op119C, Op__,   Op__,   Op__,
3320         Op__,   Op__,   Op__,   Op11A3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11AC, Op__,   Op__,   Op__,
3321         Op__,   Op__,   Op__,   Op11B3, Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op11BC, Op__,   Op__,   Op__,
3322         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3323         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3324         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,
3325         Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__,   Op__
3326 };
3327
3328 // These are here to save typing a ton of forward declarations...
3329
3330 // Page 1 opcode
3331 static void Op10(void)
3332 {
3333 //      exec_op1[regs.RdMem(regs.pc++)]();
3334         uint8_t opcode = regs.RdMem(regs.pc++);
3335         exec_op1[opcode]();
3336         regs.clock += page1Cycles[opcode];
3337 }
3338
3339 // Page 2 opcode
3340 static void Op11(void)
3341 {
3342 //      exec_op2[regs.RdMem(regs.pc++)]();
3343         uint8_t opcode = regs.RdMem(regs.pc++);
3344         exec_op2[opcode]();
3345         regs.clock += page2Cycles[opcode];
3346 }
3347
3348
3349 //
3350 // Internal "memcpy" (so we don't have to link with any external libraries!)
3351 //
3352 static void myMemcpy(void * dst, void * src, uint32_t size)
3353 {
3354         uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3355
3356         for(uint32_t i=0; i<size; i++)
3357                 d[i] = s[i];
3358 }
3359
3360 //
3361 // Function to execute 6809 instructions
3362 //
3363 //#define DEBUG_ILLEGAL
3364 #ifdef DEBUG_ILLEGAL
3365 #include "log.h"
3366 #include "dis6809.h"
3367 uint8_t btPtr = 0;
3368 uint8_t backTrace[256];
3369 V6809REGS btRegs[256];
3370 bool tripped = false;
3371 #endif
3372 void Execute6809(V6809REGS * context, uint32_t cycles)
3373 {
3374         // If this is not in place, the clockOverrun calculations can cause the V6809 to get
3375         // stuck in an infinite loop.
3376         if (cycles == 0)                                                        // Nothing to do, so bail!
3377                 return;
3378
3379         myMemcpy(&regs, context, sizeof(V6809REGS));
3380         UNPACK_FLAGS;                                                           // Explode flags register into individual uint8_ts
3381
3382         // Execute here...
3383
3384         // Since we can't guarantee that we'll execute the number of cycles passed in
3385         // exactly, we have to keep track of how much we overran the number of cycles
3386         // the last time we executed. Since we already executed those cycles, this time
3387         // through we remove them from the cycles passed in in order to come out
3388         // approximately even. Over the long run, this unevenness in execution times
3389         // evens out.
3390         uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3391
3392         while (regs.clock < endCycles)
3393         {
3394 #ifdef DEBUG_ILLEGAL
3395 if (!tripped)
3396 {
3397         backTrace[btPtr] = regs.RdMem(regs.pc);
3398         btRegs[btPtr] = regs;
3399         btPtr = (btPtr + 1) & 0xFF;
3400
3401         if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3402         {
3403                 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3404                 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3405
3406                 for(uint16_t i=btPtr; i<btPtr+256; i++)
3407                 {
3408                         Decode6809(btRegs[i & 0xFF].pc);
3409 // Note that these values are *before* execution, so stale...
3410                         WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3411                                 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);//*/
3412                 }
3413
3414                 tripped = true;
3415         }
3416 }
3417 #endif
3418 #ifdef __DEBUG__
3419 if (disasm)
3420 {
3421         Decode6809(regs.pc);
3422 //      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);
3423 }
3424 #if 0 //we solved this...
3425 if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
3426         WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
3427 #endif
3428 //static bool disasm = false;
3429 /*//if (regs.pc == 0x15BA)      disasm = true;
3430 //if (regs.pc == 0xFE76)        disasm = true;
3431 if (regs.x == 0xFED4)   disasm = true;
3432 if (disasm) Decode6809(regs.pc);
3433 //if (regs.pc == 0x164A)        disasm = false;//*/
3434
3435 //temp, for testing...
3436 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3437 btPC[btPtr] = regs.pc;
3438 btPtr = (btPtr + 1) & 0xFF;//*/
3439 #endif
3440 //              exec_op0[regs.RdMem(regs.pc++)]();
3441                 uint8_t opcode = regs.RdMem(regs.pc++);
3442                 exec_op0[opcode]();
3443                 regs.clock += page0Cycles[opcode];
3444
3445                 // Handle any pending interrupts
3446
3447 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3448 //              uint32_t flags = context->cpuFlags;
3449                 uint32_t flags = regs.cpuFlags;
3450
3451                 if (flags & V6809_ASSERT_LINE_RESET)                    // *** RESET handler ***
3452                 {
3453 #ifdef __DEBUG__
3454 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3455 #endif
3456                         flagF = flagI = 1;                                                      // Set F, I
3457                         regs.dp = 0;                                                            // Reset direct page register
3458                         regs.pc = RdMemW(0xFFFE);                                       // And load PC with the RESET vector
3459                         context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3460                         regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3461                 }
3462                 else if (flags & V6809_ASSERT_LINE_NMI)                 // *** NMI handler ***
3463                 {
3464 #ifdef __DEBUG__
3465 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3466 #endif
3467                         flagE = 1;                                                                      // Set Entire flag
3468                         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
3469
3470                         PUSHS16(regs.pc);                                                       // Save all regs...
3471                         PUSHS16(regs.u);
3472                         PUSHS16(regs.y);
3473                         PUSHS16(regs.x);
3474                         PUSHS(regs.dp);
3475                         PUSHS(regs.b);
3476                         PUSHS(regs.a);
3477                         PUSHS(regs.cc);
3478
3479                         flagI = flagF = 1;                                                      // Set IRQ/FIRQ suppress flags
3480                         regs.pc = RdMemW(0xFFFC);                                       // And load PC with the NMI vector
3481                         regs.clock += 19;
3482 //                      context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3483 //                      regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI;        // Reset the asserted line (NMI)...
3484                 }
3485                 else if (flags & V6809_ASSERT_LINE_FIRQ)                // *** FIRQ handler ***
3486                 {
3487 #ifdef __DEBUG__
3488 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3489 #endif
3490                         if (!flagF)                                                                     // Is the FIRQ masked (F == 1)?
3491                         {
3492 #ifdef __DEBUG__
3493 if (disasm) WriteLog("       FIRQ taken...\n");
3494 #endif
3495                                 flagE = 0;                                                              // Clear Entire flag
3496                                 regs.cc = PACK_FLAGS;                                   // Mash flags back into the CC register
3497
3498                                 PUSHS16(regs.pc);
3499                                 PUSHS(regs.cc);
3500
3501                                 flagI = flagF = 1;                                              // Set IRQ/FIRQ suppress flags
3502                                 regs.pc = RdMemW(0xFFF6);                               // And load PC with the IRQ vector
3503                                 regs.clock += 10;
3504 //                              context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;   // Reset the asserted line (FIRQ)...
3505 //                              regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ;       // Reset the asserted line (FIRQ)...
3506                         }
3507                 }
3508                 else if (flags & V6809_ASSERT_LINE_IRQ)                 // *** IRQ handler ***
3509                 {
3510 #ifdef __DEBUG__
3511 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3512 #endif
3513                         if (!flagI)                                                                     // Is the IRQ masked (I == 1)?
3514                         {
3515 #ifdef __DEBUG__
3516 if (disasm) WriteLog("       IRQ taken...\n");
3517 #endif
3518                                 flagE = 1;                                                              // Set the Entire flag
3519                                 regs.cc = PACK_FLAGS;                                   // Mash flags back into the CC register
3520
3521                                 PUSHS16(regs.pc);
3522                                 PUSHS16(regs.u);
3523                                 PUSHS16(regs.y);
3524                                 PUSHS16(regs.x);
3525                                 PUSHS(regs.dp);
3526                                 PUSHS(regs.b);
3527                                 PUSHS(regs.a);
3528                                 PUSHS(regs.cc);
3529
3530                                 flagI = 1;                                                              // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3531                                 regs.pc = RdMemW(0xFFF8);                               // And load PC with the IRQ vector
3532                                 regs.clock += 19;
3533 // Apparently, not done here!
3534 //                              context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ;    // Reset the asserted line (IRQ)...
3535 //                              regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ;        // Reset the asserted line (IRQ)...
3536                         }
3537                 }
3538 #ifdef __DEBUG__
3539 if (disasm) WriteLog("CC=%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",
3540         (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
3541         (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
3542         regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3543 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3544         regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3545 #endif
3546         }
3547
3548         // Keep track of how much we overran so we can adjust on the next run...
3549         regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3550
3551         regs.cc = PACK_FLAGS;                                           // Mash flags back into the CC register
3552         myMemcpy(context, &regs, sizeof(V6809REGS));
3553 }
3554
3555 //
3556 // Get the clock of the currently executing CPU
3557 //
3558 uint64_t GetCurrentV6809Clock(void)
3559 {
3560         return regs.clock;
3561 }
3562
3563 //
3564 // Get the PC of the currently executing CPU
3565 //
3566 uint16_t GetCurrentV6809PC(void)
3567 {
3568         return regs.pc;
3569 }
3570
3571 // Set a line of the currently executing CPU
3572 void SetLineOfCurrentV6809(uint32_t line)
3573 {
3574         regs.cpuFlags |= line;
3575 }
3576
3577 // Clear a line of the currently executing CPU
3578 void ClearLineOfCurrentV6809(uint32_t line)
3579 {
3580 #ifdef __DEBUG__
3581 if (disasm)
3582         WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
3583 #endif
3584         regs.cpuFlags &= ~line;
3585 }
3586
3587 #if 0
3588 FE54: 27 6A          BEQ   $FEC0        CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
3589 E S=BFFF U=0000 PC=FEC0
3590 FEC0: 6E A4          JMP   ,Y   CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
3591  U=0000 PC=F51E
3592 F51E: 86 34          LDA   #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
3593  U=0000 PC=F520
3594 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
3595 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
3596 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
3597 F529: 86 9C          LDA   #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
3598 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
3599 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
3600 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
3601 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
3602 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
3603 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
3604 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
3605 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
3606 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
3607 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
3608 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
3609 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
3610 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
3611 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
3612 13D5: 11 83 00 00    CMPU  #$0000       CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000
3613 #endif