2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
21 #define NMI_VEC 0xfffa
22 #define RST_VEC 0xfffc
23 #define IRQ_VEC 0xfffe
35 // some shortcuts for improved readability
45 P = (P & ~F_N) | F_Z; \
47 P = (P & ~(F_N | F_Z)) | ((n) & F_N)
70 // virtual machine interface
72 #define RDMEM_ID(addr) d_mem->read_data8(addr)
73 #define WRMEM_ID(addr, data) d_mem->write_data8(addr, data)
75 #define RDOP() d_mem->read_data8(PCW++)
76 #define PEEKOP() d_mem->read_data8(PCW)
77 #define RDOPARG() d_mem->read_data8(PCW++)
79 #define RDMEM(addr) d_mem->read_data8(addr)
80 #define WRMEM(addr, data) d_mem->write_data8(addr, data)
82 #define CYCLES(c) icount -= (c)
87 int8_t tmp2 = RDOPARG(); \
90 EAW = PCW + (int8_t)tmp2; \
92 RDMEM((PCH << 8) | EAL) ; \
100 // Helper macros to build the effective address
124 if(EAL + X > 0xff) { \
125 RDMEM((EAH << 8) | ((EAL + X) & 0xff)); \
132 RDMEM((EAH << 8) | ((EAL + X) & 0xff)); \
137 if(EAL + Y > 0xff) { \
138 RDMEM((EAH << 8) | ((EAL + Y) & 0xff)); \
145 RDMEM((EAH << 8) | ((EAL + Y) & 0xff)); \
161 if(EAL + Y > 0xff) { \
162 RDMEM((EAH << 8) | ((EAL + Y) & 0xff)); \
172 RDMEM((EAH << 8) | ((EAL + Y) & 0xff)); \
188 // read a value into tmp
190 #define RD_IMM tmp = RDOPARG()
191 #define RD_DUM RDMEM(PCW)
192 #define RD_ACC tmp = A
193 #define RD_ZPG EA_ZPG; tmp = RDMEM(EAD)
194 #define RD_ZPX EA_ZPX; tmp = RDMEM(EAD)
195 #define RD_ZPY EA_ZPY; tmp = RDMEM(EAD)
196 #define RD_ABS EA_ABS; tmp = RDMEM(EAD)
197 #define RD_ABX_P EA_ABX_P; tmp = RDMEM(EAD)
198 #define RD_ABX_NP EA_ABX_NP; tmp = RDMEM(EAD)
199 #define RD_ABY_P EA_ABY_P; tmp = RDMEM(EAD)
200 #define RD_ABY_NP EA_ABY_NP; tmp = RDMEM(EAD)
201 #define RD_IDX EA_IDX; tmp = RDMEM_ID(EAD)
202 #define RD_IDY_P EA_IDY_P; tmp = RDMEM_ID(EAD)
203 #define RD_IDY_NP EA_IDY_NP; tmp = RDMEM_ID(EAD)
204 #define RD_ZPI EA_ZPI; tmp = RDMEM(EAD)
206 // write a value from tmp
208 #define WR_ZPG EA_ZPG; WRMEM(EAD, tmp)
209 #define WR_ZPX EA_ZPX; WRMEM(EAD, tmp)
210 #define WR_ZPY EA_ZPY; WRMEM(EAD, tmp)
211 #define WR_ABS EA_ABS; WRMEM(EAD, tmp)
212 #define WR_ABX_NP EA_ABX_NP; WRMEM(EAD, tmp)
213 #define WR_ABY_NP EA_ABY_NP; WRMEM(EAD, tmp)
214 #define WR_IDX EA_IDX; WRMEM_ID(EAD, tmp)
215 #define WR_IDY_NP EA_IDY_NP; WRMEM_ID(EAD, tmp)
216 #define WR_ZPI EA_ZPI; WRMEM(EAD, tmp)
218 // dummy read from the last EA
220 #define RD_EA RDMEM(EAD)
222 // write back a value from tmp to the last EA
224 #define WB_ACC A = (uint8_t)tmp;
225 #define WB_EA WRMEM(EAD, tmp)
229 #define PUSH(Rg) WRMEM(SPD, Rg); S--
230 #define PULL(Rg) S++; Rg = RDMEM(SPD)
235 int sum = A + tmp + c; \
237 if(~(A ^ tmp) & (A ^ sum) & F_N) { \
248 A = (uint8_t)(A & tmp); \
252 P = (P & ~F_C) | ((tmp >> 7) & F_C); \
253 tmp = (uint8_t)(tmp << 1); \
256 #define BCC BRA(!(P & F_C))
257 #define BCS BRA(P & F_C)
258 #define BEQ BRA(P & F_Z)
261 P &= ~(F_N | F_V | F_Z); \
262 P |= tmp & (F_N | F_V); \
266 #define BMI BRA(P & F_N)
267 #define BNE BRA(!(P & F_Z))
268 #define BPL BRA(!(P & F_N))
276 PCL = RDMEM(IRQ_VEC); \
277 PCH = RDMEM(IRQ_VEC + 1)
279 #define BVC BRA(!(P & F_V))
280 #define BVS BRA(P & F_V)
282 #define CLC P &= ~F_C
283 #define CLD P &= ~F_D
285 if(irq_state && (P & F_I)) { \
286 if(PEEKOP() != 0x40) { \
291 #define CLV P &= ~F_V
298 SET_NZ((uint8_t)(A - tmp))
304 SET_NZ((uint8_t)(X - tmp))
310 SET_NZ((uint8_t)(Y - tmp))
313 tmp = (uint8_t)(tmp - 1); \
316 X = (uint8_t)(X - 1); \
319 Y = (uint8_t)(Y - 1); \
323 A = (uint8_t)(A ^ tmp); \
327 tmp = (uint8_t)(tmp + 1); \
330 X = (uint8_t)(X + 1); \
333 Y = (uint8_t)(Y + 1); \
336 #define JMP PCD = EAD
356 P = (P & ~F_C) | (tmp & F_C); \
357 tmp = (uint8_t)tmp >> 1; \
363 A = (uint8_t)(A | tmp); \
377 if(irq_state && !(P & F_I)) { \
386 tmp = (tmp << 1) | (P & F_C); \
387 P = (P & ~F_C) | ((tmp >> 8) & F_C); \
388 tmp = (uint8_t)tmp; \
391 tmp |= (P & F_C) << 8; \
392 P = (P & ~F_C) | (tmp & F_C); \
393 tmp = (uint8_t)(tmp >> 1); \
403 if(irq_state && !(P & F_I)) { \
417 int c = (P & F_C) ^ F_C; \
418 int sum = A - tmp - c; \
420 if((A ^ tmp) & (A ^ sum) & F_N) { \
423 if((sum & 0xff00) == 0) { \
457 A = (uint8_t)(A & tmp); \
481 if((tmp & 0x60) == 0x20 || (tmp & 0x60) == 0x40) { \
492 X = (uint8_t)(X - tmp); \
496 A = (uint8_t)((A | 0xee) & X & tmp); \
500 tmp = (uint8_t)(tmp - 1); \
505 SET_NZ((uint8_t)(A - tmp))
507 #define DOP RDOPARG()
510 tmp = (uint8_t)(tmp + 1); \
514 A = X = (uint8_t)tmp; \
519 A = X = (uint8_t)((A | 0xff) & tmp); \
523 tmp = (tmp << 1) | (P & F_C); \
524 P = (P & ~F_C) | ((tmp >> 8) & F_C); \
525 tmp = (uint8_t)tmp; \
529 tmp |= (P & F_C) << 8; \
530 P = (P & ~F_C) | (tmp & F_C); \
531 tmp = (uint8_t)(tmp >> 1); \
534 #define SAX tmp = A & X
537 P = (P & ~F_C) | ((tmp >> 7) & F_C); \
538 tmp = (uint8_t)(tmp << 1); \
543 P = (P & ~F_C) | (tmp & F_C); \
544 tmp = (uint8_t)tmp >> 1; \
548 #define SAH tmp = A & X & (EAH + 1)
569 void N2A03::OP(uint8_t code)
574 case 0x00: { CYCLES(7); BRK; } break; /* 7 BRK */
575 case 0x01: { CYCLES(6); RD_IDX; ORA; } break; /* 6 ORA IDX */
576 case 0x02: { CYCLES(1); KIL; } break; /* 1 KIL */
577 case 0x03: { CYCLES(7); RD_IDX; RD_EA; SLO; WB_EA; } break; /* 7 SLO IDX */
578 case 0x04: { CYCLES(3); RD_ZPG; NOP; } break; /* 3 NOP ZPG */
579 case 0x05: { CYCLES(3); RD_ZPG; ORA; } break; /* 3 ORA ZPG */
580 case 0x06: { CYCLES(5); RD_ZPG; RD_EA; ASL; WB_EA; } break; /* 5 ASL ZPG */
581 case 0x07: { CYCLES(5); RD_ZPG; RD_EA; SLO; WB_EA; } break; /* 5 SLO ZPG */
582 case 0x08: { CYCLES(3); RD_DUM; PHP; } break; /* 3 PHP */
583 case 0x09: { CYCLES(2); RD_IMM; ORA; } break; /* 2 ORA IMM */
584 case 0x0a: { CYCLES(2); RD_DUM; RD_ACC; ASL; WB_ACC; } break; /* 2 ASL A */
585 case 0x0b: { CYCLES(2); RD_IMM; ANC; } break; /* 2 ANC IMM */
586 case 0x0c: { CYCLES(4); RD_ABS; NOP; } break; /* 4 NOP ABS */
587 case 0x0d: { CYCLES(4); RD_ABS; ORA; } break; /* 4 ORA ABS */
588 case 0x0e: { CYCLES(6); RD_ABS; RD_EA; ASL; WB_EA; } break; /* 6 ASL ABS */
589 case 0x0f: { CYCLES(6); RD_ABS; RD_EA; SLO; WB_EA; } break; /* 6 SLO ABS */
590 case 0x10: { CYCLES(2); BPL; } break; /* 2-4 BPL REL */
591 case 0x11: { CYCLES(5); RD_IDY_P; ORA; } break; /* 5 ORA IDY page penalty */
592 case 0x12: { CYCLES(1); KIL; } break; /* 1 KIL */
593 case 0x13: { CYCLES(7); RD_IDY_NP; RD_EA; SLO; WB_EA; } break; /* 7 SLO IDY */
594 case 0x14: { CYCLES(4); RD_ZPX; NOP; } break; /* 4 NOP ZPX */
595 case 0x15: { CYCLES(4); RD_ZPX; ORA; } break; /* 4 ORA ZPX */
596 case 0x16: { CYCLES(6); RD_ZPX; RD_EA; ASL; WB_EA; } break; /* 6 ASL ZPX */
597 case 0x17: { CYCLES(6); RD_ZPX; RD_EA; SLO; WB_EA; } break; /* 6 SLO ZPX */
598 case 0x18: { CYCLES(2); RD_DUM; CLC; } break; /* 2 CLC */
599 case 0x19: { CYCLES(4); RD_ABY_P; ORA; } break; /* 4 ORA ABY page penalty */
600 case 0x1a: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
601 case 0x1b: { CYCLES(7); RD_ABY_NP; RD_EA; SLO; WB_EA; } break; /* 7 SLO ABY */
602 case 0x1c: { CYCLES(4); RD_ABX_P; NOP; } break; /* 4 NOP ABX page penalty */
603 case 0x1d: { CYCLES(4); RD_ABX_P; ORA; } break; /* 4 ORA ABX page penalty */
604 case 0x1e: { CYCLES(7); RD_ABX_NP; RD_EA; ASL; WB_EA; } break; /* 7 ASL ABX */
605 case 0x1f: { CYCLES(7); RD_ABX_NP; RD_EA; SLO; WB_EA; } break; /* 7 SLO ABX */
606 case 0x20: { CYCLES(6); JSR; } break; /* 6 JSR */
607 case 0x21: { CYCLES(6); RD_IDX; AND; } break; /* 6 AND IDX */
608 case 0x22: { CYCLES(1); KIL; } break; /* 1 KIL */
609 case 0x23: { CYCLES(7); RD_IDX; RD_EA; RLA; WB_EA; } break; /* 7 RLA IDX */
610 case 0x24: { CYCLES(3); RD_ZPG; BIT; } break; /* 3 BIT ZPG */
611 case 0x25: { CYCLES(3); RD_ZPG; AND; } break; /* 3 AND ZPG */
612 case 0x26: { CYCLES(5); RD_ZPG; RD_EA; ROL; WB_EA; } break; /* 5 ROL ZPG */
613 case 0x27: { CYCLES(5); RD_ZPG; RD_EA; RLA; WB_EA; } break; /* 5 RLA ZPG */
614 case 0x28: { CYCLES(4); RD_DUM; PLP; } break; /* 4 PLP */
615 case 0x29: { CYCLES(2); RD_IMM; AND; } break; /* 2 AND IMM */
616 case 0x2a: { CYCLES(2); RD_DUM; RD_ACC; ROL; WB_ACC; } break; /* 2 ROL A */
617 case 0x2b: { CYCLES(2); RD_IMM; ANC; } break; /* 2 ANC IMM */
618 case 0x2c: { CYCLES(4); RD_ABS; BIT; } break; /* 4 BIT ABS */
619 case 0x2d: { CYCLES(4); RD_ABS; AND; } break; /* 4 AND ABS */
620 case 0x2e: { CYCLES(6); RD_ABS; RD_EA; ROL; WB_EA; } break; /* 6 ROL ABS */
621 case 0x2f: { CYCLES(6); RD_ABS; RD_EA; RLA; WB_EA; } break; /* 6 RLA ABS */
622 case 0x30: { CYCLES(2); BMI; } break; /* 2-4 BMI REL */
623 case 0x31: { CYCLES(5); RD_IDY_P; AND; } break; /* 5 AND IDY page penalty */
624 case 0x32: { CYCLES(1); KIL; } break; /* 1 KIL */
625 case 0x33: { CYCLES(7); RD_IDY_NP; RD_EA; RLA; WB_EA; } break; /* 7 RLA IDY */
626 case 0x34: { CYCLES(4); RD_ZPX; NOP; } break; /* 4 NOP ZPX */
627 case 0x35: { CYCLES(4); RD_ZPX; AND; } break; /* 4 AND ZPX */
628 case 0x36: { CYCLES(6); RD_ZPX; RD_EA; ROL; WB_EA; } break; /* 6 ROL ZPX */
629 case 0x37: { CYCLES(6); RD_ZPX; RD_EA; RLA; WB_EA; } break; /* 6 RLA ZPX */
630 case 0x38: { CYCLES(2); RD_DUM; SEC; } break; /* 2 SEC */
631 case 0x39: { CYCLES(4); RD_ABY_P; AND; } break; /* 4 AND ABY page penalty */
632 case 0x3a: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
633 case 0x3b: { CYCLES(7); RD_ABY_NP; RD_EA; RLA; WB_EA; } break; /* 7 RLA ABY */
634 case 0x3c: { CYCLES(4); RD_ABX_P; NOP; } break; /* 4 NOP ABX page penalty */
635 case 0x3d: { CYCLES(4); RD_ABX_P; AND; } break; /* 4 AND ABX page penalty */
636 case 0x3e: { CYCLES(7); RD_ABX_NP; RD_EA; ROL; WB_EA; } break; /* 7 ROL ABX */
637 case 0x3f: { CYCLES(7); RD_ABX_NP; RD_EA; RLA; WB_EA; } break; /* 7 RLA ABX */
638 case 0x40: { CYCLES(6); RTI; } break; /* 6 RTI */
639 case 0x41: { CYCLES(6); RD_IDX; EOR; } break; /* 6 EOR IDX */
640 case 0x42: { CYCLES(1); KIL; } break; /* 1 KIL */
641 case 0x43: { CYCLES(7); RD_IDX; RD_EA; SRE; WB_EA; } break; /* 7 SRE IDX */
642 case 0x44: { CYCLES(3); RD_ZPG; NOP; } break; /* 3 NOP ZPG */
643 case 0x45: { CYCLES(3); RD_ZPG; EOR; } break; /* 3 EOR ZPG */
644 case 0x46: { CYCLES(5); RD_ZPG; RD_EA; LSR; WB_EA; } break; /* 5 LSR ZPG */
645 case 0x47: { CYCLES(5); RD_ZPG; RD_EA; SRE; WB_EA; } break; /* 5 SRE ZPG */
646 case 0x48: { CYCLES(3); RD_DUM; PHA; } break; /* 3 PHA */
647 case 0x49: { CYCLES(2); RD_IMM; EOR; } break; /* 2 EOR IMM */
648 case 0x4a: { CYCLES(2); RD_DUM; RD_ACC; LSR; WB_ACC; } break; /* 2 LSR A */
649 case 0x4b: { CYCLES(2); RD_IMM; ASR; WB_ACC; } break; /* 2 ASR IMM */
650 case 0x4c: { CYCLES(3); EA_ABS; JMP; } break; /* 3 JMP ABS */
651 case 0x4d: { CYCLES(4); RD_ABS; EOR; } break; /* 4 EOR ABS */
652 case 0x4e: { CYCLES(6); RD_ABS; RD_EA; LSR; WB_EA; } break; /* 6 LSR ABS */
653 case 0x4f: { CYCLES(6); RD_ABS; RD_EA; SRE; WB_EA; } break; /* 6 SRE ABS */
654 case 0x50: { CYCLES(2); BVC; } break; /* 2-4 BVC REL */
655 case 0x51: { CYCLES(5); RD_IDY_P; EOR; } break; /* 5 EOR IDY page penalty */
656 case 0x52: { CYCLES(1); KIL; } break; /* 1 KIL */
657 case 0x53: { CYCLES(7); RD_IDY_NP; RD_EA; SRE; WB_EA; } break; /* 7 SRE IDY */
658 case 0x54: { CYCLES(4); RD_ZPX; NOP; } break; /* 4 NOP ZPX */
659 case 0x55: { CYCLES(4); RD_ZPX; EOR; } break; /* 4 EOR ZPX */
660 case 0x56: { CYCLES(6); RD_ZPX; RD_EA; LSR; WB_EA; } break; /* 6 LSR ZPX */
661 case 0x57: { CYCLES(6); RD_ZPX; RD_EA; SRE; WB_EA; } break; /* 6 SRE ZPX */
662 case 0x58: { CYCLES(2); RD_DUM; CLI; } break; /* 2 CLI */
663 case 0x59: { CYCLES(4); RD_ABY_P; EOR; } break; /* 4 EOR ABY page penalty */
664 case 0x5a: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
665 case 0x5b: { CYCLES(7); RD_ABY_NP; RD_EA; SRE; WB_EA; } break; /* 7 SRE ABY */
666 case 0x5c: { CYCLES(4); RD_ABX_P; NOP; } break; /* 4 NOP ABX page penalty */
667 case 0x5d: { CYCLES(4); RD_ABX_P; EOR; } break; /* 4 EOR ABX page penalty */
668 case 0x5e: { CYCLES(7); RD_ABX_NP; RD_EA; LSR; WB_EA; } break; /* 7 LSR ABX */
669 case 0x5f: { CYCLES(7); RD_ABX_NP; RD_EA; SRE; WB_EA; } break; /* 7 SRE ABX */
670 case 0x60: { CYCLES(6); RTS; } break; /* 6 RTS */
671 case 0x61: { CYCLES(6); RD_IDX; ADC; } break; /* 6 ADC IDX */
672 case 0x62: { CYCLES(1); KIL; } break; /* 1 KIL */
673 case 0x63: { CYCLES(7); RD_IDX; RD_EA; RRA; WB_EA; } break; /* 7 RRA IDX */
674 case 0x64: { CYCLES(3); RD_ZPG; NOP; } break; /* 3 NOP ZPG */
675 case 0x65: { CYCLES(3); RD_ZPG; ADC; } break; /* 3 ADC ZPG */
676 case 0x66: { CYCLES(5); RD_ZPG; RD_EA; ROR; WB_EA; } break; /* 5 ROR ZPG */
677 case 0x67: { CYCLES(5); RD_ZPG; RD_EA; RRA; WB_EA; } break; /* 5 RRA ZPG */
678 case 0x68: { CYCLES(4); RD_DUM; PLA; } break; /* 4 PLA */
679 case 0x69: { CYCLES(2); RD_IMM; ADC; } break; /* 2 ADC IMM */
680 case 0x6a: { CYCLES(2); RD_DUM; RD_ACC; ROR; WB_ACC; } break; /* 2 ROR A */
681 case 0x6b: { CYCLES(2); RD_IMM; ARR; WB_ACC; } break; /* 2 ARR IMM */
682 case 0x6c: { CYCLES(5); EA_IND; JMP; } break; /* 5 JMP IND */
683 case 0x6d: { CYCLES(4); RD_ABS; ADC; } break; /* 4 ADC ABS */
684 case 0x6e: { CYCLES(6); RD_ABS; RD_EA; ROR; WB_EA; } break; /* 6 ROR ABS */
685 case 0x6f: { CYCLES(6); RD_ABS; RD_EA; RRA; WB_EA; } break; /* 6 RRA ABS */
686 case 0x70: { CYCLES(2); BVS; } break; /* 2-4 BVS REL */
687 case 0x71: { CYCLES(5); RD_IDY_P; ADC; } break; /* 5 ADC IDY page penalty */
688 case 0x72: { CYCLES(1); KIL; } break; /* 1 KIL */
689 case 0x73: { CYCLES(7); RD_IDY_NP; RD_EA; RRA; WB_EA; } break; /* 7 RRA IDY */
690 case 0x74: { CYCLES(4); RD_ZPX; NOP; } break; /* 4 NOP ZPX */
691 case 0x75: { CYCLES(4); RD_ZPX; ADC; } break; /* 4 ADC ZPX */
692 case 0x76: { CYCLES(6); RD_ZPX; RD_EA; ROR; WB_EA; } break; /* 6 ROR ZPX */
693 case 0x77: { CYCLES(6); RD_ZPX; RD_EA; RRA; WB_EA; } break; /* 6 RRA ZPX */
694 case 0x78: { CYCLES(2); RD_DUM; SEI; } break; /* 2 SEI */
695 case 0x79: { CYCLES(4); RD_ABY_P; ADC; } break; /* 4 ADC ABY page penalty */
696 case 0x7a: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
697 case 0x7b: { CYCLES(7); RD_ABY_NP; RD_EA; RRA; WB_EA; } break; /* 7 RRA ABY */
698 case 0x7c: { CYCLES(4); RD_ABX_P; NOP; } break; /* 4 NOP ABX page penalty */
699 case 0x7d: { CYCLES(4); RD_ABX_P; ADC; } break; /* 4 ADC ABX page penalty */
700 case 0x7e: { CYCLES(7); RD_ABX_NP; RD_EA; ROR; WB_EA; } break; /* 7 ROR ABX */
701 case 0x7f: { CYCLES(7); RD_ABX_NP; RD_EA; RRA; WB_EA; } break; /* 7 RRA ABX */
702 case 0x80: { CYCLES(2); RD_IMM; NOP; } break; /* 2 NOP IMM */
703 case 0x81: { CYCLES(6); STA; WR_IDX; } break; /* 6 STA IDX */
704 case 0x82: { CYCLES(2); RD_IMM; NOP; } break; /* 2 NOP IMM */
705 case 0x83: { CYCLES(6); SAX; WR_IDX; } break; /* 6 SAX IDX */
706 case 0x84: { CYCLES(3); STY; WR_ZPG; } break; /* 3 STY ZPG */
707 case 0x85: { CYCLES(3); STA; WR_ZPG; } break; /* 3 STA ZPG */
708 case 0x86: { CYCLES(3); STX; WR_ZPG; } break; /* 3 STX ZPG */
709 case 0x87: { CYCLES(3); SAX; WR_ZPG; } break; /* 3 SAX ZPG */
710 case 0x88: { CYCLES(2); RD_DUM; DEY; } break; /* 2 DEY */
711 case 0x89: { CYCLES(2); RD_IMM; NOP; } break; /* 2 NOP IMM */
712 case 0x8a: { CYCLES(2); RD_DUM; TXA; } break; /* 2 TXA */
713 case 0x8b: { CYCLES(2); RD_IMM; AXA; } break; /* 2 AXA IMM */
714 case 0x8c: { CYCLES(4); STY; WR_ABS; } break; /* 4 STY ABS */
715 case 0x8d: { CYCLES(4); STA; WR_ABS; } break; /* 4 STA ABS */
716 case 0x8e: { CYCLES(4); STX; WR_ABS; } break; /* 4 STX ABS */
717 case 0x8f: { CYCLES(4); SAX; WR_ABS; } break; /* 4 SAX ABS */
718 case 0x90: { CYCLES(2); BCC; } break; /* 2-4 BCC REL */
719 case 0x91: { CYCLES(6); STA; WR_IDY_NP; } break; /* 6 STA IDY */
720 case 0x92: { CYCLES(1); KIL; } break; /* 1 KIL */
721 case 0x93: { CYCLES(5); EA_IDY_NP; SAH; WB_EA; } break; /* 5 SAH IDY */
722 case 0x94: { CYCLES(4); STY; WR_ZPX; } break; /* 4 STY ZPX */
723 case 0x95: { CYCLES(4); STA; WR_ZPX; } break; /* 4 STA ZPX */
724 case 0x96: { CYCLES(4); STX; WR_ZPY; } break; /* 4 STX ZPY */
725 case 0x97: { CYCLES(4); SAX; WR_ZPY; } break; /* 4 SAX ZPY */
726 case 0x98: { CYCLES(2); RD_DUM; TYA; } break; /* 2 TYA */
727 case 0x99: { CYCLES(5); STA; WR_ABY_NP; } break; /* 5 STA ABY */
728 case 0x9a: { CYCLES(2); RD_DUM; TXS; } break; /* 2 TXS */
729 case 0x9b: { CYCLES(5); EA_ABY_NP; SSH; WB_EA; } break; /* 5 SSH ABY */
730 case 0x9c: { CYCLES(5); EA_ABX_NP; SYH; WB_EA; } break; /* 5 SYH ABX */
731 case 0x9d: { CYCLES(5); STA; WR_ABX_NP; } break; /* 5 STA ABX */
732 case 0x9e: { CYCLES(5); EA_ABY_NP; SXH; WB_EA; } break; /* 5 SXH ABY */
733 case 0x9f: { CYCLES(5); EA_ABY_NP; SAH; WB_EA; } break; /* 5 SAH ABY */
734 case 0xa0: { CYCLES(2); RD_IMM; LDY; } break; /* 2 LDY IMM */
735 case 0xa1: { CYCLES(6); RD_IDX; LDA; } break; /* 6 LDA IDX */
736 case 0xa2: { CYCLES(2); RD_IMM; LDX; } break; /* 2 LDX IMM */
737 case 0xa3: { CYCLES(6); RD_IDX; LAX; } break; /* 6 LAX IDX */
738 case 0xa4: { CYCLES(3); RD_ZPG; LDY; } break; /* 3 LDY ZPG */
739 case 0xa5: { CYCLES(3); RD_ZPG; LDA; } break; /* 3 LDA ZPG */
740 case 0xa6: { CYCLES(3); RD_ZPG; LDX; } break; /* 3 LDX ZPG */
741 case 0xa7: { CYCLES(3); RD_ZPG; LAX; } break; /* 3 LAX ZPG */
742 case 0xa8: { CYCLES(2); RD_DUM; TAY; } break; /* 2 TAY */
743 case 0xa9: { CYCLES(2); RD_IMM; LDA; } break; /* 2 LDA IMM */
744 case 0xaa: { CYCLES(2); RD_DUM; TAX; } break; /* 2 TAX */
745 case 0xab: { CYCLES(2); RD_IMM; OAL; } break; /* 2 OAL IMM */
746 case 0xac: { CYCLES(4); RD_ABS; LDY; } break; /* 4 LDY ABS */
747 case 0xad: { CYCLES(4); RD_ABS; LDA; } break; /* 4 LDA ABS */
748 case 0xae: { CYCLES(4); RD_ABS; LDX; } break; /* 4 LDX ABS */
749 case 0xaf: { CYCLES(4); RD_ABS; LAX; } break; /* 4 LAX ABS */
750 case 0xb0: { CYCLES(2); BCS; } break; /* 2-4 BCS REL */
751 case 0xb1: { CYCLES(5); RD_IDY_P; LDA; } break; /* 5 LDA IDY page penalty */
752 case 0xb2: { CYCLES(1); KIL; } break; /* 1 KIL */
753 case 0xb3: { CYCLES(5); RD_IDY_P; LAX; } break; /* 5 LAX IDY page penalty */
754 case 0xb4: { CYCLES(4); RD_ZPX; LDY; } break; /* 4 LDY ZPX */
755 case 0xb5: { CYCLES(4); RD_ZPX; LDA; } break; /* 4 LDA ZPX */
756 case 0xb6: { CYCLES(4); RD_ZPY; LDX; } break; /* 4 LDX ZPY */
757 case 0xb7: { CYCLES(4); RD_ZPY; LAX; } break; /* 4 LAX ZPY */
758 case 0xb8: { CYCLES(2); RD_DUM; CLV; } break; /* 2 CLV */
759 case 0xb9: { CYCLES(4); RD_ABY_P; LDA; } break; /* 4 LDA ABY page penalty */
760 case 0xba: { CYCLES(2); RD_DUM; TSX; } break; /* 2 TSX */
761 case 0xbb: { CYCLES(4); RD_ABY_P; AST; } break; /* 4 AST ABY page penalty */
762 case 0xbc: { CYCLES(4); RD_ABX_P; LDY; } break; /* 4 LDY ABX page penalty */
763 case 0xbd: { CYCLES(4); RD_ABX_P; LDA; } break; /* 4 LDA ABX page penalty */
764 case 0xbe: { CYCLES(4); RD_ABY_P; LDX; } break; /* 4 LDX ABY page penalty */
765 case 0xbf: { CYCLES(4); RD_ABY_P; LAX; } break; /* 4 LAX ABY page penalty */
766 case 0xc0: { CYCLES(2); RD_IMM; CPY; } break; /* 2 CPY IMM */
767 case 0xc1: { CYCLES(6); RD_IDX; CMP; } break; /* 6 CMP IDX */
768 case 0xc2: { CYCLES(2); RD_IMM; NOP; } break; /* 2 NOP IMM */
769 case 0xc3: { CYCLES(7); RD_IDX; RD_EA; DCP; WB_EA; } break; /* 7 DCP IDX */
770 case 0xc4: { CYCLES(3); RD_ZPG; CPY; } break; /* 3 CPY ZPG */
771 case 0xc5: { CYCLES(3); RD_ZPG; CMP; } break; /* 3 CMP ZPG */
772 case 0xc6: { CYCLES(5); RD_ZPG; RD_EA; DEC; WB_EA; } break; /* 5 DEC ZPG */
773 case 0xc7: { CYCLES(5); RD_ZPG; RD_EA; DCP; WB_EA; } break; /* 5 DCP ZPG */
774 case 0xc8: { CYCLES(2); RD_DUM; INY; } break; /* 2 INY */
775 case 0xc9: { CYCLES(2); RD_IMM; CMP; } break; /* 2 CMP IMM */
776 case 0xca: { CYCLES(2); RD_DUM; DEX; } break; /* 2 DEX */
777 case 0xcb: { CYCLES(2); RD_IMM; ASX; } break; /* 2 ASX IMM */
778 case 0xcc: { CYCLES(4); RD_ABS; CPY; } break; /* 4 CPY ABS */
779 case 0xcd: { CYCLES(4); RD_ABS; CMP; } break; /* 4 CMP ABS */
780 case 0xce: { CYCLES(6); RD_ABS; RD_EA; DEC; WB_EA; } break; /* 6 DEC ABS */
781 case 0xcf: { CYCLES(6); RD_ABS; RD_EA; DCP; WB_EA; } break; /* 6 DCP ABS */
782 case 0xd0: { CYCLES(2); BNE; } break; /* 2-4 BNE REL */
783 case 0xd1: { CYCLES(5); RD_IDY_P; CMP; } break; /* 5 CMP IDY page penalty */
784 case 0xd2: { CYCLES(1); KIL; } break; /* 1 KIL */
785 case 0xd3: { CYCLES(7); RD_IDY_NP; RD_EA; DCP; WB_EA; } break; /* 7 DCP IDY */
786 case 0xd4: { CYCLES(4); RD_ZPX; NOP; } break; /* 4 NOP ZPX */
787 case 0xd5: { CYCLES(4); RD_ZPX; CMP; } break; /* 4 CMP ZPX */
788 case 0xd6: { CYCLES(6); RD_ZPX; RD_EA; DEC; WB_EA; } break; /* 6 DEC ZPX */
789 case 0xd7: { CYCLES(6); RD_ZPX; RD_EA; DCP; WB_EA; } break; /* 6 DCP ZPX */
790 case 0xd8: { CYCLES(2); RD_DUM; CLD; } break; /* 2 CLD */
791 case 0xd9: { CYCLES(4); RD_ABY_P; CMP; } break; /* 4 CMP ABY page penalty */
792 case 0xda: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
793 case 0xdb: { CYCLES(7); RD_ABY_NP; RD_EA; DCP; WB_EA; } break; /* 7 DCP ABY */
794 case 0xdc: { CYCLES(4); RD_ABX_P; NOP; } break; /* 4 NOP ABX page penalty */
795 case 0xdd: { CYCLES(4); RD_ABX_P; CMP; } break; /* 4 CMP ABX page penalty */
796 case 0xde: { CYCLES(7); RD_ABX_NP; RD_EA; DEC; WB_EA; } break; /* 7 DEC ABX */
797 case 0xdf: { CYCLES(7); RD_ABX_NP; RD_EA; DCP; WB_EA; } break; /* 7 DCP ABX */
798 case 0xe0: { CYCLES(2); RD_IMM; CPX; } break; /* 2 CPX IMM */
799 case 0xe1: { CYCLES(6); RD_IDX; SBC; } break; /* 6 SBC IDX */
800 case 0xe2: { CYCLES(2); RD_IMM; NOP; } break; /* 2 NOP IMM */
801 case 0xe3: { CYCLES(7); RD_IDX; RD_EA; ISB; WB_EA; } break; /* 7 ISB IDX */
802 case 0xe4: { CYCLES(3); RD_ZPG; CPX; } break; /* 3 CPX ZPG */
803 case 0xe5: { CYCLES(3); RD_ZPG; SBC; } break; /* 3 SBC ZPG */
804 case 0xe6: { CYCLES(5); RD_ZPG; RD_EA; INC; WB_EA; } break; /* 5 INC ZPG */
805 case 0xe7: { CYCLES(5); RD_ZPG; RD_EA; ISB; WB_EA; } break; /* 5 ISB ZPG */
806 case 0xe8: { CYCLES(2); RD_DUM; INX; } break; /* 2 INX */
807 case 0xe9: { CYCLES(2); RD_IMM; SBC; } break; /* 2 SBC IMM */
808 case 0xea: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
809 case 0xeb: { CYCLES(2); RD_IMM; SBC; } break; /* 2 SBC IMM */
810 case 0xec: { CYCLES(4); RD_ABS; CPX; } break; /* 4 CPX ABS */
811 case 0xed: { CYCLES(4); RD_ABS; SBC; } break; /* 4 SBC ABS */
812 case 0xee: { CYCLES(6); RD_ABS; RD_EA; INC; WB_EA; } break; /* 6 INC ABS */
813 case 0xef: { CYCLES(6); RD_ABS; RD_EA; ISB; WB_EA; } break; /* 6 ISB ABS */
814 case 0xf0: { CYCLES(2); BEQ; } break; /* 2-4 BEQ REL */
815 case 0xf1: { CYCLES(5); RD_IDY_P; SBC; } break; /* 5 SBC IDY page penalty */
816 case 0xf2: { CYCLES(1); KIL; } break; /* 1 KIL */
817 case 0xf3: { CYCLES(7); RD_IDY_NP; RD_EA; ISB; WB_EA; } break; /* 7 ISB IDY */
818 case 0xf4: { CYCLES(4); RD_ZPX; NOP; } break; /* 4 NOP ZPX */
819 case 0xf5: { CYCLES(4); RD_ZPX; SBC; } break; /* 4 SBC ZPX */
820 case 0xf6: { CYCLES(6); RD_ZPX; RD_EA; INC; WB_EA; } break; /* 6 INC ZPX */
821 case 0xf7: { CYCLES(6); RD_ZPX; RD_EA; ISB; WB_EA; } break; /* 6 ISB ZPX */
822 case 0xf8: { CYCLES(2); RD_DUM; SED; } break; /* 2 SED */
823 case 0xf9: { CYCLES(4); RD_ABY_P; SBC; } break; /* 4 SBC ABY page penalty */
824 case 0xfa: { CYCLES(2); RD_DUM; NOP; } break; /* 2 NOP */
825 case 0xfb: { CYCLES(7); RD_ABY_NP; RD_EA; ISB; WB_EA; } break; /* 7 ISB ABY */
826 case 0xfc: { CYCLES(4); RD_ABX_P; NOP; } break; /* 4 NOP ABX page penalty */
827 case 0xfd: { CYCLES(4); RD_ABX_P; SBC; } break; /* 4 SBC ABX page penalty */
828 case 0xfe: { CYCLES(7); RD_ABX_NP; RD_EA; INC; WB_EA; } break; /* 7 INC ABX */
829 case 0xff: { CYCLES(7); RD_ABX_NP; RD_EA; ISB; WB_EA; } break; /* 7 ISB ABX */
830 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
831 default: __assume(0);
838 void N2A03::initialize()
840 DEVICE::initialize();
842 SPD = EAD = ZPD = PCD = 0;
844 d_mem_stored = d_mem;
845 d_debugger->set_context_mem(d_mem);
851 PCL = RDMEM(RST_VEC);
852 PCH = RDMEM(RST_VEC + 1);
854 P = F_T | F_I | F_Z | F_B | (P & F_D);
857 pending_irq = after_cli = false;
858 irq_state = nmi_state = so_state = false;
861 int N2A03::run(int clock)
868 // run only one opcode
871 bool now_debugging = d_debugger->now_debugging;
873 d_debugger->check_break_points(PCW);
874 if(d_debugger->now_suspended) {
876 d_debugger->now_waiting = true;
877 while(d_debugger->now_debugging && d_debugger->now_suspended) {
880 d_debugger->now_waiting = false;
882 if(d_debugger->now_debugging) {
885 now_debugging = false;
891 if(!d_debugger->now_going) {
892 d_debugger->now_suspended = true;
894 d_mem = d_mem_stored;
906 int first_icount = icount;
908 // run cpu while given clocks
909 while(icount > 0 && !busreq) {
911 bool now_debugging = d_debugger->now_debugging;
913 d_debugger->check_break_points(PCW);
914 if(d_debugger->now_suspended) {
916 d_debugger->now_waiting = true;
917 while(d_debugger->now_debugging && d_debugger->now_suspended) {
920 d_debugger->now_waiting = false;
922 if(d_debugger->now_debugging) {
925 now_debugging = false;
931 if(!d_debugger->now_going) {
932 d_debugger->now_suspended = true;
934 d_mem = d_mem_stored;
943 // if busreq is raised, spin cpu while remained clock
944 if(icount > 0 && busreq) {
947 return first_icount - icount;
951 #define offs_t UINT16
953 #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name
954 #define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol)
955 #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, oprom, d_debugger->first_symbol)
956 const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
958 extern CPU_DISASSEMBLE(m6502);
960 int N2A03::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
964 uint8_t *opram = oprom;
966 for(int i = 0; i < 4; i++) {
968 oprom[i] = d_mem->read_data8w(pc + i, &wait);
970 return CPU_DISASSEMBLE_CALL(m6502) & DASMFLAG_LENGTHMASK;
972 return (int)(pc & DASMFLAG_LENGTHMASK);
976 #define STATE_VERSION 2
978 bool N2A03::process_state(FILEIO* state_fio, bool loading)
980 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
983 if(!state_fio->StateCheckInt32(this_device_id)) {
986 state_fio->StateUint32(pc.d);
987 state_fio->StateUint32(sp.d);
988 state_fio->StateUint32(zp.d);
989 state_fio->StateUint32(ea.d);
990 state_fio->StateUint16(prev_pc);
991 state_fio->StateUint8(a);
992 state_fio->StateUint8(x);
993 state_fio->StateUint8(y);
994 state_fio->StateUint8(p);
995 state_fio->StateBool(pending_irq);
996 state_fio->StateBool(after_cli);
997 state_fio->StateBool(nmi_state);
998 state_fio->StateBool(irq_state);
999 state_fio->StateBool(so_state);
1001 state_fio->StateUint64(total_icount);
1003 state_fio->StateInt32(icount);
1004 state_fio->StateBool(busreq);
1009 prev_total_icount = total_icount;