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