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