5 // (c) 1997, 2009 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!
22 #include "dis6809.h" // Temporary...
23 #include "log.h" // Temporary...
24 bool disasm = false;//so we can extern this shit
27 #define TEST_DONT_BRANCH_OPTIMIZATION
31 #define CLR_Z (flagZ = 0)
32 #define CLR_ZN (flagZ = flagN = 0)
33 #define CLR_ZNC (flagZ = flagN = flagC = 0)
34 #define CLR_V (flagV = 0)
35 #define CLR_N (flagN = 0)
36 #define SET_Z(r) (flagZ = ((r) == 0 ? 1 : 0))
37 #define SET_N(r) (flagN = ((r) & 0x80) >> 7)
38 #define SET_N16(r) (flagN = ((r) & 0x8000) >> 15)
39 #define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
40 #define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
41 #define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4)
43 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
44 //#define SET_C_ADD(a,b) (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0))
45 //#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
46 //#define SET_C_CMP(a,b) (flagC = ((uint8_t)(b) >= (uint8_t)(a) ? 1 : 0))
47 #define SET_ZN(r) SET_N(r); SET_Z(r)
48 #define SET_ZN16(r) SET_N16(r); SET_Z(r)
49 //#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
50 //#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
51 //#define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b)
53 #define EA_IMM regs.pc++
54 #define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++)
55 #define EA_IDX DecodeIDX(regs.RdMem(regs.pc++))
56 #define EA_ABS FetchMemW(regs.pc)
58 #define READ_IMM regs.RdMem(EA_IMM)
59 #define READ_IMM16 FetchMemW(regs.pc)
60 #define READ_DP regs.RdMem(EA_DP)
61 #define READ_DP16 RdMemW(EA_DP)
62 #define READ_IDX regs.RdMem(EA_IDX)
63 #define READ_IDX16 RdMemW(EA_IDX)
64 #define READ_ABS regs.RdMem(EA_ABS)
65 #define READ_ABS16 RdMemW(EA_ABS)
67 #define READ_IMM_WB(v) uint16_t addr = EA_IMM; v = regs.RdMem(addr)
68 #define READ_DP_WB(v) uint16_t addr = EA_DP; v = regs.RdMem(addr)
69 #define READ_IDX_WB(v) uint16_t addr = EA_IDX; v = regs.RdMem(addr)
70 #define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr)
72 #define WRITE_BACK(d) regs.WrMem(addr, (d))
74 #define PULLS(r) r = regs.RdMem(regs.s++)
75 #define PUSHS(r) regs.WrMem(--regs.s, (r))
76 #define PULLS16(r) { r = RdMemW(regs.s); regs.s += 2; }
77 #define PUSHS16(r) { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
78 #define PULLU(r) r = regs.RdMem(regs.u++)
79 #define PUSHU(r) regs.WrMem(--regs.u, (r))
80 #define PULLU16(r) { r = RdMemW(regs.u); regs.u += 2; }
81 #define PUSHU16(r) { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
83 #define PACK_FLAGS ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
84 #define UNPACK_FLAGS flagE = (regs.cc & FLAG_E) >> 7; \
85 flagF = (regs.cc & FLAG_F) >> 6; \
86 flagH = (regs.cc & FLAG_H) >> 5; \
87 flagI = (regs.cc & FLAG_I) >> 4; \
88 flagN = (regs.cc & FLAG_N) >> 3; \
89 flagZ = (regs.cc & FLAG_Z) >> 2; \
90 flagV = (regs.cc & FLAG_V) >> 1; \
91 flagC = (regs.cc & FLAG_C)
93 // Private global variables
95 static V6809REGS regs;
96 static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
98 uint8_t page0Cycles[256] = {
99 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x
100 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x
101 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x
102 4, 4, 4, 4, 5, 5, 5, 5, 1, 5, 3, 6, 21, 11, 0, 19, // $3x
103 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, // $4x
104 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, // $5x
105 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $6x
106 7, 1, 1, 7, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 3, 7, // $7x
107 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, // $8x
108 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $9x
109 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $Ax
110 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, // $Bx
111 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, // $Cx
112 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Dx
113 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Ex
114 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx
117 uint8_t page1Cycles[256] = {
118 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
119 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
120 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x
121 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
122 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
123 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
124 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
125 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
126 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, // $8x
127 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $9x
128 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $Ax
129 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 7, 7, // $Bx
130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, // $Cx
131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Dx
132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Ex
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx
136 uint8_t page2Cycles[256] = {
137 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x
140 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
141 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
142 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
144 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
145 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, // $8x
146 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $9x
147 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $Ax
148 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, // $Bx
149 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Cx
150 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Dx
151 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Ex
152 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx
155 // Private function prototypes
157 static uint16_t RdMemW(uint16_t addr);
158 static uint16_t FetchMemW(uint16_t addr);
159 static void WrMemW(uint16_t addr, uint16_t w);
160 static uint16_t ReadEXG(uint8_t); // Read TFR/EXG post byte
161 static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data
162 static uint16_t DecodeReg(uint8_t); // Decode register data
163 static uint16_t DecodeIDX(uint8_t); // Decode IDX data
166 // Read word from memory function
168 static inline uint16_t RdMemW(uint16_t addr)
170 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
174 // Fetch a word from memory function. Increments PC
176 static inline uint16_t FetchMemW(uint16_t addr)
179 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
183 // Write word to memory function
185 static inline void WrMemW(uint16_t addr, uint16_t w)
187 regs.WrMem(addr + 0, w >> 8);
188 regs.WrMem(addr + 1, w & 0xFF);
192 // Function to read TFR/EXG post byte
194 uint16_t ReadEXG(uint8_t code)
201 retval = (regs.a << 8) | regs.b;
239 // Function to set TFR/EXG data
241 void WriteEXG(uint8_t code, uint16_t data)
246 regs.a = data >> 8, regs.b = data & 0xFF; break;
248 regs.x = data; break;
250 regs.y = data; break;
252 regs.u = data; break;
254 regs.s = data; break;
256 regs.pc = data; break;
258 regs.a = data & 0xFF; break;
260 regs.b = data & 0xFF; break;
262 regs.cc = data & 0xFF; UNPACK_FLAGS; break;
264 regs.dp = data & 0xFF; break;
269 // Function to decode register data
271 uint16_t DecodeReg(uint8_t reg)
278 retval = regs.x; break;
280 retval = regs.y; break;
282 retval = regs.u; break;
284 retval = regs.s; break;
291 // Function to decode IDX data
293 uint16_t DecodeIDX(uint8_t code)
296 uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
298 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
299 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
307 woff = DecodeReg(reg);
311 case 0: regs.x += 2; break;
312 case 1: regs.y += 2; break;
313 case 2: regs.u += 2; break;
314 case 3: regs.s += 2; break;
320 case 0: regs.x -= 2; break;
321 case 1: regs.y -= 2; break;
322 case 2: regs.u -= 2; break;
323 case 3: regs.s -= 2; break;
325 woff = DecodeReg(reg);
329 woff = DecodeReg(reg);
333 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
337 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
341 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
345 woff = DecodeReg(reg) + FetchMemW(regs.pc);
349 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
353 woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
357 woff = regs.pc + FetchMemW(regs.pc);
361 woff = FetchMemW(regs.pc);
371 addr = DecodeReg(reg);
374 case 0: regs.x++; break;
375 case 1: regs.y++; break;
376 case 2: regs.u++; break;
377 case 3: regs.s++; break;
381 addr = DecodeReg(reg);
384 case 0: regs.x += 2; break;
385 case 1: regs.y += 2; break;
386 case 2: regs.u += 2; break;
387 case 3: regs.s += 2; break;
390 case 2: { switch(reg)
392 case 0: regs.x--; break;
393 case 1: regs.y--; break;
394 case 2: regs.u--; break;
395 case 3: regs.s--; break;
397 addr = DecodeReg(reg); break; }
398 case 3: { switch(reg)
400 case 0: regs.x--; regs.x--; break;
401 case 1: regs.y--; regs.y--; break;
402 case 2: regs.u--; regs.u--; break;
403 case 3: regs.s--; regs.s--; break;
405 addr = DecodeReg(reg); break; }
406 case 4: { addr = DecodeReg(reg); break; }
407 case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; }
408 case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; }
409 case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
410 case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; }
411 case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
412 case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; }
413 case 13: { addr = regs.pc + FetchMemW(regs.pc); break; }
422 // 6809 OPCODE IMPLEMENTATION
424 // NOTE: Lots of macros are used here to save a LOT of typing. Also
425 // helps speed the debugging process. :-) Because of this, combining
426 // certain lines may look like a good idea but would end in disaster.
427 // You have been warned! ;-)
431 +-----------------------------------------------------------------+
432 | Opcode | | Addressing | | |
433 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
434 +------------+-------------+--------------+-------+-------+-------+
435 | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa |
436 | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa |
437 | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa |
438 | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa |
439 | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa |
440 | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa |
441 | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa |
442 | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa |
447 #define OP_ADC_HANDLER(m, acc) \
448 uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
449 flagC = (sum >> 8) & 0x01; \
450 SET_H(m, acc, sum); \
451 SET_V(m, acc, sum); \
456 Old flag handling code:
457 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
458 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
459 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
460 regs.a = addr & 0xFF; // Set accumulator
461 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
462 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
465 static void Op89(void) // ADCA #
467 uint16_t m = READ_IMM;
468 OP_ADC_HANDLER(m, regs.a);
471 static void Op99(void) // ADCA DP
473 uint16_t m = READ_DP;
474 OP_ADC_HANDLER(m, regs.a);
477 static void OpA9(void) // ADCA IDX
479 uint16_t m = READ_IDX;
480 OP_ADC_HANDLER(m, regs.a);
483 static void OpB9(void) // ADCA ABS
485 uint16_t m = READ_ABS;
486 OP_ADC_HANDLER(m, regs.a);
489 static void OpC9(void) // ADCB #
491 uint16_t m = READ_IMM;
492 OP_ADC_HANDLER(m, regs.b);
495 static void OpD9(void) // ADCB DP
497 uint16_t m = READ_DP;
498 OP_ADC_HANDLER(m, regs.b);
501 static void OpE9(void) // ADCB IDX
503 uint16_t m = READ_IDX;
504 OP_ADC_HANDLER(m, regs.b);
507 static void OpF9(void) // ADCB ABS
509 uint16_t m = READ_ABS;
510 OP_ADC_HANDLER(m, regs.b);
514 +-----------------------------------------------------------------+
515 | Opcode | | Addressing | | |
516 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
517 +------------+-------------+--------------+-------+-------+-------+
518 | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- |
519 | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa |
520 | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa |
521 | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa |
522 | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa |
523 | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa |
524 | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa |
525 | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa |
526 | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa |
527 | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa |
528 | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa |
529 | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa |
530 | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa |
535 #define OP_ADD_HANDLER(m, acc) \
536 uint16_t sum = (uint16_t)(acc) + (m); \
537 flagC = (sum >> 8) & 0x01; \
538 SET_H(m, acc, sum); \
539 SET_V(m, acc, sum); \
540 (acc) = sum & 0xFF; \
543 #define OP_ADD_HANDLER16(m, hireg, loreg) \
544 uint32_t acc = (uint32_t)((hireg << 8) | loreg); \
545 uint32_t sum = acc + (m); \
546 flagC = (sum >> 16) & 0x01; \
547 SET_V16(m, acc, sum); \
548 acc = sum & 0xFFFF; \
549 hireg = (acc >> 8) & 0xFF; \
550 loreg = acc & 0xFF; \
555 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
556 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
557 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
558 regs.a = addr & 0xFF; // Set accumulator
559 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
560 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
563 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
565 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
566 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
567 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
568 regs.a = dr>>8; regs.b = dr&0xFF;
572 static void Op3A(void) // ABX
574 regs.x += (uint16_t)regs.b;
577 static void Op8B(void) // ADDA #
579 uint16_t m = READ_IMM;
580 OP_ADD_HANDLER(m, regs.a);
583 static void Op9B(void) // ADDA DP
585 uint16_t m = READ_DP;
586 OP_ADD_HANDLER(m, regs.a);
589 static void OpAB(void) // ADDA IDX
591 uint16_t m = READ_IDX;
592 OP_ADD_HANDLER(m, regs.a);
595 static void OpBB(void) // ADDA ABS
597 uint16_t m = READ_ABS;
598 OP_ADD_HANDLER(m, regs.a);
601 static void OpC3(void) // ADDD #
603 uint32_t m = READ_IMM16;
604 OP_ADD_HANDLER16(m, regs.a, regs.b);
607 static void OpCB(void) // ADDB #
609 uint16_t m = READ_IMM;
610 OP_ADD_HANDLER(m, regs.b);
613 static void OpD3(void) // ADDD DP
615 uint32_t m = READ_DP16;
616 OP_ADD_HANDLER16(m, regs.a, regs.b);
619 static void OpDB(void) // ADDB DP
621 uint16_t m = READ_DP;
622 OP_ADD_HANDLER(m, regs.b);
625 static void OpE3(void) // ADDD IDX
627 uint32_t m = READ_IDX16;
628 OP_ADD_HANDLER16(m, regs.a, regs.b);
631 static void OpEB(void) // ADDB IDX
633 uint16_t m = READ_IDX;
634 OP_ADD_HANDLER(m, regs.b);
637 static void OpF3(void) // ADDD ABS
639 uint32_t m = READ_ABS16;
640 OP_ADD_HANDLER16(m, regs.a, regs.b);
643 static void OpFB(void) // ADDB ABS
645 uint16_t m = READ_ABS;
646 OP_ADD_HANDLER(m, regs.b);
650 +-----------------------------------------------------------------+
651 | Opcode | | Addressing | | |
652 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
653 +------------+-------------+--------------+-------+-------+-------+
654 | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- |
655 | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- |
656 | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- |
657 | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- |
658 | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- |
659 | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- |
660 | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- |
661 | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- |
666 #define OP_AND_HANDLER(m, acc) \
671 static void Op84(void) // ANDA #
673 uint16_t m = READ_IMM;
674 OP_AND_HANDLER(m, regs.a);
677 static void Op94(void) // ANDA DP
679 uint16_t m = READ_DP;
680 OP_AND_HANDLER(m, regs.a);
683 static void OpA4(void) // ANDA IDX
685 uint16_t m = READ_IDX;
686 OP_AND_HANDLER(m, regs.a);
689 static void OpB4(void) // ANDA ABS
691 uint16_t m = READ_ABS;
692 OP_AND_HANDLER(m, regs.a);
695 static void OpC4(void) // ANDB #
697 uint16_t m = READ_IMM;
698 OP_AND_HANDLER(m, regs.b);
701 static void OpD4(void) // ANDB DP
703 uint16_t m = READ_DP;
704 OP_AND_HANDLER(m, regs.b);
707 static void OpE4(void) // ANDB IDX
709 uint16_t m = READ_IDX;
710 OP_AND_HANDLER(m, regs.b);
713 static void OpF4(void) // ANDB ABS
715 uint16_t m = READ_ABS;
716 OP_AND_HANDLER(m, regs.b);
720 +-----------------------------------------------------------------+
721 | Opcode | | Addressing | | |
722 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
723 +------------+-------------+--------------+-------+-------+-------+
724 | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas |
725 | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas |
726 | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas |
727 | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas |
728 | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas |
733 #define OP_ASL_HANDLER(m) \
734 uint16_t res = m << 1; \
736 flagC = (res >> 8) & 0x01; \
740 static void Op08(void) // ASL DP
748 static void Op48(void) // ASLA
750 OP_ASL_HANDLER(regs.a);
753 static void Op58(void) // ASLB
755 OP_ASL_HANDLER(regs.b);
758 static void Op68(void) // ASL IDX
766 static void Op78(void) // ASL ABS
775 +-----------------------------------------------------------------+
776 | Opcode | | Addressing | | |
777 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
778 +------------+-------------+--------------+-------+-------+-------+
779 | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s |
780 | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s |
781 | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s |
782 | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s |
783 | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s |
786 // ASR opcodes (arithmetic, so preserves the sign)
788 #define OP_ASR_HANDLER(m) \
789 uint8_t res = (m & 0x80) | (m >> 1); \
794 static void Op07(void) // ASR DP
802 static void Op47(void) // ASRA
804 OP_ASR_HANDLER(regs.a);
807 static void Op57(void) // ASRB
809 OP_ASR_HANDLER(regs.b);
812 static void Op67(void) // ASR IDX
820 static void Op77(void) // ASR ABS
829 +-----------------------------------------------------------------+
830 | Opcode | | Addressing | | |
831 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
832 +------------+-------------+--------------+-------+-------+-------+
833 | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- |
834 | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- |
835 | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- |
836 | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- |
837 | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- |
838 | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- |
839 | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- |
840 | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- |
841 | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- |
842 | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- |
843 | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- |
844 | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- |
845 | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- |
846 | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- |
847 | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- |
848 | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- |
849 | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- |
850 | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- |
851 | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- |
852 | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- |
853 | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- |
854 | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- |
855 | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- |
856 | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- |
857 | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- |
858 | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- |
859 | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- |
860 | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- |
861 | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- |
862 | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- |
863 | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- |
864 | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- |
869 static void Op16(void) // LBRA
871 uint16_t offset = READ_IMM16;
875 static void Op20(void) // BRA
877 int16_t offset = (int16_t)(int8_t)READ_IMM;
881 static void Op21(void) // BRN
883 // This is basically a 2 byte NOP
884 int16_t offset = (int16_t)(int8_t)READ_IMM;
887 static void Op22(void) // BHI
890 int16_t offset = (int16_t)(int8_t)READ_IMM;
892 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
893 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
894 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
896 if (!(flagZ || flagC))
901 static void Op23(void) // BLS
904 int16_t offset = (int16_t)(int8_t)READ_IMM;
906 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
907 regs.pc += offset * (flagZ | flagC);
914 static void Op24(void) // BHS/CC
917 int16_t offset = (int16_t)(int8_t)READ_IMM;
919 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
920 regs.pc += offset * (flagC ^ 0x01);
927 static void Op25(void) // BLO/CS
930 int16_t offset = (int16_t)(int8_t)READ_IMM;
932 // WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
934 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
935 regs.pc += offset * flagC;
942 static void Op26(void) // BNE
945 int16_t offset = (int16_t)(int8_t)READ_IMM;
947 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
948 regs.pc += offset * (flagZ ^ 0x01);
955 static void Op27(void) // BEQ
958 int16_t offset = (int16_t)(int8_t)READ_IMM;
960 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
961 regs.pc += offset * flagZ;
968 static void Op28(void) // BVC
971 int16_t offset = (int16_t)(int8_t)READ_IMM;
973 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
974 regs.pc += offset * (flagV ^ 0x01);
981 static void Op29(void) // BVS
984 int16_t offset = (int16_t)(int8_t)READ_IMM;
986 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
987 regs.pc += offset * flagV;
994 static void Op2A(void) // BPL
997 int16_t offset = (int16_t)(int8_t)READ_IMM;
999 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1000 regs.pc += offset * (flagN ^ 0x01);
1007 static void Op2B(void) // BMI
1010 int16_t offset = (int16_t)(int8_t)READ_IMM;
1012 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1013 regs.pc += offset * flagN;
1020 static void Op2C(void) // BGE
1022 // (N && V) || (!N && !V)
1023 int16_t offset = (int16_t)(int8_t)READ_IMM;
1025 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1026 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1028 if ((flagN && flagV) || (!flagN && !flagV))
1033 static void Op2D(void) // BLT
1035 // (N && !V) || (!N && V)
1036 int16_t offset = (int16_t)(int8_t)READ_IMM;
1038 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1039 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1041 if ((flagN && !flagV) || (!flagN && flagV))
1046 static void Op2E(void) // BGT
1048 // (N && V && !Z) || (!N && !V && !Z)
1049 int16_t offset = (int16_t)(int8_t)READ_IMM;
1051 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1052 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1054 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1059 static void Op2F(void) // BLE
1061 // Z || (N && !V) || (!N && V)
1062 int16_t offset = (int16_t)(int8_t)READ_IMM;
1064 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1065 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1067 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1072 static void Op1021(void) // LBRN
1074 // This is basically a 4 byte NOP
1075 uint16_t offset = READ_IMM16;
1078 static void Op1022(void) // LBHI
1081 uint16_t offset = READ_IMM16;
1083 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1084 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1085 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1087 if (!(flagZ || flagC))
1092 static void Op1023(void) // LBLS
1095 uint16_t offset = READ_IMM16;
1097 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1098 regs.pc += offset * (flagZ | flagC);
1105 static void Op1024(void) // LBHS/CC
1108 uint16_t offset = READ_IMM16;
1110 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1111 regs.pc += offset * (flagC ^ 0x01);
1118 static void Op1025(void) // LBLO/CS
1121 uint16_t offset = READ_IMM16;
1123 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1124 regs.pc += offset * flagC;
1131 static void Op1026(void) // LBNE
1134 uint16_t offset = READ_IMM16;
1136 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1137 regs.pc += offset * (flagZ ^ 0x01);
1144 static void Op1027(void) // LBEQ
1147 uint16_t offset = READ_IMM16;
1149 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1150 regs.pc += offset * flagZ;
1157 static void Op1028(void) // LBVC
1160 uint16_t offset = READ_IMM16;
1162 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1163 regs.pc += offset * (flagV ^ 0x01);
1170 static void Op1029(void) // LBVS
1173 uint16_t offset = READ_IMM16;
1175 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1176 regs.pc += offset * flagV;
1183 static void Op102A(void) // LBPL
1186 uint16_t offset = READ_IMM16;
1188 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1189 regs.pc += offset * (flagN ^ 0x01);
1196 static void Op102B(void) // LBMI
1199 uint16_t offset = READ_IMM16;
1201 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1202 regs.pc += offset * flagN;
1209 static void Op102C(void) // LBGE
1211 // (N && V) || (!N && !V)
1212 uint16_t offset = READ_IMM16;
1214 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1215 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1217 if ((flagN && flagV) || (!flagN && !flagV))
1222 static void Op102D(void) // LBLT
1224 // (N && !V) || (!N && V)
1225 uint16_t offset = READ_IMM16;
1227 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1228 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1230 if ((flagN && !flagV) || (!flagN && flagV))
1235 static void Op102E(void) // LBGT
1237 // (N && V && !Z) || (!N && !V && !Z)
1238 uint16_t offset = READ_IMM16;
1240 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1241 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1243 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1248 static void Op102F(void) // LBLE
1250 // Z || (N && !V) || (!N && V)
1251 uint16_t offset = READ_IMM16;
1253 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1254 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1256 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1262 +-----------------------------------------------------------------+
1263 | Opcode | | Addressing | | |
1264 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1265 +------------+-------------+--------------+-------+-------+-------+
1266 | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- |
1267 | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- |
1268 | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- |
1269 | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- |
1270 | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- |
1271 | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- |
1272 | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- |
1273 | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- |
1278 #define OP_BIT_HANDLER(m, acc) \
1279 uint8_t result = acc & (m); \
1283 static void Op85(void) // BITA #
1285 uint8_t m = READ_IMM;
1286 OP_BIT_HANDLER(m, regs.a);
1289 static void Op95(void) // BITA DP
1291 uint8_t m = READ_DP;
1292 OP_BIT_HANDLER(m, regs.a);
1295 static void OpA5(void) // BITA IDX
1297 uint8_t m = READ_IDX;
1298 OP_BIT_HANDLER(m, regs.a);
1301 static void OpB5(void) // BITA ABS
1303 uint8_t m = READ_ABS;
1304 OP_BIT_HANDLER(m, regs.a);
1307 static void OpC5(void) // BITB #
1309 uint8_t m = READ_IMM;
1310 OP_BIT_HANDLER(m, regs.b);
1313 static void OpD5(void) // BITB DP
1315 uint8_t m = READ_DP;
1316 OP_BIT_HANDLER(m, regs.b);
1319 static void OpE5(void) // BITB IDX
1321 uint8_t m = READ_IDX;
1322 OP_BIT_HANDLER(m, regs.b);
1325 static void OpF5(void) // BITB ABS
1327 uint8_t m = READ_ABS;
1328 OP_BIT_HANDLER(m, regs.b);
1332 +-----------------------------------------------------------------+
1333 | Opcode | | Addressing | | |
1334 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1335 +------------+-------------+--------------+-------+-------+-------+
1336 | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 |
1337 | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 |
1338 | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 |
1339 | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 |
1340 | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 |
1345 #define OP_CLR_HANDLER(m) \
1346 flagN = flagV = flagC = 0; \
1350 static void Op0F(void) // CLR DP
1358 static void Op4F(void) // CLRA
1360 OP_CLR_HANDLER(regs.a);
1363 static void Op5F(void) // CLRB
1365 OP_CLR_HANDLER(regs.b);
1368 static void Op6F(void) // CLR IDX
1376 static void Op7F(void) // CLR ABS
1385 +-----------------------------------------------------------------+
1386 | Opcode | | Addressing | | |
1387 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1388 +------------+-------------+--------------+-------+-------+-------+
1389 | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa |
1390 | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa |
1391 | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa |
1392 | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa |
1393 | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa |
1394 | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa |
1395 | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa |
1396 | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa |
1397 | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa |
1398 | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa |
1399 | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa |
1400 | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa |
1401 | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa |
1402 | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa |
1403 | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa |
1404 | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa |
1405 | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa |
1406 | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa |
1407 | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa |
1408 | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa |
1409 | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa |
1410 | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa |
1411 | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa |
1412 | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa |
1413 | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa |
1414 | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa |
1415 | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa |
1416 | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa |
1421 #define OP_CMP_HANDLER(m, acc) \
1422 uint16_t sum = (uint16_t)(acc) - (m); \
1423 flagC = (sum >> 8) & 0x01; \
1424 SET_V(m, acc, sum); \
1427 #define OP_CMP_HANDLER16(m, acc) \
1428 uint32_t sum = (uint32_t)(acc) - (m); \
1429 flagC = (sum >> 16) & 0x01; \
1430 SET_V16(m, acc, sum); \
1433 static void Op81(void) // CMPA #
1435 uint8_t m = READ_IMM;
1436 OP_CMP_HANDLER(m, regs.a);
1439 static void Op8C(void) // CMPX #
1441 uint16_t m = READ_IMM16;
1442 OP_CMP_HANDLER16(m, regs.x);
1445 static void Op91(void) // CMPA DP
1447 uint8_t m = READ_DP;
1448 OP_CMP_HANDLER(m, regs.a);
1451 static void Op9C(void) // CMPX DP
1453 uint16_t m = READ_DP16;
1454 OP_CMP_HANDLER16(m, regs.x);
1457 static void OpA1(void) // CMPA IDX
1459 uint8_t m = READ_IDX;
1460 OP_CMP_HANDLER(m, regs.a);
1463 static void OpAC(void) // CMPX IDX
1465 uint16_t m = READ_IDX16;
1466 OP_CMP_HANDLER16(m, regs.x);
1469 static void OpB1(void) // CMPA ABS
1471 uint8_t m = READ_ABS;
1472 OP_CMP_HANDLER(m, regs.a);
1475 static void OpBC(void) // CMPX ABS
1477 uint16_t m = READ_ABS16;
1478 OP_CMP_HANDLER16(m, regs.x);
1481 static void OpC1(void) // CMPB #
1483 uint8_t m = READ_IMM;
1484 OP_CMP_HANDLER(m, regs.b);
1487 static void OpD1(void) // CMPB DP
1489 uint8_t m = READ_DP;
1490 OP_CMP_HANDLER(m, regs.b);
1493 static void OpE1(void) // CMPB IDX
1495 uint8_t m = READ_IDX;
1496 OP_CMP_HANDLER(m, regs.b);
1499 static void OpF1(void) // CMPB ABS
1501 uint8_t m = READ_ABS;
1502 OP_CMP_HANDLER(m, regs.b);
1505 static void Op1083(void) // CMPD #
1507 uint16_t m = READ_IMM16;
1508 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1511 static void Op108C(void) // CMPY #
1513 uint16_t m = READ_IMM16;
1514 OP_CMP_HANDLER16(m, regs.y);
1517 static void Op1093(void) // CMPD DP
1519 uint16_t m = READ_DP16;
1520 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1523 static void Op109C(void) // CMPY DP
1525 uint16_t m = READ_DP16;
1526 OP_CMP_HANDLER16(m, regs.y);
1529 static void Op10A3(void) // CMPD IDX
1531 uint16_t m = READ_IDX16;
1532 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1535 static void Op10AC(void) // CMPY IDX
1537 uint16_t m = READ_IDX16;
1538 OP_CMP_HANDLER16(m, regs.y);
1541 static void Op10B3(void) // CMPD ABS
1543 uint16_t m = READ_ABS16;
1544 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1547 static void Op10BC(void) // CMPY ABS
1549 uint16_t m = READ_ABS16;
1550 OP_CMP_HANDLER16(m, regs.y);
1553 static void Op1183(void) // CMPU #
1555 uint16_t m = READ_IMM16;
1556 OP_CMP_HANDLER16(m, regs.u);
1559 static void Op118C(void) // CMPS #
1561 uint16_t m = READ_IMM16;
1562 OP_CMP_HANDLER16(m, regs.s);
1565 static void Op1193(void) // CMPU DP
1567 uint16_t m = READ_DP16;
1568 OP_CMP_HANDLER16(m, regs.u);
1571 static void Op119C(void) // CMPS DP
1573 uint16_t m = READ_DP16;
1574 OP_CMP_HANDLER16(m, regs.s);
1577 static void Op11A3(void) // CMPU IDX
1579 uint16_t m = READ_IDX16;
1580 OP_CMP_HANDLER16(m, regs.u);
1583 static void Op11AC(void) // CMPS IDX
1585 uint16_t m = READ_IDX16;
1586 OP_CMP_HANDLER16(m, regs.s);
1589 static void Op11B3(void) // CMPU ABS
1591 uint16_t m = READ_ABS16;
1592 OP_CMP_HANDLER16(m, regs.u);
1595 static void Op11BC(void) // CMPS ABS
1597 uint16_t m = READ_ABS16;
1598 OP_CMP_HANDLER16(m, regs.s);
1602 +-----------------------------------------------------------------+
1603 | Opcode | | Addressing | | |
1604 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1605 +------------+-------------+--------------+-------+-------+-------+
1606 | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 |
1607 | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 |
1608 | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 |
1609 | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 |
1610 | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 |
1615 #define OP_COM_HANDLER(m) \
1621 static void Op03(void) // COM DP
1629 static void Op43(void) // COMA
1631 OP_COM_HANDLER(regs.a);
1634 static void Op53(void) // COMB
1636 OP_COM_HANDLER(regs.b);
1639 static void Op63(void) // COM IDX
1647 static void Op73(void) // COM ABS
1656 +-----------------------------------------------------------------+
1657 | Opcode | | Addressing | | |
1658 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1659 +------------+-------------+--------------+-------+-------+-------+
1660 | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- |
1661 | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd |
1662 | 3E 0062 | RESET* | INHERENT | * | 1 | ***** |
1663 | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- |
1664 | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- |
1665 | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- |
1668 static void Op13(void) // SYNC
1670 #warning "!!! SYNC not implemented !!!"
1672 /* SYNC stops processing instructions until an interrupt request happens. */
1673 /* This doesn't require the corresponding interrupt to be enabled: if it */
1674 /* is disabled, execution continues with the next instruction. */
1675 m68_state->int_state |= M6809_SYNC; /* HJB 990227 */
1676 check_irq_lines(m68_state);
1677 /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1678 * stop execution until the interrupt lines change. */
1679 if( m68_state->int_state & M6809_SYNC )
1680 if (m68_state->icount > 0) m68_state->icount = 0;
1684 static void Op3C(void) // CWAI
1686 #warning "!!! CWAI not implemented !!!"
1692 * CWAI stacks the entire machine state on the hardware stack,
1693 * then waits for an interrupt; when the interrupt is taken
1694 * later, the state is *not* saved again after CWAI.
1696 CC |= CC_E; /* HJB 990225: save entire state */
1705 m68_state->int_state |= M6809_CWAI; /* HJB 990228 */
1706 check_irq_lines(m68_state); /* HJB 990116 */
1707 if( m68_state->int_state & M6809_CWAI )
1708 if( m68_state->icount > 0 )
1709 m68_state->icount = 0;
1713 static void Op3E(void) // RESET
1715 regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
1718 static void Op3F(void) // SWI
1721 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1731 regs.pc = RdMemW(0xFFFA);
1734 static void Op103F(void) // SWI2
1737 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1746 regs.pc = RdMemW(0xFFF4);
1749 static void Op113F(void) // SWI3
1752 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1761 regs.pc = RdMemW(0xFFF2);
1765 +-----------------------------------------------------------------+
1766 | Opcode | | Addressing | | |
1767 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1768 +------------+-------------+--------------+-------+-------+-------+
1769 | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
1770 | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
1771 | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
1772 | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
1773 | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
1776 static void Op12() // NOP
1781 D3F8: A6 47 LDA (7),U CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA
1782 D3FA: 8B 01 ADDA #$01 CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC
1783 D3FC: 19 DAA CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD
1786 static void Op19() // DAA
1788 uint16_t result = (uint16_t)regs.a;
1790 // if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
1791 if ((regs.a & 0x0F) > 0x09 || flagH)
1794 // if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1795 if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1798 regs.a = (uint8_t)result;
1801 flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
1804 static void Op1A() // ORCC
1806 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1807 regs.cc |= READ_IMM;
1808 UNPACK_FLAGS; // & unmash 'em
1811 static void Op1C() // ANDCC
1813 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1814 regs.cc &= READ_IMM;
1815 UNPACK_FLAGS; // & unmash 'em
1818 static void Op1D() // SEX
1820 regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1821 SET_ZN16((regs.a << 8) | regs.b);
1826 +-----------------------------------------------------------------+
1827 | Opcode | | Addressing | | |
1828 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1829 +------------+-------------+--------------+-------+-------+-------+
1830 | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- |
1831 | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- |
1832 | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- |
1833 | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- |
1834 | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- |
1837 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1839 #define OP_DEC_HANDLER(m) \
1842 flagV = (m == 0x7F ? 1 : 0)
1844 static void Op0A(void) // DEC DP
1852 static void Op4A(void) // DECA
1854 OP_DEC_HANDLER(regs.a);
1857 static void Op5A(void) // DECB
1859 OP_DEC_HANDLER(regs.b);
1862 static void Op6A(void) // DEC IDX
1870 static void Op7A(void) // DEC ABS
1879 +-----------------------------------------------------------------+
1880 | Opcode | | Addressing | | |
1881 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1882 +------------+-------------+--------------+-------+-------+-------+
1883 | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- |
1884 | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- |
1885 | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- |
1886 | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- |
1887 | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- |
1888 | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- |
1889 | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- |
1890 | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- |
1895 #define OP_EOR_HANDLER(m, acc) \
1900 static void Op88(void) // EORA #
1902 uint8_t m = READ_IMM;
1903 OP_EOR_HANDLER(m, regs.a);
1906 static void Op98(void) // EORA DP
1908 uint8_t m = READ_DP;
1909 OP_EOR_HANDLER(m, regs.a);
1912 static void OpA8(void) // EORA IDX
1914 uint8_t m = READ_IDX;
1915 OP_EOR_HANDLER(m, regs.a);
1918 static void OpB8(void) // EORA ABS
1920 uint8_t m = READ_ABS;
1921 OP_EOR_HANDLER(m, regs.a);
1924 static void OpC8(void) // EORB #
1926 uint8_t m = READ_IMM;
1927 OP_EOR_HANDLER(m, regs.b);
1930 static void OpD8(void) // EORB DP
1932 uint8_t m = READ_DP;
1933 OP_EOR_HANDLER(m, regs.b);
1936 static void OpE8(void) // EORB IDX
1938 uint8_t m = READ_IDX;
1939 OP_EOR_HANDLER(m, regs.b);
1942 static void OpF8(void) // EORB ABS
1944 uint8_t m = READ_ABS;
1945 OP_EOR_HANDLER(m, regs.b);
1949 +-----------------------------------------------------------------+
1950 | Opcode | | Addressing | | |
1951 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1952 +------------+-------------+--------------+-------+-------+-------+
1953 | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- |
1954 | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- |
1955 | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- |
1956 | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- |
1957 | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- |
1960 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1962 #define OP_INC_HANDLER(m) \
1965 flagV = (m == 0x80 ? 1 : 0)
1967 static void Op0C(void) // INC DP
1975 static void Op4C(void) // INCA
1977 OP_INC_HANDLER(regs.a);
1980 static void Op5C(void) // INCB
1982 OP_INC_HANDLER(regs.b);
1985 static void Op6C(void) // INC IDX
1993 static void Op7C(void) // INC ABS
2002 +-----------------------------------------------------------------+
2003 | Opcode | | Addressing | | |
2004 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2005 +------------+-------------+--------------+-------+-------+-------+
2006 | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- |
2007 | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- |
2008 | 39 0057 | RTS | INHERENT | 5 | 1 | ----- |
2009 | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- |
2010 | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- |
2011 | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- |
2012 | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- |
2013 | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- |
2014 | AD 0173 | JSR | INDEXED | 7 | 2 | ----- |
2015 | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- |
2018 static void Op0E(void) // JMP DP
2023 static void Op17(void) // LBSR
2025 uint16_t word = FetchMemW(regs.pc);
2030 static void Op39(void) // RTS
2035 static void Op3B(void) // RTI
2040 // If E flag set, pull all regs
2055 static void Op6E(void) // JMP IDX
2060 static void Op7E(void) // JMP ABS
2065 static void Op8D(void) // BSR
2067 uint16_t word = (int16_t)(int8_t)READ_IMM;
2072 static void Op9D(void) // JSR DP
2074 uint16_t word = EA_DP;
2079 static void OpAD(void) // JSR IDX
2081 uint16_t word = EA_IDX;
2086 static void OpBD(void) // JSR ABS
2088 uint16_t word = EA_ABS;
2094 +-----------------------------------------------------------------+
2095 | Opcode | | Addressing | | |
2096 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2097 +------------+-------------+--------------+-------+-------+-------+
2098 | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
2099 | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
2102 static void Op1E(void) // EXG
2104 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2106 uint8_t m = READ_IMM;
2107 uint8_t reg1 = m >> 4, reg2 = m & 0x0F;
2108 uint16_t acc1 = ReadEXG(reg1);
2109 uint16_t acc2 = ReadEXG(reg2);
2111 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2112 if (((m >> 4) ^ m) & 0x08)
2115 WriteEXG(reg1, acc2);
2116 WriteEXG(reg2, acc1);
2119 static void Op1F(void) // TFR
2121 uint8_t m = READ_IMM;
2122 uint16_t acc = ReadEXG(m >> 4);
2124 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2125 if (((m >> 4) ^ m) & 0x08)
2128 WriteEXG(m & 0x0F, acc);
2132 +-----------------------------------------------------------------+
2133 | Opcode | | Addressing | | |
2134 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2135 +------------+-------------+--------------+-------+-------+-------+
2136 | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
2137 | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
2138 | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
2139 | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
2140 | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
2141 | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
2142 | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
2143 | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
2144 | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
2145 | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
2146 | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
2147 | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
2148 | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
2149 | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
2150 | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
2151 | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
2152 | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
2153 | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
2154 | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
2155 | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
2156 | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
2157 | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
2158 | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
2159 | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
2160 | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
2161 | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
2162 | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
2163 | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
2168 #define OP_LDA_HANDLER(m, acc) \
2173 #define OP_LDA_HANDLER16(m, acc) \
2178 #define OP_LDA_HANDLER16D(m) \
2179 regs.a = (m >> 8); \
2180 regs.b = m & 0xFF; \
2184 static void Op86(void) // LDA #
2186 uint8_t m = READ_IMM;
2187 OP_LDA_HANDLER(m, regs.a);
2190 static void Op8E(void) // LDX #
2192 uint16_t m = READ_IMM16;
2193 OP_LDA_HANDLER16(m, regs.x);
2196 static void Op96(void) // LDA DP
2198 uint8_t m = READ_DP;
2199 OP_LDA_HANDLER(m, regs.a);
2202 static void Op9E(void) // LDX DP
2204 uint16_t m = READ_DP16;
2205 OP_LDA_HANDLER16(m, regs.x);
2208 static void OpA6(void) // LDA IDX
2210 uint8_t m = READ_IDX;
2211 OP_LDA_HANDLER(m, regs.a);
2214 static void OpAE(void) // LDX IDX
2216 uint16_t m = READ_IDX16;
2217 OP_LDA_HANDLER16(m, regs.x);
2220 static void OpB6(void) // LDA ABS
2222 uint8_t m = READ_ABS;
2223 OP_LDA_HANDLER(m, regs.a);
2226 static void OpBE(void) // LDX ABS
2228 uint16_t m = READ_ABS16;
2229 OP_LDA_HANDLER16(m, regs.x);
2232 static void OpC6(void) // LDB #
2234 uint8_t m = READ_IMM;
2235 OP_LDA_HANDLER(m, regs.b);
2238 static void OpCC(void) // LDD #
2240 uint16_t m = READ_IMM16;
2241 OP_LDA_HANDLER16D(m);
2244 static void OpCE(void) // LDU #
2246 uint16_t m = READ_IMM16;
2247 OP_LDA_HANDLER16(m, regs.u);
2250 static void OpD6(void) // LDB DP
2252 uint8_t m = READ_DP;
2253 OP_LDA_HANDLER(m, regs.b);
2256 static void OpDC(void) // LDD DP
2258 uint16_t m = READ_DP16;
2259 OP_LDA_HANDLER16D(m);
2262 static void OpDE(void) // LDU DP
2264 uint16_t m = READ_DP16;
2265 OP_LDA_HANDLER16(m, regs.u);
2268 static void OpE6(void) // LDB IDX
2270 uint8_t m = READ_IDX;
2271 OP_LDA_HANDLER(m, regs.b);
2274 static void OpEC(void) // LDD IDX
2276 uint16_t m = READ_IDX16;
2277 OP_LDA_HANDLER16D(m);
2280 static void OpEE(void) // LDU IDX
2282 uint16_t m = READ_IDX16;
2283 OP_LDA_HANDLER16(m, regs.u);
2286 static void OpF6(void) // LDB ABS
2288 uint8_t m = READ_ABS;
2289 OP_LDA_HANDLER(m, regs.b);
2292 static void OpFC(void) // LDD ABS
2294 uint16_t m = READ_ABS16;
2295 OP_LDA_HANDLER16D(m);
2298 static void OpFE(void) // LDU ABS
2300 uint16_t m = READ_ABS16;
2301 OP_LDA_HANDLER16(m, regs.u);
2304 static void Op108E(void) // LDY #
2306 uint16_t m = READ_IMM16;
2307 OP_LDA_HANDLER16(m, regs.y);
2310 static void Op109E(void) // LDY DP
2312 uint16_t m = READ_DP16;
2313 OP_LDA_HANDLER16(m, regs.y);
2316 static void Op10AE(void) // LDY IDX
2318 uint16_t m = READ_IDX16;
2319 OP_LDA_HANDLER16(m, regs.y);
2322 static void Op10BE(void) // LDY ABS
2324 uint16_t m = READ_ABS16;
2325 OP_LDA_HANDLER16(m, regs.y);
2328 static void Op10CE(void) // LDS #
2330 uint16_t m = READ_IMM16;
2331 OP_LDA_HANDLER16(m, regs.s);
2334 static void Op10DE(void) // LDS DP
2336 uint16_t m = READ_DP16;
2337 OP_LDA_HANDLER16(m, regs.s);
2340 static void Op10EE(void) // LDS IDX
2342 uint16_t m = READ_IDX16;
2343 OP_LDA_HANDLER16(m, regs.s);
2346 static void Op10FE(void) // LDS ABS
2348 uint16_t m = READ_ABS16;
2349 OP_LDA_HANDLER16(m, regs.s);
2353 +-----------------------------------------------------------------+
2354 | Opcode | | Addressing | | |
2355 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2356 +------------+-------------+--------------+-------+-------+-------+
2357 | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- |
2358 | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- |
2359 | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- |
2360 | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- |
2363 static void Op30(void) // LEAX
2369 static void Op31(void) // LEAY
2375 static void Op32(void) // LEAS
2380 static void Op33(void) // LEAU
2386 +-----------------------------------------------------------------+
2387 | Opcode | | Addressing | | |
2388 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2389 +------------+-------------+--------------+-------+-------+-------+
2390 | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s |
2391 | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s |
2392 | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s |
2393 | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s |
2394 | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s |
2399 #define OP_LSR_HANDLER(m) \
2404 static void Op04(void) // LSR DP
2412 static void Op44(void) // LSRA
2414 OP_LSR_HANDLER(regs.a);
2417 static void Op54(void) // LSRB
2419 OP_LSR_HANDLER(regs.b);
2422 static void Op64(void) // LSR IDX
2430 static void Op74(void) // LSR ABS
2439 +-----------------------------------------------------------------+
2440 | Opcode | | Addressing | | |
2441 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2442 +------------+-------------+--------------+-------+-------+-------+
2443 | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a |
2446 static void Op3D(void) // MUL
2448 uint16_t prod = regs.a * regs.b;
2450 regs.b = prod & 0xFF;
2452 // flagC = (prod & 0x0080 ? 1 : 0);
2453 flagC = (prod >> 7) & 0x01;
2457 +-----------------------------------------------------------------+
2458 | Opcode | | Addressing | | |
2459 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2460 +------------+-------------+--------------+-------+-------+-------+
2461 | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa |
2462 | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa |
2463 | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa |
2464 | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa |
2465 | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa |
2470 #define OP_NEG_HANDLER(m) \
2474 flagC = (res >= 0x80 ? 1 : 0); \
2484 #define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
2485 #define SET_C8(a) CC|=((a&0x100)>>8)
2487 static void Op00(void) // NEG DP
2495 static void Op40(void) // NEGA
2497 OP_NEG_HANDLER(regs.a);
2500 static void Op50(void) // NEGB
2502 OP_NEG_HANDLER(regs.b);
2505 static void Op60(void) // NEG IDX
2513 static void Op70(void) // NEG ABS
2522 +-----------------------------------------------------------------+
2523 | Opcode | | Addressing | | |
2524 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2525 +------------+-------------+--------------+-------+-------+-------+
2526 | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- |
2527 | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- |
2528 | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- |
2529 | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- |
2530 | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- |
2531 | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- |
2532 | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- |
2533 | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- |
2538 #define OP_OR_HANDLER(m, acc) \
2543 static void Op8A(void) // ORA #
2545 uint8_t m = READ_IMM;
2546 OP_OR_HANDLER(m, regs.a);
2549 static void Op9A(void) // ORA DP
2551 uint8_t m = READ_DP;
2552 OP_OR_HANDLER(m, regs.a);
2555 static void OpAA(void) // ORA IDX
2557 uint8_t m = READ_IDX;
2558 OP_OR_HANDLER(m, regs.a);
2561 static void OpBA(void) // ORA ABS
2563 uint8_t m = READ_ABS;
2564 OP_OR_HANDLER(m, regs.a);
2567 static void OpCA(void) // ORB #
2569 uint8_t m = READ_IMM;
2570 OP_OR_HANDLER(m, regs.b);
2573 static void OpDA(void) // ORB DP
2575 uint8_t m = READ_DP;
2576 OP_OR_HANDLER(m, regs.b);
2579 static void OpEA(void) // ORB IDX
2581 uint8_t m = READ_IDX;
2582 OP_OR_HANDLER(m, regs.b);
2585 static void OpFA(void) // ORB ABS
2587 uint8_t m = READ_ABS;
2588 OP_OR_HANDLER(m, regs.b);
2592 +-----------------------------------------------------------------+
2593 | Opcode | | Addressing | | |
2594 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2595 +------------+-------------+--------------+-------+-------+-------+
2596 | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- |
2597 | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc |
2598 | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- |
2599 | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc |
2602 static void Op34(void) // PSHS
2604 uint8_t m = READ_IMM;
2622 regs.cc = PACK_FLAGS;
2626 // Count bits in each nybble to come up with correct cycle counts...
2627 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2628 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2631 static void Op35(void) // PULS
2633 uint8_t m = READ_IMM;
2655 // Count bits in each nybble to come up with correct cycle counts...
2656 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2657 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2660 static void Op36(void) // PHSU
2662 uint8_t m = READ_IMM;
2680 regs.cc = PACK_FLAGS;
2684 // Count bits in each nybble to come up with correct cycle counts...
2685 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2686 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2689 static void Op37(void) // PULU
2691 uint8_t m = READ_IMM;
2713 // Count bits in each nybble to come up with correct cycle counts...
2714 uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2715 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2719 +-----------------------------------------------------------------+
2720 | Opcode | | Addressing | | |
2721 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2722 +------------+-------------+--------------+-------+-------+-------+
2723 | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas |
2724 | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas |
2725 | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas |
2726 | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas |
2727 | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas |
2732 #define OP_ROL_HANDLER(m) \
2733 uint8_t res = (m << 1) | flagC; \
2736 flagC = (m >> 7) & 0x01; \
2742 r = (CC & CC_C) | (t << 1);
2747 static void Op09(void) // ROL DP
2755 static void Op49(void) // ROLA
2757 OP_ROL_HANDLER(regs.a);
2760 static void Op59(void) // ROLB
2762 OP_ROL_HANDLER(regs.b);
2765 static void Op69(void) // ROL IDX
2773 static void Op79(void) // ROL ABS
2782 +-----------------------------------------------------------------+
2783 | Opcode | | Addressing | | |
2784 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2785 +------------+-------------+--------------+-------+-------+-------+
2786 | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s |
2787 | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s |
2788 | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s |
2789 | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s |
2790 | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s |
2795 #define OP_ROR_HANDLER(m) \
2796 uint8_t res = (flagC << 7) | (m >> 1); \
2802 static void Op06(void) // ROR DP
2810 static void Op46(void) // RORA
2812 OP_ROR_HANDLER(regs.a);
2815 static void Op56(void) // RORB
2817 OP_ROR_HANDLER(regs.b);
2820 static void Op66(void) // ROR IDX
2828 static void Op76(void) // ROR ABS
2837 +-----------------------------------------------------------------+
2838 | Opcode | | Addressing | | |
2839 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2840 +------------+-------------+--------------+-------+-------+-------+
2841 | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
2842 | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
2843 | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
2844 | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
2845 | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
2846 | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
2847 | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
2848 | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
2853 #define OP_SBC_HANDLER(m, acc) \
2854 uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
2855 flagC = (sum >> 8) & 0x01; \
2856 SET_V(m, acc, sum); \
2857 acc = (uint8_t)sum; \
2860 static void Op82(void) // SBCA #
2862 uint8_t m = READ_IMM;
2863 OP_SBC_HANDLER(m, regs.a);
2866 static void Op92(void) // SBCA DP
2868 uint8_t m = READ_DP;
2869 OP_SBC_HANDLER(m, regs.a);
2872 static void OpA2(void) // SBCA IDX
2874 uint8_t m = READ_IDX;
2875 OP_SBC_HANDLER(m, regs.a);
2878 static void OpB2(void) // SBCA ABS
2880 uint8_t m = READ_ABS;
2881 OP_SBC_HANDLER(m, regs.a);
2884 static void OpC2(void) // SBCB #
2886 uint8_t m = READ_IMM;
2887 OP_SBC_HANDLER(m, regs.b);
2890 static void OpD2(void) // SBCB DP
2892 uint8_t m = READ_DP;
2893 OP_SBC_HANDLER(m, regs.b);
2896 static void OpE2(void) // SBCB IDX
2898 uint8_t m = READ_IDX;
2899 OP_SBC_HANDLER(m, regs.b);
2902 static void OpF2(void) // SBCB ABS
2904 uint8_t m = READ_ABS;
2905 OP_SBC_HANDLER(m, regs.b);
2909 +-----------------------------------------------------------------+
2910 | Opcode | | Addressing | | |
2911 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2912 +------------+-------------+--------------+-------+-------+-------+
2913 | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- |
2914 | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- |
2915 | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- |
2916 | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- |
2917 | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- |
2918 | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- |
2919 | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- |
2920 | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- |
2921 | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- |
2922 | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- |
2923 | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- |
2924 | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- |
2925 | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- |
2926 | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- |
2927 | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- |
2928 | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- |
2929 | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- |
2930 | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- |
2931 | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- |
2932 | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- |
2933 | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- |
2938 #define OP_STA_HANDLER(m, acc) \
2939 regs.WrMem(m, acc); \
2943 #define OP_STA_HANDLER16(m, acc) \
2948 static void Op97(void) // STA DP
2950 uint16_t addr = EA_DP;
2951 OP_STA_HANDLER(addr, regs.a);
2954 static void Op9F(void) // STX DP
2956 uint16_t addr = EA_DP;
2957 OP_STA_HANDLER16(addr, regs.x);
2960 static void OpA7(void) // STA IDX
2962 uint16_t addr = EA_IDX;
2963 OP_STA_HANDLER(addr, regs.a);
2966 static void OpAF(void) // STX IDX
2968 uint16_t addr = EA_IDX;
2969 OP_STA_HANDLER16(addr, regs.x);
2972 static void OpB7(void) // STA ABS
2974 uint16_t addr = EA_ABS;
2975 OP_STA_HANDLER(addr, regs.a);
2978 static void OpBF(void) // STX ABS
2980 uint16_t addr = EA_ABS;
2981 OP_STA_HANDLER16(addr, regs.x);
2984 static void OpD7(void) // STB DP
2986 uint16_t addr = EA_DP;
2987 OP_STA_HANDLER(addr, regs.b);
2990 static void OpDD(void) // STD DP
2992 uint16_t addr = EA_DP;
2993 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2996 static void OpDF(void) // STU DP
2998 uint16_t addr = EA_DP;
2999 OP_STA_HANDLER16(addr, regs.u);
3002 static void OpE7(void) // STB IDX
3004 uint16_t addr = EA_IDX;
3005 OP_STA_HANDLER(addr, regs.b);
3008 static void OpED(void) // STD IDX
3010 uint16_t addr = EA_IDX;
3011 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3014 static void OpEF(void) // STU IDX
3016 uint16_t addr = EA_IDX;
3017 OP_STA_HANDLER16(addr, regs.u);
3020 static void OpF7(void) // STB ABS
3022 uint16_t addr = EA_ABS;
3023 OP_STA_HANDLER(addr, regs.b);
3026 static void OpFD(void) // STD ABS
3028 uint16_t addr = EA_ABS;
3029 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3032 static void OpFF(void) // STU ABS
3034 uint16_t addr = EA_ABS;
3035 OP_STA_HANDLER16(addr, regs.u);
3038 static void Op109F(void) // STY DP
3040 uint16_t addr = EA_DP;
3041 OP_STA_HANDLER16(addr, regs.y);
3044 static void Op10AF(void) // STY IDX
3046 uint16_t addr = EA_IDX;
3047 OP_STA_HANDLER16(addr, regs.y);
3050 static void Op10BF(void) // STY ABS
3052 uint16_t addr = EA_ABS;
3053 OP_STA_HANDLER16(addr, regs.y);
3056 static void Op10DF(void) // STS DP
3058 uint16_t addr = EA_DP;
3059 OP_STA_HANDLER16(addr, regs.s);
3062 static void Op10EF(void) // STS IDX
3064 uint16_t addr = EA_IDX;
3065 OP_STA_HANDLER16(addr, regs.s);
3068 static void Op10FF(void) // STS ABS
3070 uint16_t addr = EA_ABS;
3071 OP_STA_HANDLER16(addr, regs.s);
3075 +-----------------------------------------------------------------+
3076 | Opcode | | Addressing | | |
3077 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3078 +------------+-------------+--------------+-------+-------+-------+
3079 | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
3080 | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
3081 | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
3082 | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
3083 | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
3084 | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
3085 | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
3086 | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
3087 | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
3088 | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
3089 | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
3090 | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
3095 #define OP_SUB_HANDLER(m, acc) \
3096 uint16_t sum = (uint16_t)acc - (m); \
3097 flagC = (sum >> 8) & 0x01; \
3098 SET_V(m, acc, sum); \
3099 acc = (uint8_t)sum; \
3102 #define OP_SUB_HANDLER16D(m) \
3103 uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \
3104 uint32_t sum = acc - (m); \
3105 flagC = (sum >> 16) & 0x01; \
3106 SET_V16(m, acc, sum); \
3107 acc = sum & 0xFFFF; \
3108 regs.a = (acc >> 8) & 0xFF; \
3109 regs.b = acc & 0xFF; \
3112 static void Op80(void) // SUBA #
3114 uint8_t m = READ_IMM;
3115 OP_SUB_HANDLER(m, regs.a);
3118 static void Op83(void) // SUBD #
3120 uint16_t m = READ_IMM16;
3121 OP_SUB_HANDLER16D(m);
3124 static void Op90(void) // SUBA DP
3126 uint8_t m = READ_DP;
3127 OP_SUB_HANDLER(m, regs.a);
3130 static void Op93(void) // SUBD DP
3132 uint16_t m = READ_DP16;
3133 OP_SUB_HANDLER16D(m);
3136 static void OpA0(void) // SUBA IDX
3138 uint8_t m = READ_IDX;
3139 OP_SUB_HANDLER(m, regs.a);
3142 static void OpA3(void) // SUBD IDX
3144 uint16_t m = READ_IDX16;
3145 OP_SUB_HANDLER16D(m);
3148 static void OpB0(void) // SUBA ABS
3150 uint8_t m = READ_ABS;
3151 OP_SUB_HANDLER(m, regs.a);
3154 static void OpB3(void) // SUBD ABS
3156 uint16_t m = READ_ABS16;
3157 OP_SUB_HANDLER16D(m);
3160 static void OpC0(void) // SUBB #
3162 uint8_t m = READ_IMM;
3163 OP_SUB_HANDLER(m, regs.b);
3166 static void OpD0(void) // SUBB DP
3168 uint8_t m = READ_DP;
3169 OP_SUB_HANDLER(m, regs.b);
3172 static void OpE0(void) // SUBB IDX
3174 uint8_t m = READ_IDX;
3175 OP_SUB_HANDLER(m, regs.b);
3178 static void OpF0(void) // SUBB ABS
3180 uint8_t m = READ_ABS;
3181 OP_SUB_HANDLER(m, regs.b);
3185 +-----------------------------------------------------------------+
3186 | Opcode | | Addressing | | |
3187 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3188 +------------+-------------+--------------+-------+-------+-------+
3189 | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
3190 | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
3191 | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
3192 | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
3193 | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
3198 #define OP_TST_HANDLER(m) \
3202 static void Op0D(void) // TST DP
3204 uint8_t m = READ_DP;
3208 static void Op4D(void) // TSTA
3210 OP_TST_HANDLER(regs.a);
3213 static void Op5D(void) // TSTB
3215 OP_TST_HANDLER(regs.b);
3218 static void Op6D(void) // TST IDX
3220 uint8_t m = READ_IDX;
3224 static void Op7D(void) // TST ABS
3226 uint8_t m = READ_ABS;
3230 // Undocumented Opcodes
3232 static void Op01(void)
3238 //temp, for testing...
3240 static uint8_t backTrace[256];
3241 static uint16_t btPC[256];
3242 static int btPtr = 0;//*/
3244 static void Op__(void) // Illegal opcode
3248 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3250 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
3251 for(int i=0; i<256; i++)
3253 Decode6809(btPC[(btPtr + i) & 0xFF]);
3263 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
3264 static void Op10(void);
3265 static void Op11(void);
3267 // Array of page zero opcode functions...
3269 static void (* exec_op0[256])() = {
3270 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
3271 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
3272 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
3273 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
3274 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
3275 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
3276 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
3277 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
3278 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
3279 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
3280 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
3281 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
3282 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
3283 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
3284 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
3285 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
3288 // Array of page one opcode functions...
3289 static void (* exec_op1[256])() = {
3290 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3291 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3292 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
3293 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
3294 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3295 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3296 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3297 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3298 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
3299 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
3300 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
3301 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
3302 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
3303 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
3304 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
3305 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
3308 // Array of page two opcode functions...
3309 static void (* exec_op2[256])() = {
3310 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3311 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3312 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3313 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
3314 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3315 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3316 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3317 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3318 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
3319 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
3320 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
3321 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
3322 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3323 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3324 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3325 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
3328 // These are here to save typing a ton of forward declarations...
3331 static void Op10(void)
3333 // exec_op1[regs.RdMem(regs.pc++)]();
3334 uint8_t opcode = regs.RdMem(regs.pc++);
3336 regs.clock += page1Cycles[opcode];
3340 static void Op11(void)
3342 // exec_op2[regs.RdMem(regs.pc++)]();
3343 uint8_t opcode = regs.RdMem(regs.pc++);
3345 regs.clock += page2Cycles[opcode];
3350 // Internal "memcpy" (so we don't have to link with any external libraries!)
3352 static void myMemcpy(void * dst, void * src, uint32_t size)
3354 uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3356 for(uint32_t i=0; i<size; i++)
3361 // Function to execute 6809 instructions
3363 //#define DEBUG_ILLEGAL
3364 #ifdef DEBUG_ILLEGAL
3366 #include "dis6809.h"
3368 uint8_t backTrace[256];
3369 V6809REGS btRegs[256];
3370 bool tripped = false;
3372 void Execute6809(V6809REGS * context, uint32_t cycles)
3374 // If this is not in place, the clockOverrun calculations can cause the V6809 to get
3375 // stuck in an infinite loop.
3376 if (cycles == 0) // Nothing to do, so bail!
3379 myMemcpy(®s, context, sizeof(V6809REGS));
3380 UNPACK_FLAGS; // Explode flags register into individual uint8_ts
3384 // Since we can't guarantee that we'll execute the number of cycles passed in
3385 // exactly, we have to keep track of how much we overran the number of cycles
3386 // the last time we executed. Since we already executed those cycles, this time
3387 // through we remove them from the cycles passed in in order to come out
3388 // approximately even. Over the long run, this unevenness in execution times
3390 uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3392 while (regs.clock < endCycles)
3394 #ifdef DEBUG_ILLEGAL
3397 backTrace[btPtr] = regs.RdMem(regs.pc);
3398 btRegs[btPtr] = regs;
3399 btPtr = (btPtr + 1) & 0xFF;
3401 if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
3403 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
3404 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
3406 for(uint16_t i=btPtr; i<btPtr+256; i++)
3408 Decode6809(btRegs[i & 0xFF].pc);
3409 // Note that these values are *before* execution, so stale...
3410 WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3411 btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
3421 Decode6809(regs.pc);
3422 // WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC);
3424 #if 0 //we solved this...
3425 if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
3426 WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
3428 //static bool disasm = false;
3429 /*//if (regs.pc == 0x15BA) disasm = true;
3430 //if (regs.pc == 0xFE76) disasm = true;
3431 if (regs.x == 0xFED4) disasm = true;
3432 if (disasm) Decode6809(regs.pc);
3433 //if (regs.pc == 0x164A) disasm = false;//*/
3435 //temp, for testing...
3436 /*backTrace[btPtr] = regs.RdMem(regs.pc);
3437 btPC[btPtr] = regs.pc;
3438 btPtr = (btPtr + 1) & 0xFF;//*/
3440 // exec_op0[regs.RdMem(regs.pc++)]();
3441 uint8_t opcode = regs.RdMem(regs.pc++);
3443 regs.clock += page0Cycles[opcode];
3445 // Handle any pending interrupts
3447 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3448 // uint32_t flags = context->cpuFlags;
3449 uint32_t flags = regs.cpuFlags;
3451 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
3454 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
3456 flagF = flagI = 1; // Set F, I
3457 regs.dp = 0; // Reset direct page register
3458 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3459 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3460 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
3462 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
3465 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
3467 flagE = 1; // Set Entire flag
3468 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3470 PUSHS16(regs.pc); // Save all regs...
3479 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3480 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3482 // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
3483 // regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
3485 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
3488 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
3490 if (!flagF) // Is the FIRQ masked (F == 1)?
3493 if (disasm) WriteLog(" FIRQ taken...\n");
3495 flagE = 0; // Clear Entire flag
3496 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3501 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3502 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3504 // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3505 // regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
3508 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
3511 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
3513 if (!flagI) // Is the IRQ masked (I == 1)?
3516 if (disasm) WriteLog(" IRQ taken...\n");
3518 flagE = 1; // Set the Entire flag
3519 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3530 flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3531 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3533 // Apparently, not done here!
3534 // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3535 // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
3539 if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3540 (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
3541 (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
3542 regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3543 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
3544 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
3548 // Keep track of how much we overran so we can adjust on the next run...
3549 regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3551 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3552 myMemcpy(context, ®s, sizeof(V6809REGS));
3556 // Get the clock of the currently executing CPU
3558 uint64_t GetCurrentV6809Clock(void)
3564 // Get the PC of the currently executing CPU
3566 uint16_t GetCurrentV6809PC(void)
3571 // Set a line of the currently executing CPU
3572 void SetLineOfCurrentV6809(uint32_t line)
3574 regs.cpuFlags |= line;
3577 // Clear a line of the currently executing CPU
3578 void ClearLineOfCurrentV6809(uint32_t line)
3582 WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
3584 regs.cpuFlags &= ~line;
3588 FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
3589 E S=BFFF U=0000 PC=FEC0
3590 FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
3592 F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
3594 F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523
3595 F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526
3596 F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529
3597 F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
3598 F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D
3599 F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531
3600 F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD
3601 13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF
3602 13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2
3603 13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5
3604 13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7
3605 13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9
3606 13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB
3607 13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD
3608 13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF
3609 13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1
3610 13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3
3611 13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5
3612 13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000