5 // (C) 1997, 2009, 2014 Underground Software
7 // JLH = James L. Hammons <jlhamm@acm.org>
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
23 #include "dis6809.h" // Temporary...
24 #include "log.h" // Temporary...
25 bool disasm = false;//so we can extern this shit
28 #define TEST_DONT_BRANCH_OPTIMIZATION
32 #define CLR_Z (flagZ = 0)
33 #define CLR_ZN (flagZ = flagN = 0)
34 #define CLR_ZNC (flagZ = flagN = flagC = 0)
35 #define CLR_V (flagV = 0)
36 #define CLR_N (flagN = 0)
37 #define SET_Z(r) (flagZ = ((r) == 0 ? 1 : 0))
38 #define SET_N(r) (flagN = ((r) & 0x80) >> 7)
39 #define SET_N16(r) (flagN = ((r) & 0x8000) >> 15)
40 #define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
41 #define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
42 #define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4)
44 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
45 //#define SET_C_ADD(a,b) (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0))
46 //#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
47 //#define SET_C_CMP(a,b) (flagC = ((uint8_t)(b) >= (uint8_t)(a) ? 1 : 0))
48 #define SET_ZN(r) SET_N(r); SET_Z(r)
49 #define SET_ZN16(r) SET_N16(r); SET_Z(r)
50 //#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
51 //#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
52 //#define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b)
54 #define EA_IMM regs.pc++
55 #define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++)
56 #define EA_IDX DecodeIDX(regs.RdMem(regs.pc++))
57 #define EA_ABS FetchMemW(regs.pc)
59 #define READ_IMM regs.RdMem(EA_IMM)
60 #define READ_IMM16 FetchMemW(regs.pc)
61 #define READ_DP regs.RdMem(EA_DP)
62 #define READ_DP16 RdMemW(EA_DP)
63 #define READ_IDX regs.RdMem(EA_IDX)
64 #define READ_IDX16 RdMemW(EA_IDX)
65 #define READ_ABS regs.RdMem(EA_ABS)
66 #define READ_ABS16 RdMemW(EA_ABS)
68 #define READ_IMM_WB(v) uint16_t addr = EA_IMM; v = regs.RdMem(addr)
69 #define READ_DP_WB(v) uint16_t addr = EA_DP; v = regs.RdMem(addr)
70 #define READ_IDX_WB(v) uint16_t addr = EA_IDX; v = regs.RdMem(addr)
71 #define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr)
73 #define WRITE_BACK(d) regs.WrMem(addr, (d))
75 #define PULLS(r) r = regs.RdMem(regs.s++)
76 #define PUSHS(r) regs.WrMem(--regs.s, (r))
77 #define PULLS16(r) { r = RdMemW(regs.s); regs.s += 2; }
78 #define PUSHS16(r) { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
79 #define PULLU(r) r = regs.RdMem(regs.u++)
80 #define PUSHU(r) regs.WrMem(--regs.u, (r))
81 #define PULLU16(r) { r = RdMemW(regs.u); regs.u += 2; }
82 #define PUSHU16(r) { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
84 #define PACK_FLAGS ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
85 #define UNPACK_FLAGS flagE = (regs.cc & FLAG_E) >> 7; \
86 flagF = (regs.cc & FLAG_F) >> 6; \
87 flagH = (regs.cc & FLAG_H) >> 5; \
88 flagI = (regs.cc & FLAG_I) >> 4; \
89 flagN = (regs.cc & FLAG_N) >> 3; \
90 flagZ = (regs.cc & FLAG_Z) >> 2; \
91 flagV = (regs.cc & FLAG_V) >> 1; \
92 flagC = (regs.cc & FLAG_C)
94 // Private global variables
96 static V6809REGS regs;
97 static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
99 static const uint8_t page0Cycles[256] = {
100 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x
101 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x
102 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x
103 4, 4, 4, 4, 5, 5, 5, 5, 1, 5, 3, 6, 21, 11, 0, 19, // $3x
104 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, // $4x
105 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, // $5x
106 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $6x
107 7, 1, 1, 7, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 3, 7, // $7x
108 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, // $8x
109 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $9x
110 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $Ax
111 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, // $Bx
112 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, // $Cx
113 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Dx
114 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Ex
115 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx
118 static const uint8_t page1Cycles[256] = {
119 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
120 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
121 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x
122 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
123 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
124 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
125 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
126 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
127 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, // $8x
128 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $9x
129 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $Ax
130 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 7, 7, // $Bx
131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, // $Cx
132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Dx
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Ex
134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx
137 static const uint8_t page2Cycles[256] = {
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
140 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x
141 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
142 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
144 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
145 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
146 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, // $8x
147 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $9x
148 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $Ax
149 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, // $Bx
150 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Cx
151 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Dx
152 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Ex
153 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx
156 // Private function prototypes
158 static uint16_t RdMemW(uint16_t addr);
159 static uint16_t FetchMemW(uint16_t addr);
160 static void WrMemW(uint16_t addr, uint16_t w);
161 static uint16_t ReadEXG(uint8_t); // Read TFR/EXG post byte
162 static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data
163 static uint16_t DecodeReg(uint8_t); // Decode register data
164 static uint16_t DecodeIDX(uint8_t); // Decode IDX data
168 // Read word from memory function
170 static inline uint16_t RdMemW(uint16_t addr)
172 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
177 // Fetch a word from memory function. Increments PC
179 static inline uint16_t FetchMemW(uint16_t addr)
182 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
187 // Write word to memory function
189 static inline void WrMemW(uint16_t addr, uint16_t w)
191 regs.WrMem(addr + 0, w >> 8);
192 regs.WrMem(addr + 1, w & 0xFF);
197 // Function to read TFR/EXG post byte
199 static uint16_t ReadEXG(uint8_t code)
206 retval = (regs.a << 8) | regs.b;
245 // Function to set TFR/EXG data
247 static void WriteEXG(uint8_t code, uint16_t data)
252 regs.a = data >> 8, regs.b = data & 0xFF; break;
254 regs.x = data; break;
256 regs.y = data; break;
258 regs.u = data; break;
260 regs.s = data; break;
262 regs.pc = data; break;
264 regs.a = data & 0xFF; break;
266 regs.b = data & 0xFF; break;
268 regs.cc = data & 0xFF; UNPACK_FLAGS; break;
270 regs.dp = data & 0xFF; break;
276 // Function to decode register data
278 static uint16_t DecodeReg(uint8_t reg)
285 retval = regs.x; break;
287 retval = regs.y; break;
289 retval = regs.u; break;
291 retval = regs.s; break;
299 // Function to decode IDX data
301 static uint16_t DecodeIDX(uint8_t code)
304 uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
306 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
307 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
315 woff = DecodeReg(reg);
319 case 0: regs.x += 2; break;
320 case 1: regs.y += 2; break;
321 case 2: regs.u += 2; break;
322 case 3: regs.s += 2; break;
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;
333 woff = DecodeReg(reg);
337 woff = DecodeReg(reg);
341 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
345 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
349 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
353 woff = DecodeReg(reg) + FetchMemW(regs.pc);
357 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
361 // woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
362 woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
367 woff = regs.pc + FetchMemW(regs.pc);
371 woff = FetchMemW(regs.pc);
381 addr = DecodeReg(reg);
384 case 0: regs.x++; break;
385 case 1: regs.y++; break;
386 case 2: regs.u++; break;
387 case 3: regs.s++; break;
391 addr = DecodeReg(reg);
394 case 0: regs.x += 2; break;
395 case 1: regs.y += 2; break;
396 case 2: regs.u += 2; break;
397 case 3: regs.s += 2; break;
400 case 2: { switch(reg)
402 case 0: regs.x--; break;
403 case 1: regs.y--; break;
404 case 2: regs.u--; break;
405 case 3: regs.s--; break;
407 addr = DecodeReg(reg); break; }
408 case 3: { switch(reg)
410 case 0: regs.x--; regs.x--; break;
411 case 1: regs.y--; regs.y--; break;
412 case 2: regs.u--; regs.u--; break;
413 case 3: regs.s--; regs.s--; break;
415 addr = DecodeReg(reg); break; }
416 case 4: { addr = DecodeReg(reg); break; }
417 case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; }
418 case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; }
419 case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
420 case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; }
421 case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
422 // case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
423 case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); regs.pc++; break; }
424 case 13: { addr = regs.pc + FetchMemW(regs.pc); break; }
434 // 6809 OPCODE IMPLEMENTATION
436 // NOTE: Lots of macros are used here to save a LOT of typing. Also
437 // helps speed the debugging process. :-) Because of this, combining
438 // certain lines may look like a good idea but would end in disaster.
439 // You have been warned! ;-)
443 +-----------------------------------------------------------------+
444 | Opcode | | Addressing | | |
445 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
446 +------------+-------------+--------------+-------+-------+-------+
447 | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa |
448 | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa |
449 | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa |
450 | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa |
451 | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa |
452 | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa |
453 | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa |
454 | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa |
459 #define OP_ADC_HANDLER(m, acc) \
460 uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
461 flagC = (sum >> 8) & 0x01; \
462 SET_H(m, acc, sum); \
463 SET_V(m, acc, sum); \
468 Old flag handling code:
469 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
470 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
471 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
472 regs.a = addr & 0xFF; // Set accumulator
473 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
474 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
477 static void Op89(void) // ADCA #
479 uint16_t m = READ_IMM;
480 OP_ADC_HANDLER(m, regs.a);
484 static void Op99(void) // ADCA DP
486 uint16_t m = READ_DP;
487 OP_ADC_HANDLER(m, regs.a);
491 static void OpA9(void) // ADCA IDX
493 uint16_t m = READ_IDX;
494 OP_ADC_HANDLER(m, regs.a);
498 static void OpB9(void) // ADCA ABS
500 uint16_t m = READ_ABS;
501 OP_ADC_HANDLER(m, regs.a);
505 static void OpC9(void) // ADCB #
507 uint16_t m = READ_IMM;
508 OP_ADC_HANDLER(m, regs.b);
512 static void OpD9(void) // ADCB DP
514 uint16_t m = READ_DP;
515 OP_ADC_HANDLER(m, regs.b);
519 static void OpE9(void) // ADCB IDX
521 uint16_t m = READ_IDX;
522 OP_ADC_HANDLER(m, regs.b);
526 static void OpF9(void) // ADCB ABS
528 uint16_t m = READ_ABS;
529 OP_ADC_HANDLER(m, regs.b);
534 +-----------------------------------------------------------------+
535 | Opcode | | Addressing | | |
536 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
537 +------------+-------------+--------------+-------+-------+-------+
538 | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- |
539 | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa |
540 | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa |
541 | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa |
542 | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa |
543 | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa |
544 | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa |
545 | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa |
546 | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa |
547 | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa |
548 | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa |
549 | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa |
550 | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa |
555 #define OP_ADD_HANDLER(m, acc) \
556 uint16_t sum = (uint16_t)(acc) + (m); \
557 flagC = (sum >> 8) & 0x01; \
558 SET_H(m, acc, sum); \
559 SET_V(m, acc, sum); \
560 (acc) = sum & 0xFF; \
563 #define OP_ADD_HANDLER16(m, hireg, loreg) \
564 uint32_t acc = (uint32_t)((hireg << 8) | loreg); \
565 uint32_t sum = acc + (m); \
566 flagC = (sum >> 16) & 0x01; \
567 SET_V16(m, acc, sum); \
568 acc = sum & 0xFFFF; \
569 hireg = (acc >> 8) & 0xFF; \
570 loreg = acc & 0xFF; \
575 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
576 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
577 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
578 regs.a = addr & 0xFF; // Set accumulator
579 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
580 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
583 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
585 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
586 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
587 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
588 regs.a = dr>>8; regs.b = dr&0xFF;
592 static void Op3A(void) // ABX
594 regs.x += (uint16_t)regs.b;
598 static void Op8B(void) // ADDA #
600 uint16_t m = READ_IMM;
601 OP_ADD_HANDLER(m, regs.a);
605 static void Op9B(void) // ADDA DP
607 uint16_t m = READ_DP;
608 OP_ADD_HANDLER(m, regs.a);
612 static void OpAB(void) // ADDA IDX
614 uint16_t m = READ_IDX;
615 OP_ADD_HANDLER(m, regs.a);
619 static void OpBB(void) // ADDA ABS
621 uint16_t m = READ_ABS;
622 OP_ADD_HANDLER(m, regs.a);
626 static void OpC3(void) // ADDD #
628 uint32_t m = READ_IMM16;
629 OP_ADD_HANDLER16(m, regs.a, regs.b);
633 static void OpCB(void) // ADDB #
635 uint16_t m = READ_IMM;
636 OP_ADD_HANDLER(m, regs.b);
640 static void OpD3(void) // ADDD DP
642 uint32_t m = READ_DP16;
643 OP_ADD_HANDLER16(m, regs.a, regs.b);
647 static void OpDB(void) // ADDB DP
649 uint16_t m = READ_DP;
650 OP_ADD_HANDLER(m, regs.b);
654 static void OpE3(void) // ADDD IDX
656 uint32_t m = READ_IDX16;
657 OP_ADD_HANDLER16(m, regs.a, regs.b);
661 static void OpEB(void) // ADDB IDX
663 uint16_t m = READ_IDX;
664 OP_ADD_HANDLER(m, regs.b);
668 static void OpF3(void) // ADDD ABS
670 uint32_t m = READ_ABS16;
671 OP_ADD_HANDLER16(m, regs.a, regs.b);
675 static void OpFB(void) // ADDB ABS
677 uint16_t m = READ_ABS;
678 OP_ADD_HANDLER(m, regs.b);
683 +-----------------------------------------------------------------+
684 | Opcode | | Addressing | | |
685 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
686 +------------+-------------+--------------+-------+-------+-------+
687 | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- |
688 | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- |
689 | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- |
690 | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- |
691 | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- |
692 | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- |
693 | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- |
694 | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- |
699 #define OP_AND_HANDLER(m, acc) \
704 static void Op84(void) // ANDA #
706 uint16_t m = READ_IMM;
707 OP_AND_HANDLER(m, regs.a);
710 static void Op94(void) // ANDA DP
712 uint16_t m = READ_DP;
713 OP_AND_HANDLER(m, regs.a);
716 static void OpA4(void) // ANDA IDX
718 uint16_t m = READ_IDX;
719 OP_AND_HANDLER(m, regs.a);
722 static void OpB4(void) // ANDA ABS
724 uint16_t m = READ_ABS;
725 OP_AND_HANDLER(m, regs.a);
728 static void OpC4(void) // ANDB #
730 uint16_t m = READ_IMM;
731 OP_AND_HANDLER(m, regs.b);
734 static void OpD4(void) // ANDB DP
736 uint16_t m = READ_DP;
737 OP_AND_HANDLER(m, regs.b);
740 static void OpE4(void) // ANDB IDX
742 uint16_t m = READ_IDX;
743 OP_AND_HANDLER(m, regs.b);
746 static void OpF4(void) // ANDB ABS
748 uint16_t m = READ_ABS;
749 OP_AND_HANDLER(m, regs.b);
753 +-----------------------------------------------------------------+
754 | Opcode | | Addressing | | |
755 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
756 +------------+-------------+--------------+-------+-------+-------+
757 | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas |
758 | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas |
759 | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas |
760 | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas |
761 | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas |
766 #define OP_ASL_HANDLER(m) \
767 uint16_t res = m << 1; \
769 flagC = (res >> 8) & 0x01; \
773 static void Op08(void) // ASL DP
781 static void Op48(void) // ASLA
783 OP_ASL_HANDLER(regs.a);
786 static void Op58(void) // ASLB
788 OP_ASL_HANDLER(regs.b);
791 static void Op68(void) // ASL IDX
799 static void Op78(void) // ASL ABS
808 +-----------------------------------------------------------------+
809 | Opcode | | Addressing | | |
810 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
811 +------------+-------------+--------------+-------+-------+-------+
812 | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s |
813 | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s |
814 | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s |
815 | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s |
816 | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s |
819 // ASR opcodes (arithmetic, so preserves the sign)
821 #define OP_ASR_HANDLER(m) \
822 uint8_t res = (m & 0x80) | (m >> 1); \
827 static void Op07(void) // ASR DP
835 static void Op47(void) // ASRA
837 OP_ASR_HANDLER(regs.a);
840 static void Op57(void) // ASRB
842 OP_ASR_HANDLER(regs.b);
845 static void Op67(void) // ASR IDX
853 static void Op77(void) // ASR ABS
862 +-----------------------------------------------------------------+
863 | Opcode | | Addressing | | |
864 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
865 +------------+-------------+--------------+-------+-------+-------+
866 | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- |
867 | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- |
868 | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- |
869 | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- |
870 | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- |
871 | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- |
872 | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- |
873 | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- |
874 | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- |
875 | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- |
876 | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- |
877 | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- |
878 | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- |
879 | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- |
880 | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- |
881 | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- |
882 | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- |
883 | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- |
884 | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- |
885 | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- |
886 | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- |
887 | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- |
888 | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- |
889 | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- |
890 | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- |
891 | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- |
892 | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- |
893 | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- |
894 | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- |
895 | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- |
896 | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- |
897 | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- |
902 static void Op16(void) // LBRA
904 uint16_t offset = READ_IMM16;
908 static void Op20(void) // BRA
910 int16_t offset = (int16_t)(int8_t)READ_IMM;
914 static void Op21(void) // BRN
916 // This is basically a 2 byte NOP
917 int16_t offset = (int16_t)(int8_t)READ_IMM;
920 static void Op22(void) // BHI
923 int16_t offset = (int16_t)(int8_t)READ_IMM;
925 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
926 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
927 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
929 if (!(flagZ || flagC))
934 static void Op23(void) // BLS
937 int16_t offset = (int16_t)(int8_t)READ_IMM;
939 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
940 regs.pc += offset * (flagZ | flagC);
947 static void Op24(void) // BHS/CC
950 int16_t offset = (int16_t)(int8_t)READ_IMM;
952 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
953 regs.pc += offset * (flagC ^ 0x01);
960 static void Op25(void) // BLO/CS
963 int16_t offset = (int16_t)(int8_t)READ_IMM;
965 // WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
967 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
968 regs.pc += offset * flagC;
975 static void Op26(void) // BNE
978 int16_t offset = (int16_t)(int8_t)READ_IMM;
980 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
981 regs.pc += offset * (flagZ ^ 0x01);
988 static void Op27(void) // BEQ
991 int16_t offset = (int16_t)(int8_t)READ_IMM;
993 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
994 regs.pc += offset * flagZ;
1001 static void Op28(void) // BVC
1004 int16_t offset = (int16_t)(int8_t)READ_IMM;
1006 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1007 regs.pc += offset * (flagV ^ 0x01);
1014 static void Op29(void) // BVS
1017 int16_t offset = (int16_t)(int8_t)READ_IMM;
1019 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1020 regs.pc += offset * flagV;
1027 static void Op2A(void) // BPL
1030 int16_t offset = (int16_t)(int8_t)READ_IMM;
1032 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1033 regs.pc += offset * (flagN ^ 0x01);
1040 static void Op2B(void) // BMI
1043 int16_t offset = (int16_t)(int8_t)READ_IMM;
1045 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1046 regs.pc += offset * flagN;
1053 static void Op2C(void) // BGE
1055 // (N && V) || (!N && !V)
1056 int16_t offset = (int16_t)(int8_t)READ_IMM;
1058 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1059 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1061 if ((flagN && flagV) || (!flagN && !flagV))
1066 static void Op2D(void) // BLT
1068 // (N && !V) || (!N && V)
1069 int16_t offset = (int16_t)(int8_t)READ_IMM;
1071 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1072 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1074 if ((flagN && !flagV) || (!flagN && flagV))
1079 static void Op2E(void) // BGT
1081 // (N && V && !Z) || (!N && !V && !Z)
1082 int16_t offset = (int16_t)(int8_t)READ_IMM;
1084 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1085 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1087 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1092 static void Op2F(void) // BLE
1094 // Z || (N && !V) || (!N && V)
1095 int16_t offset = (int16_t)(int8_t)READ_IMM;
1097 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1098 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1100 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1105 static void Op1021(void) // LBRN
1107 // This is basically a 4 byte NOP
1108 uint16_t offset = READ_IMM16;
1111 static void Op1022(void) // LBHI
1114 uint16_t offset = READ_IMM16;
1116 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1117 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1118 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1120 if (!(flagZ || flagC))
1125 static void Op1023(void) // LBLS
1128 uint16_t offset = READ_IMM16;
1130 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1131 regs.pc += offset * (flagZ | flagC);
1138 static void Op1024(void) // LBHS/CC
1141 uint16_t offset = READ_IMM16;
1143 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1144 regs.pc += offset * (flagC ^ 0x01);
1151 static void Op1025(void) // LBLO/CS
1154 uint16_t offset = READ_IMM16;
1156 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1157 regs.pc += offset * flagC;
1164 static void Op1026(void) // LBNE
1167 uint16_t offset = READ_IMM16;
1169 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1170 regs.pc += offset * (flagZ ^ 0x01);
1177 static void Op1027(void) // LBEQ
1180 uint16_t offset = READ_IMM16;
1182 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1183 regs.pc += offset * flagZ;
1190 static void Op1028(void) // LBVC
1193 uint16_t offset = READ_IMM16;
1195 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1196 regs.pc += offset * (flagV ^ 0x01);
1203 static void Op1029(void) // LBVS
1206 uint16_t offset = READ_IMM16;
1208 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1209 regs.pc += offset * flagV;
1216 static void Op102A(void) // LBPL
1219 uint16_t offset = READ_IMM16;
1221 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1222 regs.pc += offset * (flagN ^ 0x01);
1229 static void Op102B(void) // LBMI
1232 uint16_t offset = READ_IMM16;
1234 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1235 regs.pc += offset * flagN;
1242 static void Op102C(void) // LBGE
1244 // (N && V) || (!N && !V)
1245 uint16_t offset = READ_IMM16;
1247 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1248 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1250 if ((flagN && flagV) || (!flagN && !flagV))
1255 static void Op102D(void) // LBLT
1257 // (N && !V) || (!N && V)
1258 uint16_t offset = READ_IMM16;
1260 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1261 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1263 if ((flagN && !flagV) || (!flagN && flagV))
1268 static void Op102E(void) // LBGT
1270 // (N && V && !Z) || (!N && !V && !Z)
1271 uint16_t offset = READ_IMM16;
1273 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1274 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1276 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1281 static void Op102F(void) // LBLE
1283 // Z || (N && !V) || (!N && V)
1284 uint16_t offset = READ_IMM16;
1286 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1287 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1289 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1295 +-----------------------------------------------------------------+
1296 | Opcode | | Addressing | | |
1297 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1298 +------------+-------------+--------------+-------+-------+-------+
1299 | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- |
1300 | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- |
1301 | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- |
1302 | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- |
1303 | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- |
1304 | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- |
1305 | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- |
1306 | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- |
1311 #define OP_BIT_HANDLER(m, acc) \
1312 uint8_t result = acc & (m); \
1316 static void Op85(void) // BITA #
1318 uint8_t m = READ_IMM;
1319 OP_BIT_HANDLER(m, regs.a);
1322 static void Op95(void) // BITA DP
1324 uint8_t m = READ_DP;
1325 OP_BIT_HANDLER(m, regs.a);
1328 static void OpA5(void) // BITA IDX
1330 uint8_t m = READ_IDX;
1331 OP_BIT_HANDLER(m, regs.a);
1334 static void OpB5(void) // BITA ABS
1336 uint8_t m = READ_ABS;
1337 OP_BIT_HANDLER(m, regs.a);
1340 static void OpC5(void) // BITB #
1342 uint8_t m = READ_IMM;
1343 OP_BIT_HANDLER(m, regs.b);
1346 static void OpD5(void) // BITB DP
1348 uint8_t m = READ_DP;
1349 OP_BIT_HANDLER(m, regs.b);
1352 static void OpE5(void) // BITB IDX
1354 uint8_t m = READ_IDX;
1355 OP_BIT_HANDLER(m, regs.b);
1358 static void OpF5(void) // BITB ABS
1360 uint8_t m = READ_ABS;
1361 OP_BIT_HANDLER(m, regs.b);
1365 +-----------------------------------------------------------------+
1366 | Opcode | | Addressing | | |
1367 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1368 +------------+-------------+--------------+-------+-------+-------+
1369 | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 |
1370 | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 |
1371 | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 |
1372 | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 |
1373 | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 |
1378 #define OP_CLR_HANDLER(m) \
1379 flagN = flagV = flagC = 0; \
1383 static void Op0F(void) // CLR DP
1391 static void Op4F(void) // CLRA
1393 OP_CLR_HANDLER(regs.a);
1396 static void Op5F(void) // CLRB
1398 OP_CLR_HANDLER(regs.b);
1401 static void Op6F(void) // CLR IDX
1409 static void Op7F(void) // CLR ABS
1418 +-----------------------------------------------------------------+
1419 | Opcode | | Addressing | | |
1420 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1421 +------------+-------------+--------------+-------+-------+-------+
1422 | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa |
1423 | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa |
1424 | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa |
1425 | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa |
1426 | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa |
1427 | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa |
1428 | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa |
1429 | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa |
1430 | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa |
1431 | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa |
1432 | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa |
1433 | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa |
1434 | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa |
1435 | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa |
1436 | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa |
1437 | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa |
1438 | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa |
1439 | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa |
1440 | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa |
1441 | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa |
1442 | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa |
1443 | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa |
1444 | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa |
1445 | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa |
1446 | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa |
1447 | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa |
1448 | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa |
1449 | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa |
1454 #define OP_CMP_HANDLER(m, acc) \
1455 uint16_t sum = (uint16_t)(acc) - (m); \
1456 flagC = (sum >> 8) & 0x01; \
1457 SET_V(m, acc, sum); \
1460 #define OP_CMP_HANDLER16(m, acc) \
1461 uint32_t sum = (uint32_t)(acc) - (m); \
1462 flagC = (sum >> 16) & 0x01; \
1463 SET_V16(m, acc, sum); \
1466 static void Op81(void) // CMPA #
1468 uint8_t m = READ_IMM;
1469 OP_CMP_HANDLER(m, regs.a);
1472 static void Op8C(void) // CMPX #
1474 uint16_t m = READ_IMM16;
1475 OP_CMP_HANDLER16(m, regs.x);
1478 static void Op91(void) // CMPA DP
1480 uint8_t m = READ_DP;
1481 OP_CMP_HANDLER(m, regs.a);
1484 static void Op9C(void) // CMPX DP
1486 uint16_t m = READ_DP16;
1487 OP_CMP_HANDLER16(m, regs.x);
1490 static void OpA1(void) // CMPA IDX
1492 uint8_t m = READ_IDX;
1493 OP_CMP_HANDLER(m, regs.a);
1496 static void OpAC(void) // CMPX IDX
1498 uint16_t m = READ_IDX16;
1499 OP_CMP_HANDLER16(m, regs.x);
1502 static void OpB1(void) // CMPA ABS
1504 uint8_t m = READ_ABS;
1505 OP_CMP_HANDLER(m, regs.a);
1508 static void OpBC(void) // CMPX ABS
1510 uint16_t m = READ_ABS16;
1511 OP_CMP_HANDLER16(m, regs.x);
1514 static void OpC1(void) // CMPB #
1516 uint8_t m = READ_IMM;
1517 OP_CMP_HANDLER(m, regs.b);
1520 static void OpD1(void) // CMPB DP
1522 uint8_t m = READ_DP;
1523 OP_CMP_HANDLER(m, regs.b);
1526 static void OpE1(void) // CMPB IDX
1528 uint8_t m = READ_IDX;
1529 OP_CMP_HANDLER(m, regs.b);
1532 static void OpF1(void) // CMPB ABS
1534 uint8_t m = READ_ABS;
1535 OP_CMP_HANDLER(m, regs.b);
1538 static void Op1083(void) // CMPD #
1540 uint16_t m = READ_IMM16;
1541 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1544 static void Op108C(void) // CMPY #
1546 uint16_t m = READ_IMM16;
1547 OP_CMP_HANDLER16(m, regs.y);
1550 static void Op1093(void) // CMPD DP
1552 uint16_t m = READ_DP16;
1553 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1556 static void Op109C(void) // CMPY DP
1558 uint16_t m = READ_DP16;
1559 OP_CMP_HANDLER16(m, regs.y);
1562 static void Op10A3(void) // CMPD IDX
1564 uint16_t m = READ_IDX16;
1565 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1568 static void Op10AC(void) // CMPY IDX
1570 uint16_t m = READ_IDX16;
1571 OP_CMP_HANDLER16(m, regs.y);
1574 static void Op10B3(void) // CMPD ABS
1576 uint16_t m = READ_ABS16;
1577 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1580 static void Op10BC(void) // CMPY ABS
1582 uint16_t m = READ_ABS16;
1583 OP_CMP_HANDLER16(m, regs.y);
1586 static void Op1183(void) // CMPU #
1588 uint16_t m = READ_IMM16;
1589 OP_CMP_HANDLER16(m, regs.u);
1592 static void Op118C(void) // CMPS #
1594 uint16_t m = READ_IMM16;
1595 OP_CMP_HANDLER16(m, regs.s);
1598 static void Op1193(void) // CMPU DP
1600 uint16_t m = READ_DP16;
1601 OP_CMP_HANDLER16(m, regs.u);
1604 static void Op119C(void) // CMPS DP
1606 uint16_t m = READ_DP16;
1607 OP_CMP_HANDLER16(m, regs.s);
1610 static void Op11A3(void) // CMPU IDX
1612 uint16_t m = READ_IDX16;
1613 OP_CMP_HANDLER16(m, regs.u);
1616 static void Op11AC(void) // CMPS IDX
1618 uint16_t m = READ_IDX16;
1619 OP_CMP_HANDLER16(m, regs.s);
1622 static void Op11B3(void) // CMPU ABS
1624 uint16_t m = READ_ABS16;
1625 OP_CMP_HANDLER16(m, regs.u);
1628 static void Op11BC(void) // CMPS ABS
1630 uint16_t m = READ_ABS16;
1631 OP_CMP_HANDLER16(m, regs.s);
1635 +-----------------------------------------------------------------+
1636 | Opcode | | Addressing | | |
1637 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1638 +------------+-------------+--------------+-------+-------+-------+
1639 | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 |
1640 | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 |
1641 | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 |
1642 | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 |
1643 | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 |
1648 #define OP_COM_HANDLER(m) \
1654 static void Op03(void) // COM DP
1662 static void Op43(void) // COMA
1664 OP_COM_HANDLER(regs.a);
1667 static void Op53(void) // COMB
1669 OP_COM_HANDLER(regs.b);
1672 static void Op63(void) // COM IDX
1680 static void Op73(void) // COM ABS
1689 +-----------------------------------------------------------------+
1690 | Opcode | | Addressing | | |
1691 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1692 +------------+-------------+--------------+-------+-------+-------+
1693 | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- |
1694 | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd |
1695 | 3E 0062 | RESET* | INHERENT | * | 1 | ***** |
1696 | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- |
1697 | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- |
1698 | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- |
1701 static void Op13(void) // SYNC
1703 #warning "!!! SYNC not implemented !!!"
1705 /* SYNC stops processing instructions until an interrupt request happens. */
1706 /* This doesn't require the corresponding interrupt to be enabled: if it */
1707 /* is disabled, execution continues with the next instruction. */
1708 m68_state->int_state |= M6809_SYNC; /* HJB 990227 */
1709 check_irq_lines(m68_state);
1710 /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1711 * stop execution until the interrupt lines change. */
1712 if( m68_state->int_state & M6809_SYNC )
1713 if (m68_state->icount > 0) m68_state->icount = 0;
1717 static void Op3C(void) // CWAI
1719 #warning "!!! CWAI not implemented !!!"
1725 * CWAI stacks the entire machine state on the hardware stack,
1726 * then waits for an interrupt; when the interrupt is taken
1727 * later, the state is *not* saved again after CWAI.
1729 CC |= CC_E; /* HJB 990225: save entire state */
1738 m68_state->int_state |= M6809_CWAI; /* HJB 990228 */
1739 check_irq_lines(m68_state); /* HJB 990116 */
1740 if( m68_state->int_state & M6809_CWAI )
1741 if( m68_state->icount > 0 )
1742 m68_state->icount = 0;
1746 static void Op3E(void) // RESET
1748 regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
1751 static void Op3F(void) // SWI
1754 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1764 regs.pc = RdMemW(0xFFFA);
1767 static void Op103F(void) // SWI2
1770 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1779 regs.pc = RdMemW(0xFFF4);
1782 static void Op113F(void) // SWI3
1785 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1794 regs.pc = RdMemW(0xFFF2);
1798 +-----------------------------------------------------------------+
1799 | Opcode | | Addressing | | |
1800 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1801 +------------+-------------+--------------+-------+-------+-------+
1802 | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
1803 | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
1804 | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
1805 | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
1806 | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
1809 static void Op12() // NOP
1814 D3F8: A6 47 LDA (7),U CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA
1815 D3FA: 8B 01 ADDA #$01 CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC
1816 D3FC: 19 DAA CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD
1819 static void Op19() // DAA
1821 uint16_t result = (uint16_t)regs.a;
1823 // if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
1824 if ((regs.a & 0x0F) > 0x09 || flagH)
1827 // if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1828 if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1831 regs.a = (uint8_t)result;
1834 flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
1837 static void Op1A() // ORCC
1839 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1840 regs.cc |= READ_IMM;
1841 UNPACK_FLAGS; // & unmash 'em
1844 static void Op1C() // ANDCC
1846 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1847 regs.cc &= READ_IMM;
1848 UNPACK_FLAGS; // & unmash 'em
1851 static void Op1D() // SEX
1853 regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1854 SET_ZN16((regs.a << 8) | regs.b);
1859 +-----------------------------------------------------------------+
1860 | Opcode | | Addressing | | |
1861 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1862 +------------+-------------+--------------+-------+-------+-------+
1863 | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- |
1864 | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- |
1865 | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- |
1866 | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- |
1867 | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- |
1870 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1872 #define OP_DEC_HANDLER(m) \
1875 flagV = (m == 0x7F ? 1 : 0)
1877 static void Op0A(void) // DEC DP
1885 static void Op4A(void) // DECA
1887 OP_DEC_HANDLER(regs.a);
1890 static void Op5A(void) // DECB
1892 OP_DEC_HANDLER(regs.b);
1895 static void Op6A(void) // DEC IDX
1903 static void Op7A(void) // DEC ABS
1912 +-----------------------------------------------------------------+
1913 | Opcode | | Addressing | | |
1914 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1915 +------------+-------------+--------------+-------+-------+-------+
1916 | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- |
1917 | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- |
1918 | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- |
1919 | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- |
1920 | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- |
1921 | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- |
1922 | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- |
1923 | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- |
1928 #define OP_EOR_HANDLER(m, acc) \
1933 static void Op88(void) // EORA #
1935 uint8_t m = READ_IMM;
1936 OP_EOR_HANDLER(m, regs.a);
1939 static void Op98(void) // EORA DP
1941 uint8_t m = READ_DP;
1942 OP_EOR_HANDLER(m, regs.a);
1945 static void OpA8(void) // EORA IDX
1947 uint8_t m = READ_IDX;
1948 OP_EOR_HANDLER(m, regs.a);
1951 static void OpB8(void) // EORA ABS
1953 uint8_t m = READ_ABS;
1954 OP_EOR_HANDLER(m, regs.a);
1957 static void OpC8(void) // EORB #
1959 uint8_t m = READ_IMM;
1960 OP_EOR_HANDLER(m, regs.b);
1963 static void OpD8(void) // EORB DP
1965 uint8_t m = READ_DP;
1966 OP_EOR_HANDLER(m, regs.b);
1969 static void OpE8(void) // EORB IDX
1971 uint8_t m = READ_IDX;
1972 OP_EOR_HANDLER(m, regs.b);
1975 static void OpF8(void) // EORB ABS
1977 uint8_t m = READ_ABS;
1978 OP_EOR_HANDLER(m, regs.b);
1982 +-----------------------------------------------------------------+
1983 | Opcode | | Addressing | | |
1984 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1985 +------------+-------------+--------------+-------+-------+-------+
1986 | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- |
1987 | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- |
1988 | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- |
1989 | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- |
1990 | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- |
1993 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1995 #define OP_INC_HANDLER(m) \
1998 flagV = (m == 0x80 ? 1 : 0)
2000 static void Op0C(void) // INC DP
2009 static void Op4C(void) // INCA
2011 OP_INC_HANDLER(regs.a);
2015 static void Op5C(void) // INCB
2017 OP_INC_HANDLER(regs.b);
2021 static void Op6C(void) // INC IDX
2030 static void Op7C(void) // INC ABS
2040 +-----------------------------------------------------------------+
2041 | Opcode | | Addressing | | |
2042 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2043 +------------+-------------+--------------+-------+-------+-------+
2044 | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- |
2045 | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- |
2046 | 39 0057 | RTS | INHERENT | 5 | 1 | ----- |
2047 | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- |
2048 | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- |
2049 | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- |
2050 | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- |
2051 | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- |
2052 | AD 0173 | JSR | INDEXED | 7 | 2 | ----- |
2053 | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- |
2056 static void Op0E(void) // JMP DP
2058 // This needs to be separate because of the EA_DP adding to regs.pc.
2064 static void Op17(void) // LBSR
2066 uint16_t word = FetchMemW(regs.pc);
2072 static void Op39(void) // RTS
2078 static void Op3B(void) // RTI
2083 // If E flag set, pull all regs
2099 static void Op6E(void) // JMP IDX
2105 static void Op7E(void) // JMP ABS
2111 static void Op8D(void) // BSR
2113 uint16_t word = (int16_t)(int8_t)READ_IMM;
2119 static void Op9D(void) // JSR DP
2121 uint16_t word = EA_DP;
2127 static void OpAD(void) // JSR IDX
2129 uint16_t word = EA_IDX;
2135 static void OpBD(void) // JSR ABS
2137 uint16_t word = EA_ABS;
2144 +-----------------------------------------------------------------+
2145 | Opcode | | Addressing | | |
2146 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2147 +------------+-------------+--------------+-------+-------+-------+
2148 | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
2149 | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
2152 static void Op1E(void) // EXG
2154 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2156 uint8_t m = READ_IMM;
2157 uint8_t reg1 = m >> 4, reg2 = m & 0x0F;
2158 uint16_t acc1 = ReadEXG(reg1);
2159 uint16_t acc2 = ReadEXG(reg2);
2161 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2162 if (((m >> 4) ^ m) & 0x08)
2165 WriteEXG(reg1, acc2);
2166 WriteEXG(reg2, acc1);
2169 static void Op1F(void) // TFR
2171 uint8_t m = READ_IMM;
2172 uint16_t acc = ReadEXG(m >> 4);
2174 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2175 if (((m >> 4) ^ m) & 0x08)
2178 WriteEXG(m & 0x0F, acc);
2182 +-----------------------------------------------------------------+
2183 | Opcode | | Addressing | | |
2184 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2185 +------------+-------------+--------------+-------+-------+-------+
2186 | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
2187 | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
2188 | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
2189 | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
2190 | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
2191 | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
2192 | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
2193 | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
2194 | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
2195 | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
2196 | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
2197 | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
2198 | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
2199 | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
2200 | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
2201 | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
2202 | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
2203 | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
2204 | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
2205 | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
2206 | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
2207 | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
2208 | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
2209 | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
2210 | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
2211 | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
2212 | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
2213 | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
2218 #define OP_LDA_HANDLER(m, acc) \
2223 #define OP_LDA_HANDLER16(m, acc) \
2228 #define OP_LDA_HANDLER16D(m) \
2229 regs.a = (m >> 8); \
2230 regs.b = m & 0xFF; \
2234 static void Op86(void) // LDA #
2236 uint8_t m = READ_IMM;
2237 OP_LDA_HANDLER(m, regs.a);
2240 static void Op8E(void) // LDX #
2242 uint16_t m = READ_IMM16;
2243 OP_LDA_HANDLER16(m, regs.x);
2246 static void Op96(void) // LDA DP
2248 uint8_t m = READ_DP;
2249 OP_LDA_HANDLER(m, regs.a);
2252 static void Op9E(void) // LDX DP
2254 uint16_t m = READ_DP16;
2255 OP_LDA_HANDLER16(m, regs.x);
2258 static void OpA6(void) // LDA IDX
2260 uint8_t m = READ_IDX;
2261 OP_LDA_HANDLER(m, regs.a);
2264 static void OpAE(void) // LDX IDX
2266 uint16_t m = READ_IDX16;
2267 OP_LDA_HANDLER16(m, regs.x);
2270 static void OpB6(void) // LDA ABS
2272 uint8_t m = READ_ABS;
2273 OP_LDA_HANDLER(m, regs.a);
2276 static void OpBE(void) // LDX ABS
2278 uint16_t m = READ_ABS16;
2279 OP_LDA_HANDLER16(m, regs.x);
2282 static void OpC6(void) // LDB #
2284 uint8_t m = READ_IMM;
2285 OP_LDA_HANDLER(m, regs.b);
2288 static void OpCC(void) // LDD #
2290 uint16_t m = READ_IMM16;
2291 OP_LDA_HANDLER16D(m);
2294 static void OpCE(void) // LDU #
2296 uint16_t m = READ_IMM16;
2297 OP_LDA_HANDLER16(m, regs.u);
2300 static void OpD6(void) // LDB DP
2302 uint8_t m = READ_DP;
2303 OP_LDA_HANDLER(m, regs.b);
2306 static void OpDC(void) // LDD DP
2308 uint16_t m = READ_DP16;
2309 OP_LDA_HANDLER16D(m);
2312 static void OpDE(void) // LDU DP
2314 uint16_t m = READ_DP16;
2315 OP_LDA_HANDLER16(m, regs.u);
2318 static void OpE6(void) // LDB IDX
2320 uint8_t m = READ_IDX;
2321 OP_LDA_HANDLER(m, regs.b);
2324 static void OpEC(void) // LDD IDX
2326 uint16_t m = READ_IDX16;
2327 OP_LDA_HANDLER16D(m);
2330 static void OpEE(void) // LDU IDX
2332 uint16_t m = READ_IDX16;
2333 OP_LDA_HANDLER16(m, regs.u);
2336 static void OpF6(void) // LDB ABS
2338 uint8_t m = READ_ABS;
2339 OP_LDA_HANDLER(m, regs.b);
2342 static void OpFC(void) // LDD ABS
2344 uint16_t m = READ_ABS16;
2345 OP_LDA_HANDLER16D(m);
2348 static void OpFE(void) // LDU ABS
2350 uint16_t m = READ_ABS16;
2351 OP_LDA_HANDLER16(m, regs.u);
2354 static void Op108E(void) // LDY #
2356 uint16_t m = READ_IMM16;
2357 OP_LDA_HANDLER16(m, regs.y);
2360 static void Op109E(void) // LDY DP
2362 uint16_t m = READ_DP16;
2363 OP_LDA_HANDLER16(m, regs.y);
2366 static void Op10AE(void) // LDY IDX
2368 uint16_t m = READ_IDX16;
2369 OP_LDA_HANDLER16(m, regs.y);
2372 static void Op10BE(void) // LDY ABS
2374 uint16_t m = READ_ABS16;
2375 OP_LDA_HANDLER16(m, regs.y);
2378 static void Op10CE(void) // LDS #
2380 uint16_t m = READ_IMM16;
2381 OP_LDA_HANDLER16(m, regs.s);
2384 static void Op10DE(void) // LDS DP
2386 uint16_t m = READ_DP16;
2387 OP_LDA_HANDLER16(m, regs.s);
2390 static void Op10EE(void) // LDS IDX
2392 uint16_t m = READ_IDX16;
2393 OP_LDA_HANDLER16(m, regs.s);
2396 static void Op10FE(void) // LDS ABS
2398 uint16_t m = READ_ABS16;
2399 OP_LDA_HANDLER16(m, regs.s);
2403 +-----------------------------------------------------------------+
2404 | Opcode | | Addressing | | |
2405 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2406 +------------+-------------+--------------+-------+-------+-------+
2407 | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- |
2408 | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- |
2409 | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- |
2410 | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- |
2413 static void Op30(void) // LEAX
2419 static void Op31(void) // LEAY
2425 static void Op32(void) // LEAS
2430 static void Op33(void) // LEAU
2436 +-----------------------------------------------------------------+
2437 | Opcode | | Addressing | | |
2438 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2439 +------------+-------------+--------------+-------+-------+-------+
2440 | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s |
2441 | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s |
2442 | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s |
2443 | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s |
2444 | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s |
2449 #define OP_LSR_HANDLER(m) \
2454 static void Op04(void) // LSR DP
2462 static void Op44(void) // LSRA
2464 OP_LSR_HANDLER(regs.a);
2467 static void Op54(void) // LSRB
2469 OP_LSR_HANDLER(regs.b);
2472 static void Op64(void) // LSR IDX
2480 static void Op74(void) // LSR ABS
2489 +-----------------------------------------------------------------+
2490 | Opcode | | Addressing | | |
2491 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2492 +------------+-------------+--------------+-------+-------+-------+
2493 | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a |
2496 static void Op3D(void) // MUL
2498 uint16_t prod = regs.a * regs.b;
2500 regs.b = prod & 0xFF;
2502 // flagC = (prod & 0x0080 ? 1 : 0);
2503 flagC = (prod >> 7) & 0x01;
2507 +-----------------------------------------------------------------+
2508 | Opcode | | Addressing | | |
2509 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2510 +------------+-------------+--------------+-------+-------+-------+
2511 | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa |
2512 | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa |
2513 | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa |
2514 | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa |
2515 | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa |
2520 #define OP_NEG_HANDLER(m) \
2524 flagC = (res >= 0x80 ? 1 : 0); \
2534 #define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
2535 #define SET_C8(a) CC|=((a&0x100)>>8)
2537 static void Op00(void) // NEG DP
2545 static void Op40(void) // NEGA
2547 OP_NEG_HANDLER(regs.a);
2550 static void Op50(void) // NEGB
2552 OP_NEG_HANDLER(regs.b);
2555 static void Op60(void) // NEG IDX
2563 static void Op70(void) // NEG ABS
2572 +-----------------------------------------------------------------+
2573 | Opcode | | Addressing | | |
2574 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2575 +------------+-------------+--------------+-------+-------+-------+
2576 | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- |
2577 | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- |
2578 | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- |
2579 | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- |
2580 | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- |
2581 | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- |
2582 | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- |
2583 | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- |
2588 #define OP_OR_HANDLER(m, acc) \
2593 static void Op8A(void) // ORA #
2595 uint8_t m = READ_IMM;
2596 OP_OR_HANDLER(m, regs.a);
2599 static void Op9A(void) // ORA DP
2601 uint8_t m = READ_DP;
2602 OP_OR_HANDLER(m, regs.a);
2605 static void OpAA(void) // ORA IDX
2607 uint8_t m = READ_IDX;
2608 OP_OR_HANDLER(m, regs.a);
2611 static void OpBA(void) // ORA ABS
2613 uint8_t m = READ_ABS;
2614 OP_OR_HANDLER(m, regs.a);
2617 static void OpCA(void) // ORB #
2619 uint8_t m = READ_IMM;
2620 OP_OR_HANDLER(m, regs.b);
2623 static void OpDA(void) // ORB DP
2625 uint8_t m = READ_DP;
2626 OP_OR_HANDLER(m, regs.b);
2629 static void OpEA(void) // ORB IDX
2631 uint8_t m = READ_IDX;
2632 OP_OR_HANDLER(m, regs.b);
2635 static void OpFA(void) // ORB ABS
2637 uint8_t m = READ_ABS;
2638 OP_OR_HANDLER(m, regs.b);
2642 +-----------------------------------------------------------------+
2643 | Opcode | | Addressing | | |
2644 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2645 +------------+-------------+--------------+-------+-------+-------+
2646 | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- |
2647 | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc |
2648 | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- |
2649 | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc |
2652 static void Op34(void) // PSHS
2654 uint8_t m = READ_IMM;
2672 regs.cc = PACK_FLAGS;
2676 // Count bits in each nybble to come up with correct cycle counts...
2677 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2678 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2681 static void Op35(void) // PULS
2683 uint8_t m = READ_IMM;
2705 // Count bits in each nybble to come up with correct cycle counts...
2706 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2707 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2710 static void Op36(void) // PHSU
2712 uint8_t m = READ_IMM;
2730 regs.cc = PACK_FLAGS;
2734 // Count bits in each nybble to come up with correct cycle counts...
2735 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2736 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2739 static void Op37(void) // PULU
2741 uint8_t m = READ_IMM;
2763 // Count bits in each nybble to come up with correct cycle counts...
2764 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2765 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2769 +-----------------------------------------------------------------+
2770 | Opcode | | Addressing | | |
2771 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2772 +------------+-------------+--------------+-------+-------+-------+
2773 | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas |
2774 | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas |
2775 | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas |
2776 | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas |
2777 | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas |
2782 #define OP_ROL_HANDLER(m) \
2783 uint8_t res = (m << 1) | flagC; \
2786 flagC = (m >> 7) & 0x01; \
2792 r = (CC & CC_C) | (t << 1);
2797 static void Op09(void) // ROL DP
2805 static void Op49(void) // ROLA
2807 OP_ROL_HANDLER(regs.a);
2810 static void Op59(void) // ROLB
2812 OP_ROL_HANDLER(regs.b);
2815 static void Op69(void) // ROL IDX
2823 static void Op79(void) // ROL ABS
2832 +-----------------------------------------------------------------+
2833 | Opcode | | Addressing | | |
2834 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2835 +------------+-------------+--------------+-------+-------+-------+
2836 | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s |
2837 | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s |
2838 | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s |
2839 | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s |
2840 | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s |
2845 #define OP_ROR_HANDLER(m) \
2846 uint8_t res = (flagC << 7) | (m >> 1); \
2852 static void Op06(void) // ROR DP
2860 static void Op46(void) // RORA
2862 OP_ROR_HANDLER(regs.a);
2865 static void Op56(void) // RORB
2867 OP_ROR_HANDLER(regs.b);
2870 static void Op66(void) // ROR IDX
2878 static void Op76(void) // ROR ABS
2887 +-----------------------------------------------------------------+
2888 | Opcode | | Addressing | | |
2889 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2890 +------------+-------------+--------------+-------+-------+-------+
2891 | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
2892 | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
2893 | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
2894 | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
2895 | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
2896 | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
2897 | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
2898 | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
2903 #define OP_SBC_HANDLER(m, acc) \
2904 uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
2905 flagC = (sum >> 8) & 0x01; \
2906 SET_V(m, acc, sum); \
2907 acc = (uint8_t)sum; \
2910 static void Op82(void) // SBCA #
2912 uint8_t m = READ_IMM;
2913 OP_SBC_HANDLER(m, regs.a);
2916 static void Op92(void) // SBCA DP
2918 uint8_t m = READ_DP;
2919 OP_SBC_HANDLER(m, regs.a);
2922 static void OpA2(void) // SBCA IDX
2924 uint8_t m = READ_IDX;
2925 OP_SBC_HANDLER(m, regs.a);
2928 static void OpB2(void) // SBCA ABS
2930 uint8_t m = READ_ABS;
2931 OP_SBC_HANDLER(m, regs.a);
2934 static void OpC2(void) // SBCB #
2936 uint8_t m = READ_IMM;
2937 OP_SBC_HANDLER(m, regs.b);
2940 static void OpD2(void) // SBCB DP
2942 uint8_t m = READ_DP;
2943 OP_SBC_HANDLER(m, regs.b);
2946 static void OpE2(void) // SBCB IDX
2948 uint8_t m = READ_IDX;
2949 OP_SBC_HANDLER(m, regs.b);
2952 static void OpF2(void) // SBCB ABS
2954 uint8_t m = READ_ABS;
2955 OP_SBC_HANDLER(m, regs.b);
2959 +-----------------------------------------------------------------+
2960 | Opcode | | Addressing | | |
2961 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2962 +------------+-------------+--------------+-------+-------+-------+
2963 | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- |
2964 | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- |
2965 | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- |
2966 | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- |
2967 | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- |
2968 | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- |
2969 | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- |
2970 | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- |
2971 | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- |
2972 | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- |
2973 | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- |
2974 | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- |
2975 | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- |
2976 | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- |
2977 | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- |
2978 | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- |
2979 | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- |
2980 | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- |
2981 | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- |
2982 | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- |
2983 | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- |
2988 #define OP_STA_HANDLER(m, acc) \
2989 regs.WrMem(m, acc); \
2993 #define OP_STA_HANDLER16(m, acc) \
2998 static void Op97(void) // STA DP
3000 uint16_t addr = EA_DP;
3001 OP_STA_HANDLER(addr, regs.a);
3004 static void Op9F(void) // STX DP
3006 uint16_t addr = EA_DP;
3007 OP_STA_HANDLER16(addr, regs.x);
3010 static void OpA7(void) // STA IDX
3012 uint16_t addr = EA_IDX;
3013 OP_STA_HANDLER(addr, regs.a);
3016 static void OpAF(void) // STX IDX
3018 uint16_t addr = EA_IDX;
3019 OP_STA_HANDLER16(addr, regs.x);
3022 static void OpB7(void) // STA ABS
3024 uint16_t addr = EA_ABS;
3025 OP_STA_HANDLER(addr, regs.a);
3028 static void OpBF(void) // STX ABS
3030 uint16_t addr = EA_ABS;
3031 OP_STA_HANDLER16(addr, regs.x);
3034 static void OpD7(void) // STB DP
3036 uint16_t addr = EA_DP;
3037 OP_STA_HANDLER(addr, regs.b);
3040 static void OpDD(void) // STD DP
3042 uint16_t addr = EA_DP;
3043 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3046 static void OpDF(void) // STU DP
3048 uint16_t addr = EA_DP;
3049 OP_STA_HANDLER16(addr, regs.u);
3052 static void OpE7(void) // STB IDX
3054 uint16_t addr = EA_IDX;
3055 OP_STA_HANDLER(addr, regs.b);
3058 static void OpED(void) // STD IDX
3060 uint16_t addr = EA_IDX;
3061 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3064 static void OpEF(void) // STU IDX
3066 uint16_t addr = EA_IDX;
3067 OP_STA_HANDLER16(addr, regs.u);
3070 static void OpF7(void) // STB ABS
3072 uint16_t addr = EA_ABS;
3073 OP_STA_HANDLER(addr, regs.b);
3076 static void OpFD(void) // STD ABS
3078 uint16_t addr = EA_ABS;
3079 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3082 static void OpFF(void) // STU ABS
3084 uint16_t addr = EA_ABS;
3085 OP_STA_HANDLER16(addr, regs.u);
3088 static void Op109F(void) // STY DP
3090 uint16_t addr = EA_DP;
3091 OP_STA_HANDLER16(addr, regs.y);
3094 static void Op10AF(void) // STY IDX
3096 uint16_t addr = EA_IDX;
3097 OP_STA_HANDLER16(addr, regs.y);
3100 static void Op10BF(void) // STY ABS
3102 uint16_t addr = EA_ABS;
3103 OP_STA_HANDLER16(addr, regs.y);
3106 static void Op10DF(void) // STS DP
3108 uint16_t addr = EA_DP;
3109 OP_STA_HANDLER16(addr, regs.s);
3112 static void Op10EF(void) // STS IDX
3114 uint16_t addr = EA_IDX;
3115 OP_STA_HANDLER16(addr, regs.s);
3118 static void Op10FF(void) // STS ABS
3120 uint16_t addr = EA_ABS;
3121 OP_STA_HANDLER16(addr, regs.s);
3125 +-----------------------------------------------------------------+
3126 | Opcode | | Addressing | | |
3127 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3128 +------------+-------------+--------------+-------+-------+-------+
3129 | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
3130 | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
3131 | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
3132 | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
3133 | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
3134 | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
3135 | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
3136 | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
3137 | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
3138 | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
3139 | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
3140 | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
3145 #define OP_SUB_HANDLER(m, acc) \
3146 uint16_t sum = (uint16_t)acc - (m); \
3147 flagC = (sum >> 8) & 0x01; \
3148 SET_V(m, acc, sum); \
3149 acc = (uint8_t)sum; \
3152 #define OP_SUB_HANDLER16D(m) \
3153 uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \
3154 uint32_t sum = acc - (m); \
3155 flagC = (sum >> 16) & 0x01; \
3156 SET_V16(m, acc, sum); \
3157 acc = sum & 0xFFFF; \
3158 regs.a = (acc >> 8) & 0xFF; \
3159 regs.b = acc & 0xFF; \
3162 static void Op80(void) // SUBA #
3164 uint8_t m = READ_IMM;
3165 OP_SUB_HANDLER(m, regs.a);
3168 static void Op83(void) // SUBD #
3170 uint16_t m = READ_IMM16;
3171 OP_SUB_HANDLER16D(m);
3174 static void Op90(void) // SUBA DP
3176 uint8_t m = READ_DP;
3177 OP_SUB_HANDLER(m, regs.a);
3180 static void Op93(void) // SUBD DP
3182 uint16_t m = READ_DP16;
3183 OP_SUB_HANDLER16D(m);
3186 static void OpA0(void) // SUBA IDX
3188 uint8_t m = READ_IDX;
3189 OP_SUB_HANDLER(m, regs.a);
3192 static void OpA3(void) // SUBD IDX
3194 uint16_t m = READ_IDX16;
3195 OP_SUB_HANDLER16D(m);
3198 static void OpB0(void) // SUBA ABS
3200 uint8_t m = READ_ABS;
3201 OP_SUB_HANDLER(m, regs.a);
3204 static void OpB3(void) // SUBD ABS
3206 uint16_t m = READ_ABS16;
3207 OP_SUB_HANDLER16D(m);
3210 static void OpC0(void) // SUBB #
3212 uint8_t m = READ_IMM;
3213 OP_SUB_HANDLER(m, regs.b);
3216 static void OpD0(void) // SUBB DP
3218 uint8_t m = READ_DP;
3219 OP_SUB_HANDLER(m, regs.b);
3222 static void OpE0(void) // SUBB IDX
3224 uint8_t m = READ_IDX;
3225 OP_SUB_HANDLER(m, regs.b);
3228 static void OpF0(void) // SUBB ABS
3230 uint8_t m = READ_ABS;
3231 OP_SUB_HANDLER(m, regs.b);
3235 +-----------------------------------------------------------------+
3236 | Opcode | | Addressing | | |
3237 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3238 +------------+-------------+--------------+-------+-------+-------+
3239 | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
3240 | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
3241 | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
3242 | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
3243 | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
3248 #define OP_TST_HANDLER(m) \
3252 static void Op0D(void) // TST DP
3254 uint8_t m = READ_DP;
3259 static void Op4D(void) // TSTA
3261 OP_TST_HANDLER(regs.a);
3265 static void Op5D(void) // TSTB
3267 OP_TST_HANDLER(regs.b);
3271 static void Op6D(void) // TST IDX
3273 uint8_t m = READ_IDX;
3278 static void Op7D(void) // TST ABS
3280 uint8_t m = READ_ABS;
3286 // Undocumented Opcodes
3288 static void Op01(void)
3294 //temp, for testing...
3296 static uint8_t backTrace[256];
3297 static uint16_t btPC[256];
3298 static int btPtr = 0;//*/
3300 static void Op__(void) // Illegal opcode
3304 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3306 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3307 for(int i=0; i<256; i++)
3309 Decode6809(btPC[(btPtr + i) & 0xFF]);
3319 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
3320 static void Op10(void);
3321 static void Op11(void);
3323 // Array of page zero opcode functions...
3325 static void (* exec_op0[256])() = {
3326 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
3327 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
3328 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
3329 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
3330 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
3331 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
3332 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
3333 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
3334 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
3335 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
3336 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
3337 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
3338 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
3339 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
3340 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
3341 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
3344 // Array of page one opcode functions...
3345 static void (* exec_op1[256])() = {
3346 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3347 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3348 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
3349 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
3350 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3351 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3352 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3353 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3354 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
3355 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
3356 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
3357 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
3358 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
3359 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
3360 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
3361 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
3364 // Array of page two opcode functions...
3365 static void (* exec_op2[256])() = {
3366 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3367 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3368 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3369 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
3370 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3371 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3372 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3373 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3374 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
3375 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
3376 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
3377 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
3378 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3379 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3380 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3381 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
3385 // These are here to save typing a ton of forward declarations...
3389 static void Op10(void)
3391 // exec_op1[regs.RdMem(regs.pc++)]();
3392 uint8_t opcode = regs.RdMem(regs.pc++);
3394 regs.clock += page1Cycles[opcode];
3399 static void Op11(void)
3401 // exec_op2[regs.RdMem(regs.pc++)]();
3402 uint8_t opcode = regs.RdMem(regs.pc++);
3404 regs.clock += page2Cycles[opcode];
3409 // Internal "memcpy" (so we don't have to link with any external libraries!)
3411 static void myMemcpy(void * dst, void * src, uint32_t size)
3413 uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3415 for(uint32_t i=0; i<size; i++)
3421 // Function to execute 6809 instructions
3423 //#define DEBUG_ILLEGAL
3424 #ifdef DEBUG_ILLEGAL
3426 #include "dis6809.h"
3428 uint8_t backTrace[256];
3429 V6809REGS btRegs[256];
3430 bool tripped = false;
3432 void Execute6809(V6809REGS * context, uint32_t cycles)
3434 // If this is not in place, the clockOverrun calculations can cause the
3435 // V6809 to get stuck in an infinite loop.
3439 myMemcpy(®s, context, sizeof(V6809REGS));
3440 // Explode flags register into individual uint8_ts
3445 // Since we can't guarantee that we'll execute the number of cycles passed
3446 // in exactly, we have to keep track of how much we overran the number of
3447 // cycles the last time we executed. Since we already executed those
3448 // cycles, this time through we remove them from the cycles passed in in
3449 // order to come out approximately even. Over the long run, this unevenness
3450 // in execution times evens out. :-)
3451 uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3453 while (regs.clock < endCycles)
3455 #ifdef DEBUG_ILLEGAL
3458 backTrace[btPtr] = regs.RdMem(regs.pc);
3459 btRegs[btPtr] = regs;
3460 btPtr = (btPtr + 1) & 0xFF;
3462 if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3464 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3465 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3467 for(uint16_t i=btPtr; i<btPtr+256; i++)
3469 Decode6809(btRegs[i & 0xFF].pc);
3470 // Note that these values are *before* execution, so stale...
3471 WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3472 btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
3483 // WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC);
3485 #if 0 //we solved this...
3486 if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
3487 WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
3489 //static bool disasm = false;
3490 /*//if (regs.pc == 0x15BA) disasm = true;
3491 //if (regs.pc == 0xFE76) disasm = true;
3492 if (regs.x == 0xFED4) disasm = true;
3493 if (disasm) Decode6809(regs.pc);
3494 //if (regs.pc == 0x164A) disasm = false;//*/
3496 //temp, for testing...
3497 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3498 btPC[btPtr] = regs.pc;
3499 btPtr = (btPtr + 1) & 0xFF;//*/
3501 // exec_op0[regs.RdMem(regs.pc++)]();
3502 uint8_t opcode = regs.RdMem(regs.pc++);
3504 regs.clock += page0Cycles[opcode];
3506 // Handle any pending interrupts
3508 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3509 // uint32_t flags = context->cpuFlags;
3510 uint32_t flags = regs.cpuFlags;
3512 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
3515 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3517 flagF = flagI = 1; // Set F, I
3518 regs.dp = 0; // Reset direct page register
3519 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3520 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3521 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3523 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
3526 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3528 flagE = 1; // Set Entire flag
3529 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3531 PUSHS16(regs.pc); // Save all regs...
3540 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3541 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3543 // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3544 // regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
3546 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
3549 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3551 if (!flagF) // Is the FIRQ masked (F == 1)?
3554 if (disasm) WriteLog(" FIRQ taken...\n");
3556 flagE = 0; // Clear Entire flag
3557 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3562 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3563 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3565 // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3566 // regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3569 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
3572 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3574 if (!flagI) // Is the IRQ masked (I == 1)?
3577 if (disasm) WriteLog(" IRQ taken...\n");
3579 flagE = 1; // Set the Entire flag
3580 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3591 flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3592 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3594 // Apparently, not done here!
3595 // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3596 // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3600 if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3601 (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
3602 (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
3603 regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3604 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3605 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3609 // Keep track of how much we overran so we can adjust on the next run...
3610 regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3612 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3613 myMemcpy(context, ®s, sizeof(V6809REGS));
3618 // Get the clock of the currently executing CPU
3620 uint64_t GetCurrentV6809Clock(void)
3627 // Get the PC of the currently executing CPU
3629 uint16_t GetCurrentV6809PC(void)
3635 // Set a line of the currently executing CPU
3636 void SetLineOfCurrentV6809(uint32_t line)
3638 regs.cpuFlags |= line;
3642 // Clear a line of the currently executing CPU
3643 void ClearLineOfCurrentV6809(uint32_t line)
3647 WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
3649 regs.cpuFlags &= ~line;
3654 FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
3655 E S=BFFF U=0000 PC=FEC0
3656 FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
3658 F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
3660 F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523
3661 F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526
3662 F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529
3663 F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
3664 F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D
3665 F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531
3666 F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD
3667 13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF
3668 13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2
3669 13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5
3670 13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7
3671 13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9
3672 13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB
3673 13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD
3674 13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF
3675 13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1
3676 13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3
3677 13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5
3678 13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000