5 // (C) 1997, 2009, 2014, 2023 Underground Software
7 // JLH = James 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
16 // JLH 01/03/2023 Added missing clock cycles to indexed memory accesses
21 #define TEST_DONT_BRANCH_OPTIMIZATION
25 #define CLR_Z (flagZ = 0)
26 #define CLR_ZN (flagZ = flagN = 0)
27 #define CLR_ZNC (flagZ = flagN = flagC = 0)
28 #define CLR_V (flagV = 0)
29 #define CLR_N (flagN = 0)
30 #define SET_Z(r) (flagZ = ((r) == 0 ? 1 : 0))
31 #define SET_N(r) (flagN = ((r) & 0x80) >> 7)
32 #define SET_N16(r) (flagN = ((r) & 0x8000) >> 15)
33 #define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
34 #define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
35 #define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4)
36 #define SET_ZN(r) SET_N(r); SET_Z(r)
37 #define SET_ZN16(r) SET_N16(r); SET_Z(r)
39 #define EA_IMM regs.pc++
40 #define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++)
41 #define EA_IDX DecodeIDX(regs.RdMem(regs.pc++))
42 #define EA_ABS FetchMemW(regs.pc)
44 #define READ_IMM regs.RdMem(EA_IMM)
45 #define READ_IMM16 FetchMemW(regs.pc)
46 #define READ_DP regs.RdMem(EA_DP)
47 #define READ_DP16 RdMemW(EA_DP)
48 #define READ_IDX regs.RdMem(EA_IDX)
49 #define READ_IDX16 RdMemW(EA_IDX)
50 #define READ_ABS regs.RdMem(EA_ABS)
51 #define READ_ABS16 RdMemW(EA_ABS)
53 #define READ_IMM_WB(v) uint16_t addr = EA_IMM; v = regs.RdMem(addr)
54 #define READ_DP_WB(v) uint16_t addr = EA_DP; v = regs.RdMem(addr)
55 #define READ_IDX_WB(v) uint16_t addr = EA_IDX; v = regs.RdMem(addr)
56 #define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr)
58 #define WRITE_BACK(d) regs.WrMem(addr, (d))
60 #define PULLS(r) r = regs.RdMem(regs.s++)
61 #define PUSHS(r) regs.WrMem(--regs.s, (r))
62 #define PULLS16(r) { r = RdMemW(regs.s); regs.s += 2; }
63 #define PUSHS16(r) { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
64 #define PULLU(r) r = regs.RdMem(regs.u++)
65 #define PUSHU(r) regs.WrMem(--regs.u, (r))
66 #define PULLU16(r) { r = RdMemW(regs.u); regs.u += 2; }
67 #define PUSHU16(r) { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
69 #define PACK_FLAGS ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
70 #define UNPACK_FLAGS flagE = (regs.cc & FLAG_E) >> 7; \
71 flagF = (regs.cc & FLAG_F) >> 6; \
72 flagH = (regs.cc & FLAG_H) >> 5; \
73 flagI = (regs.cc & FLAG_I) >> 4; \
74 flagN = (regs.cc & FLAG_N) >> 3; \
75 flagZ = (regs.cc & FLAG_Z) >> 2; \
76 flagV = (regs.cc & FLAG_V) >> 1; \
77 flagC = (regs.cc & FLAG_C)
79 // Private global variables
81 static V6809REGS regs;
82 static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
84 static const uint8_t page0Cycles[256] = {
85 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x
86 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x
87 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x
88 4, 4, 4, 4, 5, 5, 5, 5, 1, 5, 3, 6, 21, 11, 0, 19, // $3x
89 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, // $4x
90 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, // $5x
91 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $6x
92 7, 1, 1, 7, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 3, 7, // $7x
93 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, // $8x
94 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $9x
95 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $Ax
96 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, // $Bx
97 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, // $Cx
98 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Dx
99 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Ex
100 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx
103 static const uint8_t page1Cycles[256] = {
104 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
105 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
106 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x
107 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
108 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
112 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, // $8x
113 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $9x
114 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $Ax
115 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 7, 7, // $Bx
116 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, // $Cx
117 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Dx
118 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Ex
119 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx
122 static const uint8_t page2Cycles[256] = {
123 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
124 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
125 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x
126 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
127 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
129 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
131 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, // $8x
132 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $9x
133 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $Ax
134 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, // $Bx
135 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Cx
136 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Dx
137 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Ex
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx
141 // Cycle counts for PUL/PSHx instructions
142 static uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
144 // Private function prototypes
146 static uint16_t RdMemW(uint16_t addr);
147 static uint16_t FetchMemW(uint16_t addr);
148 static void WrMemW(uint16_t addr, uint16_t w);
149 static uint16_t ReadEXG(uint8_t); // Read TFR/EXG post byte
150 static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data
151 static uint16_t DecodeReg(uint8_t); // Decode register data
152 static uint16_t DecodeIDX(uint8_t); // Decode IDX data
155 // Read word from memory function
157 static inline uint16_t RdMemW(uint16_t addr)
159 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
163 // Fetch a word from memory function. Increments PC
165 static inline uint16_t FetchMemW(uint16_t addr)
168 return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
172 // Write word to memory function
174 static inline void WrMemW(uint16_t addr, uint16_t w)
176 regs.WrMem(addr + 0, w >> 8);
177 regs.WrMem(addr + 1, w & 0xFF);
181 // Function to read TFR/EXG post byte
183 static uint16_t ReadEXG(uint8_t code)
190 retval = (regs.a << 8) | regs.b;
228 // Function to set TFR/EXG data
230 static void WriteEXG(uint8_t code, uint16_t data)
235 regs.a = data >> 8, regs.b = data & 0xFF; break;
237 regs.x = data; break;
239 regs.y = data; break;
241 regs.u = data; break;
243 regs.s = data; break;
245 regs.pc = data; break;
247 regs.a = data & 0xFF; break;
249 regs.b = data & 0xFF; break;
251 regs.cc = data & 0xFF; UNPACK_FLAGS; break;
253 regs.dp = data & 0xFF; break;
258 // Function to decode register data
260 static uint16_t DecodeReg(uint8_t reg)
267 retval = regs.x; break;
269 retval = regs.y; break;
271 retval = regs.u; break;
273 retval = regs.s; break;
280 // Function to decode IDX data
282 static uint16_t DecodeIDX(uint8_t code)
285 Cycle counts are now taken into account here...
287 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
288 90 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
289 B0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
290 D0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
291 F0 5 6 5 6 3 4 4 0 4 7 0 7 4 8 0 5
293 80 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
294 A0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
295 C0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
296 E0 2 3 2 3 0 1 1 0 1 4 0 4 1 5 0 5
300 uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
302 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
304 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
314 woff = DecodeReg(reg);
318 case 0: regs.x += 2; break;
319 case 1: regs.y += 2; break;
320 case 2: regs.u += 2; break;
321 case 3: regs.s += 2; break;
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);
338 woff = DecodeReg(reg);
343 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
348 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
353 woff = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
358 woff = DecodeReg(reg) + FetchMemW(regs.pc);
363 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
368 // woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
370 // I believe this is the correct interpretation
371 offset = (int16_t)(int8_t)regs.RdMem(regs.pc++);
372 woff = regs.pc + offset;
374 woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
381 woff = regs.pc + FetchMemW(regs.pc);
386 woff = FetchMemW(regs.pc);
399 addr = DecodeReg(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;
410 addr = DecodeReg(reg);
413 case 0: regs.x += 2; break;
414 case 1: regs.y += 2; break;
415 case 2: regs.u += 2; break;
416 case 3: regs.s += 2; break;
423 case 0: regs.x--; break;
424 case 1: regs.y--; break;
425 case 2: regs.u--; break;
426 case 3: regs.s--; break;
428 addr = DecodeReg(reg);
434 case 0: regs.x -= 2; break;
435 case 1: regs.y -= 2; break;
436 case 2: regs.u -= 2; break;
437 case 3: regs.s -= 2; break;
439 addr = DecodeReg(reg);
443 addr = DecodeReg(reg);
446 addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b;
450 addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a;
454 addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++);
458 addr = DecodeReg(reg) + FetchMemW(regs.pc);
462 addr = DecodeReg(reg) + ((regs.a << 8) | regs.b);
466 // addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++);
468 // I believe this is the correct interpretation of the above
469 offset = (int16_t)(int8_t)regs.RdMem(regs.pc++);
470 addr = regs.pc + offset;
472 addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc);
478 addr = regs.pc + FetchMemW(regs.pc);
491 // 6809 OPCODE IMPLEMENTATION
493 // NOTE: Lots of macros are used here to save a LOT of typing. Also
494 // helps speed the debugging process. :-) Because of this, combining
495 // certain lines may look like a good idea but would end in disaster.
496 // You have been warned! ;-)
500 +-----------------------------------------------------------------+
501 | Opcode | | Addressing | | |
502 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
503 +------------+-------------+--------------+-------+-------+-------+
504 | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa |
505 | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa |
506 | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa |
507 | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa |
508 | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa |
509 | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa |
510 | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa |
511 | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa |
516 #define OP_ADC_HANDLER(m, acc) \
517 uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
518 flagC = (sum >> 8) & 0x01; \
519 SET_H(m, acc, sum); \
520 SET_V(m, acc, sum); \
524 static void Op89(void) // ADCA #
526 uint16_t m = READ_IMM;
527 OP_ADC_HANDLER(m, regs.a);
530 static void Op99(void) // ADCA DP
532 uint16_t m = READ_DP;
533 OP_ADC_HANDLER(m, regs.a);
536 static void OpA9(void) // ADCA IDX
538 uint16_t m = READ_IDX;
539 OP_ADC_HANDLER(m, regs.a);
542 static void OpB9(void) // ADCA ABS
544 uint16_t m = READ_ABS;
545 OP_ADC_HANDLER(m, regs.a);
548 static void OpC9(void) // ADCB #
550 uint16_t m = READ_IMM;
551 OP_ADC_HANDLER(m, regs.b);
554 static void OpD9(void) // ADCB DP
556 uint16_t m = READ_DP;
557 OP_ADC_HANDLER(m, regs.b);
560 static void OpE9(void) // ADCB IDX
562 uint16_t m = READ_IDX;
563 OP_ADC_HANDLER(m, regs.b);
566 static void OpF9(void) // ADCB ABS
568 uint16_t m = READ_ABS;
569 OP_ADC_HANDLER(m, regs.b);
573 +-----------------------------------------------------------------+
574 | Opcode | | Addressing | | |
575 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
576 +------------+-------------+--------------+-------+-------+-------+
577 | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- |
578 | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa |
579 | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa |
580 | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa |
581 | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa |
582 | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa |
583 | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa |
584 | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa |
585 | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa |
586 | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa |
587 | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa |
588 | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa |
589 | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa |
594 #define OP_ADD_HANDLER(m, acc) \
595 uint16_t sum = (uint16_t)(acc) + (m); \
596 flagC = (sum >> 8) & 0x01; \
597 SET_H(m, acc, sum); \
598 SET_V(m, acc, sum); \
599 (acc) = sum & 0xFF; \
602 #define OP_ADD_HANDLER16(m, hireg, loreg) \
603 uint32_t acc = (uint32_t)((hireg << 8) | loreg); \
604 uint32_t sum = acc + (m); \
605 flagC = (sum >> 16) & 0x01; \
606 SET_V16(m, acc, sum); \
607 acc = sum & 0xFFFF; \
608 hireg = (acc >> 8) & 0xFF; \
609 loreg = acc & 0xFF; \
612 static void Op3A(void) // ABX
614 regs.x += (uint16_t)regs.b;
617 static void Op8B(void) // ADDA #
619 uint16_t m = READ_IMM;
620 OP_ADD_HANDLER(m, regs.a);
623 static void Op9B(void) // ADDA DP
625 uint16_t m = READ_DP;
626 OP_ADD_HANDLER(m, regs.a);
629 static void OpAB(void) // ADDA IDX
631 uint16_t m = READ_IDX;
632 OP_ADD_HANDLER(m, regs.a);
635 static void OpBB(void) // ADDA ABS
637 uint16_t m = READ_ABS;
638 OP_ADD_HANDLER(m, regs.a);
641 static void OpC3(void) // ADDD #
643 uint32_t m = READ_IMM16;
644 OP_ADD_HANDLER16(m, regs.a, regs.b);
647 static void OpCB(void) // ADDB #
649 uint16_t m = READ_IMM;
650 OP_ADD_HANDLER(m, regs.b);
653 static void OpD3(void) // ADDD DP
655 uint32_t m = READ_DP16;
656 OP_ADD_HANDLER16(m, regs.a, regs.b);
659 static void OpDB(void) // ADDB DP
661 uint16_t m = READ_DP;
662 OP_ADD_HANDLER(m, regs.b);
665 static void OpE3(void) // ADDD IDX
667 uint32_t m = READ_IDX16;
668 OP_ADD_HANDLER16(m, regs.a, regs.b);
671 static void OpEB(void) // ADDB IDX
673 uint16_t m = READ_IDX;
674 OP_ADD_HANDLER(m, regs.b);
677 static void OpF3(void) // ADDD ABS
679 uint32_t m = READ_ABS16;
680 OP_ADD_HANDLER16(m, regs.a, regs.b);
683 static void OpFB(void) // ADDB ABS
685 uint16_t m = READ_ABS;
686 OP_ADD_HANDLER(m, regs.b);
690 +-----------------------------------------------------------------+
691 | Opcode | | Addressing | | |
692 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
693 +------------+-------------+--------------+-------+-------+-------+
694 | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- |
695 | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- |
696 | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- |
697 | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- |
698 | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- |
699 | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- |
700 | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- |
701 | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- |
706 #define OP_AND_HANDLER(m, acc) \
711 static void Op84(void) // ANDA #
713 uint16_t m = READ_IMM;
714 OP_AND_HANDLER(m, regs.a);
717 static void Op94(void) // ANDA DP
719 uint16_t m = READ_DP;
720 OP_AND_HANDLER(m, regs.a);
723 static void OpA4(void) // ANDA IDX
725 uint16_t m = READ_IDX;
726 OP_AND_HANDLER(m, regs.a);
729 static void OpB4(void) // ANDA ABS
731 uint16_t m = READ_ABS;
732 OP_AND_HANDLER(m, regs.a);
735 static void OpC4(void) // ANDB #
737 uint16_t m = READ_IMM;
738 OP_AND_HANDLER(m, regs.b);
741 static void OpD4(void) // ANDB DP
743 uint16_t m = READ_DP;
744 OP_AND_HANDLER(m, regs.b);
747 static void OpE4(void) // ANDB IDX
749 uint16_t m = READ_IDX;
750 OP_AND_HANDLER(m, regs.b);
753 static void OpF4(void) // ANDB ABS
755 uint16_t m = READ_ABS;
756 OP_AND_HANDLER(m, regs.b);
760 +-----------------------------------------------------------------+
761 | Opcode | | Addressing | | |
762 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
763 +------------+-------------+--------------+-------+-------+-------+
764 | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas |
765 | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas |
766 | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas |
767 | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas |
768 | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas |
773 #define OP_ASL_HANDLER(m) \
774 uint16_t res = m << 1; \
776 flagC = (res >> 8) & 0x01; \
780 static void Op08(void) // ASL DP
788 static void Op48(void) // ASLA
790 OP_ASL_HANDLER(regs.a);
793 static void Op58(void) // ASLB
795 OP_ASL_HANDLER(regs.b);
798 static void Op68(void) // ASL IDX
806 static void Op78(void) // ASL ABS
815 +-----------------------------------------------------------------+
816 | Opcode | | Addressing | | |
817 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
818 +------------+-------------+--------------+-------+-------+-------+
819 | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s |
820 | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s |
821 | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s |
822 | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s |
823 | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s |
826 // ASR opcodes (arithmetic, so preserves the sign)
828 #define OP_ASR_HANDLER(m) \
829 uint8_t res = (m & 0x80) | (m >> 1); \
834 static void Op07(void) // ASR DP
842 static void Op47(void) // ASRA
844 OP_ASR_HANDLER(regs.a);
847 static void Op57(void) // ASRB
849 OP_ASR_HANDLER(regs.b);
852 static void Op67(void) // ASR IDX
860 static void Op77(void) // ASR ABS
869 +-----------------------------------------------------------------+
870 | Opcode | | Addressing | | |
871 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
872 +------------+-------------+--------------+-------+-------+-------+
873 | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- |
874 | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- |
875 | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- |
876 | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- |
877 | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- |
878 | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- |
879 | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- |
880 | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- |
881 | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- |
882 | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- |
883 | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- |
884 | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- |
885 | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- |
886 | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- |
887 | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- |
888 | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- |
889 | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- |
890 | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- |
891 | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- |
892 | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- |
893 | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- |
894 | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- |
895 | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- |
896 | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- |
897 | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- |
898 | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- |
899 | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- |
900 | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- |
901 | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- |
902 | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- |
903 | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- |
904 | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- |
909 static void Op16(void) // LBRA
911 uint16_t offset = READ_IMM16;
915 static void Op20(void) // BRA
917 int16_t offset = (int16_t)(int8_t)READ_IMM;
921 static void Op21(void) // BRN
923 // This is basically a 2 byte NOP
924 int16_t offset = (int16_t)(int8_t)READ_IMM;
927 static void Op22(void) // BHI
930 int16_t offset = (int16_t)(int8_t)READ_IMM;
932 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
933 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
934 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
936 if (!(flagZ || flagC))
941 static void Op23(void) // BLS
944 int16_t offset = (int16_t)(int8_t)READ_IMM;
946 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
947 regs.pc += offset * (flagZ | flagC);
954 static void Op24(void) // BHS/CC
957 int16_t offset = (int16_t)(int8_t)READ_IMM;
959 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
960 regs.pc += offset * (flagC ^ 0x01);
967 static void Op25(void) // BLO/CS
970 int16_t offset = (int16_t)(int8_t)READ_IMM;
972 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
973 regs.pc += offset * flagC;
980 static void Op26(void) // BNE
983 int16_t offset = (int16_t)(int8_t)READ_IMM;
985 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
986 regs.pc += offset * (flagZ ^ 0x01);
993 static void Op27(void) // BEQ
996 int16_t offset = (int16_t)(int8_t)READ_IMM;
998 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
999 regs.pc += offset * flagZ;
1006 static void Op28(void) // BVC
1009 int16_t offset = (int16_t)(int8_t)READ_IMM;
1011 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1012 regs.pc += offset * (flagV ^ 0x01);
1019 static void Op29(void) // BVS
1022 int16_t offset = (int16_t)(int8_t)READ_IMM;
1024 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1025 regs.pc += offset * flagV;
1032 static void Op2A(void) // BPL
1035 int16_t offset = (int16_t)(int8_t)READ_IMM;
1037 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1038 regs.pc += offset * (flagN ^ 0x01);
1045 static void Op2B(void) // BMI
1048 int16_t offset = (int16_t)(int8_t)READ_IMM;
1050 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1051 regs.pc += offset * flagN;
1058 static void Op2C(void) // BGE
1060 // (N && V) || (!N && !V)
1061 int16_t offset = (int16_t)(int8_t)READ_IMM;
1063 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1064 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1066 if ((flagN && flagV) || (!flagN && !flagV))
1071 static void Op2D(void) // BLT
1073 // (N && !V) || (!N && V)
1074 int16_t offset = (int16_t)(int8_t)READ_IMM;
1076 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1077 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1079 if ((flagN && !flagV) || (!flagN && flagV))
1084 static void Op2E(void) // BGT
1086 // (N && V && !Z) || (!N && !V && !Z)
1087 int16_t offset = (int16_t)(int8_t)READ_IMM;
1089 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1090 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1092 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1097 static void Op2F(void) // BLE
1099 // Z || (N && !V) || (!N && V)
1100 int16_t offset = (int16_t)(int8_t)READ_IMM;
1102 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1103 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1105 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1110 static void Op1021(void) // LBRN
1112 // This is basically a 4 byte NOP
1113 uint16_t offset = READ_IMM16;
1116 static void Op1022(void) // LBHI
1119 uint16_t offset = READ_IMM16;
1121 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1122 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1123 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1125 if (!(flagZ || flagC))
1130 static void Op1023(void) // LBLS
1133 uint16_t offset = READ_IMM16;
1135 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1136 regs.pc += offset * (flagZ | flagC);
1143 static void Op1024(void) // LBHS/CC
1146 uint16_t offset = READ_IMM16;
1148 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1149 regs.pc += offset * (flagC ^ 0x01);
1156 static void Op1025(void) // LBLO/CS
1159 uint16_t offset = READ_IMM16;
1161 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1162 regs.pc += offset * flagC;
1169 static void Op1026(void) // LBNE
1172 uint16_t offset = READ_IMM16;
1174 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1175 regs.pc += offset * (flagZ ^ 0x01);
1182 static void Op1027(void) // LBEQ
1185 uint16_t offset = READ_IMM16;
1187 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1188 regs.pc += offset * flagZ;
1195 static void Op1028(void) // LBVC
1198 uint16_t offset = READ_IMM16;
1200 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1201 regs.pc += offset * (flagV ^ 0x01);
1208 static void Op1029(void) // LBVS
1211 uint16_t offset = READ_IMM16;
1213 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1214 regs.pc += offset * flagV;
1221 static void Op102A(void) // LBPL
1224 uint16_t offset = READ_IMM16;
1226 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1227 regs.pc += offset * (flagN ^ 0x01);
1234 static void Op102B(void) // LBMI
1237 uint16_t offset = READ_IMM16;
1239 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1240 regs.pc += offset * flagN;
1247 static void Op102C(void) // LBGE
1249 // (N && V) || (!N && !V)
1250 uint16_t offset = READ_IMM16;
1252 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1253 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1255 if ((flagN && flagV) || (!flagN && !flagV))
1260 static void Op102D(void) // LBLT
1262 // (N && !V) || (!N && V)
1263 uint16_t offset = READ_IMM16;
1265 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1266 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1268 if ((flagN && !flagV) || (!flagN && flagV))
1273 static void Op102E(void) // LBGT
1275 // (N && V && !Z) || (!N && !V && !Z)
1276 uint16_t offset = READ_IMM16;
1278 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1279 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1281 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1286 static void Op102F(void) // LBLE
1288 // Z || (N && !V) || (!N && V)
1289 uint16_t offset = READ_IMM16;
1291 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1292 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1294 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1300 +-----------------------------------------------------------------+
1301 | Opcode | | Addressing | | |
1302 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1303 +------------+-------------+--------------+-------+-------+-------+
1304 | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- |
1305 | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- |
1306 | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- |
1307 | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- |
1308 | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- |
1309 | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- |
1310 | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- |
1311 | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- |
1316 #define OP_BIT_HANDLER(m, acc) \
1317 uint8_t result = acc & (m); \
1321 static void Op85(void) // BITA #
1323 uint8_t m = READ_IMM;
1324 OP_BIT_HANDLER(m, regs.a);
1327 static void Op95(void) // BITA DP
1329 uint8_t m = READ_DP;
1330 OP_BIT_HANDLER(m, regs.a);
1333 static void OpA5(void) // BITA IDX
1335 uint8_t m = READ_IDX;
1336 OP_BIT_HANDLER(m, regs.a);
1339 static void OpB5(void) // BITA ABS
1341 uint8_t m = READ_ABS;
1342 OP_BIT_HANDLER(m, regs.a);
1345 static void OpC5(void) // BITB #
1347 uint8_t m = READ_IMM;
1348 OP_BIT_HANDLER(m, regs.b);
1351 static void OpD5(void) // BITB DP
1353 uint8_t m = READ_DP;
1354 OP_BIT_HANDLER(m, regs.b);
1357 static void OpE5(void) // BITB IDX
1359 uint8_t m = READ_IDX;
1360 OP_BIT_HANDLER(m, regs.b);
1363 static void OpF5(void) // BITB ABS
1365 uint8_t m = READ_ABS;
1366 OP_BIT_HANDLER(m, regs.b);
1370 +-----------------------------------------------------------------+
1371 | Opcode | | Addressing | | |
1372 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1373 +------------+-------------+--------------+-------+-------+-------+
1374 | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 |
1375 | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 |
1376 | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 |
1377 | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 |
1378 | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 |
1383 #define OP_CLR_HANDLER(m) \
1384 flagN = flagV = flagC = 0; \
1388 static void Op0F(void) // CLR DP
1396 static void Op4F(void) // CLRA
1398 OP_CLR_HANDLER(regs.a);
1401 static void Op5F(void) // CLRB
1403 OP_CLR_HANDLER(regs.b);
1406 static void Op6F(void) // CLR IDX
1414 static void Op7F(void) // CLR ABS
1423 +-----------------------------------------------------------------+
1424 | Opcode | | Addressing | | |
1425 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1426 +------------+-------------+--------------+-------+-------+-------+
1427 | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa |
1428 | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa |
1429 | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa |
1430 | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa |
1431 | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa |
1432 | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa |
1433 | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa |
1434 | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa |
1435 | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa |
1436 | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa |
1437 | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa |
1438 | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa |
1439 | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa |
1440 | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa |
1441 | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa |
1442 | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa |
1443 | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa |
1444 | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa |
1445 | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa |
1446 | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa |
1447 | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa |
1448 | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa |
1449 | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa |
1450 | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa |
1451 | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa |
1452 | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa |
1453 | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa |
1454 | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa |
1459 #define OP_CMP_HANDLER(m, acc) \
1460 uint16_t sum = (uint16_t)(acc) - (m); \
1461 flagC = (sum >> 8) & 0x01; \
1462 SET_V(m, acc, sum); \
1465 #define OP_CMP_HANDLER16(m, acc) \
1466 uint32_t sum = (uint32_t)(acc) - (m); \
1467 flagC = (sum >> 16) & 0x01; \
1468 SET_V16(m, acc, sum); \
1471 static void Op81(void) // CMPA #
1473 uint8_t m = READ_IMM;
1474 OP_CMP_HANDLER(m, regs.a);
1477 static void Op8C(void) // CMPX #
1479 uint16_t m = READ_IMM16;
1480 OP_CMP_HANDLER16(m, regs.x);
1483 static void Op91(void) // CMPA DP
1485 uint8_t m = READ_DP;
1486 OP_CMP_HANDLER(m, regs.a);
1489 static void Op9C(void) // CMPX DP
1491 uint16_t m = READ_DP16;
1492 OP_CMP_HANDLER16(m, regs.x);
1495 static void OpA1(void) // CMPA IDX
1497 uint8_t m = READ_IDX;
1498 OP_CMP_HANDLER(m, regs.a);
1501 static void OpAC(void) // CMPX IDX
1503 uint16_t m = READ_IDX16;
1504 OP_CMP_HANDLER16(m, regs.x);
1507 static void OpB1(void) // CMPA ABS
1509 uint8_t m = READ_ABS;
1510 OP_CMP_HANDLER(m, regs.a);
1513 static void OpBC(void) // CMPX ABS
1515 uint16_t m = READ_ABS16;
1516 OP_CMP_HANDLER16(m, regs.x);
1519 static void OpC1(void) // CMPB #
1521 uint8_t m = READ_IMM;
1522 OP_CMP_HANDLER(m, regs.b);
1525 static void OpD1(void) // CMPB DP
1527 uint8_t m = READ_DP;
1528 OP_CMP_HANDLER(m, regs.b);
1531 static void OpE1(void) // CMPB IDX
1533 uint8_t m = READ_IDX;
1534 OP_CMP_HANDLER(m, regs.b);
1537 static void OpF1(void) // CMPB ABS
1539 uint8_t m = READ_ABS;
1540 OP_CMP_HANDLER(m, regs.b);
1543 static void Op1083(void) // CMPD #
1545 uint16_t m = READ_IMM16;
1546 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1549 static void Op108C(void) // CMPY #
1551 uint16_t m = READ_IMM16;
1552 OP_CMP_HANDLER16(m, regs.y);
1555 static void Op1093(void) // CMPD DP
1557 uint16_t m = READ_DP16;
1558 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1561 static void Op109C(void) // CMPY DP
1563 uint16_t m = READ_DP16;
1564 OP_CMP_HANDLER16(m, regs.y);
1567 static void Op10A3(void) // CMPD IDX
1569 uint16_t m = READ_IDX16;
1570 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1573 static void Op10AC(void) // CMPY IDX
1575 uint16_t m = READ_IDX16;
1576 OP_CMP_HANDLER16(m, regs.y);
1579 static void Op10B3(void) // CMPD ABS
1581 uint16_t m = READ_ABS16;
1582 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1585 static void Op10BC(void) // CMPY ABS
1587 uint16_t m = READ_ABS16;
1588 OP_CMP_HANDLER16(m, regs.y);
1591 static void Op1183(void) // CMPU #
1593 uint16_t m = READ_IMM16;
1594 OP_CMP_HANDLER16(m, regs.u);
1597 static void Op118C(void) // CMPS #
1599 uint16_t m = READ_IMM16;
1600 OP_CMP_HANDLER16(m, regs.s);
1603 static void Op1193(void) // CMPU DP
1605 uint16_t m = READ_DP16;
1606 OP_CMP_HANDLER16(m, regs.u);
1609 static void Op119C(void) // CMPS DP
1611 uint16_t m = READ_DP16;
1612 OP_CMP_HANDLER16(m, regs.s);
1615 static void Op11A3(void) // CMPU IDX
1617 uint16_t m = READ_IDX16;
1618 OP_CMP_HANDLER16(m, regs.u);
1621 static void Op11AC(void) // CMPS IDX
1623 uint16_t m = READ_IDX16;
1624 OP_CMP_HANDLER16(m, regs.s);
1627 static void Op11B3(void) // CMPU ABS
1629 uint16_t m = READ_ABS16;
1630 OP_CMP_HANDLER16(m, regs.u);
1633 static void Op11BC(void) // CMPS ABS
1635 uint16_t m = READ_ABS16;
1636 OP_CMP_HANDLER16(m, regs.s);
1640 +-----------------------------------------------------------------+
1641 | Opcode | | Addressing | | |
1642 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1643 +------------+-------------+--------------+-------+-------+-------+
1644 | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 |
1645 | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 |
1646 | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 |
1647 | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 |
1648 | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 |
1653 #define OP_COM_HANDLER(m) \
1659 static void Op03(void) // COM DP
1667 static void Op43(void) // COMA
1669 OP_COM_HANDLER(regs.a);
1672 static void Op53(void) // COMB
1674 OP_COM_HANDLER(regs.b);
1677 static void Op63(void) // COM IDX
1685 static void Op73(void) // COM ABS
1694 +-----------------------------------------------------------------+
1695 | Opcode | | Addressing | | |
1696 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1697 +------------+-------------+--------------+-------+-------+-------+
1698 | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- |
1699 | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd |
1700 | 3E 0062 | RESET* | INHERENT | * | 1 | ***** |
1701 | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- |
1702 | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- |
1703 | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- |
1706 static void Op13(void) // SYNC
1708 #warning "!!! SYNC not implemented !!!"
1710 /* SYNC stops processing instructions until an interrupt request happens. */
1711 /* This doesn't require the corresponding interrupt to be enabled: if it */
1712 /* is disabled, execution continues with the next instruction. */
1713 m68_state->int_state |= M6809_SYNC; /* HJB 990227 */
1714 check_irq_lines(m68_state);
1715 /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1716 * stop execution until the interrupt lines change. */
1717 if( m68_state->int_state & M6809_SYNC )
1718 if (m68_state->icount > 0) m68_state->icount = 0;
1722 static void Op3C(void) // CWAI
1724 #warning "!!! CWAI not implemented !!!"
1730 * CWAI stacks the entire machine state on the hardware stack,
1731 * then waits for an interrupt; when the interrupt is taken
1732 * later, the state is *not* saved again after CWAI.
1734 CC |= CC_E; /* HJB 990225: save entire state */
1743 m68_state->int_state |= M6809_CWAI; /* HJB 990228 */
1744 check_irq_lines(m68_state); /* HJB 990116 */
1745 if( m68_state->int_state & M6809_CWAI )
1746 if( m68_state->icount > 0 )
1747 m68_state->icount = 0;
1751 static void Op3E(void) // RESET
1753 regs.cpuFlags |= V6809_LINE_RESET;
1756 static void Op3F(void) // SWI
1759 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1769 regs.pc = RdMemW(0xFFFA);
1772 static void Op103F(void) // SWI2
1775 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1784 regs.pc = RdMemW(0xFFF4);
1787 static void Op113F(void) // SWI3
1790 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1799 regs.pc = RdMemW(0xFFF2);
1803 +-----------------------------------------------------------------+
1804 | Opcode | | Addressing | | |
1805 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1806 +------------+-------------+--------------+-------+-------+-------+
1807 | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
1808 | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
1809 | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
1810 | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
1811 | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
1814 static void Op12() // NOP
1818 static void Op19() // DAA
1820 uint16_t result = (uint16_t)regs.a;
1822 if ((regs.a & 0x0F) > 0x09 || flagH)
1825 if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1828 regs.a = (uint8_t)result;
1831 flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
1834 static void Op1A() // ORCC
1836 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1837 regs.cc |= READ_IMM;
1838 UNPACK_FLAGS; // & unmash 'em
1841 static void Op1C() // ANDCC
1843 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1844 regs.cc &= READ_IMM;
1845 UNPACK_FLAGS; // & unmash 'em
1848 static void Op1D() // SEX
1850 regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1851 SET_ZN16((regs.a << 8) | regs.b);
1856 +-----------------------------------------------------------------+
1857 | Opcode | | Addressing | | |
1858 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1859 +------------+-------------+--------------+-------+-------+-------+
1860 | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- |
1861 | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- |
1862 | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- |
1863 | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- |
1864 | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- |
1867 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1869 #define OP_DEC_HANDLER(m) \
1872 flagV = (m == 0x7F ? 1 : 0)
1874 static void Op0A(void) // DEC DP
1882 static void Op4A(void) // DECA
1884 OP_DEC_HANDLER(regs.a);
1887 static void Op5A(void) // DECB
1889 OP_DEC_HANDLER(regs.b);
1892 static void Op6A(void) // DEC IDX
1900 static void Op7A(void) // DEC ABS
1909 +-----------------------------------------------------------------+
1910 | Opcode | | Addressing | | |
1911 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1912 +------------+-------------+--------------+-------+-------+-------+
1913 | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- |
1914 | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- |
1915 | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- |
1916 | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- |
1917 | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- |
1918 | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- |
1919 | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- |
1920 | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- |
1925 #define OP_EOR_HANDLER(m, acc) \
1930 static void Op88(void) // EORA #
1932 uint8_t m = READ_IMM;
1933 OP_EOR_HANDLER(m, regs.a);
1936 static void Op98(void) // EORA DP
1938 uint8_t m = READ_DP;
1939 OP_EOR_HANDLER(m, regs.a);
1942 static void OpA8(void) // EORA IDX
1944 uint8_t m = READ_IDX;
1945 OP_EOR_HANDLER(m, regs.a);
1948 static void OpB8(void) // EORA ABS
1950 uint8_t m = READ_ABS;
1951 OP_EOR_HANDLER(m, regs.a);
1954 static void OpC8(void) // EORB #
1956 uint8_t m = READ_IMM;
1957 OP_EOR_HANDLER(m, regs.b);
1960 static void OpD8(void) // EORB DP
1962 uint8_t m = READ_DP;
1963 OP_EOR_HANDLER(m, regs.b);
1966 static void OpE8(void) // EORB IDX
1968 uint8_t m = READ_IDX;
1969 OP_EOR_HANDLER(m, regs.b);
1972 static void OpF8(void) // EORB ABS
1974 uint8_t m = READ_ABS;
1975 OP_EOR_HANDLER(m, regs.b);
1979 +-----------------------------------------------------------------+
1980 | Opcode | | Addressing | | |
1981 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1982 +------------+-------------+--------------+-------+-------+-------+
1983 | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- |
1984 | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- |
1985 | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- |
1986 | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- |
1987 | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- |
1990 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1992 #define OP_INC_HANDLER(m) \
1995 flagV = (m == 0x80 ? 1 : 0)
1997 static void Op0C(void) // INC DP
2005 static void Op4C(void) // INCA
2007 OP_INC_HANDLER(regs.a);
2010 static void Op5C(void) // INCB
2012 OP_INC_HANDLER(regs.b);
2015 static void Op6C(void) // INC IDX
2023 static void Op7C(void) // INC ABS
2032 +-----------------------------------------------------------------+
2033 | Opcode | | Addressing | | |
2034 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2035 +------------+-------------+--------------+-------+-------+-------+
2036 | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- |
2037 | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- |
2038 | 39 0057 | RTS | INHERENT | 5 | 1 | ----- |
2039 | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- |
2040 | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- |
2041 | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- |
2042 | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- |
2043 | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- |
2044 | AD 0173 | JSR | INDEXED | 7 | 2 | ----- |
2045 | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- |
2048 static void Op0E(void) // JMP DP
2050 // This needs to be separate because of the EA_DP adding to regs.pc.
2055 static void Op17(void) // LBSR
2057 uint16_t word = FetchMemW(regs.pc);
2062 static void Op39(void) // RTS
2067 static void Op3B(void) // RTI
2072 // If E flag set, pull all regs
2087 static void Op6E(void) // JMP IDX
2092 static void Op7E(void) // JMP ABS
2097 static void Op8D(void) // BSR
2099 uint16_t word = (int16_t)(int8_t)READ_IMM;
2104 static void Op9D(void) // JSR DP
2106 uint16_t word = EA_DP;
2111 static void OpAD(void) // JSR IDX
2113 uint16_t word = EA_IDX;
2118 static void OpBD(void) // JSR ABS
2120 uint16_t word = EA_ABS;
2126 +-----------------------------------------------------------------+
2127 | Opcode | | Addressing | | |
2128 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2129 +------------+-------------+--------------+-------+-------+-------+
2130 | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
2131 | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
2134 static void Op1E(void) // EXG
2136 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2138 uint8_t m = READ_IMM;
2139 uint8_t reg1 = m >> 4, reg2 = m & 0x0F;
2140 uint16_t acc1 = ReadEXG(reg1);
2141 uint16_t acc2 = ReadEXG(reg2);
2143 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2144 if (((m >> 4) ^ m) & 0x08)
2147 WriteEXG(reg1, acc2);
2148 WriteEXG(reg2, acc1);
2151 static void Op1F(void) // TFR
2153 uint8_t m = READ_IMM;
2154 uint16_t acc = ReadEXG(m >> 4);
2156 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2157 if (((m >> 4) ^ m) & 0x08)
2160 WriteEXG(m & 0x0F, acc);
2164 +-----------------------------------------------------------------+
2165 | Opcode | | Addressing | | |
2166 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2167 +------------+-------------+--------------+-------+-------+-------+
2168 | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
2169 | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
2170 | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
2171 | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
2172 | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
2173 | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
2174 | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
2175 | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
2176 | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
2177 | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
2178 | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
2179 | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
2180 | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
2181 | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
2182 | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
2183 | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
2184 | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
2185 | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
2186 | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
2187 | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
2188 | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
2189 | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
2190 | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
2191 | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
2192 | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
2193 | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
2194 | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
2195 | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
2200 #define OP_LDA_HANDLER(m, acc) \
2205 #define OP_LDA_HANDLER16(m, acc) \
2210 #define OP_LDA_HANDLER16D(m) \
2211 regs.a = (m >> 8); \
2212 regs.b = m & 0xFF; \
2216 static void Op86(void) // LDA #
2218 uint8_t m = READ_IMM;
2219 OP_LDA_HANDLER(m, regs.a);
2222 static void Op8E(void) // LDX #
2224 uint16_t m = READ_IMM16;
2225 OP_LDA_HANDLER16(m, regs.x);
2228 static void Op96(void) // LDA DP
2230 uint8_t m = READ_DP;
2231 OP_LDA_HANDLER(m, regs.a);
2234 static void Op9E(void) // LDX DP
2236 uint16_t m = READ_DP16;
2237 OP_LDA_HANDLER16(m, regs.x);
2240 static void OpA6(void) // LDA IDX
2242 uint8_t m = READ_IDX;
2243 OP_LDA_HANDLER(m, regs.a);
2246 static void OpAE(void) // LDX IDX
2248 uint16_t m = READ_IDX16;
2249 OP_LDA_HANDLER16(m, regs.x);
2252 static void OpB6(void) // LDA ABS
2254 uint8_t m = READ_ABS;
2255 OP_LDA_HANDLER(m, regs.a);
2258 static void OpBE(void) // LDX ABS
2260 uint16_t m = READ_ABS16;
2261 OP_LDA_HANDLER16(m, regs.x);
2264 static void OpC6(void) // LDB #
2266 uint8_t m = READ_IMM;
2267 OP_LDA_HANDLER(m, regs.b);
2270 static void OpCC(void) // LDD #
2272 uint16_t m = READ_IMM16;
2273 OP_LDA_HANDLER16D(m);
2276 static void OpCE(void) // LDU #
2278 uint16_t m = READ_IMM16;
2279 OP_LDA_HANDLER16(m, regs.u);
2282 static void OpD6(void) // LDB DP
2284 uint8_t m = READ_DP;
2285 OP_LDA_HANDLER(m, regs.b);
2288 static void OpDC(void) // LDD DP
2290 uint16_t m = READ_DP16;
2291 OP_LDA_HANDLER16D(m);
2294 static void OpDE(void) // LDU DP
2296 uint16_t m = READ_DP16;
2297 OP_LDA_HANDLER16(m, regs.u);
2300 static void OpE6(void) // LDB IDX
2302 uint8_t m = READ_IDX;
2303 OP_LDA_HANDLER(m, regs.b);
2306 static void OpEC(void) // LDD IDX
2308 uint16_t m = READ_IDX16;
2309 OP_LDA_HANDLER16D(m);
2312 static void OpEE(void) // LDU IDX
2314 uint16_t m = READ_IDX16;
2315 OP_LDA_HANDLER16(m, regs.u);
2318 static void OpF6(void) // LDB ABS
2320 uint8_t m = READ_ABS;
2321 OP_LDA_HANDLER(m, regs.b);
2324 static void OpFC(void) // LDD ABS
2326 uint16_t m = READ_ABS16;
2327 OP_LDA_HANDLER16D(m);
2330 static void OpFE(void) // LDU ABS
2332 uint16_t m = READ_ABS16;
2333 OP_LDA_HANDLER16(m, regs.u);
2336 static void Op108E(void) // LDY #
2338 uint16_t m = READ_IMM16;
2339 OP_LDA_HANDLER16(m, regs.y);
2342 static void Op109E(void) // LDY DP
2344 uint16_t m = READ_DP16;
2345 OP_LDA_HANDLER16(m, regs.y);
2348 static void Op10AE(void) // LDY IDX
2350 uint16_t m = READ_IDX16;
2351 OP_LDA_HANDLER16(m, regs.y);
2354 static void Op10BE(void) // LDY ABS
2356 uint16_t m = READ_ABS16;
2357 OP_LDA_HANDLER16(m, regs.y);
2360 static void Op10CE(void) // LDS #
2362 uint16_t m = READ_IMM16;
2363 OP_LDA_HANDLER16(m, regs.s);
2366 static void Op10DE(void) // LDS DP
2368 uint16_t m = READ_DP16;
2369 OP_LDA_HANDLER16(m, regs.s);
2372 static void Op10EE(void) // LDS IDX
2374 uint16_t m = READ_IDX16;
2375 OP_LDA_HANDLER16(m, regs.s);
2378 static void Op10FE(void) // LDS ABS
2380 uint16_t m = READ_ABS16;
2381 OP_LDA_HANDLER16(m, regs.s);
2385 +-----------------------------------------------------------------+
2386 | Opcode | | Addressing | | |
2387 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2388 +------------+-------------+--------------+-------+-------+-------+
2389 | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- |
2390 | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- |
2391 | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- |
2392 | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- |
2395 static void Op30(void) // LEAX
2401 static void Op31(void) // LEAY
2407 static void Op32(void) // LEAS
2412 static void Op33(void) // LEAU
2418 +-----------------------------------------------------------------+
2419 | Opcode | | Addressing | | |
2420 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2421 +------------+-------------+--------------+-------+-------+-------+
2422 | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s |
2423 | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s |
2424 | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s |
2425 | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s |
2426 | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s |
2431 #define OP_LSR_HANDLER(m) \
2436 static void Op04(void) // LSR DP
2444 static void Op44(void) // LSRA
2446 OP_LSR_HANDLER(regs.a);
2449 static void Op54(void) // LSRB
2451 OP_LSR_HANDLER(regs.b);
2454 static void Op64(void) // LSR IDX
2462 static void Op74(void) // LSR ABS
2471 +-----------------------------------------------------------------+
2472 | Opcode | | Addressing | | |
2473 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2474 +------------+-------------+--------------+-------+-------+-------+
2475 | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a |
2478 static void Op3D(void) // MUL
2480 uint16_t prod = regs.a * regs.b;
2482 regs.b = prod & 0xFF;
2484 // flagC = (prod & 0x0080 ? 1 : 0);
2485 flagC = (prod >> 7) & 0x01;
2489 +-----------------------------------------------------------------+
2490 | Opcode | | Addressing | | |
2491 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2492 +------------+-------------+--------------+-------+-------+-------+
2493 | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa |
2494 | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa |
2495 | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa |
2496 | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa |
2497 | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa |
2502 #define OP_NEG_HANDLER(m) \
2506 flagC = (res >= 0x80 ? 1 : 0); \
2509 static void Op00(void) // NEG DP
2517 static void Op40(void) // NEGA
2519 OP_NEG_HANDLER(regs.a);
2522 static void Op50(void) // NEGB
2524 OP_NEG_HANDLER(regs.b);
2527 static void Op60(void) // NEG IDX
2535 static void Op70(void) // NEG ABS
2544 +-----------------------------------------------------------------+
2545 | Opcode | | Addressing | | |
2546 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2547 +------------+-------------+--------------+-------+-------+-------+
2548 | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- |
2549 | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- |
2550 | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- |
2551 | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- |
2552 | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- |
2553 | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- |
2554 | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- |
2555 | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- |
2560 #define OP_OR_HANDLER(m, acc) \
2565 static void Op8A(void) // ORA #
2567 uint8_t m = READ_IMM;
2568 OP_OR_HANDLER(m, regs.a);
2571 static void Op9A(void) // ORA DP
2573 uint8_t m = READ_DP;
2574 OP_OR_HANDLER(m, regs.a);
2577 static void OpAA(void) // ORA IDX
2579 uint8_t m = READ_IDX;
2580 OP_OR_HANDLER(m, regs.a);
2583 static void OpBA(void) // ORA ABS
2585 uint8_t m = READ_ABS;
2586 OP_OR_HANDLER(m, regs.a);
2589 static void OpCA(void) // ORB #
2591 uint8_t m = READ_IMM;
2592 OP_OR_HANDLER(m, regs.b);
2595 static void OpDA(void) // ORB DP
2597 uint8_t m = READ_DP;
2598 OP_OR_HANDLER(m, regs.b);
2601 static void OpEA(void) // ORB IDX
2603 uint8_t m = READ_IDX;
2604 OP_OR_HANDLER(m, regs.b);
2607 static void OpFA(void) // ORB ABS
2609 uint8_t m = READ_ABS;
2610 OP_OR_HANDLER(m, regs.b);
2614 +-----------------------------------------------------------------+
2615 | Opcode | | Addressing | | |
2616 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2617 +------------+-------------+--------------+-------+-------+-------+
2618 | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- |
2619 | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc |
2620 | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- |
2621 | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc |
2624 static void Op34(void) // PSHS
2626 uint8_t m = READ_IMM;
2644 regs.cc = PACK_FLAGS;
2648 // Count bits in each nybble to come up with correct cycle counts...
2649 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2652 static void Op35(void) // PULS
2654 uint8_t m = READ_IMM;
2676 // Count bits in each nybble to come up with correct cycle counts...
2677 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2680 static void Op36(void) // PHSU
2682 uint8_t m = READ_IMM;
2700 regs.cc = PACK_FLAGS;
2704 // Count bits in each nybble to come up with correct cycle counts...
2705 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2708 static void Op37(void) // PULU
2710 uint8_t m = READ_IMM;
2732 // Count bits in each nybble to come up with correct cycle counts...
2733 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2737 +-----------------------------------------------------------------+
2738 | Opcode | | Addressing | | |
2739 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2740 +------------+-------------+--------------+-------+-------+-------+
2741 | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas |
2742 | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas |
2743 | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas |
2744 | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas |
2745 | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas |
2750 #define OP_ROL_HANDLER(m) \
2751 uint8_t res = (m << 1) | flagC; \
2754 flagC = (m >> 7) & 0x01; \
2757 static void Op09(void) // ROL DP
2765 static void Op49(void) // ROLA
2767 OP_ROL_HANDLER(regs.a);
2770 static void Op59(void) // ROLB
2772 OP_ROL_HANDLER(regs.b);
2775 static void Op69(void) // ROL IDX
2783 static void Op79(void) // ROL ABS
2792 +-----------------------------------------------------------------+
2793 | Opcode | | Addressing | | |
2794 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2795 +------------+-------------+--------------+-------+-------+-------+
2796 | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s |
2797 | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s |
2798 | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s |
2799 | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s |
2800 | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s |
2805 #define OP_ROR_HANDLER(m) \
2806 uint8_t res = (flagC << 7) | (m >> 1); \
2812 static void Op06(void) // ROR DP
2820 static void Op46(void) // RORA
2822 OP_ROR_HANDLER(regs.a);
2825 static void Op56(void) // RORB
2827 OP_ROR_HANDLER(regs.b);
2830 static void Op66(void) // ROR IDX
2838 static void Op76(void) // ROR ABS
2847 +-----------------------------------------------------------------+
2848 | Opcode | | Addressing | | |
2849 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2850 +------------+-------------+--------------+-------+-------+-------+
2851 | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
2852 | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
2853 | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
2854 | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
2855 | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
2856 | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
2857 | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
2858 | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
2863 #define OP_SBC_HANDLER(m, acc) \
2864 uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
2865 flagC = (sum >> 8) & 0x01; \
2866 SET_V(m, acc, sum); \
2867 acc = (uint8_t)sum; \
2870 static void Op82(void) // SBCA #
2872 uint8_t m = READ_IMM;
2873 OP_SBC_HANDLER(m, regs.a);
2876 static void Op92(void) // SBCA DP
2878 uint8_t m = READ_DP;
2879 OP_SBC_HANDLER(m, regs.a);
2882 static void OpA2(void) // SBCA IDX
2884 uint8_t m = READ_IDX;
2885 OP_SBC_HANDLER(m, regs.a);
2888 static void OpB2(void) // SBCA ABS
2890 uint8_t m = READ_ABS;
2891 OP_SBC_HANDLER(m, regs.a);
2894 static void OpC2(void) // SBCB #
2896 uint8_t m = READ_IMM;
2897 OP_SBC_HANDLER(m, regs.b);
2900 static void OpD2(void) // SBCB DP
2902 uint8_t m = READ_DP;
2903 OP_SBC_HANDLER(m, regs.b);
2906 static void OpE2(void) // SBCB IDX
2908 uint8_t m = READ_IDX;
2909 OP_SBC_HANDLER(m, regs.b);
2912 static void OpF2(void) // SBCB ABS
2914 uint8_t m = READ_ABS;
2915 OP_SBC_HANDLER(m, regs.b);
2919 +-----------------------------------------------------------------+
2920 | Opcode | | Addressing | | |
2921 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2922 +------------+-------------+--------------+-------+-------+-------+
2923 | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- |
2924 | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- |
2925 | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- |
2926 | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- |
2927 | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- |
2928 | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- |
2929 | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- |
2930 | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- |
2931 | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- |
2932 | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- |
2933 | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- |
2934 | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- |
2935 | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- |
2936 | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- |
2937 | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- |
2938 | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- |
2939 | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- |
2940 | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- |
2941 | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- |
2942 | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- |
2943 | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- |
2948 #define OP_STA_HANDLER(m, acc) \
2949 regs.WrMem(m, acc); \
2953 #define OP_STA_HANDLER16(m, acc) \
2958 static void Op97(void) // STA DP
2960 uint16_t addr = EA_DP;
2961 OP_STA_HANDLER(addr, regs.a);
2964 static void Op9F(void) // STX DP
2966 uint16_t addr = EA_DP;
2967 OP_STA_HANDLER16(addr, regs.x);
2970 static void OpA7(void) // STA IDX
2972 uint16_t addr = EA_IDX;
2973 OP_STA_HANDLER(addr, regs.a);
2976 static void OpAF(void) // STX IDX
2978 uint16_t addr = EA_IDX;
2979 OP_STA_HANDLER16(addr, regs.x);
2982 static void OpB7(void) // STA ABS
2984 uint16_t addr = EA_ABS;
2985 OP_STA_HANDLER(addr, regs.a);
2988 static void OpBF(void) // STX ABS
2990 uint16_t addr = EA_ABS;
2991 OP_STA_HANDLER16(addr, regs.x);
2994 static void OpD7(void) // STB DP
2996 uint16_t addr = EA_DP;
2997 OP_STA_HANDLER(addr, regs.b);
3000 static void OpDD(void) // STD DP
3002 uint16_t addr = EA_DP;
3003 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3006 static void OpDF(void) // STU DP
3008 uint16_t addr = EA_DP;
3009 OP_STA_HANDLER16(addr, regs.u);
3012 static void OpE7(void) // STB IDX
3014 uint16_t addr = EA_IDX;
3015 OP_STA_HANDLER(addr, regs.b);
3018 static void OpED(void) // STD IDX
3020 uint16_t addr = EA_IDX;
3021 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3024 static void OpEF(void) // STU IDX
3026 uint16_t addr = EA_IDX;
3027 OP_STA_HANDLER16(addr, regs.u);
3030 static void OpF7(void) // STB ABS
3032 uint16_t addr = EA_ABS;
3033 OP_STA_HANDLER(addr, regs.b);
3036 static void OpFD(void) // STD ABS
3038 uint16_t addr = EA_ABS;
3039 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3042 static void OpFF(void) // STU ABS
3044 uint16_t addr = EA_ABS;
3045 OP_STA_HANDLER16(addr, regs.u);
3048 static void Op109F(void) // STY DP
3050 uint16_t addr = EA_DP;
3051 OP_STA_HANDLER16(addr, regs.y);
3054 static void Op10AF(void) // STY IDX
3056 uint16_t addr = EA_IDX;
3057 OP_STA_HANDLER16(addr, regs.y);
3060 static void Op10BF(void) // STY ABS
3062 uint16_t addr = EA_ABS;
3063 OP_STA_HANDLER16(addr, regs.y);
3066 static void Op10DF(void) // STS DP
3068 uint16_t addr = EA_DP;
3069 OP_STA_HANDLER16(addr, regs.s);
3072 static void Op10EF(void) // STS IDX
3074 uint16_t addr = EA_IDX;
3075 OP_STA_HANDLER16(addr, regs.s);
3078 static void Op10FF(void) // STS ABS
3080 uint16_t addr = EA_ABS;
3081 OP_STA_HANDLER16(addr, regs.s);
3085 +-----------------------------------------------------------------+
3086 | Opcode | | Addressing | | |
3087 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3088 +------------+-------------+--------------+-------+-------+-------+
3089 | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
3090 | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
3091 | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
3092 | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
3093 | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
3094 | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
3095 | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
3096 | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
3097 | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
3098 | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
3099 | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
3100 | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
3105 #define OP_SUB_HANDLER(m, acc) \
3106 uint16_t sum = (uint16_t)acc - (m); \
3107 flagC = (sum >> 8) & 0x01; \
3108 SET_V(m, acc, sum); \
3109 acc = (uint8_t)sum; \
3112 #define OP_SUB_HANDLER16D(m) \
3113 uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \
3114 uint32_t sum = acc - (m); \
3115 flagC = (sum >> 16) & 0x01; \
3116 SET_V16(m, acc, sum); \
3117 acc = sum & 0xFFFF; \
3118 regs.a = (acc >> 8) & 0xFF; \
3119 regs.b = acc & 0xFF; \
3122 static void Op80(void) // SUBA #
3124 uint8_t m = READ_IMM;
3125 OP_SUB_HANDLER(m, regs.a);
3128 static void Op83(void) // SUBD #
3130 uint16_t m = READ_IMM16;
3131 OP_SUB_HANDLER16D(m);
3134 static void Op90(void) // SUBA DP
3136 uint8_t m = READ_DP;
3137 OP_SUB_HANDLER(m, regs.a);
3140 static void Op93(void) // SUBD DP
3142 uint16_t m = READ_DP16;
3143 OP_SUB_HANDLER16D(m);
3146 static void OpA0(void) // SUBA IDX
3148 uint8_t m = READ_IDX;
3149 OP_SUB_HANDLER(m, regs.a);
3152 static void OpA3(void) // SUBD IDX
3154 uint16_t m = READ_IDX16;
3155 OP_SUB_HANDLER16D(m);
3158 static void OpB0(void) // SUBA ABS
3160 uint8_t m = READ_ABS;
3161 OP_SUB_HANDLER(m, regs.a);
3164 static void OpB3(void) // SUBD ABS
3166 uint16_t m = READ_ABS16;
3167 OP_SUB_HANDLER16D(m);
3170 static void OpC0(void) // SUBB #
3172 uint8_t m = READ_IMM;
3173 OP_SUB_HANDLER(m, regs.b);
3176 static void OpD0(void) // SUBB DP
3178 uint8_t m = READ_DP;
3179 OP_SUB_HANDLER(m, regs.b);
3182 static void OpE0(void) // SUBB IDX
3184 uint8_t m = READ_IDX;
3185 OP_SUB_HANDLER(m, regs.b);
3188 static void OpF0(void) // SUBB ABS
3190 uint8_t m = READ_ABS;
3191 OP_SUB_HANDLER(m, regs.b);
3195 +-----------------------------------------------------------------+
3196 | Opcode | | Addressing | | |
3197 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3198 +------------+-------------+--------------+-------+-------+-------+
3199 | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
3200 | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
3201 | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
3202 | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
3203 | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
3208 #define OP_TST_HANDLER(m) \
3212 static void Op0D(void) // TST DP
3214 uint8_t m = READ_DP;
3218 static void Op4D(void) // TSTA
3220 OP_TST_HANDLER(regs.a);
3223 static void Op5D(void) // TSTB
3225 OP_TST_HANDLER(regs.b);
3228 static void Op6D(void) // TST IDX
3230 uint8_t m = READ_IDX;
3234 static void Op7D(void) // TST ABS
3236 uint8_t m = READ_ABS;
3241 // Undocumented Opcodes
3243 static void Op01(void)
3248 static void Op__(void) // Illegal opcode
3251 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3258 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
3259 static void Op10(void);
3260 static void Op11(void);
3262 // Array of page zero opcode functions...
3264 static void (* exec_op0[256])() = {
3265 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
3266 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
3267 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
3268 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
3269 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
3270 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
3271 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
3272 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
3273 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
3274 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
3275 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
3276 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
3277 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
3278 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
3279 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
3280 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
3283 // Array of page one opcode functions...
3284 static void (* exec_op1[256])() = {
3285 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3286 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3287 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
3288 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
3289 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3290 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3291 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3292 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3293 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
3294 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
3295 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
3296 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
3297 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
3298 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
3299 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
3300 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
3303 // Array of page two opcode functions...
3304 static void (* exec_op2[256])() = {
3305 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3306 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3307 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3308 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
3309 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3310 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3311 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3312 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3313 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
3314 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
3315 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
3316 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
3317 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3318 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3319 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3320 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
3323 // These are here to save typing a ton of forward declarations...
3326 static void Op10(void)
3328 uint8_t opcode = regs.RdMem(regs.pc++);
3330 regs.clock += page1Cycles[opcode];
3334 static void Op11(void)
3336 uint8_t opcode = regs.RdMem(regs.pc++);
3338 regs.clock += page2Cycles[opcode];
3342 // Internal "memcpy" (so we don't have to link with any external libraries!)
3344 static void myMemcpy(void * dst, void * src, uint32_t size)
3346 uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3348 for(uint32_t i=0; i<size; i++)
3353 // Function to execute 6809 instructions
3355 void Execute6809(V6809REGS * context, uint32_t cycles)
3357 // If this is not in place, the clockOverrun calculations can cause the
3358 // V6809 to get stuck in an infinite loop.
3359 if (cycles == 0) // Nothing to do, so bail!
3362 myMemcpy(®s, context, sizeof(V6809REGS));
3363 // Explode flags register into individual uint8_ts
3368 // Since we can't guarantee that we'll execute the number of cycles passed
3369 // in exactly, we have to keep track of how much we overran the number of
3370 // cycles the last time we executed. Since we already executed those
3371 // cycles, this time through we remove them from the cycles passed in in
3372 // order to come out approximately even. Over the long run, this unevenness
3373 // in execution times evens out. :-)
3374 uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3376 while (regs.clock < endCycles)
3378 uint8_t opcode = regs.RdMem(regs.pc++);
3380 regs.clock += page0Cycles[opcode];
3382 // Handle any pending interrupts
3384 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3385 // uint32_t flags = context->cpuFlags;
3386 uint32_t flags = regs.cpuFlags;
3388 // *** RESET handler ***
3389 if (flags & V6809_LINE_RESET)
3391 flagF = flagI = 1; // Set F, I
3392 regs.dp = 0; // Reset direct page register
3393 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3394 context->cpuFlags &= ~V6809_LINE_RESET;
3395 regs.cpuFlags &= ~V6809_LINE_RESET;
3397 // *** NMI handler ***
3398 else if (flags & V6809_LINE_NMI)
3400 flagE = 1; // Set Entire flag
3401 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3403 PUSHS16(regs.pc); // Save all regs...
3412 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3413 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3416 // *** FIRQ handler ***
3417 else if (flags & V6809_LINE_FIRQ)
3419 if (!flagF) // Is the FIRQ masked (F == 1)?
3421 flagE = 0; // Clear Entire flag
3422 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3427 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3428 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3432 // *** IRQ handler ***
3433 else if (flags & V6809_LINE_IRQ)
3435 if (!flagI) // Is the IRQ masked (I == 1)?
3437 flagE = 1; // Set the Entire flag
3438 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3449 flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3450 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3456 // Keep track of how much we overran so we can adjust on the next run...
3457 regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3459 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3460 myMemcpy(context, ®s, sizeof(V6809REGS));
3464 // Get the clock of the currently executing CPU
3466 uint64_t GetCurrentV6809Clock(void)
3472 // Get the PC of the currently executing CPU
3474 uint16_t GetCurrentV6809PC(void)
3479 // Set a line of the currently executing CPU
3480 void SetLineOfCurrentV6809(uint32_t line)
3482 regs.cpuFlags |= line;
3485 // Clear a line of the currently executing CPU
3486 void ClearLineOfCurrentV6809(uint32_t line)
3488 regs.cpuFlags &= ~line;