5 // (c) 1997, 2006 Underground Software
7 // JLH = James L. Hammons <jlhamm@acm.org>
10 // --- ---------- ------------------------------------------------------------
11 // JLH 06/15/2006 Added changelog ;-)
12 // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code
13 // JLH 11/11/2006 Removed all SignedX() references
16 // Mebbe someday I'll get around to fixing the core to be more like V65C02...
17 // We have a start... ;-)
25 #include "dis6809.h" // Temporary...
26 #include "log.h" // Temporary...
27 bool disasm = false;//so we can extern this shit
30 #define TEST_DONT_BRANCH_OPTIMIZATION
34 #define CLR_Z (flagZ = 0)
35 #define CLR_ZN (flagZ = flagN = 0)
36 #define CLR_ZNC (flagZ = flagN = flagC = 0)
37 #define CLR_V (flagV = 0)
38 #define CLR_N (flagN = 0)
39 #define SET_Z(r) (flagZ = ((r) == 0 ? 1 : 0))
40 #define SET_N(r) (flagN = ((r) & 0x80) >> 7)
41 #define SET_N16(r) (flagN = ((r) & 0x8000) >> 15)
42 #define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
43 #define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15)
45 //Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
46 #define SET_C_ADD(a,b) (flagC = ((uint8)(b) > (uint8)(~(a)) ? 1 : 0))
47 //#define SET_C_SUB(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
48 #define SET_C_CMP(a,b) (flagC = ((uint8)(b) >= (uint8)(a) ? 1 : 0))
49 #define SET_ZN(r) SET_N(r); SET_Z(r)
50 #define SET_ZN16(r) SET_N16(r); SET_Z(r)
51 #define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
52 //#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b)
53 #define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b)
55 //Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!!
56 //Hmm, why not do like we did for READ_ABS*???
57 //Because the EA_* macros are usually used as an argument to a function call, that's why.
58 //Now, we CAN fix it using FetchMemW()!!! [DONE]
59 #define EA_IMM regs.pc++
60 #define EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++)
61 #define EA_IDX DecodeIDX(regs.RdMem(regs.pc++))
62 #define EA_ABS FetchMemW(regs.pc)
64 #define READ_IMM regs.RdMem(EA_IMM)
65 #define READ_IMM16 FetchMemW(regs.pc)
66 #define READ_DP regs.RdMem(EA_DP)
67 #define READ_DP16 RdMemW(EA_DP)
68 #define READ_IDX regs.RdMem(EA_IDX)
69 #define READ_IDX16 RdMemW(EA_IDX)
70 #define READ_ABS regs.RdMem(EA_ABS)
71 #define READ_ABS16 RdMemW(EA_ABS)
73 #define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr)
74 #define READ_DP_WB(v) uint16 addr = EA_DP; v = regs.RdMem(addr)
75 #define READ_IDX_WB(v) uint16 addr = EA_IDX; v = regs.RdMem(addr)
76 #define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr)
78 #define WRITE_BACK(d) regs.WrMem(addr, (d))
80 #define PULLS(r) r = regs.RdMem(regs.s++)
81 #define PUSHS(r) regs.WrMem(--regs.s, (r))
82 #define PULLS16(r) { r = RdMemW(regs.s); regs.s += 2; }
83 #define PUSHS16(r) { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); }
84 #define PULLU(r) r = regs.RdMem(regs.u++)
85 #define PUSHU(r) regs.WrMem(--regs.u, (r))
86 #define PULLU16(r) { r = RdMemW(regs.u); regs.u += 2; }
87 #define PUSHU16(r) { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); }
89 #define PACK_FLAGS ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC)
90 #define UNPACK_FLAGS flagE = (regs.cc & FLAG_E) >> 7; \
91 flagF = (regs.cc & FLAG_F) >> 6; \
92 flagH = (regs.cc & FLAG_H) >> 5; \
93 flagI = (regs.cc & FLAG_I) >> 4; \
94 flagN = (regs.cc & FLAG_N) >> 3; \
95 flagZ = (regs.cc & FLAG_Z) >> 2; \
96 flagV = (regs.cc & FLAG_V) >> 1; \
97 flagC = (regs.cc & FLAG_C)
99 // Private global variables
101 static V6809REGS regs;
102 static uint8 flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC;
104 uint8 page0Cycles[256] = {
105 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x
106 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x
107 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x
108 4, 4, 4, 4, 5, 5, 5, 5, 1, 5, 3, 6, 21, 11, 0, 19, // $3x
109 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, // $4x
110 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, // $5x
111 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $6x
112 7, 1, 1, 7, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 3, 7, // $7x
113 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, // $8x
114 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $9x
115 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $Ax
116 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, // $Bx
117 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, // $Cx
118 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Dx
119 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Ex
120 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx
123 uint8 page1Cycles[256] = {
124 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
125 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
126 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x
127 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
129 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
132 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, // $8x
133 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $9x
134 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $Ax
135 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 7, 7, // $Bx
136 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, // $Cx
137 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Dx
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Ex
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx
142 uint8 page2Cycles[256] = {
143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x
144 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x
145 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x
146 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x
147 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x
148 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x
149 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x
150 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x
151 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, // $8x
152 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $9x
153 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $Ax
154 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, // $Bx
155 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Cx
156 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Dx
157 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Ex
158 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx
161 // Private function prototypes
163 static uint16 RdMemW(uint16 addr);
164 static uint16 FetchMemW(uint16 addr);
165 static void WrMemW(uint16 addr, uint16 w);
166 static uint16 ReadEXG(uint8); // Read TFR/EXG post byte
167 static void WriteEXG(uint8, uint16); // Set TFR/EXG data
168 static uint16 DecodeReg(uint8); // Decode register data
169 static uint16 DecodeIDX(uint8); // Decode IDX data
172 // Read word from memory function
174 static inline uint16 RdMemW(uint16 addr)
176 return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
180 // Fetch a word from memory function. Increments PC
182 static inline uint16 FetchMemW(uint16 addr)
185 return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
189 // Write word to memory function
191 static inline void WrMemW(uint16 addr, uint16 w)
193 regs.WrMem(addr + 0, w >> 8);
194 regs.WrMem(addr + 1, w & 0xFF);
198 // Function to read TFR/EXG post byte
200 uint16 ReadEXG(uint8 code)
207 retval = (regs.a << 8) | regs.b;
244 // Function to set TFR/EXG data
246 void WriteEXG(uint8 code, uint16 data)
251 regs.a = data >> 8, regs.b = data & 0xFF; break;
253 regs.x = data; break;
255 regs.y = data; break;
257 regs.u = data; break;
259 regs.s = data; break;
261 regs.pc = data; break;
263 regs.a = data & 0xFF; break;
265 regs.b = data & 0xFF; break;
267 regs.cc = data & 0xFF; break;
269 regs.dp = data & 0xFF; break;
274 // Function to decode register data
276 uint16 DecodeReg(uint8 reg)
283 retval = regs.x; break;
285 retval = regs.y; break;
287 retval = regs.u; break;
289 retval = regs.s; break;
296 // Function to decode IDX data
298 uint16 DecodeIDX(uint8 code)
301 uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F;
303 if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset
304 addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb);
312 woff = DecodeReg(reg);
316 case 0: regs.x += 2; break;
317 case 1: regs.y += 2; break;
318 case 2: regs.u += 2; break;
319 case 3: regs.s += 2; break;
325 case 0: regs.x -= 2; break;
326 case 1: regs.y -= 2; break;
327 case 2: regs.u -= 2; break;
328 case 3: regs.s -= 2; break;
330 woff = DecodeReg(reg);
334 woff = DecodeReg(reg);
338 woff = DecodeReg(reg) + (int16)(int8)regs.b;
342 woff = DecodeReg(reg) + (int16)(int8)regs.a;
346 woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);
350 woff = DecodeReg(reg) + FetchMemW(regs.pc);
354 woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
358 woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);
362 woff = regs.pc + FetchMemW(regs.pc);
366 woff = FetchMemW(regs.pc);
376 addr = DecodeReg(reg);
379 case 0: regs.x++; break;
380 case 1: regs.y++; break;
381 case 2: regs.u++; break;
382 case 3: regs.s++; break;
386 addr = DecodeReg(reg);
389 case 0: regs.x += 2; break;
390 case 1: regs.y += 2; break;
391 case 2: regs.u += 2; break;
392 case 3: regs.s += 2; break;
395 case 2: { switch(reg)
397 case 0: regs.x--; break;
398 case 1: regs.y--; break;
399 case 2: regs.u--; break;
400 case 3: regs.s--; break;
402 addr = DecodeReg(reg); break; }
403 case 3: { switch(reg)
405 case 0: regs.x--; regs.x--; break;
406 case 1: regs.y--; regs.y--; break;
407 case 2: regs.u--; regs.u--; break;
408 case 3: regs.s--; regs.s--; break;
410 addr = DecodeReg(reg); break; }
411 case 4: { addr = DecodeReg(reg); break; }
412 case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; }
413 case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; }
414 case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; }
415 case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; }
416 case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
417 case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; }
418 case 13: { addr = regs.pc + FetchMemW(regs.pc); break; }
429 // 6809 OPCODE IMPLEMENTATION
431 // NOTE: Lots of macros are used here to save a LOT of typing. Also
432 // helps speed the debugging process. :-) Because of this, combining
433 // certain lines may look like a good idea but would end in disaster.
434 // You have been warned! ;-)
438 +-----------------------------------------------------------------+
439 | Opcode | | Addressing | | |
440 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
441 +------------+-------------+--------------+-------+-------+-------+
442 | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa |
443 | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa |
444 | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa |
445 | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa |
446 | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa |
447 | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa |
448 | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa |
449 | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa |
454 #define OP_ADC_HANDLER(m, acc) \
455 uint16 sum = (uint16)acc + (m) + (uint16)flagC; \
456 flagC = (sum >> 8) & 0x01; \
457 flagH = (sum >> 4) & 0x01; \
458 SET_V(m, acc, sum); \
463 Old flag handling code:
464 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
465 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
466 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
467 regs.a = addr & 0xFF; // Set accumulator
468 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
469 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
472 static void Op89(void) // ADCA #
475 OP_ADC_HANDLER(m, regs.a);
478 static void Op99(void) // ADCA DP
481 OP_ADC_HANDLER(m, regs.a);
484 static void OpA9(void) // ADCA IDX
487 OP_ADC_HANDLER(m, regs.a);
490 static void OpB9(void) // ADCA ABS
493 OP_ADC_HANDLER(m, regs.a);
496 static void OpC9(void) // ADCB #
499 OP_ADC_HANDLER(m, regs.b);
502 static void OpD9(void) // ADCB DP
505 OP_ADC_HANDLER(m, regs.b);
508 static void OpE9(void) // ADCB IDX
511 OP_ADC_HANDLER(m, regs.b);
514 static void OpF9(void) // ADCB ABS
517 OP_ADC_HANDLER(m, regs.b);
521 +-----------------------------------------------------------------+
522 | Opcode | | Addressing | | |
523 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
524 +------------+-------------+--------------+-------+-------+-------+
525 | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- |
526 | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa |
527 | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa |
528 | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa |
529 | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa |
530 | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa |
531 | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa |
532 | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa |
533 | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa |
534 | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa |
535 | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa |
536 | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa |
537 | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa |
542 #define OP_ADD_HANDLER(m, acc) \
543 uint16 sum = (uint16)(acc) + (m); \
544 flagC = (sum >> 8) & 0x01; \
545 flagH = (sum >> 4) & 0x01; \
546 SET_V(m, acc, sum); \
547 (acc) = sum & 0xFF; \
550 #define OP_ADD_HANDLER16(m, hireg, loreg) \
551 uint32 acc = (uint32)((hireg << 8) | loreg); \
552 uint32 sum = acc + (m); \
553 flagC = (sum >> 16) & 0x01; \
554 SET_V16(m, acc, sum); \
555 acc = sum & 0xFFFF; \
556 hireg = (acc >> 8) & 0xFF; \
557 loreg = acc & 0xFF; \
562 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
563 ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
564 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
565 regs.a = addr & 0xFF; // Set accumulator
566 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
567 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
570 (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
572 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
573 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
574 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
575 regs.a = dr>>8; regs.b = dr&0xFF;
579 static void Op3A(void) // ABX
581 regs.x += (uint16)regs.b;
584 static void Op8B(void) // ADDA #
587 OP_ADD_HANDLER(m, regs.a);
590 static void Op9B(void) // ADDA DP
593 OP_ADD_HANDLER(m, regs.a);
596 static void OpAB(void) // ADDA IDX
599 OP_ADD_HANDLER(m, regs.a);
602 static void OpBB(void) // ADDA ABS
605 OP_ADD_HANDLER(m, regs.a);
608 static void OpC3(void) // ADDD #
610 uint32 m = READ_IMM16;
611 OP_ADD_HANDLER16(m, regs.a, regs.b);
614 static void OpCB(void) // ADDB #
617 OP_ADD_HANDLER(m, regs.b);
620 static void OpD3(void) // ADDD DP
622 uint32 m = READ_DP16;
623 OP_ADD_HANDLER16(m, regs.a, regs.b);
626 static void OpDB(void) // ADDB DP
629 OP_ADD_HANDLER(m, regs.b);
632 static void OpE3(void) // ADDD IDX
634 uint32 m = READ_IDX16;
635 OP_ADD_HANDLER16(m, regs.a, regs.b);
638 static void OpEB(void) // ADDB IDX
641 OP_ADD_HANDLER(m, regs.b);
644 static void OpF3(void) // ADDD ABS
646 uint32 m = READ_ABS16;
647 OP_ADD_HANDLER16(m, regs.a, regs.b);
650 static void OpFB(void) // ADDB ABS
653 OP_ADD_HANDLER(m, regs.b);
657 +-----------------------------------------------------------------+
658 | Opcode | | Addressing | | |
659 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
660 +------------+-------------+--------------+-------+-------+-------+
661 | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- |
662 | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- |
663 | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- |
664 | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- |
665 | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- |
666 | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- |
667 | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- |
668 | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- |
673 #define OP_AND_HANDLER(m, acc) \
678 static void Op84(void) // ANDA #
681 OP_AND_HANDLER(m, regs.a);
684 static void Op94(void) // ANDA DP
687 OP_AND_HANDLER(m, regs.a);
690 static void OpA4(void) // ANDA IDX
693 OP_AND_HANDLER(m, regs.a);
696 static void OpB4(void) // ANDA ABS
699 OP_AND_HANDLER(m, regs.a);
702 static void OpC4(void) // ANDB #
705 OP_AND_HANDLER(m, regs.b);
708 static void OpD4(void) // ANDB DP
711 OP_AND_HANDLER(m, regs.b);
714 static void OpE4(void) // ANDB IDX
717 OP_AND_HANDLER(m, regs.b);
720 static void OpF4(void) // ANDB ABS
723 OP_AND_HANDLER(m, regs.b);
727 +-----------------------------------------------------------------+
728 | Opcode | | Addressing | | |
729 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
730 +------------+-------------+--------------+-------+-------+-------+
731 | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas |
732 | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas |
733 | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas |
734 | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas |
735 | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas |
740 #define OP_ASL_HANDLER(m) \
741 uint16 res = m << 1; \
743 flagC = (res >> 8) & 0x01; \
747 static void Op08(void) // ASL DP
755 static void Op48(void) // ASLA
757 OP_ASL_HANDLER(regs.a);
760 static void Op58(void) // ASLB
762 OP_ASL_HANDLER(regs.b);
765 static void Op68(void) // ASL IDX
773 static void Op78(void) // ASL ABS
782 +-----------------------------------------------------------------+
783 | Opcode | | Addressing | | |
784 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
785 +------------+-------------+--------------+-------+-------+-------+
786 | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s |
787 | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s |
788 | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s |
789 | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s |
790 | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s |
793 // ASR opcodes (arithmetic, so preserves the sign)
795 #define OP_ASR_HANDLER(m) \
796 uint8 res = (m & 0x80) | (m >> 1); \
801 static void Op07(void) // ASR DP
809 static void Op47(void) // ASRA
811 OP_ASR_HANDLER(regs.a);
814 static void Op57(void) // ASRB
816 OP_ASR_HANDLER(regs.b);
819 static void Op67(void) // ASR IDX
827 static void Op77(void) // ASR ABS
836 +-----------------------------------------------------------------+
837 | Opcode | | Addressing | | |
838 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
839 +------------+-------------+--------------+-------+-------+-------+
840 | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- |
841 | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- |
842 | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- |
843 | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- |
844 | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- |
845 | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- |
846 | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- |
847 | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- |
848 | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- |
849 | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- |
850 | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- |
851 | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- |
852 | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- |
853 | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- |
854 | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- |
855 | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- |
856 | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- |
857 | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- |
858 | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- |
859 | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- |
860 | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- |
861 | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- |
862 | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- |
863 | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- |
864 | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- |
865 | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- |
866 | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- |
867 | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- |
868 | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- |
869 | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- |
870 | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- |
871 | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- |
876 static void Op16(void) // LBRA
878 uint16 offset = READ_IMM16;
882 static void Op20(void) // BRA
884 int16 offset = (int16)(int8)READ_IMM;
888 static void Op21(void) // BRN
890 // This is basically a 2 byte NOP
891 int16 offset = (int16)(int8)READ_IMM;
894 static void Op22(void) // BHI
897 int16 offset = (int16)(int8)READ_IMM;
899 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
900 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
901 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
903 if (!(flagZ || flagC))
908 static void Op23(void) // BLS
911 int16 offset = (int16)(int8)READ_IMM;
913 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
914 regs.pc += offset * (flagZ | flagC);
921 static void Op24(void) // BHS/CC
924 int16 offset = (int16)(int8)READ_IMM;
926 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
927 regs.pc += offset * (flagC ^ 0x01);
934 static void Op25(void) // BLO/CS
937 int16 offset = (int16)(int8)READ_IMM;
939 // WriteLog("[offset=%04X,flagC=%08X]", offset, flagC);
941 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
942 regs.pc += offset * flagC;
949 static void Op26(void) // BNE
952 int16 offset = (int16)(int8)READ_IMM;
954 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
955 regs.pc += offset * (flagZ ^ 0x01);
962 static void Op27(void) // BEQ
965 int16 offset = (int16)(int8)READ_IMM;
967 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
968 regs.pc += offset * flagZ;
975 static void Op28(void) // BVC
978 int16 offset = (int16)(int8)READ_IMM;
980 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
981 regs.pc += offset * (flagV ^ 0x01);
988 static void Op29(void) // BVS
991 int16 offset = (int16)(int8)READ_IMM;
993 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
994 regs.pc += offset * flagV;
1001 static void Op2A(void) // BPL
1004 int16 offset = (int16)(int8)READ_IMM;
1006 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1007 regs.pc += offset * (flagN ^ 0x01);
1014 static void Op2B(void) // BMI
1017 int16 offset = (int16)(int8)READ_IMM;
1019 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1020 regs.pc += offset * flagN;
1027 static void Op2C(void) // BGE
1029 // (N && V) || (!N && !V)
1030 int16 offset = (int16)(int8)READ_IMM;
1032 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1033 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1035 if ((flagN && flagV) || (!flagN && !flagV))
1040 static void Op2D(void) // BLT
1042 // (N && !V) || (!N && V)
1043 int16 offset = (int16)(int8)READ_IMM;
1045 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1046 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1048 if ((flagN && !flagV) || (!flagN && flagV))
1053 static void Op2E(void) // BGT
1055 // (N && V && !Z) || (!N && !V && !Z)
1056 int16 offset = (int16)(int8)READ_IMM;
1058 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1059 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1061 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1066 static void Op2F(void) // BLE
1068 // Z || (N && !V) || (!N && V)
1069 int16 offset = (int16)(int8)READ_IMM;
1071 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1072 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1074 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1079 static void Op1021(void) // LBRN
1081 // This is basically a 4 byte NOP
1082 uint16 offset = READ_IMM16;
1085 static void Op1022(void) // LBHI
1088 uint16 offset = READ_IMM16;
1090 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1091 //Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)...
1092 regs.pc += offset * ((flagZ | flagC) ^ 0x01);
1094 if (!(flagZ || flagC))
1099 static void Op1023(void) // LBLS
1102 uint16 offset = READ_IMM16;
1104 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1105 regs.pc += offset * (flagZ | flagC);
1112 static void Op1024(void) // LBHS/CC
1115 uint16 offset = READ_IMM16;
1117 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1118 regs.pc += offset * (flagC ^ 0x01);
1125 static void Op1025(void) // LBLO/CS
1128 uint16 offset = READ_IMM16;
1130 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1131 regs.pc += offset * flagC;
1138 static void Op1026(void) // LBNE
1141 uint16 offset = READ_IMM16;
1143 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1144 regs.pc += offset * (flagZ ^ 0x01);
1151 static void Op1027(void) // LBEQ
1154 uint16 offset = READ_IMM16;
1156 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1157 regs.pc += offset * flagZ;
1164 static void Op1028(void) // LBVC
1167 uint16 offset = READ_IMM16;
1169 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1170 regs.pc += offset * (flagV ^ 0x01);
1177 static void Op1029(void) // LBVS
1180 uint16 offset = READ_IMM16;
1182 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1183 regs.pc += offset * flagV;
1190 static void Op102A(void) // LBPL
1193 uint16 offset = READ_IMM16;
1195 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1196 regs.pc += offset * (flagN ^ 0x01);
1203 static void Op102B(void) // LBMI
1206 uint16 offset = READ_IMM16;
1208 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1209 regs.pc += offset * flagN;
1216 static void Op102C(void) // LBGE
1218 // (N && V) || (!N && !V)
1219 uint16 offset = READ_IMM16;
1221 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1222 regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01)));
1224 if ((flagN && flagV) || (!flagN && !flagV))
1229 static void Op102D(void) // LBLT
1231 // (N && !V) || (!N && V)
1232 uint16 offset = READ_IMM16;
1234 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1235 regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1237 if ((flagN && !flagV) || (!flagN && flagV))
1242 static void Op102E(void) // LBGT
1244 // (N && V && !Z) || (!N && !V && !Z)
1245 uint16 offset = READ_IMM16;
1247 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1248 regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01)));
1250 if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ))
1255 static void Op102F(void) // LBLE
1257 // Z || (N && !V) || (!N && V)
1258 uint16 offset = READ_IMM16;
1260 #ifdef TEST_DONT_BRANCH_OPTIMIZATION
1261 regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV));
1263 if (flagZ || (flagN && !flagV) || (!flagN && flagV))
1269 +-----------------------------------------------------------------+
1270 | Opcode | | Addressing | | |
1271 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1272 +------------+-------------+--------------+-------+-------+-------+
1273 | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- |
1274 | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- |
1275 | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- |
1276 | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- |
1277 | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- |
1278 | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- |
1279 | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- |
1280 | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- |
1285 #define OP_BIT_HANDLER(m, acc) \
1286 uint8 result = acc & (m); \
1290 static void Op85(void) // BITA #
1293 OP_BIT_HANDLER(m, regs.a);
1296 static void Op95(void) // BITA DP
1299 OP_BIT_HANDLER(m, regs.a);
1302 static void OpA5(void) // BITA IDX
1305 OP_BIT_HANDLER(m, regs.a);
1308 static void OpB5(void) // BITA ABS
1311 OP_BIT_HANDLER(m, regs.a);
1314 static void OpC5(void) // BITB #
1317 OP_BIT_HANDLER(m, regs.b);
1320 static void OpD5(void) // BITB DP
1323 OP_BIT_HANDLER(m, regs.b);
1326 static void OpE5(void) // BITB IDX
1329 OP_BIT_HANDLER(m, regs.b);
1332 static void OpF5(void) // BITB ABS
1335 OP_BIT_HANDLER(m, regs.b);
1339 +-----------------------------------------------------------------+
1340 | Opcode | | Addressing | | |
1341 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1342 +------------+-------------+--------------+-------+-------+-------+
1343 | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 |
1344 | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 |
1345 | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 |
1346 | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 |
1347 | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 |
1352 #define OP_CLR_HANDLER(m) \
1353 flagN = flagV = flagC = 0; \
1357 static void Op0F(void) // CLR DP
1365 static void Op4F(void) // CLRA
1367 OP_CLR_HANDLER(regs.a);
1370 static void Op5F(void) // CLRB
1372 OP_CLR_HANDLER(regs.b);
1375 static void Op6F(void) // CLR IDX
1383 static void Op7F(void) // CLR ABS
1392 +-----------------------------------------------------------------+
1393 | Opcode | | Addressing | | |
1394 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1395 +------------+-------------+--------------+-------+-------+-------+
1396 | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa |
1397 | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa |
1398 | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa |
1399 | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa |
1400 | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa |
1401 | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa |
1402 | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa |
1403 | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa |
1404 | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa |
1405 | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa |
1406 | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa |
1407 | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa |
1408 | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa |
1409 | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa |
1410 | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa |
1411 | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa |
1412 | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa |
1413 | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa |
1414 | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa |
1415 | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa |
1416 | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa |
1417 | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa |
1418 | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa |
1419 | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa |
1420 | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa |
1421 | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa |
1422 | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa |
1423 | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa |
1428 #define OP_CMP_HANDLER(m, acc) \
1429 uint16 sum = (uint16)(acc) - (m); \
1430 flagC = (sum >> 8) & 0x01; \
1431 SET_V(m, acc, sum); \
1434 #define OP_CMP_HANDLER16(m, acc) \
1435 uint32 sum = (uint32)(acc) - (m); \
1436 flagC = (sum >> 16) & 0x01; \
1437 SET_V16(m, acc, sum); \
1440 static void Op81(void) // CMPA #
1443 OP_CMP_HANDLER(m, regs.a);
1446 static void Op8C(void) // CMPX #
1448 uint16 m = READ_IMM16;
1449 OP_CMP_HANDLER16(m, regs.x);
1452 static void Op91(void) // CMPA DP
1455 OP_CMP_HANDLER(m, regs.a);
1458 static void Op9C(void) // CMPX DP
1460 uint16 m = READ_DP16;
1461 OP_CMP_HANDLER16(m, regs.x);
1464 static void OpA1(void) // CMPA IDX
1467 OP_CMP_HANDLER(m, regs.a);
1470 static void OpAC(void) // CMPX IDX
1472 uint16 m = READ_IDX16;
1473 OP_CMP_HANDLER16(m, regs.x);
1476 static void OpB1(void) // CMPA ABS
1479 OP_CMP_HANDLER(m, regs.a);
1482 static void OpBC(void) // CMPX ABS
1484 uint16 m = READ_ABS16;
1485 OP_CMP_HANDLER16(m, regs.x);
1488 static void OpC1(void) // CMPB #
1491 OP_CMP_HANDLER(m, regs.b);
1494 static void OpD1(void) // CMPB DP
1497 OP_CMP_HANDLER(m, regs.b);
1500 static void OpE1(void) // CMPB IDX
1503 OP_CMP_HANDLER(m, regs.b);
1506 static void OpF1(void) // CMPB ABS
1509 OP_CMP_HANDLER(m, regs.b);
1512 static void Op1083(void) // CMPD #
1514 uint16 m = READ_IMM16;
1515 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1518 static void Op108C(void) // CMPY #
1520 uint16 m = READ_IMM16;
1521 OP_CMP_HANDLER16(m, regs.y);
1524 static void Op1093(void) // CMPD DP
1526 uint16 m = READ_DP16;
1527 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1530 static void Op109C(void) // CMPY DP
1532 uint16 m = READ_DP16;
1533 OP_CMP_HANDLER16(m, regs.y);
1536 static void Op10A3(void) // CMPD IDX
1538 uint16 m = READ_IDX16;
1539 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1542 static void Op10AC(void) // CMPY IDX
1544 uint16 m = READ_IDX16;
1545 OP_CMP_HANDLER16(m, regs.y);
1548 static void Op10B3(void) // CMPD ABS
1550 uint16 m = READ_ABS16;
1551 OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b);
1554 static void Op10BC(void) // CMPY ABS
1556 uint16 m = READ_ABS16;
1557 OP_CMP_HANDLER16(m, regs.y);
1560 static void Op1183(void) // CMPU #
1562 uint16 m = READ_IMM16;
1563 OP_CMP_HANDLER16(m, regs.u);
1566 static void Op118C(void) // CMPS #
1568 uint16 m = READ_IMM16;
1569 OP_CMP_HANDLER16(m, regs.s);
1572 static void Op1193(void) // CMPU DP
1574 uint16 m = READ_DP16;
1575 OP_CMP_HANDLER16(m, regs.u);
1578 static void Op119C(void) // CMPS DP
1580 uint16 m = READ_DP16;
1581 OP_CMP_HANDLER16(m, regs.s);
1584 static void Op11A3(void) // CMPU IDX
1586 uint16 m = READ_IDX16;
1587 OP_CMP_HANDLER16(m, regs.u);
1590 static void Op11AC(void) // CMPS IDX
1592 uint16 m = READ_IDX16;
1593 OP_CMP_HANDLER16(m, regs.s);
1596 static void Op11B3(void) // CMPU ABS
1598 uint16 m = READ_ABS16;
1599 OP_CMP_HANDLER16(m, regs.u);
1602 static void Op11BC(void) // CMPS ABS
1604 uint16 m = READ_ABS16;
1605 OP_CMP_HANDLER16(m, regs.s);
1609 +-----------------------------------------------------------------+
1610 | Opcode | | Addressing | | |
1611 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1612 +------------+-------------+--------------+-------+-------+-------+
1613 | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 |
1614 | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 |
1615 | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 |
1616 | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 |
1617 | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 |
1622 #define OP_COM_HANDLER(m) \
1628 static void Op03(void) // COM DP
1636 static void Op43(void) // COMA
1638 OP_COM_HANDLER(regs.a);
1641 static void Op53(void) // COMB
1643 OP_COM_HANDLER(regs.b);
1646 static void Op63(void) // COM IDX
1654 static void Op73(void) // COM ABS
1663 +-----------------------------------------------------------------+
1664 | Opcode | | Addressing | | |
1665 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1666 +------------+-------------+--------------+-------+-------+-------+
1667 | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- |
1668 | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd |
1669 | 3E 0062 | RESET* | INHERENT | * | 1 | ***** |
1670 | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- |
1671 | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- |
1672 | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- |
1675 static void Op13(void) // SYNC
1677 #warning "!!! SYNC not implemented !!!"
1679 /* SYNC stops processing instructions until an interrupt request happens. */
1680 /* This doesn't require the corresponding interrupt to be enabled: if it */
1681 /* is disabled, execution continues with the next instruction. */
1682 m68_state->int_state |= M6809_SYNC; /* HJB 990227 */
1683 check_irq_lines(m68_state);
1684 /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state),
1685 * stop execution until the interrupt lines change. */
1686 if( m68_state->int_state & M6809_SYNC )
1687 if (m68_state->icount > 0) m68_state->icount = 0;
1691 static void Op3C(void) // CWAI
1693 #warning "!!! CWAI not implemented !!!"
1699 * CWAI stacks the entire machine state on the hardware stack,
1700 * then waits for an interrupt; when the interrupt is taken
1701 * later, the state is *not* saved again after CWAI.
1703 CC |= CC_E; /* HJB 990225: save entire state */
1712 m68_state->int_state |= M6809_CWAI; /* HJB 990228 */
1713 check_irq_lines(m68_state); /* HJB 990116 */
1714 if( m68_state->int_state & M6809_CWAI )
1715 if( m68_state->icount > 0 )
1716 m68_state->icount = 0;
1720 static void Op3E(void) // RESET
1722 regs.cpuFlags |= V6809_ASSERT_LINE_RESET;
1725 static void Op3F(void) // SWI
1728 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1738 regs.pc = RdMemW(0xFFFA);
1741 static void Op103F(void) // SWI2
1744 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1753 regs.pc = RdMemW(0xFFF4);
1756 static void Op113F(void) // SWI3
1759 regs.cc = PACK_FLAGS; // Mash flags into CC byte
1768 regs.pc = RdMemW(0xFFF2);
1772 +-----------------------------------------------------------------+
1773 | Opcode | | Addressing | | |
1774 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1775 +------------+-------------+--------------+-------+-------+-------+
1776 | 12 0018 | NOP | INHERENT | 2 | 1 | ----- |
1777 | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a |
1778 | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd |
1779 | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd |
1780 | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- |
1783 static void Op12() // NOP
1787 static void Op19() // DAA
1789 uint16 result = (uint16)regs.a;
1791 if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
1794 if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
1797 regs.a = (uint8)result;
1800 flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
1803 static void Op1A() // ORCC
1805 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1806 regs.cc |= READ_IMM;
1807 UNPACK_FLAGS; // & unmash 'em
1810 static void Op1C() // ANDCC
1812 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
1813 regs.cc &= READ_IMM;
1814 UNPACK_FLAGS; // & unmash 'em
1817 static void Op1D() // SEX
1819 regs.a = (regs.b & 0x80 ? 0xFF : 0x00);
1820 SET_ZN16((regs.a << 8) | regs.b);
1825 +-----------------------------------------------------------------+
1826 | Opcode | | Addressing | | |
1827 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1828 +------------+-------------+--------------+-------+-------+-------+
1829 | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- |
1830 | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- |
1831 | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- |
1832 | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- |
1833 | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- |
1836 // DEC opcodes (If we went from $80 -> $7F, sign overflowed.)
1838 #define OP_DEC_HANDLER(m) \
1841 flagV = (m == 0x7F ? 1 : 0)
1843 static void Op0A(void) // DEC DP
1851 static void Op4A(void) // DECA
1853 OP_DEC_HANDLER(regs.a);
1856 static void Op5A(void) // DECB
1858 OP_DEC_HANDLER(regs.b);
1861 static void Op6A(void) // DEC IDX
1869 static void Op7A(void) // DEC ABS
1878 +-----------------------------------------------------------------+
1879 | Opcode | | Addressing | | |
1880 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1881 +------------+-------------+--------------+-------+-------+-------+
1882 | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- |
1883 | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- |
1884 | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- |
1885 | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- |
1886 | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- |
1887 | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- |
1888 | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- |
1889 | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- |
1894 #define OP_EOR_HANDLER(m, acc) \
1899 static void Op88(void) // EORA #
1902 OP_EOR_HANDLER(m, regs.a);
1905 static void Op98(void) // EORA DP
1908 OP_EOR_HANDLER(m, regs.a);
1911 static void OpA8(void) // EORA IDX
1914 OP_EOR_HANDLER(m, regs.a);
1917 static void OpB8(void) // EORA ABS
1920 OP_EOR_HANDLER(m, regs.a);
1923 static void OpC8(void) // EORB #
1926 OP_EOR_HANDLER(m, regs.b);
1929 static void OpD8(void) // EORB DP
1932 OP_EOR_HANDLER(m, regs.b);
1935 static void OpE8(void) // EORB IDX
1938 OP_EOR_HANDLER(m, regs.b);
1941 static void OpF8(void) // EORB ABS
1944 OP_EOR_HANDLER(m, regs.b);
1948 +-----------------------------------------------------------------+
1949 | Opcode | | Addressing | | |
1950 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
1951 +------------+-------------+--------------+-------+-------+-------+
1952 | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- |
1953 | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- |
1954 | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- |
1955 | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- |
1956 | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- |
1959 // INC opcodes (If we went from $7F -> $80, sign overflowed.)
1961 #define OP_INC_HANDLER(m) \
1964 flagV = (m == 0x80 ? 1 : 0)
1966 static void Op0C(void) // INC DP
1974 static void Op4C(void) // INCA
1976 OP_INC_HANDLER(regs.a);
1979 static void Op5C(void) // INCB
1981 OP_INC_HANDLER(regs.b);
1984 static void Op6C(void) // INC IDX
1992 static void Op7C(void) // INC ABS
2001 +-----------------------------------------------------------------+
2002 | Opcode | | Addressing | | |
2003 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2004 +------------+-------------+--------------+-------+-------+-------+
2005 | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- |
2006 | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- |
2007 | 39 0057 | RTS | INHERENT | 5 | 1 | ----- |
2008 | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- |
2009 | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- |
2010 | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- |
2011 | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- |
2012 | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- |
2013 | AD 0173 | JSR | INDEXED | 7 | 2 | ----- |
2014 | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- |
2017 static void Op0E(void) // JMP DP
2022 static void Op17(void) // LBSR
2024 uint16 word = FetchMemW(regs.pc);
2029 static void Op39(void) // RTS
2034 static void Op3B(void) // RTI
2039 // If E flag set, pull all regs
2054 static void Op6E(void) // JMP IDX
2059 static void Op7E(void) // JMP ABS
2064 static void Op8D(void) // BSR
2066 uint16 word = (int16)(int8)READ_IMM;
2071 static void Op9D(void) // JSR DP
2073 uint16 word = EA_DP;
2078 static void OpAD(void) // JSR IDX
2080 uint16 word = EA_IDX;
2085 static void OpBD(void) // JSR ABS
2087 uint16 word = EA_ABS;
2093 +-----------------------------------------------------------------+
2094 | Opcode | | Addressing | | |
2095 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2096 +------------+-------------+--------------+-------+-------+-------+
2097 | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc |
2098 | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc |
2101 static void Op1E(void) // EXG
2104 uint8 reg1 = m >> 4, reg2 = m & 0x0F;
2105 uint16 acc = ReadEXG(reg1);
2106 WriteEXG(reg1, ReadEXG(reg2));
2107 WriteEXG(reg2, acc);
2110 static void Op1F(void) // TFR
2113 WriteEXG(m & 0x0F, ReadEXG(m >> 4));
2117 +-----------------------------------------------------------------+
2118 | Opcode | | Addressing | | |
2119 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2120 +------------+-------------+--------------+-------+-------+-------+
2121 | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- |
2122 | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- |
2123 | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- |
2124 | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- |
2125 | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- |
2126 | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- |
2127 | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- |
2128 | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- |
2129 | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- |
2130 | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- |
2131 | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- |
2132 | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- |
2133 | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- |
2134 | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- |
2135 | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- |
2136 | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- |
2137 | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- |
2138 | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- |
2139 | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- |
2140 | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- |
2141 | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- |
2142 | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- |
2143 | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- |
2144 | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- |
2145 | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- |
2146 | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- |
2147 | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- |
2148 | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- |
2153 #define OP_LDA_HANDLER(m, acc) \
2158 #define OP_LDA_HANDLER16(m, acc) \
2163 #define OP_LDA_HANDLER16D(m) \
2164 regs.a = (m >> 8); \
2165 regs.b = m & 0xFF; \
2169 static void Op86(void) // LDA #
2172 OP_LDA_HANDLER(m, regs.a);
2175 static void Op8E(void) // LDX #
2177 uint16 m = READ_IMM16;
2178 OP_LDA_HANDLER16(m, regs.x);
2181 static void Op96(void) // LDA DP
2184 OP_LDA_HANDLER(m, regs.a);
2187 static void Op9E(void) // LDX DP
2189 uint16 m = READ_DP16;
2190 OP_LDA_HANDLER16(m, regs.x);
2193 static void OpA6(void) // LDA IDX
2196 OP_LDA_HANDLER(m, regs.a);
2199 static void OpAE(void) // LDX IDX
2201 uint16 m = READ_IDX16;
2202 OP_LDA_HANDLER16(m, regs.x);
2205 static void OpB6(void) // LDA ABS
2208 OP_LDA_HANDLER(m, regs.a);
2211 static void OpBE(void) // LDX ABS
2213 uint16 m = READ_ABS16;
2214 OP_LDA_HANDLER16(m, regs.x);
2217 static void OpC6(void) // LDB #
2220 OP_LDA_HANDLER(m, regs.b);
2223 static void OpCC(void) // LDD #
2225 uint16 m = READ_IMM16;
2226 OP_LDA_HANDLER16D(m);
2229 static void OpCE(void) // LDU #
2231 uint16 m = READ_IMM16;
2232 OP_LDA_HANDLER16(m, regs.u);
2235 static void OpD6(void) // LDB DP
2238 OP_LDA_HANDLER(m, regs.b);
2241 static void OpDC(void) // LDD DP
2243 uint16 m = READ_DP16;
2244 OP_LDA_HANDLER16D(m);
2247 static void OpDE(void) // LDU DP
2249 uint16 m = READ_DP16;
2250 OP_LDA_HANDLER16(m, regs.u);
2253 static void OpE6(void) // LDB IDX
2256 OP_LDA_HANDLER(m, regs.b);
2259 static void OpEC(void) // LDD IDX
2261 uint16 m = READ_IDX16;
2262 OP_LDA_HANDLER16D(m);
2265 static void OpEE(void) // LDU IDX
2267 uint16 m = READ_IDX16;
2268 OP_LDA_HANDLER16(m, regs.u);
2271 static void OpF6(void) // LDB ABS
2274 OP_LDA_HANDLER(m, regs.b);
2277 static void OpFC(void) // LDD ABS
2279 uint16 m = READ_ABS16;
2280 OP_LDA_HANDLER16D(m);
2283 static void OpFE(void) // LDU ABS
2285 uint16 m = READ_ABS16;
2286 OP_LDA_HANDLER16(m, regs.u);
2289 static void Op108E(void) // LDY #
2291 uint16 m = READ_IMM16;
2292 OP_LDA_HANDLER16(m, regs.y);
2295 static void Op109E(void) // LDY DP
2297 uint16 m = READ_DP16;
2298 OP_LDA_HANDLER16(m, regs.y);
2301 static void Op10AE(void) // LDY IDX
2303 uint16 m = READ_IDX16;
2304 OP_LDA_HANDLER16(m, regs.y);
2307 static void Op10BE(void) // LDY ABS
2309 uint16 m = READ_ABS16;
2310 OP_LDA_HANDLER16(m, regs.y);
2313 static void Op10CE(void) // LDS #
2315 uint16 m = READ_IMM16;
2316 OP_LDA_HANDLER16(m, regs.s);
2319 static void Op10DE(void) // LDS DP
2321 uint16 m = READ_DP16;
2322 OP_LDA_HANDLER16(m, regs.s);
2325 static void Op10EE(void) // LDS IDX
2327 uint16 m = READ_IDX16;
2328 OP_LDA_HANDLER16(m, regs.s);
2331 static void Op10FE(void) // LDS ABS
2333 uint16 m = READ_ABS16;
2334 OP_LDA_HANDLER16(m, regs.s);
2338 +-----------------------------------------------------------------+
2339 | Opcode | | Addressing | | |
2340 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2341 +------------+-------------+--------------+-------+-------+-------+
2342 | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- |
2343 | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- |
2344 | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- |
2345 | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- |
2348 static void Op30(void) // LEAX
2354 static void Op31(void) // LEAY
2360 static void Op32(void) // LEAS
2365 static void Op33(void) // LEAU
2371 +-----------------------------------------------------------------+
2372 | Opcode | | Addressing | | |
2373 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2374 +------------+-------------+--------------+-------+-------+-------+
2375 | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s |
2376 | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s |
2377 | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s |
2378 | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s |
2379 | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s |
2384 #define OP_LSR_HANDLER(m) \
2389 static void Op04(void) // LSR DP
2397 static void Op44(void) // LSRA
2399 OP_LSR_HANDLER(regs.a);
2402 static void Op54(void) // LSRB
2404 OP_LSR_HANDLER(regs.b);
2407 static void Op64(void) // LSR IDX
2415 static void Op74(void) // LSR ABS
2424 +-----------------------------------------------------------------+
2425 | Opcode | | Addressing | | |
2426 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2427 +------------+-------------+--------------+-------+-------+-------+
2428 | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a |
2431 static void Op3D(void) // MUL
2433 uint16 prod = regs.a * regs.b;
2435 regs.b = prod & 0xFF;
2437 // flagC = (prod & 0x0080 ? 1 : 0);
2438 flagC = (prod >> 7) & 0x01;
2442 +-----------------------------------------------------------------+
2443 | Opcode | | Addressing | | |
2444 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2445 +------------+-------------+--------------+-------+-------+-------+
2446 | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa |
2447 | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa |
2448 | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa |
2449 | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa |
2450 | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa |
2455 #define OP_NEG_HANDLER(m) \
2459 flagC = (res >= 0x80 ? 1 : 0); \
2469 #define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);}
2470 #define SET_C8(a) CC|=((a&0x100)>>8)
2472 static void Op00(void) // NEG DP
2480 static void Op40(void) // NEGA
2482 OP_NEG_HANDLER(regs.a);
2485 static void Op50(void) // NEGB
2487 OP_NEG_HANDLER(regs.b);
2490 static void Op60(void) // NEG IDX
2498 static void Op70(void) // NEG ABS
2507 +-----------------------------------------------------------------+
2508 | Opcode | | Addressing | | |
2509 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2510 +------------+-------------+--------------+-------+-------+-------+
2511 | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- |
2512 | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- |
2513 | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- |
2514 | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- |
2515 | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- |
2516 | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- |
2517 | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- |
2518 | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- |
2523 #define OP_OR_HANDLER(m, acc) \
2528 static void Op8A(void) // ORA #
2531 OP_OR_HANDLER(m, regs.a);
2534 static void Op9A(void) // ORA DP
2537 OP_OR_HANDLER(m, regs.a);
2540 static void OpAA(void) // ORA IDX
2543 OP_OR_HANDLER(m, regs.a);
2546 static void OpBA(void) // ORA ABS
2549 OP_OR_HANDLER(m, regs.a);
2552 static void OpCA(void) // ORB #
2555 OP_OR_HANDLER(m, regs.b);
2558 static void OpDA(void) // ORB DP
2561 OP_OR_HANDLER(m, regs.b);
2564 static void OpEA(void) // ORB IDX
2567 OP_OR_HANDLER(m, regs.b);
2570 static void OpFA(void) // ORB ABS
2573 OP_OR_HANDLER(m, regs.b);
2577 +-----------------------------------------------------------------+
2578 | Opcode | | Addressing | | |
2579 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2580 +------------+-------------+--------------+-------+-------+-------+
2581 | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- |
2582 | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc |
2583 | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- |
2584 | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc |
2587 static void Op34(void) // PSHS
2607 regs.cc = PACK_FLAGS;
2612 static void Op35(void) // PULS
2637 static void Op36(void) // PHSU
2657 regs.cc = PACK_FLAGS;
2662 static void Op37(void) // PULU
2688 +-----------------------------------------------------------------+
2689 | Opcode | | Addressing | | |
2690 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2691 +------------+-------------+--------------+-------+-------+-------+
2692 | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas |
2693 | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas |
2694 | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas |
2695 | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas |
2696 | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas |
2701 #define OP_ROL_HANDLER(m) \
2702 uint8 res = (m << 1) | flagC; \
2705 flagC = (m >> 7) & 0x01; \
2711 r = (CC & CC_C) | (t << 1);
2716 static void Op09(void) // ROL DP
2724 static void Op49(void) // ROLA
2726 OP_ROL_HANDLER(regs.a);
2729 static void Op59(void) // ROLB
2731 OP_ROL_HANDLER(regs.b);
2734 static void Op69(void) // ROL IDX
2742 static void Op79(void) // ROL ABS
2751 +-----------------------------------------------------------------+
2752 | Opcode | | Addressing | | |
2753 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2754 +------------+-------------+--------------+-------+-------+-------+
2755 | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s |
2756 | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s |
2757 | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s |
2758 | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s |
2759 | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s |
2764 #define OP_ROR_HANDLER(m) \
2765 uint8 res = (flagC << 7) | (m >> 1); \
2771 static void Op06(void) // ROR DP
2779 static void Op46(void) // RORA
2781 OP_ROR_HANDLER(regs.a);
2784 static void Op56(void) // RORB
2786 OP_ROR_HANDLER(regs.b);
2789 static void Op66(void) // ROR IDX
2797 static void Op76(void) // ROR ABS
2806 +-----------------------------------------------------------------+
2807 | Opcode | | Addressing | | |
2808 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2809 +------------+-------------+--------------+-------+-------+-------+
2810 | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa |
2811 | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa |
2812 | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa |
2813 | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa |
2814 | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa |
2815 | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa |
2816 | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa |
2817 | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa |
2822 #define OP_SBC_HANDLER(m, acc) \
2823 uint16 sum = (uint16)acc - (m) - (uint16)flagC; \
2824 flagC = (sum >> 8) & 0x01; \
2825 SET_V(m, acc, sum); \
2829 static void Op82(void) // SBCA #
2832 OP_SBC_HANDLER(m, regs.a);
2835 static void Op92(void) // SBCA DP
2838 OP_SBC_HANDLER(m, regs.a);
2841 static void OpA2(void) // SBCA IDX
2844 OP_SBC_HANDLER(m, regs.a);
2847 static void OpB2(void) // SBCA ABS
2850 OP_SBC_HANDLER(m, regs.a);
2853 static void OpC2(void) // SBCB #
2856 OP_SBC_HANDLER(m, regs.b);
2859 static void OpD2(void) // SBCB DP
2862 OP_SBC_HANDLER(m, regs.b);
2865 static void OpE2(void) // SBCB IDX
2868 OP_SBC_HANDLER(m, regs.b);
2871 static void OpF2(void) // SBCB ABS
2874 OP_SBC_HANDLER(m, regs.b);
2878 +-----------------------------------------------------------------+
2879 | Opcode | | Addressing | | |
2880 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
2881 +------------+-------------+--------------+-------+-------+-------+
2882 | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- |
2883 | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- |
2884 | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- |
2885 | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- |
2886 | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- |
2887 | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- |
2888 | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- |
2889 | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- |
2890 | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- |
2891 | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- |
2892 | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- |
2893 | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- |
2894 | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- |
2895 | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- |
2896 | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- |
2897 | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- |
2898 | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- |
2899 | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- |
2900 | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- |
2901 | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- |
2902 | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- |
2907 #define OP_STA_HANDLER(m, acc) \
2908 regs.WrMem(m, acc); \
2912 #define OP_STA_HANDLER16(m, acc) \
2917 static void Op97(void) // STA DP
2919 uint16 addr = EA_DP;
2920 OP_STA_HANDLER(addr, regs.a);
2923 static void Op9F(void) // STX DP
2925 uint16 addr = EA_DP;
2926 OP_STA_HANDLER16(addr, regs.x);
2929 static void OpA7(void) // STA IDX
2931 uint16 addr = EA_IDX;
2932 OP_STA_HANDLER(addr, regs.a);
2935 static void OpAF(void) // STX IDX
2937 uint16 addr = EA_IDX;
2938 OP_STA_HANDLER16(addr, regs.x);
2941 static void OpB7(void) // STA ABS
2943 uint16 addr = EA_ABS;
2944 OP_STA_HANDLER(addr, regs.a);
2947 static void OpBF(void) // STX ABS
2949 uint16 addr = EA_ABS;
2950 OP_STA_HANDLER16(addr, regs.x);
2953 static void OpD7(void) // STB DP
2955 uint16 addr = EA_DP;
2956 OP_STA_HANDLER(addr, regs.b);
2959 static void OpDD(void) // STD DP
2961 uint16 addr = EA_DP;
2962 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2965 static void OpDF(void) // STU DP
2967 uint16 addr = EA_DP;
2968 OP_STA_HANDLER16(addr, regs.u);
2971 static void OpE7(void) // STB IDX
2973 uint16 addr = EA_IDX;
2974 OP_STA_HANDLER(addr, regs.b);
2977 static void OpED(void) // STD IDX
2979 uint16 addr = EA_IDX;
2980 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
2983 static void OpEF(void) // STU IDX
2985 uint16 addr = EA_IDX;
2986 OP_STA_HANDLER16(addr, regs.u);
2989 static void OpF7(void) // STB ABS
2991 uint16 addr = EA_ABS;
2992 OP_STA_HANDLER(addr, regs.b);
2995 static void OpFD(void) // STD ABS
2997 uint16 addr = EA_ABS;
2998 OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b);
3001 static void OpFF(void) // STU ABS
3003 uint16 addr = EA_ABS;
3004 OP_STA_HANDLER16(addr, regs.u);
3007 static void Op109F(void) // STY DP
3009 uint16 addr = EA_DP;
3010 OP_STA_HANDLER16(addr, regs.y);
3013 static void Op10AF(void) // STY IDX
3015 uint16 addr = EA_IDX;
3016 OP_STA_HANDLER16(addr, regs.y);
3019 static void Op10BF(void) // STY ABS
3021 uint16 addr = EA_ABS;
3022 OP_STA_HANDLER16(addr, regs.y);
3025 static void Op10DF(void) // STS DP
3027 uint16 addr = EA_DP;
3028 OP_STA_HANDLER16(addr, regs.s);
3031 static void Op10EF(void) // STS IDX
3033 uint16 addr = EA_IDX;
3034 OP_STA_HANDLER16(addr, regs.s);
3037 static void Op10FF(void) // STS ABS
3039 uint16 addr = EA_ABS;
3040 OP_STA_HANDLER16(addr, regs.s);
3044 +-----------------------------------------------------------------+
3045 | Opcode | | Addressing | | |
3046 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3047 +------------+-------------+--------------+-------+-------+-------+
3048 | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa |
3049 | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa |
3050 | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa |
3051 | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa |
3052 | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa |
3053 | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa |
3054 | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa |
3055 | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa |
3056 | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa |
3057 | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa |
3058 | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa |
3059 | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa |
3064 #define OP_SUB_HANDLER(m, acc) \
3065 uint16 sum = (uint16)acc - (m); \
3066 flagC = (sum >> 8) & 0x01; \
3067 SET_V(m, acc, sum); \
3071 #define OP_SUB_HANDLER16D(m) \
3072 uint32 acc = (uint32)((regs.a << 8) | regs.b); \
3073 uint32 sum = acc - (m); \
3074 flagC = (sum >> 16) & 0x01; \
3075 SET_V16(m, acc, sum); \
3076 acc = sum & 0xFFFF; \
3077 regs.a = (acc >> 8) & 0xFF; \
3078 regs.b = acc & 0xFF; \
3081 static void Op80(void) // SUBA #
3084 OP_SUB_HANDLER(m, regs.a);
3087 static void Op83(void) // SUBD #
3089 uint16 m = READ_IMM16;
3090 OP_SUB_HANDLER16D(m);
3093 static void Op90(void) // SUBA DP
3096 OP_SUB_HANDLER(m, regs.a);
3099 static void Op93(void) // SUBD DP
3101 uint16 m = READ_DP16;
3102 OP_SUB_HANDLER16D(m);
3105 static void OpA0(void) // SUBA IDX
3108 OP_SUB_HANDLER(m, regs.a);
3111 static void OpA3(void) // SUBD IDX
3113 uint16 m = READ_IDX16;
3114 OP_SUB_HANDLER16D(m);
3117 static void OpB0(void) // SUBA ABS
3120 OP_SUB_HANDLER(m, regs.a);
3123 static void OpB3(void) // SUBD ABS
3125 uint16 m = READ_ABS16;
3126 OP_SUB_HANDLER16D(m);
3129 static void OpC0(void) // SUBB #
3132 OP_SUB_HANDLER(m, regs.b);
3135 static void OpD0(void) // SUBB DP
3138 OP_SUB_HANDLER(m, regs.b);
3141 static void OpE0(void) // SUBB IDX
3144 OP_SUB_HANDLER(m, regs.b);
3147 static void OpF0(void) // SUBB ABS
3150 OP_SUB_HANDLER(m, regs.b);
3154 +-----------------------------------------------------------------+
3155 | Opcode | | Addressing | | |
3156 | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC |
3157 +------------+-------------+--------------+-------+-------+-------+
3158 | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- |
3159 | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- |
3160 | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- |
3161 | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- |
3162 | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- |
3167 #define OP_TST_HANDLER(m) \
3171 static void Op0D(void) // TST DP
3177 static void Op4D(void) // TSTA
3179 OP_TST_HANDLER(regs.a);
3182 static void Op5D(void) // TSTB
3184 OP_TST_HANDLER(regs.b);
3187 static void Op6D(void) // TST IDX
3193 static void Op7D(void) // TST ABS
3199 // Undocumented Opcodes
3201 static void Op01(void)
3209 // Page zero instructions...
3212 static void Op00(void) // NEG DP
3214 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
3215 tmp = 256 - regs.RdMem(addr);
3216 regs.WrMem(addr, tmp);
3218 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3219 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3220 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3221 (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3226 static void Op01(void) // NEG DP (Undocumented)
3231 static void Op03(void) // COM DP
3233 addr = (regs.dp << 8) | regs.RdMem(regs.pc++);
3234 tmp = 0xFF ^ regs.RdMem(addr);
3235 regs.WrMem(addr, tmp);
3237 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC
3238 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3239 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3244 static void Op04(void) // LSR DP
3246 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
3247 tmp = regs.RdMem(addr);
3248 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
3249 tmp >>= 1; regs.WrMem(addr, tmp);
3250 regs.cc &= 0xF7; // CLN
3251 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3254 static void Op06(void) // ROR DP
3256 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
3257 tmp = (tmp2>>1) + (regs.cc&0x01)*128;
3258 regs.WrMem(addr, tmp);
3259 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3260 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3261 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3264 static void Op07(void) // ASR DP
3266 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr);
3267 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3269 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
3270 regs.WrMem(addr, tmp);
3271 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3272 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3275 static void Op08(void) // LSL DP
3277 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT
3278 tmp = regs.RdMem(addr);
3279 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3281 regs.WrMem(addr, tmp);
3282 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3283 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3286 static void Op09(void) // ROL DP
3288 addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr);
3289 tmp = (tmp2<<1) + (regs.cc&0x01);
3290 regs.WrMem(addr, tmp);
3291 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3292 ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3293 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3294 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3297 static void Op0A(void) // DEC DP
3299 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
3300 tmp = regs.RdMem(addr) - 1;
3301 regs.WrMem(addr, tmp);
3302 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3303 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3304 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3307 static void Op0C(void) // INC DP
3309 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
3310 tmp = regs.RdMem(addr) + 1;
3311 regs.WrMem(addr, tmp);
3312 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3313 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3314 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3317 static void Op0D(void) // TST DP
3319 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
3320 regs.cc &= 0xFD; // CLV
3321 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3322 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3325 static void Op0E(void) // JMP DP
3327 regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++);
3330 static void Op0F(void) // CLR DP
3332 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0);
3333 regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC
3337 static void Op12(void) // NOP
3342 static void Op13(void) // SYNC
3344 // Fix this so it does the right thing (software interrupt!)
3348 static void Op16(void) // LBRA
3350 // regs.pc += SignedW(FetchW());
3351 regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities
3356 static void Op17(void) // LBSR
3358 uint16 word = FetchW();
3359 regs.WrMem(--regs.s, regs.pc & 0xFF);
3360 regs.WrMem(--regs.s, regs.pc >> 8);
3361 // regs.pc += SignedW(addr);
3362 regs.pc += word; // No need to make signed, both are 16 bit
3367 static void Op19(void) // DAA
3370 uint8 result = regs.a;
3372 if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big?
3376 regs.cc |= 0x20; // Then adjust & set half carry
3379 if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big?
3383 regs.cc |= 0x01; // Then adjust & set carry
3388 regs.cc &= 0xF1; // CL NZV
3389 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
3390 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
3392 uint16 result = (uint16)regs.a;
3394 if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
3397 if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
3400 regs.a = (uint8)result;
3402 // CLR_V; // Not sure this is correct...
3403 regs.cc &= 0xF1; // CL NZV
3404 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
3405 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
3406 // flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
3407 regs.cc |= (result & 0x100) > 8;
3412 static void Op1A(void) // ORCC #
3414 regs.cc |= regs.RdMem(regs.pc++);
3419 static void Op1C(void) // ANDCC #
3421 regs.cc &= regs.RdMem(regs.pc++);
3426 static void Op1D(void) // SEX
3428 (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00);
3430 ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3431 (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3436 static void Op1E(void) // EXG
3438 tmp = regs.RdMem(regs.pc++);
3439 addr = ReadEXG(tmp >> 4);
3440 WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF));
3441 WriteEXG(tmp & 0xF, addr);
3446 static void Op1F(void) // TFR
3448 tmp = regs.RdMem(regs.pc++);
3449 WriteEXG(tmp&0xF, ReadEXG(tmp>>4));
3453 static void Op20(void) // BRA
3455 // regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always
3456 regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1; // Branch always
3461 static void Op21(void) // BRN
3463 regs.RdMem(regs.pc++);
3468 static void Op22(void) // BHI
3470 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3472 if (!(regs.cc & 0x05))
3478 static void Op23(void) // BLS
3480 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3488 static void Op24(void) // BCC (BHS)
3490 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3492 if (!(regs.cc & 0x01))
3498 static void Op25(void) // BCS (BLO)
3500 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3508 static void Op26(void) // BNE
3510 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3512 if (!(regs.cc & 0x04))
3518 static void Op27(void) // BEQ
3520 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3528 static void Op28(void) // BVC
3530 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3532 if (!(regs.cc & 0x02))
3538 static void Op29(void) // BVS
3540 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3548 static void Op2A(void) // BPL
3550 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3552 if (!(regs.cc & 0x08))
3558 static void Op2B(void) // BMI
3560 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3568 static void Op2C(void) // BGE
3570 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3572 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
3578 static void Op2D(void) // BLT
3580 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3582 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
3588 static void Op2E(void) // BGT
3590 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3592 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
3598 static void Op2F(void) // BLE
3600 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
3602 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
3608 static void Op30(void) // LEAX
3610 regs.x = DecodeIDX(regs.RdMem(regs.pc++));
3611 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3614 static void Op31(void) // LEAY
3616 regs.y = DecodeIDX(regs.RdMem(regs.pc++));
3617 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3620 static void Op32(void) // LEAS
3622 regs.s = DecodeIDX(regs.RdMem(regs.pc++));
3623 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3626 static void Op33(void) // LEAU
3628 regs.u = DecodeIDX(regs.RdMem(regs.pc++));
3629 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3632 static void Op34(void) // PSHS
3634 tmp = regs.RdMem(regs.pc++);
3635 if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); }
3636 if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); }
3637 if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); }
3638 if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); }
3639 if (tmp&0x08) regs.WrMem(--regs.s, regs.dp);
3640 if (tmp&0x04) regs.WrMem(--regs.s, regs.b);
3641 if (tmp&0x02) regs.WrMem(--regs.s, regs.a);
3642 if (tmp&0x01) regs.WrMem(--regs.s, regs.cc);
3645 static void Op35(void) // PULS
3647 tmp = regs.RdMem(regs.pc++);
3648 if (tmp&0x01) regs.cc = regs.RdMem(regs.s++);
3649 if (tmp&0x02) regs.a = regs.RdMem(regs.s++);
3650 if (tmp&0x04) regs.b = regs.RdMem(regs.s++);
3651 if (tmp&0x08) regs.dp = regs.RdMem(regs.s++);
3652 if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3653 if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3654 if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3655 if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3659 static void Op36(void) // PSHU
3661 tmp = regs.RdMem(regs.pc++);
3663 if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); }
3664 if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); }
3665 if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); }
3666 if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); }
3667 if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp);
3668 if (tmp & 0x04) regs.WrMem(--regs.u, regs.b);
3669 if (tmp & 0x02) regs.WrMem(--regs.u, regs.a);
3670 if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc);
3675 static void Op37(void) // PULU
3677 tmp = regs.RdMem(regs.pc++);
3678 if (tmp&0x01) regs.cc = regs.RdMem(regs.u++);
3679 if (tmp&0x02) regs.a = regs.RdMem(regs.u++);
3680 if (tmp&0x04) regs.b = regs.RdMem(regs.u++);
3681 if (tmp&0x08) regs.dp = regs.RdMem(regs.u++);
3682 if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3683 if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3684 if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3685 if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++);
3688 static void Op39(void) // RTS
3690 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3693 static void Op3B(void) // RTI
3695 regs.cc = regs.RdMem(regs.s++);
3696 if (regs.cc&0x80) // If E flag set, pull all regs
3698 regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++);
3699 regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3700 regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3701 regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3708 regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++);
3710 static void Op3C(void) // CWAI
3712 regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80;
3713 regs.clock += 1000000; // Force interrupt
3715 static void Op3D(void) // MUL
3717 addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF;
3718 (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
3719 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
3722 static void Op3E(void) // RESET
3725 static void Op3F(void) // SWI
3728 static void Op40(void) // NEGA
3730 regs.a = 256 - regs.a;
3731 (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3732 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3733 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3734 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3737 static void Op43(void) // COMA
3740 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
3741 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3742 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3745 static void Op44(void) // LSRA
3747 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
3749 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3750 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3753 static void Op46(void) // RORA
3755 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
3756 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3757 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3758 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3761 static void Op47(void) // ASRA
3763 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3764 regs.a >>= 1; // Do the shift
3765 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
3766 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3767 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3770 static void Op48(void) // LSLA [Keep checking from here...]
3772 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3774 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3775 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3778 static void Op49(void) // ROLA
3780 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
3781 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3782 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3783 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3786 static void Op4A(void) // DECA
3789 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3790 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3791 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3794 static void Op4C(void) // INCA
3797 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3798 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3799 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3802 static void Op4D(void) // TSTA
3804 regs.cc &= 0xFD; // Clear oVerflow flag
3805 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3806 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3809 static void Op4F(void) // CLRA
3812 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
3815 static void Op50(void) // NEGB
3817 regs.b = 256 - regs.b;
3818 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
3819 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3820 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3821 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3822 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3825 static void Op53(void) // COMB
3828 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
3829 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3830 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3833 static void Op54(void) // LSRB
3835 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
3837 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3838 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3841 static void Op56(void) // RORB
3843 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
3844 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry
3845 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3846 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3849 static void Op57(void) // ASRB
3851 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3852 regs.b >>= 1; // Do the shift
3853 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
3854 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3855 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3858 static void Op58(void) // LSLB
3860 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3862 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3863 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3866 static void Op59(void) // ROLB
3869 regs.b = (tmp<<1) + (regs.cc&0x01);
3870 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3871 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3872 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3875 static void Op5A(void) // DECB
3878 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3879 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3880 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3883 static void Op5C(void) // INCB
3886 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3887 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3888 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3891 static void Op5D(void) // TSTB
3893 regs.cc &= 0xFD; // Clear oVerflow flag
3894 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3895 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3898 static void Op5F(void) // CLRB
3901 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
3904 static void Op60(void) // NEG IDX
3906 addr = DecodeIDX(regs.RdMem(regs.pc++));
3907 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
3908 regs.WrMem(addr, res);
3909 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry
3910 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
3911 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3912 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3913 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
3916 static void Op63(void) // COM IDX
3918 addr = DecodeIDX(regs.RdMem(regs.pc++));
3919 tmp = regs.RdMem(addr) ^ 0xFF;
3920 regs.WrMem(addr, tmp);
3921 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
3922 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3923 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3926 static void Op64(void) // LSR IDX
3928 addr = DecodeIDX(regs.RdMem(regs.pc++));
3929 tmp = regs.RdMem(addr);
3930 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
3931 tmp >>= 1; regs.WrMem(addr, tmp);
3932 regs.cc &= 0xF7; // CLN
3933 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3936 static void Op66(void) // ROR IDX
3938 addr = DecodeIDX(regs.RdMem(regs.pc++));
3939 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
3940 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
3941 regs.WrMem(addr, tmp);
3942 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3943 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3944 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3947 static void Op67(void) // ASR IDX
3949 addr = DecodeIDX(regs.RdMem(regs.pc++));
3950 tmp = regs.RdMem(addr);
3951 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
3953 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
3954 regs.WrMem(addr, tmp);
3955 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3956 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3959 static void Op68(void) // LSL IDX
3961 addr = DecodeIDX(regs.RdMem(regs.pc++));
3962 tmp = regs.RdMem(addr);
3963 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3965 regs.WrMem(addr, tmp);
3966 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3967 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3970 static void Op69(void) // ROL IDX
3972 uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
3973 tmp = (tmp2<<1) + (regs.cc&0x01);
3974 regs.WrMem(addr, tmp);
3975 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
3976 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3977 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3980 static void Op6A(void) // DEC IDX
3982 uint8 tmp; uint16 addr;
3983 addr = DecodeIDX(regs.RdMem(regs.pc++));
3984 tmp = regs.RdMem(addr) - 1;
3985 regs.WrMem(addr, tmp);
3986 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3987 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3988 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
3991 static void Op6C(void) // INC IDX
3993 addr = DecodeIDX(regs.RdMem(regs.pc++));
3994 tmp = regs.RdMem(addr) + 1;
3995 regs.WrMem(addr, tmp);
3996 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
3997 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
3998 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4001 static void Op6D(void) // TST IDX
4003 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4004 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4005 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4008 static void Op6E(void) // JMP IDX
4010 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
4013 static void Op6F(void) // CLR IDX
4015 addr = DecodeIDX(regs.RdMem(regs.pc++));
4016 regs.WrMem(addr, 0);
4017 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
4020 static void Op70(void) // NEG ABS
4023 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
4024 regs.WrMem(addr, res);
4025 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4026 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4027 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4028 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry
4031 static void Op73(void) // COM ABS
4034 tmp = regs.RdMem(addr) ^ 0xFF;
4035 regs.WrMem(addr, tmp);
4036 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
4037 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4038 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4041 static void Op74(void) // LSR ABS
4044 tmp = regs.RdMem(addr);
4045 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry
4046 tmp >>= 1; regs.WrMem(addr, tmp);
4047 regs.cc &= 0xF7; // CLN
4048 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4051 static void Op76(void) // ROR ABS
4053 uint8 tmp; uint16 addr;
4055 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
4056 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
4057 regs.WrMem(addr, tmp);
4058 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
4059 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4060 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4063 static void Op77(void) // ASR ABS
4065 uint8 tmp; uint16 addr;
4067 tmp = regs.RdMem(addr);
4068 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry
4070 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
4071 regs.WrMem(addr, tmp);
4072 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4073 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4076 static void Op78(void) // LSL ABS
4078 uint8 tmp; uint16 addr;
4080 tmp = regs.RdMem(addr);
4081 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
4083 regs.WrMem(addr, tmp);
4084 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4085 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4088 static void Op79(void) // ROL ABS
4090 uint8 tmp2 = regs.RdMem(FetchW());
4091 tmp = (tmp2<<1) + (regs.cc&0x01);
4092 regs.WrMem(addr, tmp);
4093 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry
4094 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4095 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4098 static void Op7A(void) // DEC ABS
4100 uint8 tmp; uint16 addr;
4102 tmp = regs.RdMem(addr) - 1;
4103 regs.WrMem(addr, tmp);
4104 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
4105 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4106 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4109 static void Op7C(void) // INC ABS
4111 uint8 tmp; uint16 addr;
4113 tmp = regs.RdMem(addr) + 1;
4114 regs.WrMem(addr, tmp);
4115 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
4116 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4117 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4121 static void Op7D(void) // TST ABS
4123 uint8 tmp = regs.RdMem(FetchW());
4125 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4126 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4131 static void Op7E(void) // JMP ABS
4136 static void Op7F(void) // CLR ABS
4138 regs.WrMem(FetchW(), 0);
4139 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
4142 static void Op80(void) // SUBA #
4144 uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
4146 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4147 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4148 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4149 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4152 static void Op81(void) // CMPA #
4154 tmp = regs.RdMem(regs.pc++);
4155 uint8 db = regs.a - tmp;
4156 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4157 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4158 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4159 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4162 static void Op82(void) // SBCA #
4164 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
4165 regs.a = regs.a - tmp - (regs.cc&0x01);
4166 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4167 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4168 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4169 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4172 static void Op83(void) // SUBD #
4174 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4176 (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4177 ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4178 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4179 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4180 regs.a = dr>>8; regs.b = dr&0xFF;
4183 static void Op85(void) // BITA #
4185 tmp = regs.a & regs.RdMem(regs.pc++);
4186 regs.cc &= 0xFD; // Clear oVerflow flag
4187 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4188 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4191 static void Op86(void) // LDA #
4193 regs.a = regs.RdMem(regs.pc++);
4194 regs.cc &= 0xFD; // CLV
4195 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4196 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4199 static void Op88(void) // EORA #
4201 regs.a ^= regs.RdMem(regs.pc++);
4202 regs.cc &= 0xFD; // CLV
4203 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4204 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4207 static void Op8A(void) // ORA #
4209 regs.a |= regs.RdMem(regs.pc++);
4210 regs.cc &= 0xFD; // CLV
4211 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4212 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4215 static void Op8C(void) // CMPX #
4218 uint16 dw = regs.x - addr;
4219 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4220 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
4221 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4222 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4226 static void Op8D(void) // Bregs.s
4228 uint16 word = (int16)(int8)regs.RdMem(regs.pc++);
4229 regs.WrMem(--regs.s, regs.pc & 0xFF);
4230 regs.WrMem(--regs.s, regs.pc >> 8);
4236 static void Op8E(void) // LDX #
4239 regs.cc &= 0xFD; // CLV
4240 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4241 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4244 static void Op90(void) // SUBA DP
4246 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
4248 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4249 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4250 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4251 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4254 static void Op91(void) // CMPA DP
4256 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4257 uint8 db = regs.a - tmp;
4258 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4259 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4260 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4261 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4264 static void Op92(void) // SBCA DP
4266 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
4267 regs.a = regs.a - tmp - (regs.cc&0x01);
4268 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4269 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4270 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4271 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4274 static void Op93(void) // SUBD DP
4276 addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4277 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4279 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4280 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4281 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4282 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4283 regs.a = dr>>8; regs.b = dr&0xFF;
4286 static void Op84(void) // ANDA #
4288 regs.a &= regs.RdMem(regs.pc++);
4289 regs.cc &= 0xFD; // Clear oVerflow flag
4290 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4291 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4294 static void Op94(void) // ANDA DP
4296 regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4297 regs.cc &= 0xF1; // CLV CLZ CLN
4298 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
4299 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
4302 static void Op95(void) // BITA DP
4304 tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4305 regs.cc &= 0xFD; // Clear oVerflow flag
4306 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4307 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4310 static void Op96(void) // LDA DP
4312 regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4313 regs.cc &= 0xF1; // CLN CLZ CLV
4314 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
4315 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
4318 static void Op97(void) // STA DP
4320 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a);
4321 regs.cc &= 0xFD; // CLV
4322 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4323 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4326 static void Op98(void) // EORA DP
4328 regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4329 regs.cc &= 0xFD; // CLV
4330 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4331 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4334 static void Op9A(void) // ORA DP
4336 regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4337 regs.cc &= 0xFD; // CLV
4338 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4339 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4342 static void Op9C(void) // CMPX DP
4344 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4345 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4346 uint16 dw = regs.x - adr2;
4347 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4348 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4349 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4350 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
4353 static void Op9D(void) // JSR DP
4355 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
4356 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
4357 regs.pc = addr; // JSR to DP location...
4360 static void Op9E(void) // LDX DP
4362 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
4363 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4364 regs.cc &= 0xFD; // CLV
4365 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4366 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4369 static void Op9F(void) // STX DP
4371 addr = (regs.dp<<8) | regs.RdMem(regs.pc++);
4372 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
4373 regs.cc &= 0xFD; // CLV
4374 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4375 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4378 static void OpA0(void) // SUBA IDX
4380 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
4382 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4383 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4384 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4385 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4388 static void OpA1(void) // CMPA IDX
4390 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4391 uint8 db = regs.a - tmp;
4392 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4393 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4394 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4395 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4398 static void OpA2(void) // SBCA IDX
4400 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
4401 regs.a = regs.a - tmp - (regs.cc&0x01);
4402 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4403 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4404 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4405 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4408 static void OpA3(void) // SUBD IDX
4410 addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4411 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4413 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4414 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4415 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4416 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4417 regs.a = dr>>8; regs.b = dr&0xFF;
4420 static void OpA4(void) // ANDA IDX
4422 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4423 regs.cc &= 0xFD; // Clear oVerflow flag
4424 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4425 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4428 static void OpA5(void) // BITA IDX
4430 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4431 regs.cc &= 0xFD; // Clear oVerflow flag
4432 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4433 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4436 static void OpA6(void) // LDA IDX
4438 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4439 regs.cc &= 0xF1; // CLV CLZ CLN
4440 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
4441 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
4444 static void OpA7(void) // STA IDX
4446 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
4447 regs.cc &= 0xF1; // CLV CLZ CLN
4448 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
4449 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
4452 static void OpA8(void) // EORA IDX
4454 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4455 regs.cc &= 0xFD; // CLV
4456 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4457 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4460 static void OpAA(void) // ORA IDX
4462 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4463 regs.cc &= 0xFD; // CLV
4464 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4465 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4468 static void OpAC(void) // CMPX IDX
4470 addr = DecodeIDX(regs.RdMem(regs.pc++));
4471 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4472 uint16 dw = regs.x - addr2;
4473 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4474 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4475 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4476 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4479 static void OpAD(void) // JSR IDX
4481 addr = DecodeIDX(regs.RdMem(regs.pc++));
4482 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
4483 regs.pc = addr; // Jregs.s directly to IDX ptr
4486 static void OpAE(void) // LDX IDX
4488 addr = DecodeIDX(regs.RdMem(regs.pc++));
4489 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4490 regs.cc &= 0xFD; // CLV
4491 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4492 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4495 static void OpAF(void) // STX IDX
4497 addr = DecodeIDX(regs.RdMem(regs.pc++));
4498 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
4499 regs.cc &= 0xF1; // CLV CLZ CLN
4500 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
4501 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
4504 static void OpB0(void) // SUBA ABS
4506 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
4508 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4509 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4510 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4511 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4514 static void OpB1(void) // CMPA ABS
4516 tmp = regs.RdMem(FetchW());
4517 uint8 db = regs.a - tmp;
4518 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4519 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4520 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4521 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4524 static void OpB2(void) // SBCA ABS
4526 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
4527 regs.a = regs.a - tmp - (regs.cc&0x01);
4528 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4529 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4530 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4531 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4534 static void OpB3(void) // SUBD ABS
4536 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr;
4537 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4539 (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4540 ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
4541 (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4542 (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4543 regs.a = dr>>8; regs.b = dr&0xFF;
4546 static void OpB4(void) // ANDA ABS
4548 regs.a &= regs.RdMem(FetchW());
4549 regs.cc &= 0xFD; // Clear oVerflow flag
4550 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4551 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4554 static void OpB5(void) // BITA ABS
4556 tmp = regs.a & regs.RdMem(FetchW());
4557 regs.cc &= 0xFD; // Clear oVerflow flag
4558 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4559 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4562 static void OpB6(void) // LDA ABS
4564 regs.a = regs.RdMem(FetchW());
4565 regs.cc &= 0xFD; // CLV
4566 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4567 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4570 static void OpB7(void) // STA ABS
4572 regs.WrMem(FetchW(), regs.a);
4573 regs.cc &= 0xFD; // CLV
4574 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4575 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4578 static void OpB8(void) // EORA ABS
4580 regs.a ^= regs.RdMem(FetchW());
4581 regs.cc &= 0xFD; // CLV
4582 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4583 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4586 static void OpBA(void) // ORA ABS
4588 regs.a |= regs.RdMem(FetchW());
4589 regs.cc &= 0xFD; // CLV
4590 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4591 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4594 static void OpBC(void) // CMPX ABS
4596 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
4597 uint16 dw = regs.x - addr2;
4598 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4599 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4600 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4601 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4604 static void OpBD(void) // JSR ABS
4607 regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8);
4608 regs.pc = addr; // Go to absolute address (Not indir)
4612 static void OpBE(void) // LDX ABS
4615 // regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4616 regs.x = RdMemW(FetchW());
4618 regs.cc &= 0xFD; // CLV
4619 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4620 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4625 static void OpBF(void) // STX ABS
4628 // regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
4629 WrMemW(FetchW(), regs.x);
4631 regs.cc &= 0xFD; // CLV
4632 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4633 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4638 static void OpC0(void) // SUBB #
4640 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
4642 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4643 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4644 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4645 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4648 static void OpC1(void) // CMPB #
4650 tmp = regs.RdMem(regs.pc++);
4651 uint8 db = regs.b - tmp;
4652 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4653 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4654 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4655 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4658 static void OpC2(void) // SBCB #
4660 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
4661 regs.b = regs.b - tmp - (regs.cc&0x01);
4662 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4663 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4664 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4665 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4668 static void OpC4(void) // ANDB #
4670 regs.b &= regs.RdMem(regs.pc++);
4671 regs.cc &= 0xFD; // Clear oVerflow flag
4672 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4673 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4676 static void OpC5(void) // BITB #
4678 tmp = regs.b & regs.RdMem(regs.pc++);
4679 regs.cc &= 0xF1; // CLV CLZ CLN
4680 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
4681 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
4684 static void OpC6(void) // LDB #
4686 regs.b = regs.RdMem(regs.pc++);
4687 regs.cc &= 0xF1; // CLV CLZ CLN
4688 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
4689 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
4692 static void OpC8(void) // EORB #
4694 regs.b ^= regs.RdMem(regs.pc++);
4695 regs.cc &= 0xFD; // CLV
4696 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4697 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4700 static void OpCA(void) // ORB #
4702 regs.b |= regs.RdMem(regs.pc++);
4703 regs.cc &= 0xFD; // CLV
4704 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4705 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4708 static void OpCC(void) // LDD #
4710 regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++);
4711 regs.cc &= 0xFD; // CLV
4712 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4713 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4716 static void OpCE(void) // LDU #
4719 regs.cc &= 0xFD; // CLV
4720 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4721 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4724 static void OpD0(void) // SUBB DP
4726 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
4728 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4729 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4730 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4731 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4734 static void OpD1(void) // CMPB DP
4736 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4737 uint8 db = regs.b - tmp;
4738 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4739 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4740 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4741 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4744 static void OpD2(void) // SBCB DP
4746 tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
4747 regs.b = regs.b - tmp - (regs.cc&0x01);
4748 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4749 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4750 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4751 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4754 static void OpD4(void) // ANDB DP
4756 regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4757 regs.cc &= 0xFD; // Clear oVerflow flag
4758 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4759 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4762 static void OpD5(void) // BITB DP
4764 tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4765 regs.cc &= 0xFD; // Clear oVerflow flag
4766 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4767 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4770 static void OpD6(void) // LDB DP
4772 regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4773 regs.cc &= 0xFD; // CLV
4774 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4775 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4778 static void OpD7(void) // STB DP
4780 regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b);
4781 regs.cc &= 0xFD; // CLV
4782 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4783 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4786 static void OpD8(void) // EORB DP
4788 regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4789 regs.cc &= 0xFD; // CLV
4790 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4791 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4794 static void OpDA(void) // ORB DP
4796 regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
4797 regs.cc &= 0xFD; // CLV
4798 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4799 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4802 static void OpDC(void) // LDD DP
4804 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4805 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
4806 regs.cc &= 0xFD; // CLV
4807 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4808 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4811 static void OpDD(void) // STD DP
4813 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4814 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
4815 regs.cc &= 0xFD; // CLV
4816 ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4817 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4820 static void OpDE(void) // LDU DP
4822 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4823 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4824 regs.cc &= 0xFD; // CLV
4825 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4826 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4829 static void OpDF(void) // STU DP
4831 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
4832 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
4833 regs.cc &= 0xFD; // CLV
4834 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4835 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4838 static void OpE0(void) // SUBB IDX
4840 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
4842 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4843 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4844 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4845 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4848 static void OpE1(void) // CMPB IDX
4850 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4851 uint8 db = regs.b - tmp;
4852 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4853 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4854 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4855 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4858 static void OpE2(void) // SBCB IDX
4860 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
4861 regs.b = regs.b - tmp - (regs.cc&0x01);
4862 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4863 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4864 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4865 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4868 static void OpE4(void) // ANDB IDX
4870 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4871 regs.cc &= 0xFD; // Clear oVerflow flag
4872 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4873 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4876 static void OpE5(void) // BITB IDX
4878 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4879 regs.cc &= 0xFD; // Clear oVerflow flag
4880 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4881 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4884 static void OpE6(void) // LDB IDX
4886 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4887 regs.cc &= 0xFD; // CLV
4888 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4889 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4892 static void OpE7(void) // STB IDX
4894 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
4895 regs.cc &= 0xF1; // CLV CLZ CLN
4896 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
4897 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
4900 static void OpE8(void) // EORB IDX
4902 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4903 regs.cc &= 0xFD; // CLV
4904 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4905 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4908 static void OpEA(void) // ORB IDX
4910 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
4911 regs.cc &= 0xFD; // CLV
4912 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4913 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4916 static void OpEC(void) // LDD IDX
4918 addr = DecodeIDX(regs.RdMem(regs.pc++));
4919 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
4920 regs.cc &= 0xF1; // CLV CLZ CLN
4921 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
4922 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
4925 static void OpED(void) // STD IDX
4927 addr = DecodeIDX(regs.RdMem(regs.pc++));
4928 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
4929 regs.cc &= 0xF1; // CLV CLZ CLZ
4930 if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag
4931 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
4934 static void OpEE(void) // LDU IDX
4936 addr = DecodeIDX(regs.RdMem(regs.pc++));
4937 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
4938 regs.cc &= 0xF1; // CLV CLZ CLN
4939 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
4940 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
4943 static void OpEF(void) // STU IDX
4945 addr = DecodeIDX(regs.RdMem(regs.pc++));
4946 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
4947 regs.cc &= 0xF1; // CLV CLZ CLN
4948 if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag
4949 if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag
4952 static void OpF0(void) // SUBB ABS
4954 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
4956 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4957 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4958 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4959 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4961 static void OpF1(void) // CMPB ABS
4963 tmp = regs.RdMem(FetchW());
4964 uint8 db = regs.b - tmp;
4965 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4966 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4967 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4968 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4971 static void OpF2(void) // SBCB ABS
4973 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
4974 regs.b = regs.b - tmp - (regs.cc&0x01);
4975 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4976 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4977 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
4978 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
4981 static void OpF4(void) // ANDB ABS
4983 regs.b &= regs.RdMem(FetchW());
4984 regs.cc &= 0xFD; // Clear oVerflow flag
4985 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4986 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4989 static void OpF5(void) // BITB ABS
4991 tmp = regs.b & regs.RdMem(FetchW());
4992 regs.cc &= 0xFD; // Clear oVerflow flag
4993 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
4994 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
4997 static void OpF6(void) // LDB ABS
4999 regs.b = regs.RdMem(FetchW());
5000 regs.cc &= 0xFD; // CLV
5001 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5002 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5005 static void OpF7(void) // STB ABS
5007 regs.WrMem(FetchW(), regs.b);
5008 regs.cc &= 0xFD; // CLV
5009 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5010 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5013 static void OpF8(void) // EORB ABS
5015 regs.b ^= regs.RdMem(FetchW());
5016 regs.cc &= 0xFD; // CLV
5017 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5018 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5021 static void OpFA(void) // ORB ABS
5023 regs.b |= regs.RdMem(FetchW());
5024 regs.cc &= 0xFD; // CLV
5025 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5026 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5029 static void OpFC(void) // LDD ABS
5032 regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1);
5033 regs.cc &= 0xFD; // CLV
5034 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5035 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5038 static void OpFD(void) // STD ABS
5041 regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b);
5042 regs.cc &= 0xFD; // CLV
5043 ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5044 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5047 static void OpFE(void) // LDU ABS
5050 regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
5051 regs.cc &= 0xFD; // CLV
5052 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5053 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5056 static void OpFF(void) // STU ABS
5059 regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF);
5060 regs.cc &= 0xFD; // CLV
5061 (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5062 (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5067 // Page one opcodes' execute code
5070 static void Op1021(void) // LBRN
5077 static void Op1022(void) // LBHI
5079 uint16 word = FetchW();
5081 if (!((regs.cc & 0x01) | (regs.cc & 0x04)))
5087 static void Op1023(void) // LBLS
5089 uint16 word = FetchW();
5091 if ((regs.cc & 0x01) | (regs.cc & 0x04))
5097 static void Op1024(void) // LBCC (LBHS)
5099 uint16 word = FetchW();
5101 if (!(regs.cc & 0x01))
5107 static void Op1025(void) // LBCS (LBLO)
5109 uint16 word = FetchW();
5117 static void Op1026(void) // LBNE
5119 uint16 word = FetchW();
5121 if (!(regs.cc & 0x04))
5127 static void Op1027(void) // LBEQ
5129 uint16 word = FetchW();
5137 static void Op1028(void) // LBVC
5139 uint16 word = FetchW();
5141 if (!(regs.cc & 0x02))
5147 static void Op1029(void) // LBVS
5149 uint16 word = FetchW();
5157 static void Op102A(void) // LBPL
5159 uint16 word = FetchW();
5161 if (!(regs.cc & 0x08))
5167 static void Op102B(void) // LBMI
5169 uint16 word = FetchW();
5177 static void Op102C(void) // LBGE
5179 uint16 word = FetchW();
5181 if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
5187 static void Op102D(void) // LBLT
5189 uint16 word = FetchW();
5191 if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))
5197 static void Op102E(void) // LBGT
5199 uint16 word = FetchW();
5201 if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))))
5207 static void Op102F(void) // LBLE
5209 uint16 word = FetchW();
5211 if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))
5217 static void Op103F(void) // SWI2 (Not yet implemented)
5221 static void Op1083(void) // CMPD #
5223 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
5224 uint16 dw = dr - addr;
5225 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5226 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5227 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5228 ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5231 static void Op108C(void) // CMPY #
5234 uint16 dw = regs.y - addr;
5235 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5236 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5237 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5238 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5241 static void Op108E(void) // LDY #
5244 regs.cc &= 0xFD; // CLV
5245 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5246 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5249 static void Op1093(void) // CMPD DP
5251 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b;
5252 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5253 uint16 dw = dr - addr;
5254 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5255 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5256 (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5257 ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5260 static void Op109C(void) // CMPY DP
5262 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
5263 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5264 uint16 dw = regs.y - addr;
5265 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5266 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5267 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5268 ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5272 static void Op109E(void) // LDY DP
5274 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5275 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5276 regs.cc &= 0xFD; // CLV
5277 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5278 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5282 static void Op109F(void) // STY DP
5284 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5285 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
5286 regs.cc &= 0xFD; // CLV
5287 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5288 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5291 static void Op10A3(void) // CMPD IDX
5293 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b;
5294 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5295 uint16 dw = dr - addr;
5296 regs.cc &= 0xF0; // CLC CLV CLZ CLN
5297 if (dr < addr) regs.cc |= 0x01; // Set Carry flag
5298 if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow
5299 if (dw == 0) regs.cc |= 0x04; // Set Zero flag
5300 if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag
5303 static void Op10AC(void) // CMPY IDX
5305 uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++));
5306 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5307 uint16 dw = regs.y - addr;
5308 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5309 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5310 (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5311 (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5314 static void Op10AE(void) // LDY IDX
5316 addr = DecodeIDX(regs.RdMem(regs.pc++));
5317 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5318 regs.cc &= 0xF1; // CLV CLZ CLN
5319 if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag
5320 if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag
5323 static void Op10AF(void) // STY IDX
5325 addr = DecodeIDX(regs.RdMem(regs.pc++));
5326 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
5327 regs.cc &= 0xFD; // CLV
5328 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5329 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5332 static void Op10B3(void) // CMPD ABS
5334 addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b;
5335 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5336 uint16 dw = dr - addr2;
5337 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5338 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5339 (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5340 (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5343 static void Op10BC(void) // CMPY ABS
5345 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5346 uint16 dw = regs.y - addr2;
5347 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5348 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5349 (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5350 (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5353 static void Op10BE(void) // LDY ABS
5356 regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5357 regs.cc &= 0xFD; // CLV
5358 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5359 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5362 static void Op10BF(void) // STY ABS
5365 regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF);
5366 regs.cc &= 0xFD; // CLV
5367 (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5368 (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5371 static void Op10CE(void) // LDS #
5374 regs.cc &= 0xFD; // CLV
5375 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5376 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5379 static void Op10DE(void) // LDS DP
5381 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5382 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5383 regs.cc &= 0xFD; // CLV
5384 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5385 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5388 static void Op10DF(void) // STS DP
5390 addr = (regs.dp<<8)|regs.RdMem(regs.pc++);
5391 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
5392 regs.cc &= 0xFD; // CLV
5393 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5394 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5397 static void Op10EE(void) // LDS IDX
5399 addr = DecodeIDX(regs.RdMem(regs.pc++));
5400 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5401 regs.cc &= 0xFD; // CLV
5402 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5403 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5406 static void Op10EF(void) // STS IDX
5408 addr = DecodeIDX(regs.RdMem(regs.pc++));
5409 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
5410 regs.cc &= 0xFD; // CLV
5411 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5412 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5415 static void Op10FE(void) // LDS ABS
5418 regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5419 regs.cc &= 0xFD; // CLV
5420 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5421 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5424 static void Op10FF(void) // STS ABS
5427 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
5428 regs.cc &= 0xFD; // CLV
5429 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5430 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5435 // Page two opcodes' execute code
5438 static void Op113F(void) // SWI3
5442 static void Op1183(void) // CMPU #
5445 uint16 dw = regs.u - addr;
5446 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5447 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5448 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5449 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5452 static void Op118C(void) // CMPS #
5455 uint16 dw = regs.s - addr;
5456 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5457 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5458 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5459 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5462 static void Op1193(void) // CMPU DP
5464 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
5465 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5466 uint16 dw = regs.u - addr;
5467 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5468 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5469 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5470 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5473 static void Op119C(void) // CMPS DP
5475 uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++);
5476 addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1);
5477 uint16 dw = regs.s - addr;
5478 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5479 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5480 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5481 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5484 static void Op11A3(void) // CMPU IDX
5486 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
5487 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
5488 uint16 dw = regs.u - addr;
5489 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5490 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5491 (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5492 (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5495 static void Op11AC(void) // CMPS IDX
5497 uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++));
5498 addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1);
5499 uint16 dw = regs.s - addr;
5500 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5501 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5502 (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5503 (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5506 static void Op11B3(void) // CMPU ABS
5508 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5509 uint16 dw = regs.u - addr2;
5510 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5511 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5512 (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5513 (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5517 static void Op11BC(void) // CMPS ABS
5519 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
5520 uint16 dw = regs.s - addr2;
5521 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
5522 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
5523 (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
5524 (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
5530 //temp, for testing...
5532 static uint8 backTrace[256];
5533 static uint16 btPC[256];
5534 static int btPtr = 0;//*/
5536 static void Op__(void) // Illegal opcode
5540 regs.cpuFlags |= V6809_STATE_ILLEGAL_INST;
5542 /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1);
5543 for(int i=0; i<256; i++)
5545 Decode6809(btPC[(btPtr + i) & 0xFF]);
5555 // These are defined below, so we just use forward declarations here to prevent the compiler barfing...
5556 static void Op10(void);
5557 static void Op11(void);
5559 // Array of page zero opcode functions...
5561 static void (* exec_op0[256])() = {
5562 Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F,
5563 Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F,
5564 Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
5565 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F,
5566 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
5567 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
5568 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
5569 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
5570 Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
5571 Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F,
5572 OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
5573 OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
5574 OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__,
5575 OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF,
5576 OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF,
5577 OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF
5580 // Array of page one opcode functions...
5581 static void (* exec_op1[256])() = {
5582 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5583 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5584 Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F,
5585 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F,
5586 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5587 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5588 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5589 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5590 Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__,
5591 Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F,
5592 Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF,
5593 Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF,
5594 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__,
5595 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF,
5596 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF,
5597 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF
5600 // Array of page two opcode functions...
5601 static void (* exec_op2[256])() = {
5602 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5603 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5604 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5605 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F,
5606 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5607 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5608 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5609 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5610 Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__,
5611 Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__,
5612 Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__,
5613 Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__,
5614 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5615 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5616 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__,
5617 Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__
5620 // These are here to save typing a ton of forward declarations...
5623 static void Op10(void)
5625 // exec_op1[regs.RdMem(regs.pc++)]();
5626 uint8 opcode = regs.RdMem(regs.pc++);
5628 regs.clock += page1Cycles[opcode];
5632 static void Op11(void)
5634 // exec_op2[regs.RdMem(regs.pc++)]();
5635 uint8 opcode = regs.RdMem(regs.pc++);
5637 regs.clock += page2Cycles[opcode];
5642 // Internal "memcpy" (so we don't have to link with any external libraries!)
5644 static void myMemcpy(void * dst, void * src, uint32 size)
5646 uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
5648 for(uint32 i=0; i<size; i++)
5653 // Function to execute 6809 instructions
5655 //#define DEBUG_ILLEGAL
5656 #ifdef DEBUG_ILLEGAL
5658 #include "dis6809.h"
5660 uint8 backTrace[256];
5661 V6809REGS btRegs[256];
5662 bool tripped = false;
5664 void Execute6809(V6809REGS * context, uint32 cycles)
5666 // If this is not in place, the clockOverrun calculations can cause the V6809 to get
5667 // stuck in an infinite loop.
5668 if (cycles == 0) // Nothing to do, so bail!
5671 myMemcpy(®s, context, sizeof(V6809REGS));
5672 UNPACK_FLAGS; // Explode flags register into individual uint8s
5676 // Since we can't guarantee that we'll execute the number of cycles passed in
5677 // exactly, we have to keep track of how much we overran the number of cycles
5678 // the last time we executed. Since we already executed those cycles, this time
5679 // through we remove them from the cycles passed in in order to come out
5680 // approximately even. Over the long run, this unevenness in execution times
5682 uint64 endCycles = regs.clock + (uint64)(cycles - regs.clockOverrun);
5684 while (regs.clock < endCycles)
5686 #ifdef DEBUG_ILLEGAL
5689 backTrace[btPtr] = regs.RdMem(regs.pc);
5690 btRegs[btPtr] = regs;
5691 btPtr = (btPtr + 1) & 0xFF;
5693 if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
5695 WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
5696 regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
5698 for(uint16 i=btPtr; i<btPtr+256; i++)
5700 Decode6809(btRegs[i & 0xFF].pc);
5701 // Note that these values are *before* execution, so stale...
5702 WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
5703 btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
5713 Decode6809(regs.pc);
5714 // WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC);
5716 #if 0 //we solved this...
5717 if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1)
5718 WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n");
5720 //static bool disasm = false;
5721 /*//if (regs.pc == 0x15BA) disasm = true;
5722 //if (regs.pc == 0xFE76) disasm = true;
5723 if (regs.x == 0xFED4) disasm = true;
5724 if (disasm) Decode6809(regs.pc);
5725 //if (regs.pc == 0x164A) disasm = false;//*/
5727 //temp, for testing...
5728 /*backTrace[btPtr] = regs.RdMem(regs.pc);
5729 btPC[btPtr] = regs.pc;
5730 btPtr = (btPtr + 1) & 0xFF;//*/
5732 // exec_op0[regs.RdMem(regs.pc++)]();
5733 uint8 opcode = regs.RdMem(regs.pc++);
5735 regs.clock += page0Cycles[opcode];
5737 // Handle any pending interrupts
5739 // Hmm, this is bad and only works when flags are changed OUTSIDE of the running context...
5740 // uint32 flags = context->cpuFlags;
5741 uint32 flags = regs.cpuFlags;
5743 if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler ***
5746 if (disasm) WriteLog("\nV6809: RESET line asserted!\n");
5748 flagF = flagI = 1; // Set F, I
5749 regs.dp = 0; // Reset direct page register
5750 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
5751 context->cpuFlags &= ~V6809_ASSERT_LINE_RESET;
5752 regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET;
5754 else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler ***
5757 if (disasm) WriteLog("\nV6809: NMI line asserted!\n");
5759 flagE = 1; // Set Entire flag
5760 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
5762 PUSHS16(regs.pc); // Save all regs...
5771 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
5772 regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector
5774 // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
5775 // regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
5777 else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
5780 if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n");
5782 if (!flagF) // Is the FIRQ masked (F == 1)?
5785 if (disasm) WriteLog(" FIRQ taken...\n");
5787 flagE = 0; // Clear Entire flag
5788 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
5793 flagI = flagF = 1; // Set IRQ/FIRQ suppress flags
5794 regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector
5796 // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
5797 // regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
5800 else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
5803 if (disasm) WriteLog("\nV6809: IRQ line asserted!\n");
5805 if (!flagI) // Is the IRQ masked (I == 1)?
5808 if (disasm) WriteLog(" IRQ taken...\n");
5810 flagE = 1; // Set the Entire flag
5811 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
5822 flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags]
5823 regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector
5825 // Apparently, not done here!
5826 // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
5827 // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
5831 if (disasm) WriteLog("\tCC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
5832 (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"),
5833 (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"),
5834 regs.a, regs.b, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
5835 /*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
5836 regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/
5840 // Keep track of how much we overran so we can adjust on the next run...
5841 regs.clockOverrun = (uint32)(regs.clock - endCycles);
5843 regs.cc = PACK_FLAGS; // Mash flags back into the CC register
5844 myMemcpy(context, ®s, sizeof(V6809REGS));
5848 // Get the clock of the currently executing CPU
5850 uint64 GetCurrentV6809Clock(void)
5856 // Get the PC of the currently executing CPU
5858 uint16 GetCurrentV6809PC(void)
5863 // Set a line of the currently executing CPU
5864 void SetLineOfCurrentV6809(uint32 line)
5866 regs.cpuFlags |= line;
5869 // Clear a line of the currently executing CPU
5870 void ClearLineOfCurrentV6809(uint32 line)
5874 WriteLog("V6809: Clearing line %s...", (line == V6809_ASSERT_LINE_IRQ ? "IRQ" : "OTHER"));
5876 regs.cpuFlags &= ~line;
5880 FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51
5881 E S=BFFF U=0000 PC=FEC0
5882 FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
5884 F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF
5886 F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523
5887 F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526
5888 F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529
5889 F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B
5890 F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D
5891 F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531
5892 F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD
5893 13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF
5894 13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2
5895 13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5
5896 13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7
5897 13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9
5898 13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB
5899 13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD
5900 13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF
5901 13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1
5902 13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3
5903 13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5
5904 13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000