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);
492 // 6809 OPCODE IMPLEMENTATION
494 // NOTE: Lots of macros are used here to save a LOT of typing. Also
495 // helps speed the debugging process. :-) Because of this, combining
496 // certain lines may look like a good idea but would end in disaster.
497 // You have been warned! ;-)
501 +-----------------------------------------------------------------+
502 | Opcode | | Addressing | | |
503 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
504 +------------+-------------+--------------+-------+-------+-------+
505 | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa |
506 | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa |
507 | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa |
508 | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa |
509 | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa |
510 | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa |
511 | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa |
512 | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa |
517 #define OP_ADC_HANDLER(m, acc) \
518 uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
519 flagC = (sum >> 8) & 0x01; \
520 SET_H(m, acc, sum); \
521 SET_V(m, acc, sum); \
525 static void Op89(void) // ADCA #
527 uint16_t m = READ_IMM;
528 OP_ADC_HANDLER(m, regs.a);
531 static void Op99(void) // ADCA DP
533 uint16_t m = READ_DP;
534 OP_ADC_HANDLER(m, regs.a);
537 static void OpA9(void) // ADCA IDX
539 uint16_t m = READ_IDX;
540 OP_ADC_HANDLER(m, regs.a);
543 static void OpB9(void) // ADCA ABS
545 uint16_t m = READ_ABS;
546 OP_ADC_HANDLER(m, regs.a);
549 static void OpC9(void) // ADCB #
551 uint16_t m = READ_IMM;
552 OP_ADC_HANDLER(m, regs.b);
555 static void OpD9(void) // ADCB DP
557 uint16_t m = READ_DP;
558 OP_ADC_HANDLER(m, regs.b);
561 static void OpE9(void) // ADCB IDX
563 uint16_t m = READ_IDX;
564 OP_ADC_HANDLER(m, regs.b);
567 static void OpF9(void) // ADCB ABS
569 uint16_t m = READ_ABS;
570 OP_ADC_HANDLER(m, regs.b);
574 +-----------------------------------------------------------------+
575 | Opcode | | Addressing | | |
576 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
577 +------------+-------------+--------------+-------+-------+-------+
578 | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- |
579 | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa |
580 | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa |
581 | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa |
582 | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa |
583 | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa |
584 | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa |
585 | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa |
586 | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa |
587 | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa |
588 | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa |
589 | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa |
590 | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa |
595 #define OP_ADD_HANDLER(m, acc) \
596 uint16_t sum = (uint16_t)(acc) + (m); \
597 flagC = (sum >> 8) & 0x01; \
598 SET_H(m, acc, sum); \
599 SET_V(m, acc, sum); \
600 (acc) = sum & 0xFF; \
603 #define OP_ADD_HANDLER16(m, hireg, loreg) \
604 uint32_t acc = (uint32_t)((hireg << 8) | loreg); \
605 uint32_t sum = acc + (m); \
606 flagC = (sum >> 16) & 0x01; \
607 SET_V16(m, acc, sum); \
608 acc = sum & 0xFFFF; \
609 hireg = (acc >> 8) & 0xFF; \
610 loreg = acc & 0xFF; \
613 static void Op3A(void) // ABX
615 regs.x += (uint16_t)regs.b;
618 static void Op8B(void) // ADDA #
620 uint16_t m = READ_IMM;
621 OP_ADD_HANDLER(m, regs.a);
624 static void Op9B(void) // ADDA DP
626 uint16_t m = READ_DP;
627 OP_ADD_HANDLER(m, regs.a);
630 static void OpAB(void) // ADDA IDX
632 uint16_t m = READ_IDX;
633 OP_ADD_HANDLER(m, regs.a);
636 static void OpBB(void) // ADDA ABS
638 uint16_t m = READ_ABS;
639 OP_ADD_HANDLER(m, regs.a);
642 static void OpC3(void) // ADDD #
644 uint32_t m = READ_IMM16;
645 OP_ADD_HANDLER16(m, regs.a, regs.b);
648 static void OpCB(void) // ADDB #
650 uint16_t m = READ_IMM;
651 OP_ADD_HANDLER(m, regs.b);
654 static void OpD3(void) // ADDD DP
656 uint32_t m = READ_DP16;
657 OP_ADD_HANDLER16(m, regs.a, regs.b);
660 static void OpDB(void) // ADDB DP
662 uint16_t m = READ_DP;
663 OP_ADD_HANDLER(m, regs.b);
666 static void OpE3(void) // ADDD IDX
668 uint32_t m = READ_IDX16;
669 OP_ADD_HANDLER16(m, regs.a, regs.b);
672 static void OpEB(void) // ADDB IDX
674 uint16_t m = READ_IDX;
675 OP_ADD_HANDLER(m, regs.b);
678 static void OpF3(void) // ADDD ABS
680 uint32_t m = READ_ABS16;
681 OP_ADD_HANDLER16(m, regs.a, regs.b);
684 static void OpFB(void) // ADDB ABS
686 uint16_t m = READ_ABS;
687 OP_ADD_HANDLER(m, regs.b);
691 +-----------------------------------------------------------------+
692 | Opcode | | Addressing | | |
693 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
694 +------------+-------------+--------------+-------+-------+-------+
695 | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- |
696 | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- |
697 | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- |
698 | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- |
699 | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- |
700 | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- |
701 | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- |
702 | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- |
707 #define OP_AND_HANDLER(m, acc) \
712 static void Op84(void) // ANDA #
714 uint16_t m = READ_IMM;
715 OP_AND_HANDLER(m, regs.a);
718 static void Op94(void) // ANDA DP
720 uint16_t m = READ_DP;
721 OP_AND_HANDLER(m, regs.a);
724 static void OpA4(void) // ANDA IDX
726 uint16_t m = READ_IDX;
727 OP_AND_HANDLER(m, regs.a);
730 static void OpB4(void) // ANDA ABS
732 uint16_t m = READ_ABS;
733 OP_AND_HANDLER(m, regs.a);
736 static void OpC4(void) // ANDB #
738 uint16_t m = READ_IMM;
739 OP_AND_HANDLER(m, regs.b);
742 static void OpD4(void) // ANDB DP
744 uint16_t m = READ_DP;
745 OP_AND_HANDLER(m, regs.b);
748 static void OpE4(void) // ANDB IDX
750 uint16_t m = READ_IDX;
751 OP_AND_HANDLER(m, regs.b);
754 static void OpF4(void) // ANDB ABS
756 uint16_t m = READ_ABS;
757 OP_AND_HANDLER(m, regs.b);
761 +-----------------------------------------------------------------+
762 | Opcode | | Addressing | | |
763 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
764 +------------+-------------+--------------+-------+-------+-------+
765 | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas |
766 | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas |
767 | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas |
768 | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas |
769 | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas |
774 #define OP_ASL_HANDLER(m) \
775 uint16_t res = m << 1; \
777 flagC = (res >> 8) & 0x01; \
781 static void Op08(void) // ASL DP
789 static void Op48(void) // ASLA
791 OP_ASL_HANDLER(regs.a);
794 static void Op58(void) // ASLB
796 OP_ASL_HANDLER(regs.b);
799 static void Op68(void) // ASL IDX
807 static void Op78(void) // ASL ABS
816 +-----------------------------------------------------------------+
817 | Opcode | | Addressing | | |
818 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
819 +------------+-------------+--------------+-------+-------+-------+
820 | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s |
821 | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s |
822 | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s |
823 | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s |
824 | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s |
827 // ASR opcodes (arithmetic, so preserves the sign)
829 #define OP_ASR_HANDLER(m) \
830 uint8_t res = (m & 0x80) | (m >> 1); \
835 static void Op07(void) // ASR DP
843 static void Op47(void) // ASRA
845 OP_ASR_HANDLER(regs.a);
848 static void Op57(void) // ASRB
850 OP_ASR_HANDLER(regs.b);
853 static void Op67(void) // ASR IDX
861 static void Op77(void) // ASR ABS
870 +-----------------------------------------------------------------+
871 | Opcode | | Addressing | | |
872 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
873 +------------+-------------+--------------+-------+-------+-------+
874 | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- |
875 | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- |
876 | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- |
877 | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- |
878 | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- |
879 | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- |
880 | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- |
881 | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- |
882 | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- |
883 | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- |
884 | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- |
885 | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- |
886 | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- |
887 | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- |
888 | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- |
889 | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- |
890 | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- |
891 | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- |
892 | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- |
893 | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- |
894 | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- |
895 | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- |
896 | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- |
897 | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- |
898 | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- |
899 | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- |
900 | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- |
901 | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- |
902 | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- |
903 | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- |
904 | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- |
905 | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- |
910 static void Op16(void) // LBRA
912 uint16_t offset = READ_IMM16;
916 static void Op20(void) // BRA
918 int16_t offset = (int16_t)(int8_t)READ_IMM;
922 static void Op21(void) // BRN
924 // This is basically a 2 byte NOP
925 int16_t offset = (int16_t)(int8_t)READ_IMM;
928 static void Op22(void) // BHI
931 int16_t offset = (int16_t)(int8_t)READ_IMM;
933 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
934 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
935 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
937 if (!(flagZ || flagC))
942 static void Op23(void) // BLS
945 int16_t offset = (int16_t)(int8_t)READ_IMM;
947 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
948 regs.pc += offset * (flagZ | flagC);
955 static void Op24(void) // BHS/CC
958 int16_t offset = (int16_t)(int8_t)READ_IMM;
960 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
961 regs.pc += offset * (flagC ^ 0x01);
968 static void Op25(void) // BLO/CS
971 int16_t offset = (int16_t)(int8_t)READ_IMM;
973 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
974 regs.pc += offset * flagC;
981 static void Op26(void) // BNE
984 int16_t offset = (int16_t)(int8_t)READ_IMM;
986 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
987 regs.pc += offset * (flagZ ^ 0x01);
994 static void Op27(void) // BEQ
997 int16_t offset = (int16_t)(int8_t)READ_IMM;
999 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1000 regs.pc += offset * flagZ;
1007 static void Op28(void) // BVC
1010 int16_t offset = (int16_t)(int8_t)READ_IMM;
1012 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1013 regs.pc += offset * (flagV ^ 0x01);
1020 static void Op29(void) // BVS
1023 int16_t offset = (int16_t)(int8_t)READ_IMM;
1025 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1026 regs.pc += offset * flagV;
1033 static void Op2A(void) // BPL
1036 int16_t offset = (int16_t)(int8_t)READ_IMM;
1038 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1039 regs.pc += offset * (flagN ^ 0x01);
1046 static void Op2B(void) // BMI
1049 int16_t offset = (int16_t)(int8_t)READ_IMM;
1051 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1052 regs.pc += offset * flagN;
1059 static void Op2C(void) // BGE
1061 // (N && V) || (!N && !V)
1062 int16_t offset = (int16_t)(int8_t)READ_IMM;
1064 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1065 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1067 if ((flagN && flagV) || (!flagN && !flagV))
1072 static void Op2D(void) // BLT
1074 // (N && !V) || (!N && V)
1075 int16_t offset = (int16_t)(int8_t)READ_IMM;
1077 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1078 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1080 if ((flagN && !flagV) || (!flagN && flagV))
1085 static void Op2E(void) // BGT
1087 // (N && V && !Z) || (!N && !V && !Z)
1088 int16_t offset = (int16_t)(int8_t)READ_IMM;
1090 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1091 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1093 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1098 static void Op2F(void) // BLE
1100 // Z || (N && !V) || (!N && V)
1101 int16_t offset = (int16_t)(int8_t)READ_IMM;
1103 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1104 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1106 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1111 static void Op1021(void) // LBRN
1113 // This is basically a 4 byte NOP
1114 uint16_t offset = READ_IMM16;
1117 static void Op1022(void) // LBHI
1120 uint16_t offset = READ_IMM16;
1122 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1123 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1124 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1126 if (!(flagZ || flagC))
1131 static void Op1023(void) // LBLS
1134 uint16_t offset = READ_IMM16;
1136 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1137 regs.pc += offset * (flagZ | flagC);
1144 static void Op1024(void) // LBHS/CC
1147 uint16_t offset = READ_IMM16;
1149 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1150 regs.pc += offset * (flagC ^ 0x01);
1157 static void Op1025(void) // LBLO/CS
1160 uint16_t offset = READ_IMM16;
1162 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1163 regs.pc += offset * flagC;
1170 static void Op1026(void) // LBNE
1173 uint16_t offset = READ_IMM16;
1175 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1176 regs.pc += offset * (flagZ ^ 0x01);
1183 static void Op1027(void) // LBEQ
1186 uint16_t offset = READ_IMM16;
1188 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1189 regs.pc += offset * flagZ;
1196 static void Op1028(void) // LBVC
1199 uint16_t offset = READ_IMM16;
1201 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1202 regs.pc += offset * (flagV ^ 0x01);
1209 static void Op1029(void) // LBVS
1212 uint16_t offset = READ_IMM16;
1214 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1215 regs.pc += offset * flagV;
1222 static void Op102A(void) // LBPL
1225 uint16_t offset = READ_IMM16;
1227 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1228 regs.pc += offset * (flagN ^ 0x01);
1235 static void Op102B(void) // LBMI
1238 uint16_t offset = READ_IMM16;
1240 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1241 regs.pc += offset * flagN;
1248 static void Op102C(void) // LBGE
1250 // (N && V) || (!N && !V)
1251 uint16_t offset = READ_IMM16;
1253 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1254 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1256 if ((flagN && flagV) || (!flagN && !flagV))
1261 static void Op102D(void) // LBLT
1263 // (N && !V) || (!N && V)
1264 uint16_t offset = READ_IMM16;
1266 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1267 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1269 if ((flagN && !flagV) || (!flagN && flagV))
1274 static void Op102E(void) // LBGT
1276 // (N && V && !Z) || (!N && !V && !Z)
1277 uint16_t offset = READ_IMM16;
1279 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1280 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1282 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1287 static void Op102F(void) // LBLE
1289 // Z || (N && !V) || (!N && V)
1290 uint16_t offset = READ_IMM16;
1292 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1293 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1295 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1301 +-----------------------------------------------------------------+
1302 | Opcode | | Addressing | | |
1303 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1304 +------------+-------------+--------------+-------+-------+-------+
1305 | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- |
1306 | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- |
1307 | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- |
1308 | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- |
1309 | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- |
1310 | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- |
1311 | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- |
1312 | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- |
1317 #define OP_BIT_HANDLER(m, acc) \
1318 uint8_t result = acc & (m); \
1322 static void Op85(void) // BITA #
1324 uint8_t m = READ_IMM;
1325 OP_BIT_HANDLER(m, regs.a);
1328 static void Op95(void) // BITA DP
1330 uint8_t m = READ_DP;
1331 OP_BIT_HANDLER(m, regs.a);
1334 static void OpA5(void) // BITA IDX
1336 uint8_t m = READ_IDX;
1337 OP_BIT_HANDLER(m, regs.a);
1340 static void OpB5(void) // BITA ABS
1342 uint8_t m = READ_ABS;
1343 OP_BIT_HANDLER(m, regs.a);
1346 static void OpC5(void) // BITB #
1348 uint8_t m = READ_IMM;
1349 OP_BIT_HANDLER(m, regs.b);
1352 static void OpD5(void) // BITB DP
1354 uint8_t m = READ_DP;
1355 OP_BIT_HANDLER(m, regs.b);
1358 static void OpE5(void) // BITB IDX
1360 uint8_t m = READ_IDX;
1361 OP_BIT_HANDLER(m, regs.b);
1364 static void OpF5(void) // BITB ABS
1366 uint8_t m = READ_ABS;
1367 OP_BIT_HANDLER(m, regs.b);
1371 +-----------------------------------------------------------------+
1372 | Opcode | | Addressing | | |
1373 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1374 +------------+-------------+--------------+-------+-------+-------+
1375 | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 |
1376 | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 |
1377 | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 |
1378 | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 |
1379 | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 |
1384 #define OP_CLR_HANDLER(m) \
1385 flagN = flagV = flagC = 0; \
1389 static void Op0F(void) // CLR DP
1397 static void Op4F(void) // CLRA
1399 OP_CLR_HANDLER(regs.a);
1402 static void Op5F(void) // CLRB
1404 OP_CLR_HANDLER(regs.b);
1407 static void Op6F(void) // CLR IDX
1415 static void Op7F(void) // CLR ABS
1424 +-----------------------------------------------------------------+
1425 | Opcode | | Addressing | | |
1426 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1427 +------------+-------------+--------------+-------+-------+-------+
1428 | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa |
1429 | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa |
1430 | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa |
1431 | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa |
1432 | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa |
1433 | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa |
1434 | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa |
1435 | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa |
1436 | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa |
1437 | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa |
1438 | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa |
1439 | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa |
1440 | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa |
1441 | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa |
1442 | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa |
1443 | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa |
1444 | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa |
1445 | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa |
1446 | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa |
1447 | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa |
1448 | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa |
1449 | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa |
1450 | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa |
1451 | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa |
1452 | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa |
1453 | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa |
1454 | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa |
1455 | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa |
1460 #define OP_CMP_HANDLER(m, acc) \
1461 uint16_t sum = (uint16_t)(acc) - (m); \
1462 flagC = (sum >> 8) & 0x01; \
1463 SET_V(m, acc, sum); \
1466 #define OP_CMP_HANDLER16(m, acc) \
1467 uint32_t sum = (uint32_t)(acc) - (m); \
1468 flagC = (sum >> 16) & 0x01; \
1469 SET_V16(m, acc, sum); \
1472 static void Op81(void) // CMPA #
1474 uint8_t m = READ_IMM;
1475 OP_CMP_HANDLER(m, regs.a);
1478 static void Op8C(void) // CMPX #
1480 uint16_t m = READ_IMM16;
1481 OP_CMP_HANDLER16(m, regs.x);
1484 static void Op91(void) // CMPA DP
1486 uint8_t m = READ_DP;
1487 OP_CMP_HANDLER(m, regs.a);
1490 static void Op9C(void) // CMPX DP
1492 uint16_t m = READ_DP16;
1493 OP_CMP_HANDLER16(m, regs.x);
1496 static void OpA1(void) // CMPA IDX
1498 uint8_t m = READ_IDX;
1499 OP_CMP_HANDLER(m, regs.a);
1502 static void OpAC(void) // CMPX IDX
1504 uint16_t m = READ_IDX16;
1505 OP_CMP_HANDLER16(m, regs.x);
1508 static void OpB1(void) // CMPA ABS
1510 uint8_t m = READ_ABS;
1511 OP_CMP_HANDLER(m, regs.a);
1514 static void OpBC(void) // CMPX ABS
1516 uint16_t m = READ_ABS16;
1517 OP_CMP_HANDLER16(m, regs.x);
1520 static void OpC1(void) // CMPB #
1522 uint8_t m = READ_IMM;
1523 OP_CMP_HANDLER(m, regs.b);
1526 static void OpD1(void) // CMPB DP
1528 uint8_t m = READ_DP;
1529 OP_CMP_HANDLER(m, regs.b);
1532 static void OpE1(void) // CMPB IDX
1534 uint8_t m = READ_IDX;
1535 OP_CMP_HANDLER(m, regs.b);
1538 static void OpF1(void) // CMPB ABS
1540 uint8_t m = READ_ABS;
1541 OP_CMP_HANDLER(m, regs.b);
1544 static void Op1083(void) // CMPD #
1546 uint16_t m = READ_IMM16;
1547 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1550 static void Op108C(void) // CMPY #
1552 uint16_t m = READ_IMM16;
1553 OP_CMP_HANDLER16(m, regs.y);
1556 static void Op1093(void) // CMPD DP
1558 uint16_t m = READ_DP16;
1559 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1562 static void Op109C(void) // CMPY DP
1564 uint16_t m = READ_DP16;
1565 OP_CMP_HANDLER16(m, regs.y);
1568 static void Op10A3(void) // CMPD IDX
1570 uint16_t m = READ_IDX16;
1571 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1574 static void Op10AC(void) // CMPY IDX
1576 uint16_t m = READ_IDX16;
1577 OP_CMP_HANDLER16(m, regs.y);
1580 static void Op10B3(void) // CMPD ABS
1582 uint16_t m = READ_ABS16;
1583 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1586 static void Op10BC(void) // CMPY ABS
1588 uint16_t m = READ_ABS16;
1589 OP_CMP_HANDLER16(m, regs.y);
1592 static void Op1183(void) // CMPU #
1594 uint16_t m = READ_IMM16;
1595 OP_CMP_HANDLER16(m, regs.u);
1598 static void Op118C(void) // CMPS #
1600 uint16_t m = READ_IMM16;
1601 OP_CMP_HANDLER16(m, regs.s);
1604 static void Op1193(void) // CMPU DP
1606 uint16_t m = READ_DP16;
1607 OP_CMP_HANDLER16(m, regs.u);
1610 static void Op119C(void) // CMPS DP
1612 uint16_t m = READ_DP16;
1613 OP_CMP_HANDLER16(m, regs.s);
1616 static void Op11A3(void) // CMPU IDX
1618 uint16_t m = READ_IDX16;
1619 OP_CMP_HANDLER16(m, regs.u);
1622 static void Op11AC(void) // CMPS IDX
1624 uint16_t m = READ_IDX16;
1625 OP_CMP_HANDLER16(m, regs.s);
1628 static void Op11B3(void) // CMPU ABS
1630 uint16_t m = READ_ABS16;
1631 OP_CMP_HANDLER16(m, regs.u);
1634 static void Op11BC(void) // CMPS ABS
1636 uint16_t m = READ_ABS16;
1637 OP_CMP_HANDLER16(m, regs.s);
1641 +-----------------------------------------------------------------+
1642 | Opcode | | Addressing | | |
1643 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1644 +------------+-------------+--------------+-------+-------+-------+
1645 | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 |
1646 | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 |
1647 | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 |
1648 | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 |
1649 | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 |
1654 #define OP_COM_HANDLER(m) \
1660 static void Op03(void) // COM DP
1668 static void Op43(void) // COMA
1670 OP_COM_HANDLER(regs.a);
1673 static void Op53(void) // COMB
1675 OP_COM_HANDLER(regs.b);
1678 static void Op63(void) // COM IDX
1686 static void Op73(void) // COM ABS
1695 +-----------------------------------------------------------------+
1696 | Opcode | | Addressing | | |
1697 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1698 +------------+-------------+--------------+-------+-------+-------+
1699 | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- |
1700 | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd |
1701 | 3E 0062 | RESET* | INHERENT | * | 1 | ***** |
1702 | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- |
1703 | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- |
1704 | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- |
1707 static void Op13(void) // SYNC
1709 #warning "!!! SYNC not implemented !!!"
1711 /* SYNC stops processing instructions until an interrupt request happens. */
1712 /* This doesn't require the corresponding interrupt to be enabled: if it */
1713 /* is disabled, execution continues with the next instruction. */
1714 m68_state->int_state |= M6809_SYNC; /* HJB 990227 */
1715 check_irq_lines(m68_state);
1716 /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1717 * stop execution until the interrupt lines change. */
1718 if( m68_state->int_state & M6809_SYNC )
1719 if (m68_state->icount > 0) m68_state->icount = 0;
1723 static void Op3C(void) // CWAI
1725 #warning "!!! CWAI not implemented !!!"
1731 * CWAI stacks the entire machine state on the hardware stack,
1732 * then waits for an interrupt; when the interrupt is taken
1733 * later, the state is *not* saved again after CWAI.
1735 CC |= CC_E; /* HJB 990225: save entire state */
1744 m68_state->int_state |= M6809_CWAI; /* HJB 990228 */
1745 check_irq_lines(m68_state); /* HJB 990116 */
1746 if( m68_state->int_state & M6809_CWAI )
1747 if( m68_state->icount > 0 )
1748 m68_state->icount = 0;
1752 static void Op3E(void) // RESET
1754 regs.cpuFlags |= V6809_LINE_RESET;
1757 static void Op3F(void) // SWI
1760 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1770 regs.pc = RdMemW(0xFFFA);
1773 static void Op103F(void) // SWI2
1776 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1785 regs.pc = RdMemW(0xFFF4);
1788 static void Op113F(void) // SWI3
1791 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1800 regs.pc = RdMemW(0xFFF2);
1804 +-----------------------------------------------------------------+
1805 | Opcode | | Addressing | | |
1806 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1807 +------------+-------------+--------------+-------+-------+-------+
1808 | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
1809 | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
1810 | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
1811 | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
1812 | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
1815 static void Op12() // NOP
1819 static void Op19() // DAA
1821 uint16_t result = (uint16_t)regs.a;
1823 if ((regs.a & 0x0F) > 0x09 || flagH)
1826 if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1829 regs.a = (uint8_t)result;
1832 flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
1835 static void Op1A() // ORCC
1837 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1838 regs.cc |= READ_IMM;
1839 UNPACK_FLAGS; // & unmash 'em
1842 static void Op1C() // ANDCC
1844 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1845 regs.cc &= READ_IMM;
1846 UNPACK_FLAGS; // & unmash 'em
1849 static void Op1D() // SEX
1851 regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1852 SET_ZN16((regs.a << 8) | regs.b);
1857 +-----------------------------------------------------------------+
1858 | Opcode | | Addressing | | |
1859 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1860 +------------+-------------+--------------+-------+-------+-------+
1861 | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- |
1862 | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- |
1863 | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- |
1864 | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- |
1865 | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- |
1868 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1870 #define OP_DEC_HANDLER(m) \
1873 flagV = (m == 0x7F ? 1 : 0)
1875 static void Op0A(void) // DEC DP
1883 static void Op4A(void) // DECA
1885 OP_DEC_HANDLER(regs.a);
1888 static void Op5A(void) // DECB
1890 OP_DEC_HANDLER(regs.b);
1893 static void Op6A(void) // DEC IDX
1901 static void Op7A(void) // DEC ABS
1910 +-----------------------------------------------------------------+
1911 | Opcode | | Addressing | | |
1912 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1913 +------------+-------------+--------------+-------+-------+-------+
1914 | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- |
1915 | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- |
1916 | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- |
1917 | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- |
1918 | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- |
1919 | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- |
1920 | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- |
1921 | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- |
1926 #define OP_EOR_HANDLER(m, acc) \
1931 static void Op88(void) // EORA #
1933 uint8_t m = READ_IMM;
1934 OP_EOR_HANDLER(m, regs.a);
1937 static void Op98(void) // EORA DP
1939 uint8_t m = READ_DP;
1940 OP_EOR_HANDLER(m, regs.a);
1943 static void OpA8(void) // EORA IDX
1945 uint8_t m = READ_IDX;
1946 OP_EOR_HANDLER(m, regs.a);
1949 static void OpB8(void) // EORA ABS
1951 uint8_t m = READ_ABS;
1952 OP_EOR_HANDLER(m, regs.a);
1955 static void OpC8(void) // EORB #
1957 uint8_t m = READ_IMM;
1958 OP_EOR_HANDLER(m, regs.b);
1961 static void OpD8(void) // EORB DP
1963 uint8_t m = READ_DP;
1964 OP_EOR_HANDLER(m, regs.b);
1967 static void OpE8(void) // EORB IDX
1969 uint8_t m = READ_IDX;
1970 OP_EOR_HANDLER(m, regs.b);
1973 static void OpF8(void) // EORB ABS
1975 uint8_t m = READ_ABS;
1976 OP_EOR_HANDLER(m, regs.b);
1980 +-----------------------------------------------------------------+
1981 | Opcode | | Addressing | | |
1982 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1983 +------------+-------------+--------------+-------+-------+-------+
1984 | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- |
1985 | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- |
1986 | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- |
1987 | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- |
1988 | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- |
1991 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1993 #define OP_INC_HANDLER(m) \
1996 flagV = (m == 0x80 ? 1 : 0)
1998 static void Op0C(void) // INC DP
2006 static void Op4C(void) // INCA
2008 OP_INC_HANDLER(regs.a);
2011 static void Op5C(void) // INCB
2013 OP_INC_HANDLER(regs.b);
2016 static void Op6C(void) // INC IDX
2024 static void Op7C(void) // INC ABS
2033 +-----------------------------------------------------------------+
2034 | Opcode | | Addressing | | |
2035 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2036 +------------+-------------+--------------+-------+-------+-------+
2037 | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- |
2038 | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- |
2039 | 39 0057 | RTS | INHERENT | 5 | 1 | ----- |
2040 | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- |
2041 | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- |
2042 | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- |
2043 | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- |
2044 | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- |
2045 | AD 0173 | JSR | INDEXED | 7 | 2 | ----- |
2046 | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- |
2049 static void Op0E(void) // JMP DP
2051 // This needs to be separate because of the EA_DP adding to regs.pc.
2056 static void Op17(void) // LBSR
2058 uint16_t word = FetchMemW(regs.pc);
2063 static void Op39(void) // RTS
2068 static void Op3B(void) // RTI
2073 // If E flag set, pull all regs
2088 static void Op6E(void) // JMP IDX
2093 static void Op7E(void) // JMP ABS
2098 static void Op8D(void) // BSR
2100 uint16_t word = (int16_t)(int8_t)READ_IMM;
2105 static void Op9D(void) // JSR DP
2107 uint16_t word = EA_DP;
2112 static void OpAD(void) // JSR IDX
2114 uint16_t word = EA_IDX;
2119 static void OpBD(void) // JSR ABS
2121 uint16_t word = EA_ABS;
2127 +-----------------------------------------------------------------+
2128 | Opcode | | Addressing | | |
2129 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2130 +------------+-------------+--------------+-------+-------+-------+
2131 | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
2132 | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
2135 static void Op1E(void) // EXG
2137 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2139 uint8_t m = READ_IMM;
2140 uint8_t reg1 = m >> 4, reg2 = m & 0x0F;
2141 uint16_t acc1 = ReadEXG(reg1);
2142 uint16_t acc2 = ReadEXG(reg2);
2144 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2145 if (((m >> 4) ^ m) & 0x08)
2148 WriteEXG(reg1, acc2);
2149 WriteEXG(reg2, acc1);
2152 static void Op1F(void) // TFR
2154 uint8_t m = READ_IMM;
2155 uint16_t acc = ReadEXG(m >> 4);
2157 // If bit 3 & 7 are not equal, $FF is the result (undocumented)...
2158 if (((m >> 4) ^ m) & 0x08)
2161 WriteEXG(m & 0x0F, acc);
2165 +-----------------------------------------------------------------+
2166 | Opcode | | Addressing | | |
2167 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2168 +------------+-------------+--------------+-------+-------+-------+
2169 | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
2170 | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
2171 | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
2172 | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
2173 | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
2174 | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
2175 | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
2176 | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
2177 | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
2178 | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
2179 | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
2180 | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
2181 | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
2182 | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
2183 | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
2184 | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
2185 | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
2186 | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
2187 | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
2188 | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
2189 | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
2190 | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
2191 | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
2192 | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
2193 | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
2194 | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
2195 | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
2196 | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
2201 #define OP_LDA_HANDLER(m, acc) \
2206 #define OP_LDA_HANDLER16(m, acc) \
2211 #define OP_LDA_HANDLER16D(m) \
2212 regs.a = (m >> 8); \
2213 regs.b = m & 0xFF; \
2217 static void Op86(void) // LDA #
2219 uint8_t m = READ_IMM;
2220 OP_LDA_HANDLER(m, regs.a);
2223 static void Op8E(void) // LDX #
2225 uint16_t m = READ_IMM16;
2226 OP_LDA_HANDLER16(m, regs.x);
2229 static void Op96(void) // LDA DP
2231 uint8_t m = READ_DP;
2232 OP_LDA_HANDLER(m, regs.a);
2235 static void Op9E(void) // LDX DP
2237 uint16_t m = READ_DP16;
2238 OP_LDA_HANDLER16(m, regs.x);
2241 static void OpA6(void) // LDA IDX
2243 uint8_t m = READ_IDX;
2244 OP_LDA_HANDLER(m, regs.a);
2247 static void OpAE(void) // LDX IDX
2249 uint16_t m = READ_IDX16;
2250 OP_LDA_HANDLER16(m, regs.x);
2253 static void OpB6(void) // LDA ABS
2255 uint8_t m = READ_ABS;
2256 OP_LDA_HANDLER(m, regs.a);
2259 static void OpBE(void) // LDX ABS
2261 uint16_t m = READ_ABS16;
2262 OP_LDA_HANDLER16(m, regs.x);
2265 static void OpC6(void) // LDB #
2267 uint8_t m = READ_IMM;
2268 OP_LDA_HANDLER(m, regs.b);
2271 static void OpCC(void) // LDD #
2273 uint16_t m = READ_IMM16;
2274 OP_LDA_HANDLER16D(m);
2277 static void OpCE(void) // LDU #
2279 uint16_t m = READ_IMM16;
2280 OP_LDA_HANDLER16(m, regs.u);
2283 static void OpD6(void) // LDB DP
2285 uint8_t m = READ_DP;
2286 OP_LDA_HANDLER(m, regs.b);
2289 static void OpDC(void) // LDD DP
2291 uint16_t m = READ_DP16;
2292 OP_LDA_HANDLER16D(m);
2295 static void OpDE(void) // LDU DP
2297 uint16_t m = READ_DP16;
2298 OP_LDA_HANDLER16(m, regs.u);
2301 static void OpE6(void) // LDB IDX
2303 uint8_t m = READ_IDX;
2304 OP_LDA_HANDLER(m, regs.b);
2307 static void OpEC(void) // LDD IDX
2309 uint16_t m = READ_IDX16;
2310 OP_LDA_HANDLER16D(m);
2313 static void OpEE(void) // LDU IDX
2315 uint16_t m = READ_IDX16;
2316 OP_LDA_HANDLER16(m, regs.u);
2319 static void OpF6(void) // LDB ABS
2321 uint8_t m = READ_ABS;
2322 OP_LDA_HANDLER(m, regs.b);
2325 static void OpFC(void) // LDD ABS
2327 uint16_t m = READ_ABS16;
2328 OP_LDA_HANDLER16D(m);
2331 static void OpFE(void) // LDU ABS
2333 uint16_t m = READ_ABS16;
2334 OP_LDA_HANDLER16(m, regs.u);
2337 static void Op108E(void) // LDY #
2339 uint16_t m = READ_IMM16;
2340 OP_LDA_HANDLER16(m, regs.y);
2343 static void Op109E(void) // LDY DP
2345 uint16_t m = READ_DP16;
2346 OP_LDA_HANDLER16(m, regs.y);
2349 static void Op10AE(void) // LDY IDX
2351 uint16_t m = READ_IDX16;
2352 OP_LDA_HANDLER16(m, regs.y);
2355 static void Op10BE(void) // LDY ABS
2357 uint16_t m = READ_ABS16;
2358 OP_LDA_HANDLER16(m, regs.y);
2361 static void Op10CE(void) // LDS #
2363 uint16_t m = READ_IMM16;
2364 OP_LDA_HANDLER16(m, regs.s);
2367 static void Op10DE(void) // LDS DP
2369 uint16_t m = READ_DP16;
2370 OP_LDA_HANDLER16(m, regs.s);
2373 static void Op10EE(void) // LDS IDX
2375 uint16_t m = READ_IDX16;
2376 OP_LDA_HANDLER16(m, regs.s);
2379 static void Op10FE(void) // LDS ABS
2381 uint16_t m = READ_ABS16;
2382 OP_LDA_HANDLER16(m, regs.s);
2386 +-----------------------------------------------------------------+
2387 | Opcode | | Addressing | | |
2388 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2389 +------------+-------------+--------------+-------+-------+-------+
2390 | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- |
2391 | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- |
2392 | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- |
2393 | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- |
2396 static void Op30(void) // LEAX
2402 static void Op31(void) // LEAY
2408 static void Op32(void) // LEAS
2413 static void Op33(void) // LEAU
2419 +-----------------------------------------------------------------+
2420 | Opcode | | Addressing | | |
2421 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2422 +------------+-------------+--------------+-------+-------+-------+
2423 | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s |
2424 | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s |
2425 | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s |
2426 | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s |
2427 | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s |
2432 #define OP_LSR_HANDLER(m) \
2437 static void Op04(void) // LSR DP
2445 static void Op44(void) // LSRA
2447 OP_LSR_HANDLER(regs.a);
2450 static void Op54(void) // LSRB
2452 OP_LSR_HANDLER(regs.b);
2455 static void Op64(void) // LSR IDX
2463 static void Op74(void) // LSR ABS
2472 +-----------------------------------------------------------------+
2473 | Opcode | | Addressing | | |
2474 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2475 +------------+-------------+--------------+-------+-------+-------+
2476 | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a |
2479 static void Op3D(void) // MUL
2481 uint16_t prod = regs.a * regs.b;
2483 regs.b = prod & 0xFF;
2485 // flagC = (prod & 0x0080 ? 1 : 0);
2486 flagC = (prod >> 7) & 0x01;
2490 +-----------------------------------------------------------------+
2491 | Opcode | | Addressing | | |
2492 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2493 +------------+-------------+--------------+-------+-------+-------+
2494 | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa |
2495 | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa |
2496 | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa |
2497 | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa |
2498 | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa |
2503 #define OP_NEG_HANDLER(m) \
2507 flagC = (res >= 0x80 ? 1 : 0); \
2510 static void Op00(void) // NEG DP
2518 static void Op40(void) // NEGA
2520 OP_NEG_HANDLER(regs.a);
2523 static void Op50(void) // NEGB
2525 OP_NEG_HANDLER(regs.b);
2528 static void Op60(void) // NEG IDX
2536 static void Op70(void) // NEG ABS
2545 +-----------------------------------------------------------------+
2546 | Opcode | | Addressing | | |
2547 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2548 +------------+-------------+--------------+-------+-------+-------+
2549 | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- |
2550 | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- |
2551 | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- |
2552 | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- |
2553 | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- |
2554 | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- |
2555 | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- |
2556 | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- |
2561 #define OP_OR_HANDLER(m, acc) \
2566 static void Op8A(void) // ORA #
2568 uint8_t m = READ_IMM;
2569 OP_OR_HANDLER(m, regs.a);
2572 static void Op9A(void) // ORA DP
2574 uint8_t m = READ_DP;
2575 OP_OR_HANDLER(m, regs.a);
2578 static void OpAA(void) // ORA IDX
2580 uint8_t m = READ_IDX;
2581 OP_OR_HANDLER(m, regs.a);
2584 static void OpBA(void) // ORA ABS
2586 uint8_t m = READ_ABS;
2587 OP_OR_HANDLER(m, regs.a);
2590 static void OpCA(void) // ORB #
2592 uint8_t m = READ_IMM;
2593 OP_OR_HANDLER(m, regs.b);
2596 static void OpDA(void) // ORB DP
2598 uint8_t m = READ_DP;
2599 OP_OR_HANDLER(m, regs.b);
2602 static void OpEA(void) // ORB IDX
2604 uint8_t m = READ_IDX;
2605 OP_OR_HANDLER(m, regs.b);
2608 static void OpFA(void) // ORB ABS
2610 uint8_t m = READ_ABS;
2611 OP_OR_HANDLER(m, regs.b);
2615 +-----------------------------------------------------------------+
2616 | Opcode | | Addressing | | |
2617 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2618 +------------+-------------+--------------+-------+-------+-------+
2619 | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- |
2620 | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc |
2621 | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- |
2622 | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc |
2625 static void Op34(void) // PSHS
2627 uint8_t m = READ_IMM;
2645 regs.cc = PACK_FLAGS;
2649 // Count bits in each nybble to come up with correct cycle counts...
2650 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2653 static void Op35(void) // PULS
2655 uint8_t m = READ_IMM;
2677 // Count bits in each nybble to come up with correct cycle counts...
2678 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2681 static void Op36(void) // PHSU
2683 uint8_t m = READ_IMM;
2701 regs.cc = PACK_FLAGS;
2705 // Count bits in each nybble to come up with correct cycle counts...
2706 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2709 static void Op37(void) // PULU
2711 uint8_t m = READ_IMM;
2733 // Count bits in each nybble to come up with correct cycle counts...
2734 regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]);
2738 +-----------------------------------------------------------------+
2739 | Opcode | | Addressing | | |
2740 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2741 +------------+-------------+--------------+-------+-------+-------+
2742 | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas |
2743 | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas |
2744 | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas |
2745 | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas |
2746 | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas |
2751 #define OP_ROL_HANDLER(m) \
2752 uint8_t res = (m << 1) | flagC; \
2755 flagC = (m >> 7) & 0x01; \
2758 static void Op09(void) // ROL DP
2766 static void Op49(void) // ROLA
2768 OP_ROL_HANDLER(regs.a);
2771 static void Op59(void) // ROLB
2773 OP_ROL_HANDLER(regs.b);
2776 static void Op69(void) // ROL IDX
2784 static void Op79(void) // ROL ABS
2793 +-----------------------------------------------------------------+
2794 | Opcode | | Addressing | | |
2795 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2796 +------------+-------------+--------------+-------+-------+-------+
2797 | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s |
2798 | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s |
2799 | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s |
2800 | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s |
2801 | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s |
2806 #define OP_ROR_HANDLER(m) \
2807 uint8_t res = (flagC << 7) | (m >> 1); \
2813 static void Op06(void) // ROR DP
2821 static void Op46(void) // RORA
2823 OP_ROR_HANDLER(regs.a);
2826 static void Op56(void) // RORB
2828 OP_ROR_HANDLER(regs.b);
2831 static void Op66(void) // ROR IDX
2839 static void Op76(void) // ROR ABS
2848 +-----------------------------------------------------------------+
2849 | Opcode | | Addressing | | |
2850 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2851 +------------+-------------+--------------+-------+-------+-------+
2852 | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
2853 | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
2854 | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
2855 | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
2856 | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
2857 | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
2858 | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
2859 | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
2864 #define OP_SBC_HANDLER(m, acc) \
2865 uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
2866 flagC = (sum >> 8) & 0x01; \
2867 SET_V(m, acc, sum); \
2868 acc = (uint8_t)sum; \
2871 static void Op82(void) // SBCA #
2873 uint8_t m = READ_IMM;
2874 OP_SBC_HANDLER(m, regs.a);
2877 static void Op92(void) // SBCA DP
2879 uint8_t m = READ_DP;
2880 OP_SBC_HANDLER(m, regs.a);
2883 static void OpA2(void) // SBCA IDX
2885 uint8_t m = READ_IDX;
2886 OP_SBC_HANDLER(m, regs.a);
2889 static void OpB2(void) // SBCA ABS
2891 uint8_t m = READ_ABS;
2892 OP_SBC_HANDLER(m, regs.a);
2895 static void OpC2(void) // SBCB #
2897 uint8_t m = READ_IMM;
2898 OP_SBC_HANDLER(m, regs.b);
2901 static void OpD2(void) // SBCB DP
2903 uint8_t m = READ_DP;
2904 OP_SBC_HANDLER(m, regs.b);
2907 static void OpE2(void) // SBCB IDX
2909 uint8_t m = READ_IDX;
2910 OP_SBC_HANDLER(m, regs.b);
2913 static void OpF2(void) // SBCB ABS
2915 uint8_t m = READ_ABS;
2916 OP_SBC_HANDLER(m, regs.b);
2920 +-----------------------------------------------------------------+
2921 | Opcode | | Addressing | | |
2922 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2923 +------------+-------------+--------------+-------+-------+-------+
2924 | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- |
2925 | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- |
2926 | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- |
2927 | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- |
2928 | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- |
2929 | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- |
2930 | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- |
2931 | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- |
2932 | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- |
2933 | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- |
2934 | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- |
2935 | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- |
2936 | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- |
2937 | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- |
2938 | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- |
2939 | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- |
2940 | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- |
2941 | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- |
2942 | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- |
2943 | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- |
2944 | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- |
2949 #define OP_STA_HANDLER(m, acc) \
2950 regs.WrMem(m, acc); \
2954 #define OP_STA_HANDLER16(m, acc) \
2959 static void Op97(void) // STA DP
2961 uint16_t addr = EA_DP;
2962 OP_STA_HANDLER(addr, regs.a);
2965 static void Op9F(void) // STX DP
2967 uint16_t addr = EA_DP;
2968 OP_STA_HANDLER16(addr, regs.x);
2971 static void OpA7(void) // STA IDX
2973 uint16_t addr = EA_IDX;
2974 OP_STA_HANDLER(addr, regs.a);
2977 static void OpAF(void) // STX IDX
2979 uint16_t addr = EA_IDX;
2980 OP_STA_HANDLER16(addr, regs.x);
2983 static void OpB7(void) // STA ABS
2985 uint16_t addr = EA_ABS;
2986 OP_STA_HANDLER(addr, regs.a);
2989 static void OpBF(void) // STX ABS
2991 uint16_t addr = EA_ABS;
2992 OP_STA_HANDLER16(addr, regs.x);
2995 static void OpD7(void) // STB DP
2997 uint16_t addr = EA_DP;
2998 OP_STA_HANDLER(addr, regs.b);
3001 static void OpDD(void) // STD DP
3003 uint16_t addr = EA_DP;
3004 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3007 static void OpDF(void) // STU DP
3009 uint16_t addr = EA_DP;
3010 OP_STA_HANDLER16(addr, regs.u);
3013 static void OpE7(void) // STB IDX
3015 uint16_t addr = EA_IDX;
3016 OP_STA_HANDLER(addr, regs.b);
3019 static void OpED(void) // STD IDX
3021 uint16_t addr = EA_IDX;
3022 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3025 static void OpEF(void) // STU IDX
3027 uint16_t addr = EA_IDX;
3028 OP_STA_HANDLER16(addr, regs.u);
3031 static void OpF7(void) // STB ABS
3033 uint16_t addr = EA_ABS;
3034 OP_STA_HANDLER(addr, regs.b);
3037 static void OpFD(void) // STD ABS
3039 uint16_t addr = EA_ABS;
3040 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3043 static void OpFF(void) // STU ABS
3045 uint16_t addr = EA_ABS;
3046 OP_STA_HANDLER16(addr, regs.u);
3049 static void Op109F(void) // STY DP
3051 uint16_t addr = EA_DP;
3052 OP_STA_HANDLER16(addr, regs.y);
3055 static void Op10AF(void) // STY IDX
3057 uint16_t addr = EA_IDX;
3058 OP_STA_HANDLER16(addr, regs.y);
3061 static void Op10BF(void) // STY ABS
3063 uint16_t addr = EA_ABS;
3064 OP_STA_HANDLER16(addr, regs.y);
3067 static void Op10DF(void) // STS DP
3069 uint16_t addr = EA_DP;
3070 OP_STA_HANDLER16(addr, regs.s);
3073 static void Op10EF(void) // STS IDX
3075 uint16_t addr = EA_IDX;
3076 OP_STA_HANDLER16(addr, regs.s);
3079 static void Op10FF(void) // STS ABS
3081 uint16_t addr = EA_ABS;
3082 OP_STA_HANDLER16(addr, regs.s);
3086 +-----------------------------------------------------------------+
3087 | Opcode | | Addressing | | |
3088 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3089 +------------+-------------+--------------+-------+-------+-------+
3090 | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
3091 | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
3092 | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
3093 | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
3094 | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
3095 | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
3096 | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
3097 | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
3098 | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
3099 | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
3100 | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
3101 | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
3106 #define OP_SUB_HANDLER(m, acc) \
3107 uint16_t sum = (uint16_t)acc - (m); \
3108 flagC = (sum >> 8) & 0x01; \
3109 SET_V(m, acc, sum); \
3110 acc = (uint8_t)sum; \
3113 #define OP_SUB_HANDLER16D(m) \
3114 uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \
3115 uint32_t sum = acc - (m); \
3116 flagC = (sum >> 16) & 0x01; \
3117 SET_V16(m, acc, sum); \
3118 acc = sum & 0xFFFF; \
3119 regs.a = (acc >> 8) & 0xFF; \
3120 regs.b = acc & 0xFF; \
3123 static void Op80(void) // SUBA #
3125 uint8_t m = READ_IMM;
3126 OP_SUB_HANDLER(m, regs.a);
3129 static void Op83(void) // SUBD #
3131 uint16_t m = READ_IMM16;
3132 OP_SUB_HANDLER16D(m);
3135 static void Op90(void) // SUBA DP
3137 uint8_t m = READ_DP;
3138 OP_SUB_HANDLER(m, regs.a);
3141 static void Op93(void) // SUBD DP
3143 uint16_t m = READ_DP16;
3144 OP_SUB_HANDLER16D(m);
3147 static void OpA0(void) // SUBA IDX
3149 uint8_t m = READ_IDX;
3150 OP_SUB_HANDLER(m, regs.a);
3153 static void OpA3(void) // SUBD IDX
3155 uint16_t m = READ_IDX16;
3156 OP_SUB_HANDLER16D(m);
3159 static void OpB0(void) // SUBA ABS
3161 uint8_t m = READ_ABS;
3162 OP_SUB_HANDLER(m, regs.a);
3165 static void OpB3(void) // SUBD ABS
3167 uint16_t m = READ_ABS16;
3168 OP_SUB_HANDLER16D(m);
3171 static void OpC0(void) // SUBB #
3173 uint8_t m = READ_IMM;
3174 OP_SUB_HANDLER(m, regs.b);
3177 static void OpD0(void) // SUBB DP
3179 uint8_t m = READ_DP;
3180 OP_SUB_HANDLER(m, regs.b);
3183 static void OpE0(void) // SUBB IDX
3185 uint8_t m = READ_IDX;
3186 OP_SUB_HANDLER(m, regs.b);
3189 static void OpF0(void) // SUBB ABS
3191 uint8_t m = READ_ABS;
3192 OP_SUB_HANDLER(m, regs.b);
3196 +-----------------------------------------------------------------+
3197 | Opcode | | Addressing | | |
3198 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3199 +------------+-------------+--------------+-------+-------+-------+
3200 | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
3201 | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
3202 | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
3203 | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
3204 | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
3209 #define OP_TST_HANDLER(m) \
3213 static void Op0D(void) // TST DP
3215 uint8_t m = READ_DP;
3219 static void Op4D(void) // TSTA
3221 OP_TST_HANDLER(regs.a);
3224 static void Op5D(void) // TSTB
3226 OP_TST_HANDLER(regs.b);
3229 static void Op6D(void) // TST IDX
3231 uint8_t m = READ_IDX;
3235 static void Op7D(void) // TST ABS
3237 uint8_t m = READ_ABS;
3242 // Undocumented Opcodes
3244 static void Op01(void)
3249 static void Op__(void) // Illegal opcode
3252 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
3259 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
3260 static void Op10(void);
3261 static void Op11(void);
3263 // Array of page zero opcode functions...
3265 static void (* exec_op0[256])() = {
3266 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
3267 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
3268 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
3269 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
3270 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
3271 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
3272 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
3273 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
3274 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
3275 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
3276 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
3277 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
3278 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
3279 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
3280 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
3281 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
3284 // Array of page one opcode functions...
3285 static void (* exec_op1[256])() = {
3286 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3287 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3288 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
3289 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
3290 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3291 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3292 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3293 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3294 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
3295 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
3296 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
3297 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
3298 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
3299 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
3300 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
3301 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
3304 // Array of page two opcode functions...
3305 static void (* exec_op2[256])() = {
3306 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3307 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3308 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3309 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
3310 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3311 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3312 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3313 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3314 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
3315 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
3316 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
3317 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
3318 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3319 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3320 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
3321 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
3324 // These are here to save typing a ton of forward declarations...
3327 static void Op10(void)
3329 uint8_t opcode = regs.RdMem(regs.pc++);
3331 regs.clock += page1Cycles[opcode];
3335 static void Op11(void)
3337 uint8_t opcode = regs.RdMem(regs.pc++);
3339 regs.clock += page2Cycles[opcode];
3343 // Internal "memcpy" (so we don't have to link with any external libraries!)
3345 static void myMemcpy(void * dst, void * src, uint32_t size)
3347 uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
3349 for(uint32_t i=0; i<size; i++)
3354 // Function to execute 6809 instructions
3356 void Execute6809(V6809REGS * context, uint32_t cycles)
3358 // If this is not in place, the clockOverrun calculations can cause the
3359 // V6809 to get stuck in an infinite loop.
3360 if (cycles == 0) // Nothing to do, so bail!
3363 myMemcpy(®s, context, sizeof(V6809REGS));
3364 // Explode flags register into individual uint8_ts
3369 // Since we can't guarantee that we'll execute the number of cycles passed
3370 // in exactly, we have to keep track of how much we overran the number of
3371 // cycles the last time we executed. Since we already executed those
3372 // cycles, this time through we remove them from the cycles passed in in
3373 // order to come out approximately even. Over the long run, this unevenness
3374 // in execution times evens out. :-)
3375 uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun);
3377 while (regs.clock < endCycles)
3379 uint8_t opcode = regs.RdMem(regs.pc++);
3381 regs.clock += page0Cycles[opcode];
3383 // Handle any pending interrupts
3385 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
3386 // uint32_t flags = context->cpuFlags;
3387 uint32_t flags = regs.cpuFlags;
3389 // *** RESET handler ***
3390 if (flags & V6809_LINE_RESET)
3392 flagF = flagI = 1; // Set F, I
3393 regs.dp = 0; // Reset direct page register
3394 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
3395 context->cpuFlags &= ~V6809_LINE_RESET;
3396 regs.cpuFlags &= ~V6809_LINE_RESET;
3398 // *** NMI handler ***
3399 else if (flags & V6809_LINE_NMI)
3401 flagE = 1; // Set Entire flag
3402 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3404 PUSHS16(regs.pc); // Save all regs...
3413 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3414 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
3417 // *** FIRQ handler ***
3418 else if (flags & V6809_LINE_FIRQ)
3420 if (!flagF) // Is the FIRQ masked (F == 1)?
3422 flagE = 0; // Clear Entire flag
3423 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3428 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
3429 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
3433 // *** IRQ handler ***
3434 else if (flags & V6809_LINE_IRQ)
3436 if (!flagI) // Is the IRQ masked (I == 1)?
3438 flagE = 1; // Set the Entire flag
3439 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3450 flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
3451 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
3457 // Keep track of how much we overran so we can adjust on the next run...
3458 regs.clockOverrun = (uint32_t)(regs.clock - endCycles);
3460 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
3461 myMemcpy(context, ®s, sizeof(V6809REGS));
3465 // Get the clock of the currently executing CPU
3467 uint64_t GetCurrentV6809Clock(void)
3473 // Get the PC of the currently executing CPU
3475 uint16_t GetCurrentV6809PC(void)
3480 // Set a line of the currently executing CPU
3481 void SetLineOfCurrentV6809(uint32_t line)
3483 regs.cpuFlags |= line;
3486 // Clear a line of the currently executing CPU
3487 void ClearLineOfCurrentV6809(uint32_t line)
3489 regs.cpuFlags &= ~line;