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