2 // Virtual 6808 Emulator v1.2
5 // (c) 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
15 // Mebbe someday I'll get around to fixing the core to be more like V65C02...
26 // Private global variables
28 static V6808REGS regs;
32 static uint8 CPUCycles[256] = {
33 1, 2, 1, 1, 1, 1, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2,
34 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1,
35 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
36 4, 4, 4, 4, 4, 4, 4, 4, 1, 5, 1, 10, 1, 1, 9, 12,
37 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2,
38 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2,
39 7, 1, 1, 8, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 4, 7,
40 6, 1, 1, 7, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6,
41 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 8, 3, 1,
42 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 4, 1, 4, 5,
43 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7,
44 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6,
45 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 3, 1,
46 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 1, 1, 4, 5,
47 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 1, 1, 6, 7,
48 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 1, 1, 5, 6
51 // Private function prototypes
53 static uint16 FetchW(void);
54 static uint16 RdMemW(uint16);
55 static void WrMemW(uint16, uint16);
58 // Fetch a word out of 6808 memory (little endian format)
59 // This is a leftover from when fetches were separated from garden variety reads...
61 static uint16 FetchW()
63 uint16 w = RdMemW(regs.pc);
69 // Read a word out of 6808 memory (little endian format)
71 static uint16 RdMemW(uint16 address)
73 return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
77 // Write a word into 6808 memory (little endian format)
79 static void WrMemW(uint16 address, uint16 w)
81 regs.WrMem(address + 0, w >> 8);
82 regs.WrMem(address + 1, w & 0xFF);
86 // Function to decode IDX data
88 inline uint16 DecodeIDX(uint8 code)
95 // Opcode Functions (Mostly correct... Yikes!)
98 static void Op01(void) // NOP
102 static void Op06(void) // TAP
107 static void Op07(void) // TPA
112 static void Op08(void) // INX
116 (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
119 static void Op09(void) // DEX
123 (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z);
126 static void Op0A(void) // CLV
131 static void Op0B(void) // SEV
136 static void Op0C(void) // CLC
141 static void Op0D(void) // SEC
146 static void Op0E(void) // CLI
151 static void Op0F(void) // SEI
156 static void Op10(void) // SBA
161 regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC
166 if ((as ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
176 static void Op11(void) // CBA (Compare B to A)
178 tmp = regs.a - regs.b;
180 regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC
185 if ((tmp ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80)
195 static void Op16(void) // TAB
199 regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV
208 static void Op17(void) // TBA
212 regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV
221 static void Op19(void) // DAA
224 // if (regs.cc&0x20) addr += 6; // H set? adjust
225 if ((addr&0x000F) > 9) addr += 6;
226 if (regs.cc&0x01) addr += 0x60; // C set? adjust
227 if ((addr&0x00F0) > 0x90) addr += 0x60;
228 regs.cc &= 0xFD; // CLV
229 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
231 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
232 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
235 static void Op1B(void) // ABA
237 addr = regs.a + regs.b;
239 if (addr > 0xFF) regs.cc |= 0x01; // Set Carry flag
240 if ((regs.a^regs.b^addr^(regs.cc<<7))&0x80) regs.cc |= 0x02; // Set oVerflow
241 regs.a = addr; // Set accumulator
242 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
243 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
246 static void Op20(void) // BRA (BRanch Always)
248 regs.pc += (int16)(int8)regs.RdMem(regs.pc++);
251 static void Op22(void) // BHI
253 tmp = regs.RdMem(regs.pc++);
255 if (!(regs.cc & (FLAG_C | FLAG_Z)))
256 regs.pc += (signed short int)(signed char)tmp;
259 static void Op23(void) // BLS
261 tmp = regs.RdMem(regs.pc++);
263 if (regs.cc & (FLAG_C | FLAG_Z))
264 regs.pc += (signed short int)(signed char)tmp;
267 static void Op24(void) // BCC (BHS)
269 tmp = regs.RdMem(regs.pc++);
270 if (!(regs.cc&0x01)) regs.pc += (signed short int)(signed char)tmp;
273 static void Op25(void) // BCS (BLO)
275 tmp = regs.RdMem(regs.pc++);
276 if (regs.cc&0x01) regs.pc += (signed short int)(signed char)tmp;
279 static void Op26(void) // BNE
281 tmp = regs.RdMem(regs.pc++);
282 if (!(regs.cc&0x04)) regs.pc += (signed short int)(signed char)tmp;
285 static void Op27(void) // BEQ
287 tmp = regs.RdMem(regs.pc++);
288 if (regs.cc&0x04) regs.pc += (signed short int)(signed char)tmp;
291 static void Op28(void) // BVC
293 tmp = regs.RdMem(regs.pc++);
294 if (!(regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp;
297 static void Op29(void) // BVS
299 tmp = regs.RdMem(regs.pc++);
300 if (regs.cc&0x02) regs.pc += (signed short int)(signed char)tmp;
303 static void Op2A(void) // BPL
305 tmp = regs.RdMem(regs.pc++);
306 if (!(regs.cc&0x08)) regs.pc += (signed short int)(signed char)tmp;
309 static void Op2B(void) // BMI
311 tmp = regs.RdMem(regs.pc++);
312 if (regs.cc&0x08) regs.pc += (signed short int)(signed char)tmp;
315 static void Op2C(void) // BGE
317 tmp = regs.RdMem(regs.pc++);
318 if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp;
321 static void Op2D(void) // BLT
323 tmp = regs.RdMem(regs.pc++);
324 if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp;
327 static void Op2E(void) // BGT
329 tmp = regs.RdMem(regs.pc++);
330 if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += (signed short int)(signed char)tmp;
333 static void Op2F(void) // BLE
335 tmp = regs.RdMem(regs.pc++);
336 if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp;
339 static void Op30(void) // TSX
344 static void Op31(void) // INS
349 static void Op32(void) // PULA
351 regs.a = regs.RdMem(regs.s++);
354 static void Op33(void) // PULB
356 regs.b = regs.RdMem(regs.s++);
359 static void Op34(void) // DES
364 static void Op35(void) // TXS
369 static void Op36(void) // PSHA
371 regs.WrMem(--regs.s, regs.a);
374 static void Op37(void) // PSHB
376 regs.WrMem(--regs.s, regs.b);
379 static void Op39(void) // RTS
381 regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
384 static void Op3B(void) // RTI
386 regs.cc = regs.RdMem(regs.s++);
387 regs.a = regs.RdMem(regs.s++);
388 regs.b = regs.RdMem(regs.s++);
389 regs.x = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
390 regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++);
393 static void Op3E(void) // WAI (wait for interrupt)
395 regs.cc &= regs.RdMem(regs.pc++);
396 regs.cc |= 0x80;//???Is this right???
399 static void Op3F(void) // SWI (software interrupt)
401 //Does this respect the I flag???
402 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
403 regs.WrMem(--regs.s, regs.pc >> 8);
404 regs.WrMem(--regs.s, regs.x & 0xFF);
405 regs.WrMem(--regs.s, regs.x >> 8);
406 regs.WrMem(--regs.s, regs.b);
407 regs.WrMem(--regs.s, regs.a);
408 regs.WrMem(--regs.s, regs.cc);
409 regs.pc = RdMemW(0xFFFA); // And do it!
411 regs.cc |= FLAG_I; // Also, set IRQ inhibit
414 static void Op40(void) // NEGA
416 regs.a = 256 - regs.a; regs.cc &= 0xF0;
417 if (regs.a > 0x7F) regs.cc |= 0x01; // Set Carry
418 if (regs.a == 0x80) regs.cc |= 0x02; // Set oVerflow
419 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
420 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
423 static void Op43(void) // COMA
426 regs.cc &= 0xF0; regs.cc |= 0x01; // CLV, SEC
427 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
428 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
431 static void Op44(void) // LSRA
433 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
435 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
436 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
439 static void Op46(void) // RORA
441 tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128;
442 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
443 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
444 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
447 static void Op47(void) // ASRA
449 (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
450 regs.a >>= 1; // Do the shift
451 if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set
452 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
453 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
456 static void Op48(void) // LSLA (ASLA) [Keep checking from here...]
458 (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
460 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
461 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
464 static void Op49(void) // ROLA
466 tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01);
467 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
468 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
469 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
472 static void Op4A(void) // DECA
475 (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
476 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
477 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
480 static void Op4C(void) // INCA
483 (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
484 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
485 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
488 static void Op4D(void) // TSTA
490 regs.cc &= 0xFD; // Clear oVerflow flag
491 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
492 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
495 static void Op4F(void) // CLRA
498 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
501 static void Op50(void) // NEGB
503 regs.b = 256 - regs.b;
504 // ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
505 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
506 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
507 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
508 (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
511 static void Op53(void) // COMB
514 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
515 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
516 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
519 static void Op54(void) // LSRB
521 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
523 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
524 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
527 static void Op56(void) // RORB
529 tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128;
530 (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into Carry
531 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
532 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
535 static void Op57(void) // ASRB
537 (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
538 regs.b >>= 1; // Do the shift
539 if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set
540 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
541 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
544 static void Op58(void) // LSLB
546 (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
548 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
549 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
552 static void Op59(void) // ROLB
555 regs.b = (tmp<<1) + (regs.cc&0x01);
556 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
557 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
558 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
561 static void Op5A(void) // DECB
564 (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
565 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
566 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
569 static void Op5C(void) // INCB
572 (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
573 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
574 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
577 static void Op5D(void) // TSTB
579 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
580 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
581 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
584 static void Op5F(void) // CLRB
587 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
590 static void Op60(void) // NEG IDX
592 addr = DecodeIDX(regs.RdMem(regs.pc++));
593 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
594 regs.WrMem(addr, res);
595 // ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry
596 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
597 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
598 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
599 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
602 static void Op63(void) // COM IDX
604 addr = DecodeIDX(regs.RdMem(regs.pc++));
605 tmp = regs.RdMem(addr) ^ 0xFF;
606 regs.WrMem(addr, tmp);
607 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
608 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
609 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
612 static void Op64(void) // LSR IDX
614 addr = DecodeIDX(regs.RdMem(regs.pc++));
615 tmp = regs.RdMem(addr);
616 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
617 tmp >>= 1; regs.WrMem(addr, tmp);
618 regs.cc &= 0xF7; // CLN
619 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
622 static void Op66(void) // ROR IDX
624 addr = DecodeIDX(regs.RdMem(regs.pc++));
625 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
626 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
627 regs.WrMem(addr, tmp);
628 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
629 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
630 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
633 static void Op67(void) // ASR IDX
635 addr = DecodeIDX(regs.RdMem(regs.pc++));
636 tmp = regs.RdMem(addr);
637 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
639 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
640 regs.WrMem(addr, tmp);
641 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
642 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
645 static void Op68(void) // LSL IDX
647 addr = DecodeIDX(regs.RdMem(regs.pc++));
648 tmp = regs.RdMem(addr);
649 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
651 regs.WrMem(addr, tmp);
652 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
653 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
656 static void Op69(void) // ROL IDX
658 uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
659 tmp = (tmp2<<1) + (regs.cc&0x01);
660 regs.WrMem(addr, tmp);
661 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
662 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
663 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
666 static void Op6A(void) // DEC IDX
668 uint8 tmp; uint16 addr;
669 addr = DecodeIDX(regs.RdMem(regs.pc++));
670 tmp = regs.RdMem(addr) - 1;
671 regs.WrMem(addr, tmp);
672 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
673 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
674 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
677 static void Op6C(void) // INC IDX
679 addr = DecodeIDX(regs.RdMem(regs.pc++));
680 tmp = regs.RdMem(addr) + 1;
681 regs.WrMem(addr, tmp);
682 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
683 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
684 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
687 static void Op6D(void) // TST IDX
689 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
690 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
691 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
694 static void Op6E(void) // JMP IDX
696 regs.pc = DecodeIDX(regs.RdMem(regs.pc++));
699 static void Op6F(void) // CLR IDX
701 addr = DecodeIDX(regs.RdMem(regs.pc++));
703 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
706 static void Op70(void) // NEG ABS
709 tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
710 regs.WrMem(addr, res);
711 (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
712 (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
713 (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
714 (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
717 static void Op73(void) // COM ABS
720 tmp = regs.RdMem(addr) ^ 0xFF;
721 regs.WrMem(addr, tmp);
722 regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC
723 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
724 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
727 static void Op74(void) // LSR ABS
730 tmp = regs.RdMem(addr);
731 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry
732 tmp >>= 1; regs.WrMem(addr, tmp);
733 regs.cc &= 0xF7; // CLN
734 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
737 static void Op76(void) // ROR ABS
739 uint8 tmp; uint16 addr;
741 tmp = regs.RdMem(addr); uint8 tmp2 = tmp;
742 tmp = (tmp >> 1) + (regs.cc&0x01)*128;
743 regs.WrMem(addr, tmp);
744 (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
745 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
746 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
749 static void Op77(void) // ASR ABS
751 uint8 tmp; uint16 addr;
753 tmp = regs.RdMem(addr);
754 (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry
756 if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set
757 regs.WrMem(addr, tmp);
758 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
759 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
762 static void Op78(void) // LSL ABS
764 uint8 tmp; uint16 addr;
766 tmp = regs.RdMem(addr);
767 (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
769 regs.WrMem(addr, tmp);
770 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
771 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
774 static void Op79(void) // ROL ABS
776 uint8 tmp2 = regs.RdMem(FetchW());
777 tmp = (tmp2<<1) + (regs.cc&0x01);
778 regs.WrMem(addr, tmp);
779 (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry
780 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
781 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
784 static void Op7A(void) // DEC ABS
786 uint8 tmp; uint16 addr;
788 tmp = regs.RdMem(addr) - 1;
789 regs.WrMem(addr, tmp);
790 (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
791 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
792 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
795 static void Op7C(void) // INC ABS
798 tmp = regs.RdMem(addr) + 1;
799 regs.WrMem(addr, tmp);
801 (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
802 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
803 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
806 static void Op7D(void) // TST ABS
808 uint8 tmp = regs.RdMem(FetchW());
810 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
811 (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
814 static void Op7E(void) // JMP ABS
819 static void Op7F(void) // CLR ABS
821 regs.WrMem(FetchW(), 0);
822 regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC
825 static void Op80(void) // SUBA #
827 uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
829 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
830 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
831 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
832 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
835 static void Op81(void) // CMPA #
837 tmp = regs.RdMem(regs.pc++);
838 uint8 db = regs.a - tmp;
839 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
840 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
841 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
842 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
845 static void Op82(void) // SBCA #
847 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
848 regs.a = regs.a - tmp - (regs.cc&0x01);
849 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
850 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
851 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
852 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
855 static void Op84(void) // ANDA #
857 regs.a &= regs.RdMem(regs.pc++);
858 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
859 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
860 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
863 static void Op85(void) // BITA #
865 tmp = regs.a & regs.RdMem(regs.pc++);
866 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
867 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
868 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
871 static void Op86(void) // LDAA #
873 regs.a = regs.RdMem(regs.pc++);
874 regs.cc &= 0xFD; // CLV
875 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
876 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
879 static void Op88(void) // EORA #
881 regs.a ^= regs.RdMem(regs.pc++);
882 regs.cc &= 0xFD; // CLV
883 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
884 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
887 static void Op89(void) // ADCA #
889 tmp = regs.RdMem(regs.pc++);
890 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
891 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
892 // ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half Carry
893 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
894 regs.a = addr & 0xFF; // Set accumulator
895 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
896 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
899 static void Op8A(void) // ORAA #
901 regs.a |= regs.RdMem(regs.pc++);
902 regs.cc &= 0xFD; // CLV
903 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
904 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
907 static void Op8B(void) // ADDA #
909 tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp;
910 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
911 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
912 regs.a = addr & 0xFF; // Set accumulator
913 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
914 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
917 static void Op8C(void) // CPX #
920 uint16 dw = regs.x - addr;
921 (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
922 ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
923 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
924 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
927 static void Op8D(void) // BSR
929 tmp = regs.RdMem(regs.pc++);
932 WrMemW(regs.s, regs.pc);
934 regs.pc += (signed short int)(signed char)tmp;
937 static void Op8E(void) // LDS #
940 regs.cc &= 0xFD; // CLV
941 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
942 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
945 static void Op90(void) // SUBA ZP
947 tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a;
949 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
950 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
951 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
952 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
955 static void Op91(void) // CMPA ZP
957 tmp = regs.RdMem(regs.RdMem(regs.pc++));
958 uint8 db = regs.a - tmp;
959 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
960 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
961 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
962 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
965 static void Op92(void) // SBCA ZP
967 tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a;
968 regs.a = regs.a - tmp - (regs.cc&0x01);
969 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
970 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
971 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
972 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
975 static void Op94(void) // ANDA ZP
977 regs.a &= regs.RdMem(regs.RdMem(regs.pc++));
978 regs.cc &= 0xF1; // CLV CLZ CLN
979 if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
980 if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
983 static void Op95(void) // BITA ZP
985 tmp = regs.a & regs.RdMem(regs.RdMem(regs.pc++));
986 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
987 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
988 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
991 static void Op96(void) // LDAA ZP
993 regs.a = regs.RdMem(regs.RdMem(regs.pc++));
994 regs.cc &= 0xF1; // CLN CLZ CLV
995 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
996 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
999 static void Op97(void) // STAA ZP
1001 regs.WrMem(regs.RdMem(regs.pc++), regs.a);
1002 regs.cc &= 0xFD; // CLV
1003 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1004 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1007 static void Op98(void) // EORA ZP
1009 regs.a ^= regs.RdMem(regs.RdMem(regs.pc++));
1010 regs.cc &= 0xFD; // CLV
1011 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1012 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1015 static void Op99(void) // ADCA ZP
1017 tmp = regs.RdMem(regs.RdMem(regs.pc++));
1018 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1019 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
1020 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1021 regs.a = addr & 0xFF; // Set accumulator
1022 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero
1023 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative
1026 static void Op9A(void) // ORAA ZP
1028 regs.a |= regs.RdMem(regs.RdMem(regs.pc++));
1029 regs.cc &= 0xFD; // CLV
1030 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1031 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1034 static void Op9B(void) // ADDA ZP
1036 tmp = regs.RdMem(regs.RdMem(regs.pc++));
1037 addr = (uint16)regs.a + (uint16)tmp;
1038 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1039 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1040 regs.a = addr & 0xFF; // Set accumulator
1041 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1042 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1045 static void Op9C(void) // CPX ZP
1047 addr = regs.RdMem(regs.pc++);
1048 uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1049 uint16 dw = regs.x - adr2;
1050 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1051 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1052 (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1053 ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl
1056 static void Op9E(void) // LDS ZP
1058 regs.s = RdMemW(regs.RdMem(regs.pc++));
1060 regs.cc &= 0xFD; // CLV
1061 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1062 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1065 static void Op9F(void) // STS ZP
1067 WrMemW(regs.RdMem(regs.pc++), regs.s);
1069 regs.cc &= 0xFD; // CLV
1070 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1071 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1074 static void OpA0(void) // SUBA IDX
1076 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1078 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1079 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1080 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1081 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1084 static void OpA1(void) // CMPA IDX
1086 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1087 uint8 db = regs.a - tmp;
1088 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1089 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1090 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1091 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1094 static void OpA2(void) // SBCA IDX
1096 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
1097 regs.a = regs.a - tmp - (regs.cc&0x01);
1098 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1099 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1100 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1101 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1104 static void OpA4(void) // ANDA IDX
1106 regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1107 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
1108 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1109 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1112 static void OpA5(void) // BITA IDX
1114 tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1115 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
1116 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1117 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1120 static void OpA6(void) // LDAA IDX
1122 regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1123 regs.cc &= 0xF1; // CLV CLZ CLN
1124 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1125 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1128 static void OpA7(void) // STAA IDX
1130 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a);
1131 regs.cc &= 0xF1; // CLV CLZ CLN
1132 if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag
1133 if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag
1136 static void OpA8(void) // EORA IDX
1138 regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1139 regs.cc &= 0xFD; // CLV
1140 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1141 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1144 static void OpA9(void) // ADCA IDX
1146 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1147 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1148 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1149 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1150 regs.a = addr & 0xFF; // Set accumulator
1151 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1152 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1155 static void OpAA(void) // ORAA IDX
1157 regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1158 regs.cc &= 0xFD; // CLV
1159 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1160 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1163 static void OpAB(void) // ADDA IDX
1165 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1166 addr = (uint16)regs.a + (uint16)tmp;
1167 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1168 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1169 regs.a = addr & 0xFF; // Set accumulator
1170 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1171 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1174 static void OpAC(void) // CPX IDX
1176 addr = DecodeIDX(regs.RdMem(regs.pc++));
1177 uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1178 uint16 dw = regs.x - addr2;
1179 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1180 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1181 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1182 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1185 static void OpAD(void) // JSR IDX
1187 addr = DecodeIDX(regs.RdMem(regs.pc++));
1190 WrMemW(regs.s, regs.pc);
1192 regs.pc = addr; // JSR directly to IDX ptr
1195 static void OpAE(void) // LDS IDX
1197 regs.s = RdMemW(DecodeIDX(regs.RdMem(regs.pc++)));
1200 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1201 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1204 static void OpAF(void) // STS IDX
1206 WrMemW(DecodeIDX(regs.RdMem(regs.pc++)), regs.s);
1208 regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV
1209 if (regs.s & 0x8000) regs.cc |= FLAG_N; // Set Negative flag
1210 if (regs.s == 0) regs.cc |= FLAG_Z; // Set Zero flag
1213 static void OpB0(void) // SUBA ABS
1215 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1217 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1218 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1219 (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1220 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1223 static void OpB1(void) // CMPA ABS
1225 tmp = regs.RdMem(FetchW());
1226 uint8 db = regs.a - tmp;
1227 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1228 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1229 (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1230 ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1233 static void OpB2(void) // SBCA ABS
1235 tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
1236 regs.a = regs.a - tmp - (regs.cc&0x01);
1237 (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1238 ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1239 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1240 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1243 static void OpB4(void) // ANDA ABS
1245 regs.a &= regs.RdMem(FetchW());
1246 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
1247 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1248 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1251 static void OpB5(void) // BITA ABS
1253 tmp = regs.a & regs.RdMem(FetchW());
1254 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
1255 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1256 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1259 static void OpB6(void) // LDAA ABS
1261 regs.a = regs.RdMem(FetchW());
1262 regs.cc &= 0xFD; // CLV
1263 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1264 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1267 static void OpB7(void) // STAA ABS
1269 regs.WrMem(FetchW(), regs.a);
1270 regs.cc &= 0xFD; // CLV
1271 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1272 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1275 static void OpB8(void) // EORA ABS
1277 regs.a ^= regs.RdMem(FetchW());
1278 regs.cc &= 0xFD; // CLV
1279 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1280 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1283 static void OpB9(void) // ADCA ABS
1285 tmp = regs.RdMem(FetchW());
1286 addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
1287 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1288 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1289 regs.a = addr; // Set accumulator
1290 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1291 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1294 static void OpBA(void) // ORAA ABS
1296 regs.a |= regs.RdMem(FetchW());
1297 regs.cc &= 0xFD; // CLV
1298 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1299 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1302 static void OpBB(void) // ADDA ABS
1304 tmp = regs.RdMem(FetchW());
1305 addr = (uint16)regs.a + (uint16)tmp;
1306 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1307 ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1308 regs.a = addr & 0xFF; // Set accumulator
1309 (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1310 (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1313 static void OpBC(void) // CPX ABS
1315 addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1);
1316 uint16 dw = regs.x - addr2;
1317 (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1318 (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1319 (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1320 ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1323 static void OpBD(void) // JSR ABS
1328 WrMemW(regs.s, regs.pc);
1330 regs.pc = addr; // Go to absolute address (Not indir)
1333 static void OpBE(void) // LDS ABS
1336 regs.s = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1337 regs.cc &= 0xFD; // CLV
1338 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1339 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1342 static void OpBF(void) // STS ABS
1345 regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF);
1346 regs.cc &= 0xFD; // CLV
1347 (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1348 (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1351 static void OpC0(void) // SUBB #
1353 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
1355 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1356 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1357 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1358 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1361 static void OpC1(void) // CMPB #
1363 tmp = regs.RdMem(regs.pc++);
1364 uint8 db = regs.b - tmp;
1365 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1366 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1367 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1368 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1371 static void OpC2(void) // SBCB #
1373 tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
1374 regs.b = regs.b - tmp - (regs.cc&0x01);
1375 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1376 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1377 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1378 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1381 static void OpC4(void) // ANDB #
1383 regs.b &= regs.RdMem(regs.pc++);
1384 regs.cc &= 0xFD; // Cleregs.a oVerflow flag
1385 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1386 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1389 static void OpC5(void) // BITB #
1391 tmp = regs.b & regs.RdMem(regs.pc++);
1392 regs.cc &= 0xF1; // CLV CLZ CLN
1393 if (tmp == 0) regs.cc |= 0x04; // Set Zero flag
1394 if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag
1397 static void OpC6(void) // LDAB #
1399 regs.b = regs.RdMem(regs.pc++);
1400 regs.cc &= 0xF1; // CLV CLZ CLN
1401 if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag
1402 if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag
1405 static void OpC8(void) // EORB #
1407 regs.b ^= regs.RdMem(regs.pc++);
1408 regs.cc &= 0xFD; // CLV
1409 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1410 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1413 static void OpC9(void) // ADCB #
1415 tmp = regs.RdMem(regs.pc++);
1416 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1417 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1418 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1419 regs.b = addr & 0xFF; // Set accumulator
1420 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1421 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1424 static void OpCA(void) // ORAB #
1426 regs.b |= regs.RdMem(regs.pc++);
1427 regs.cc &= 0xFD; // CLV
1428 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1429 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1432 static void OpCB(void) // ADDB #
1434 tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp;
1435 (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1436 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1437 regs.b = addr & 0xFF; // Set accumulator
1438 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1439 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1442 static void OpCE(void) // LDX #
1445 regs.cc &= 0xFD; // CLV
1446 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1447 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1450 static void OpD0(void) // SUBB ZP
1452 tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b;
1454 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1455 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1456 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1457 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1460 static void OpD1(void) // CMPB ZP
1462 tmp = regs.RdMem(regs.RdMem(regs.pc++));
1463 uint8 db = regs.b - tmp;
1464 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1465 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1466 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1467 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1470 static void OpD2(void) // SBCB ZP
1472 tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b;
1473 regs.b = regs.b - tmp - (regs.cc&0x01);
1474 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1475 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1476 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1477 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1480 static void OpD4(void) // ANDB ZP
1482 regs.b &= regs.RdMem(regs.RdMem(regs.pc++));
1483 regs.cc &= 0xFD; // Clear oVerflow flag
1484 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1485 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1488 static void OpD5(void) // BITB ZP
1490 tmp = regs.b & regs.RdMem(regs.RdMem(regs.pc++));
1491 regs.cc &= 0xFD; // Clear oVerflow flag
1492 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1493 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1496 static void OpD6(void) // LDAB ZP
1498 regs.b = regs.RdMem(regs.RdMem(regs.pc++));
1499 regs.cc &= 0xFD; // CLV
1500 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1501 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1504 static void OpD7(void) // STAB ZP
1506 regs.WrMem(regs.RdMem(regs.pc++), regs.b);
1507 regs.cc &= 0xFD; // CLV
1508 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1509 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1512 static void OpD8(void) // EORB ZP
1514 regs.b ^= regs.RdMem(regs.RdMem(regs.pc++));
1515 regs.cc &= 0xFD; // CLV
1516 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1517 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1520 static void OpD9(void) // ADCB ZP
1522 tmp = regs.RdMem(regs.RdMem(regs.pc++));
1523 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1524 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1525 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1526 regs.b = addr; // Set accumulator
1527 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1528 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1531 static void OpDA(void) // ORAB ZP
1533 regs.b |= regs.RdMem(regs.RdMem(regs.pc++));
1534 regs.cc &= 0xFD; // CLV
1535 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1536 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1539 static void OpDB(void) // ADDB ZP
1541 tmp = regs.RdMem(regs.RdMem(regs.pc++));
1542 addr = (uint16)regs.b + (uint16)tmp;
1543 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1544 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1545 regs.b = addr & 0xFF; // Set accumulator
1546 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1547 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1550 static void OpDE(void) // LDX ZP
1552 addr = regs.RdMem(regs.pc++);
1553 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1554 regs.cc &= 0xFD; // CLV
1555 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1556 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1559 static void OpDF(void) // STX ZP
1561 addr = regs.RdMem(regs.pc++);
1562 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1563 regs.cc &= 0xFD; // CLV
1564 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1565 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1568 static void OpE0(void) // SUBB IDX
1570 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
1572 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1573 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1574 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1575 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1578 static void OpE1(void) // CMPB IDX
1580 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1581 uint8 db = regs.b - tmp;
1582 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1583 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1584 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1585 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1588 static void OpE2(void) // SBCB IDX
1590 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
1591 regs.b = regs.b - tmp - (regs.cc&0x01);
1592 (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1593 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1594 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1595 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1598 static void OpE4(void) // ANDB IDX
1600 regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1601 regs.cc &= 0xFD; // Clear oVerflow flag
1602 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1603 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1606 static void OpE5(void) // BITB IDX
1608 tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1609 regs.cc &= 0xFD; // Clear oVerflow flag
1610 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1611 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1614 static void OpE6(void) // LDB IDX
1616 regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1617 regs.cc &= 0xFD; // CLV
1618 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1619 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1622 static void OpE7(void) // STB IDX
1624 regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b);
1625 regs.cc &= 0xF1; // CLV CLZ CLN
1626 if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag
1627 if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag
1630 static void OpE8(void) // EORB IDX
1632 regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1633 regs.cc &= 0xFD; // CLV
1634 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1635 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1638 static void OpE9(void) // ADCB IDX
1640 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1641 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1642 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1643 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1644 regs.b = addr; // Set accumulator
1645 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1646 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1649 static void OpEA(void) // ORB IDX
1651 regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1652 regs.cc &= 0xFD; // CLV
1653 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1654 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1657 static void OpEB(void) // ADDB IDX
1659 tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
1660 addr = (uint16)regs.b + (uint16)tmp;
1661 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1662 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1663 regs.b = addr; // Set accumulator
1664 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1665 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1668 static void OpEE(void) // LDX IDX
1670 addr = DecodeIDX(regs.RdMem(regs.pc++));
1671 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1672 regs.cc &= 0xF1; // CLV CLZ CLN
1673 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1674 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1677 static void OpEF(void) // STX IDX
1679 addr = DecodeIDX(regs.RdMem(regs.pc++));
1680 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1681 regs.cc &= 0xF1; // CLV CLZ CLN
1682 if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag
1683 if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag
1686 static void OpF0(void) // SUBB ABS
1688 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
1690 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1691 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1692 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1693 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1696 static void OpF1(void) // CMPB ABS
1698 tmp = regs.RdMem(FetchW());
1699 uint8 db = regs.b - tmp;
1700 (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1701 (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1702 (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1703 ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1706 static void OpF2(void) // SBCB ABS
1708 tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
1709 regs.b = regs.b - tmp - (regs.cc&0x01);
1710 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1711 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1712 (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
1713 ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
1716 static void OpF4(void) // ANDB ABS
1718 regs.b &= regs.RdMem(FetchW());
1719 regs.cc &= 0xFD; // Clear oVerflow flag
1720 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1721 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1724 static void OpF5(void) // BITB ABS
1726 tmp = regs.b & regs.RdMem(FetchW());
1727 regs.cc &= 0xFD; // Clear oVerflow flag
1728 (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1729 (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1732 static void OpF6(void) // LDB ABS
1734 regs.b = regs.RdMem(FetchW());
1735 regs.cc &= 0xFD; // CLV
1736 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1737 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1740 static void OpF7(void) // STB ABS
1742 regs.WrMem(FetchW(), regs.b);
1743 regs.cc &= 0xFD; // CLV
1744 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1745 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1748 static void OpF8(void) // EORB ABS
1750 regs.b ^= regs.RdMem(FetchW());
1751 regs.cc &= 0xFD; // CLV
1752 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1753 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1756 static void OpF9(void) // ADCB ABS
1758 tmp = regs.RdMem(FetchW());
1759 addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
1760 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1761 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1762 regs.b = addr & 0xFF; // Set accumulator
1763 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1764 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1767 static void OpFA(void) // ORB ABS
1769 regs.b |= regs.RdMem(FetchW());
1770 regs.cc &= 0xFD; // CLV
1771 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1772 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1775 static void OpFB(void) // ADDB ABS
1777 tmp = regs.RdMem(FetchW());
1778 addr = (uint16)regs.b + (uint16)tmp;
1779 (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
1780 ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
1781 regs.b = addr & 0xFF; // Set accumulator
1782 (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
1783 (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
1786 static void OpFE(void) // LDX ABS
1789 regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1);
1790 regs.cc &= 0xFD; // CLV
1791 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1792 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1795 static void OpFF(void) // STX ABS
1798 regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF);
1799 regs.cc &= 0xFD; // CLV
1800 (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
1801 (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
1804 static void Op__(void)
1806 regs.cpuFlags |= V6808_STATE_ILLEGAL_INST;
1811 // Ok, the exec_op[] array is globally defined here basically to save
1812 // a LOT of unnecessary typing. Sure it's ugly, but hey, it works!
1814 void (* exec_op[256])() = {
1815 Op__, Op01, Op__, Op__, Op__, Op__, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F,
1816 Op10, Op11, Op__, Op__, Op__, Op__, Op16, Op17, Op__, Op19, Op__, Op1B, Op__, Op__, Op__, Op__,
1817 Op20, Op__, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F,
1818 Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op__, Op3B, Op__, Op__, Op3E, Op3F,
1819 Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F,
1820 Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F,
1821 Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F,
1822 Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F,
1823 Op80, Op81, Op82, Op__, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__,
1824 Op90, Op91, Op92, Op__, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op__, Op9E, Op9F,
1825 OpA0, OpA1, OpA2, Op__, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF,
1826 OpB0, OpB1, OpB2, Op__, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF,
1827 OpC0, OpC1, OpC2, Op__, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, Op__, Op__, OpCE, Op__,
1828 OpD0, OpD1, OpD2, Op__, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, Op__, Op__, OpDE, OpDF,
1829 OpE0, OpE1, OpE2, Op__, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, Op__, Op__, OpEE, OpEF,
1830 OpF0, OpF1, OpF2, Op__, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, Op__, Op__, OpFE, OpFF
1835 // Internal "memcpy" (so we don't have to link with any external libraries!)
1837 static void myMemcpy(void * dst, void * src, uint32 size)
1839 uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
1841 for(uint32 i=0; i<size; i++)
1845 //int instCount[256];
1847 // Function to execute 6808 for "cycles" cycles
1849 void Execute6808(V6808REGS * context, uint32 cycles)
1851 myMemcpy(®s, context, sizeof(V6808REGS));
1854 while (regs.clock < cycles)
1857 Decode6808(regs.pc);
1859 uint8 opcode = regs.RdMem(regs.pc++);
1861 //if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
1862 //instCount[opcode]++;
1864 exec_op[opcode](); // Execute that opcode...
1865 regs.clock += CPUCycles[opcode];
1867 WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, regs.cc);
1870 if (regs.cpuFlags & V6808_ASSERT_LINE_RESET)
1872 regs.cc |= FLAG_I; // Set I
1873 regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
1875 context->cpuFlags &= ~V6808_ASSERT_LINE_RESET;
1876 regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET;
1878 else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI)
1880 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
1881 regs.WrMem(--regs.s, regs.pc >> 8);
1882 regs.WrMem(--regs.s, regs.x & 0xFF);
1883 regs.WrMem(--regs.s, regs.x >> 8);
1884 regs.WrMem(--regs.s, regs.b);
1885 regs.WrMem(--regs.s, regs.a);
1886 regs.WrMem(--regs.s, regs.cc);
1887 regs.pc = RdMemW(0xFFFC); // And do it!
1889 regs.clock += 0; // How many???
1890 context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
1891 regs.cpuFlags &= ~V6808_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
1893 else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
1895 if (!(regs.cc & FLAG_I)) // Process an interrupt (I=0)?
1897 regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs...
1898 regs.WrMem(--regs.s, regs.pc >> 8);
1899 regs.WrMem(--regs.s, regs.x & 0xFF);
1900 regs.WrMem(--regs.s, regs.x >> 8);
1901 regs.WrMem(--regs.s, regs.b);
1902 regs.WrMem(--regs.s, regs.a);
1903 regs.WrMem(--regs.s, regs.cc);
1904 regs.pc = RdMemW(0xFFF8); // And do it!
1906 regs.clock += 0; // How many???
1907 context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
1908 regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
1913 myMemcpy(context, ®s, sizeof(V6808REGS));
1917 // Get the clock of the currently executing CPU
1919 uint32 GetCurrentV6808Clock(void)