1 /*****************************************************************************/
5 /* CPU core for the 6502 */
9 /* (C) 2003-2012, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
14 /* Mar-2017, Christian Krueger, added support for 65SC02 */
16 /* This software is provided 'as-is', without any expressed or implied */
17 /* warranty. In no event will the authors be held liable for any damages */
18 /* arising from the use of this software. */
20 /* Permission is granted to anyone to use this software for any purpose, */
21 /* including commercial applications, and to alter it and redistribute it */
22 /* freely, subject to the following restrictions: */
24 /* 1. The origin of this software must not be misrepresented; you must not */
25 /* claim that you wrote the original software. If you use this software */
26 /* in a product, an acknowledgment in the product documentation would be */
27 /* appreciated but is not required. */
28 /* 2. Altered source versions must be plainly marked as such, and must not */
29 /* be misrepresented as being the original software. */
30 /* 3. This notice may not be removed or altered from any source */
33 /*****************************************************************************/
35 /* Known bugs and limitations of the 65C02 simulation:
36 * support currently only on the level of 65SC02:
37 BBRx, BBSx, RMBx, SMBx, WAI and STP are unsupported
38 * BCD flag handling equals 6502 (unchecked if bug is simulated or wrong for
40 * one cycle win for fetch-modify-write instructions ignored
41 (e.g. ROL abs,x takes only 6 cycles if no page break occurs)
51 /*****************************************************************************/
53 /*****************************************************************************/
60 /* Type of an opcode handler function */
61 typedef void (*OPFunc) (void);
63 /* The CPU registers */
66 /* Cycles for the current insn */
67 static unsigned Cycles;
69 /* Total number of CPU cycles exec'd */
70 static unsigned long TotalCycles;
72 /* NMI request active */
73 static unsigned HaveNMIRequest;
75 /* IRQ request active */
76 static unsigned HaveIRQRequest;
78 /* flag to print cycles at program termination */
82 /*****************************************************************************/
83 /* Helper functions and macros */
84 /*****************************************************************************/
88 /* Return the flags as a boolean value (0/1) */
89 #define GET_CF() ((Regs.SR & CF) != 0)
90 #define GET_ZF() ((Regs.SR & ZF) != 0)
91 #define GET_IF() ((Regs.SR & IF) != 0)
92 #define GET_DF() ((Regs.SR & DF) != 0)
93 #define GET_BF() ((Regs.SR & BF) != 0)
94 #define GET_OF() ((Regs.SR & OF) != 0)
95 #define GET_SF() ((Regs.SR & SF) != 0)
97 /* Set the flags. The parameter is a boolean flag that says if the flag should be
100 #define SET_CF(f) do { if (f) { Regs.SR |= CF; } else { Regs.SR &= ~CF; } } while (0)
101 #define SET_ZF(f) do { if (f) { Regs.SR |= ZF; } else { Regs.SR &= ~ZF; } } while (0)
102 #define SET_IF(f) do { if (f) { Regs.SR |= IF; } else { Regs.SR &= ~IF; } } while (0)
103 #define SET_DF(f) do { if (f) { Regs.SR |= DF; } else { Regs.SR &= ~DF; } } while (0)
104 #define SET_BF(f) do { if (f) { Regs.SR |= BF; } else { Regs.SR &= ~BF; } } while (0)
105 #define SET_OF(f) do { if (f) { Regs.SR |= OF; } else { Regs.SR &= ~OF; } } while (0)
106 #define SET_SF(f) do { if (f) { Regs.SR |= SF; } else { Regs.SR &= ~SF; } } while (0)
108 /* Special test and set macros. The meaning of the parameter depends on the
109 ** actual flag that should be set or reset.
111 #define TEST_ZF(v) SET_ZF (((v) & 0xFF) == 0)
112 #define TEST_SF(v) SET_SF (((v) & 0x80) != 0)
113 #define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0)
115 /* Program counter halves */
116 #define PCL (Regs.PC & 0xFF)
117 #define PCH ((Regs.PC >> 8) & 0xFF)
119 /* Stack operations */
120 #define PUSH(Val) MemWriteByte (0x0100 + Regs.SP--, Val)
121 #define POP() MemReadByte (0x0100 + ++Regs.SP)
123 /* Test for page cross */
124 #define PAGE_CROSS(addr,offs) ((((addr) & 0xFF) + offs) >= 0x100)
127 #define AC_OP_IMM(op) \
129 Regs.AC = Regs.AC op MemReadByte (Regs.PC+1); \
135 #define AC_OP_ZP(op) \
137 Regs.AC = Regs.AC op MemReadByte (MemReadByte (Regs.PC+1)); \
143 #define AC_OP_ZPX(op) \
144 unsigned char ZPAddr; \
146 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \
147 Regs.AC = Regs.AC op MemReadByte (ZPAddr); \
153 #define AC_OP_ZPY(op) \
154 unsigned char ZPAddr; \
156 ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; \
157 Regs.AC = Regs.AC op MemReadByte (ZPAddr); \
163 #define AC_OP_ABS(op) \
166 Addr = MemReadWord (Regs.PC+1); \
167 Regs.AC = Regs.AC op MemReadByte (Addr); \
173 #define AC_OP_ABSX(op) \
176 Addr = MemReadWord (Regs.PC+1); \
177 if (PAGE_CROSS (Addr, Regs.XR)) { \
180 Regs.AC = Regs.AC op MemReadByte (Addr + Regs.XR); \
186 #define AC_OP_ABSY(op) \
189 Addr = MemReadWord (Regs.PC+1); \
190 if (PAGE_CROSS (Addr, Regs.YR)) { \
193 Regs.AC = Regs.AC op MemReadByte (Addr + Regs.YR); \
199 #define AC_OP_ZPXIND(op) \
200 unsigned char ZPAddr; \
203 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \
204 Addr = MemReadZPWord (ZPAddr); \
205 Regs.AC = Regs.AC op MemReadByte (Addr); \
211 #define AC_OP_ZPINDY(op) \
212 unsigned char ZPAddr; \
215 ZPAddr = MemReadByte (Regs.PC+1); \
216 Addr = MemReadZPWord (ZPAddr); \
217 if (PAGE_CROSS (Addr, Regs.YR)) { \
221 Regs.AC = Regs.AC op MemReadByte (Addr); \
227 #define AC_OP_ZPIND(op) \
228 unsigned char ZPAddr; \
231 ZPAddr = MemReadByte (Regs.PC+1); \
232 Addr = MemReadZPWord (ZPAddr); \
233 Regs.AC = Regs.AC op MemReadByte (Addr); \
241 unsigned old = Regs.AC; \
242 unsigned rhs = (v & 0xFF); \
246 lo = (old & 0x0F) + (rhs & 0x0F) + GET_CF (); \
248 lo = ((lo + 0x06) & 0x0F) + 0x10; \
250 Regs.AC = (old & 0xF0) + (rhs & 0xF0) + lo; \
251 res = (signed char)(old & 0xF0) + \
252 (signed char)(rhs & 0xF0) + \
254 TEST_ZF (old + rhs + GET_CF ()); \
256 if (Regs.AC >= 0xA0) { \
260 SET_OF ((res < -128) || (res > 127)); \
261 if (CPU != CPU_6502) { \
265 Regs.AC += rhs + GET_CF (); \
269 SET_OF (!((old ^ rhs) & 0x80) && \
270 ((old ^ Regs.AC) & 0x80)); \
276 #define BRANCH(cond) \
280 unsigned char OldPCH; \
282 Offs = (signed char) MemReadByte (Regs.PC+1); \
284 Regs.PC += 2 + (int) Offs; \
285 if (PCH != OldPCH) { \
293 #define CMP(v1, v2) \
295 unsigned Result = v1 - v2; \
296 TEST_ZF (Result & 0xFF); \
298 SET_CF (Result <= 0xFF); \
317 SET_CF (Val & 0x01); \
325 unsigned old = Regs.AC; \
326 unsigned rhs = (v & 0xFF); \
330 lo = (old & 0x0F) - (rhs & 0x0F) + GET_CF () - 1; \
332 lo = ((lo - 0x06) & 0x0F) - 0x10; \
334 Regs.AC = (old & 0xF0) - (rhs & 0xF0) + lo; \
335 if (Regs.AC & 0x80) { \
338 res = Regs.AC - rhs + (!GET_CF ()); \
341 SET_CF (res <= 0xFF); \
342 SET_OF (((old^rhs) & (old^res) & 0x80)); \
343 if (CPU != CPU_6502) { \
347 Regs.AC -= rhs + (!GET_CF ()); \
350 SET_CF (Regs.AC <= 0xFF); \
351 SET_OF (((old^rhs) & (old^Regs.AC) & 0x80)); \
358 /*****************************************************************************/
359 /* Opcode handling functions */
360 /*****************************************************************************/
364 static void OPC_Illegal (void)
366 Error ("Illegal opcode $%02X at address $%04X",
367 MemReadByte (Regs.PC), Regs.PC);
372 static void OPC_6502_00 (void)
373 /* Opcode $00: BRK */
382 Regs.PC = MemReadWord (0xFFFE);
387 static void OPC_6502_01 (void)
388 /* Opcode $01: ORA (ind,x) */
395 static void OPC_65SC02_04 (void)
396 /* Opcode $04: TSB zp */
398 unsigned char ZPAddr;
401 ZPAddr = MemReadByte (Regs.PC+1);
402 Val = MemReadByte (ZPAddr);
403 SET_ZF ((Val & Regs.AC) == 0);
404 MemWriteByte (ZPAddr, (unsigned char)(Val | Regs.AC));
410 static void OPC_6502_05 (void)
411 /* Opcode $05: ORA zp */
418 static void OPC_6502_06 (void)
419 /* Opcode $06: ASL zp */
421 unsigned char ZPAddr;
424 ZPAddr = MemReadByte (Regs.PC+1);
425 Val = MemReadByte (ZPAddr) << 1;
426 MemWriteByte (ZPAddr, (unsigned char) Val);
427 TEST_ZF (Val & 0xFF);
429 SET_CF (Val & 0x100);
435 static void OPC_6502_08 (void)
436 /* Opcode $08: PHP */
439 PUSH (Regs.SR & ~BF);
445 static void OPC_6502_09 (void)
446 /* Opcode $09: ORA #imm */
453 static void OPC_6502_0A (void)
454 /* Opcode $0A: ASL a */
458 TEST_ZF (Regs.AC & 0xFF);
460 SET_CF (Regs.AC & 0x100);
467 static void OPC_65SC02_0C (void)
468 /* Opcode $0C: TSB abs */
473 Addr = MemReadByte (Regs.PC+1);
474 Val = MemReadByte (Addr);
475 SET_ZF ((Val & Regs.AC) == 0);
476 MemWriteByte (Addr, (unsigned char) (Val | Regs.AC));
482 static void OPC_6502_0D (void)
483 /* Opcode $0D: ORA abs */
490 static void OPC_6502_0E (void)
491 /* Opcode $0E: ALS abs */
496 Addr = MemReadWord (Regs.PC+1);
497 Val = MemReadByte (Addr) << 1;
498 MemWriteByte (Addr, (unsigned char) Val);
499 TEST_ZF (Val & 0xFF);
501 SET_CF (Val & 0x100);
507 static void OPC_6502_10 (void)
508 /* Opcode $10: BPL */
515 static void OPC_6502_11 (void)
516 /* Opcode $11: ORA (zp),y */
523 static void OPC_65SC02_12 (void)
524 /* Opcode $12: ORA (zp) */
531 static void OPC_65SC02_14 (void)
532 /* Opcode $14: TRB zp */
534 unsigned char ZPAddr;
537 ZPAddr = MemReadByte (Regs.PC+1);
538 Val = MemReadByte (ZPAddr);
539 SET_ZF ((Val & Regs.AC) == 0);
540 MemWriteByte (ZPAddr, (unsigned char)(Val & ~Regs.AC));
546 static void OPC_6502_15 (void)
547 /* Opcode $15: ORA zp,x */
554 static void OPC_6502_16 (void)
555 /* Opcode $16: ASL zp,x */
557 unsigned char ZPAddr;
560 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
561 Val = MemReadByte (ZPAddr) << 1;
562 MemWriteByte (ZPAddr, (unsigned char) Val);
563 TEST_ZF (Val & 0xFF);
565 SET_CF (Val & 0x100);
571 static void OPC_6502_18 (void)
572 /* Opcode $18: CLC */
581 static void OPC_6502_19 (void)
582 /* Opcode $19: ORA abs,y */
589 static void OPC_65SC02_1A (void)
590 /* Opcode $1A: INC a */
593 Regs.AC = (Regs.AC + 1) & 0xFF;
601 static void OPC_65SC02_1C (void)
602 /* Opcode $1C: TRB abs */
607 Addr = MemReadByte (Regs.PC+1);
608 Val = MemReadByte (Addr);
609 SET_ZF ((Val & Regs.AC) == 0);
610 MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC));
616 static void OPC_6502_1D (void)
617 /* Opcode $1D: ORA abs,x */
624 static void OPC_6502_1E (void)
625 /* Opcode $1E: ASL abs,x */
630 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
631 Val = MemReadByte (Addr) << 1;
632 MemWriteByte (Addr, (unsigned char) Val);
633 TEST_ZF (Val & 0xFF);
635 SET_CF (Val & 0x100);
641 static void OPC_6502_20 (void)
642 /* Opcode $20: JSR */
646 Addr = MemReadWord (Regs.PC+1);
652 ParaVirtHooks (&Regs);
657 static void OPC_6502_21 (void)
658 /* Opcode $21: AND (zp,x) */
665 static void OPC_6502_24 (void)
666 /* Opcode $24: BIT zp */
668 unsigned char ZPAddr;
671 ZPAddr = MemReadByte (Regs.PC+1);
672 Val = MemReadByte (ZPAddr);
675 SET_ZF ((Val & Regs.AC) == 0);
681 static void OPC_6502_25 (void)
682 /* Opcode $25: AND zp */
689 static void OPC_6502_26 (void)
690 /* Opcode $26: ROL zp */
692 unsigned char ZPAddr;
695 ZPAddr = MemReadByte (Regs.PC+1);
696 Val = MemReadByte (ZPAddr);
698 MemWriteByte (ZPAddr, Val);
704 static void OPC_6502_28 (void)
705 /* Opcode $28: PLP */
708 Regs.SR = (POP () & ~BF);
714 static void OPC_6502_29 (void)
715 /* Opcode $29: AND #imm */
722 static void OPC_6502_2A (void)
723 /* Opcode $2A: ROL a */
733 static void OPC_6502_2C (void)
734 /* Opcode $2C: BIT abs */
739 Addr = MemReadByte (Regs.PC+1);
740 Val = MemReadByte (Addr);
743 SET_ZF ((Val & Regs.AC) == 0);
749 static void OPC_6502_2D (void)
750 /* Opcode $2D: AND abs */
757 static void OPC_6502_2E (void)
758 /* Opcode $2E: ROL abs */
763 Addr = MemReadWord (Regs.PC+1);
764 Val = MemReadByte (Addr);
766 MemWriteByte (Addr, Val);
772 static void OPC_6502_30 (void)
773 /* Opcode $30: BMI */
780 static void OPC_6502_31 (void)
781 /* Opcode $31: AND (zp),y */
788 static void OPC_65SC02_32 (void)
789 /* Opcode $32: AND (zp) */
796 static void OPC_65SC02_34 (void)
797 /* Opcode $34: BIT zp,x */
799 unsigned char ZPAddr;
802 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
803 Val = MemReadByte (ZPAddr);
806 SET_ZF ((Val & Regs.AC) == 0);
812 static void OPC_6502_35 (void)
813 /* Opcode $35: AND zp,x */
820 static void OPC_6502_36 (void)
821 /* Opcode $36: ROL zp,x */
823 unsigned char ZPAddr;
826 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
827 Val = MemReadByte (ZPAddr);
829 MemWriteByte (ZPAddr, Val);
835 static void OPC_6502_38 (void)
836 /* Opcode $38: SEC */
845 static void OPC_6502_39 (void)
846 /* Opcode $39: AND abs,y */
853 static void OPC_65SC02_3A (void)
854 /* Opcode $3A: DEC a */
857 Regs.AC = (Regs.AC - 1) & 0xFF;
865 static void OPC_65SC02_3C (void)
866 /* Opcode $3C: BIT abs,x */
871 Addr = MemReadWord (Regs.PC+1);
872 if (PAGE_CROSS (Addr, Regs.XR))
874 Val = MemReadByte (Addr + Regs.XR);
877 SET_ZF ((Val & Regs.AC) == 0);
883 static void OPC_6502_3D (void)
884 /* Opcode $3D: AND abs,x */
891 static void OPC_6502_3E (void)
892 /* Opcode $3E: ROL abs,x */
897 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
898 Val = MemReadByte (Addr);
900 MemWriteByte (Addr, Val);
906 static void OPC_6502_40 (void)
907 /* Opcode $40: RTI */
911 Regs.PC = POP (); /* PCL */
912 Regs.PC |= (POP () << 8); /* PCH */
917 static void OPC_6502_41 (void)
918 /* Opcode $41: EOR (zp,x) */
925 static void OPC_65C02_44 (void)
926 /* Opcode $44: 'zp' 3 cycle NOP */
934 static void OPC_6502_45 (void)
935 /* Opcode $45: EOR zp */
942 static void OPC_6502_46 (void)
943 /* Opcode $46: LSR zp */
945 unsigned char ZPAddr;
948 ZPAddr = MemReadByte (Regs.PC+1);
949 Val = MemReadByte (ZPAddr);
952 MemWriteByte (ZPAddr, Val);
960 static void OPC_6502_48 (void)
961 /* Opcode $48: PHA */
970 static void OPC_6502_49 (void)
971 /* Opcode $49: EOR #imm */
978 static void OPC_6502_4A (void)
979 /* Opcode $4A: LSR a */
982 SET_CF (Regs.AC & 0x01);
991 static void OPC_6502_4C (void)
992 /* Opcode $4C: JMP abs */
995 Regs.PC = MemReadWord (Regs.PC+1);
997 ParaVirtHooks (&Regs);
1002 static void OPC_6502_4D (void)
1003 /* Opcode $4D: EOR abs */
1010 static void OPC_6502_4E (void)
1011 /* Opcode $4E: LSR abs */
1016 Addr = MemReadWord (Regs.PC+1);
1017 Val = MemReadByte (Addr);
1018 SET_CF (Val & 0x01);
1020 MemWriteByte (Addr, Val);
1028 static void OPC_6502_50 (void)
1029 /* Opcode $50: BVC */
1031 BRANCH (!GET_OF ());
1036 static void OPC_6502_51 (void)
1037 /* Opcode $51: EOR (zp),y */
1044 static void OPC_65SC02_52 (void)
1045 /* Opcode $52: EOR (zp) */
1052 static void OPC_6502_55 (void)
1053 /* Opcode $55: EOR zp,x */
1060 static void OPC_6502_56 (void)
1061 /* Opcode $56: LSR zp,x */
1063 unsigned char ZPAddr;
1066 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1067 Val = MemReadByte (ZPAddr);
1068 SET_CF (Val & 0x01);
1070 MemWriteByte (ZPAddr, Val);
1078 static void OPC_6502_58 (void)
1079 /* Opcode $58: CLI */
1088 static void OPC_6502_59 (void)
1089 /* Opcode $59: EOR abs,y */
1096 static void OPC_65SC02_5A (void)
1097 /* Opcode $5A: PHY */
1106 static void OPC_65C02_5C (void)
1107 /* Opcode $5C: 'Absolute' 8 cycle NOP */
1115 static void OPC_6502_5D (void)
1116 /* Opcode $5D: EOR abs,x */
1123 static void OPC_6502_5E (void)
1124 /* Opcode $5E: LSR abs,x */
1129 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1130 Val = MemReadByte (Addr);
1131 SET_CF (Val & 0x01);
1133 MemWriteByte (Addr, Val);
1141 static void OPC_6502_60 (void)
1142 /* Opcode $60: RTS */
1145 Regs.PC = POP (); /* PCL */
1146 Regs.PC |= (POP () << 8); /* PCH */
1152 static void OPC_6502_61 (void)
1153 /* Opcode $61: ADC (zp,x) */
1155 unsigned char ZPAddr;
1158 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1159 Addr = MemReadZPWord (ZPAddr);
1160 ADC (MemReadByte (Addr));
1166 static void OPC_65SC02_64 (void)
1167 /* Opcode $64: STZ zp */
1169 unsigned char ZPAddr;
1171 ZPAddr = MemReadByte (Regs.PC+1);
1172 MemWriteByte (ZPAddr, 0);
1178 static void OPC_6502_65 (void)
1179 /* Opcode $65: ADC zp */
1181 unsigned char ZPAddr;
1183 ZPAddr = MemReadByte (Regs.PC+1);
1184 ADC (MemReadByte (ZPAddr));
1190 static void OPC_6502_66 (void)
1191 /* Opcode $66: ROR zp */
1193 unsigned char ZPAddr;
1196 ZPAddr = MemReadByte (Regs.PC+1);
1197 Val = MemReadByte (ZPAddr);
1199 MemWriteByte (ZPAddr, Val);
1205 static void OPC_6502_68 (void)
1206 /* Opcode $68: PLA */
1217 static void OPC_6502_69 (void)
1218 /* Opcode $69: ADC #imm */
1221 ADC (MemReadByte (Regs.PC+1));
1227 static void OPC_6502_6A (void)
1228 /* Opcode $6A: ROR a */
1237 static void OPC_6502_6C (void)
1238 /* Opcode $6C: JMP (ind) */
1240 unsigned PC, Lo, Hi;
1242 Lo = MemReadWord (PC+1);
1244 if (CPU == CPU_6502)
1246 /* Emulate the 6502 bug */
1248 Regs.PC = MemReadByte (Lo);
1249 Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF);
1250 Regs.PC |= (MemReadByte (Hi) << 8);
1252 /* Output a warning if the bug is triggered */
1255 Warning ("6502 indirect jump bug triggered at $%04X, ind addr = $%04X",
1262 Regs.PC = MemReadWord(Lo);
1268 static void OPC_65C02_6C (void)
1269 /* Opcode $6C: JMP (ind) */
1271 /* 6502 bug fixed here */
1273 Regs.PC = MemReadWord (MemReadWord (Regs.PC+1));
1278 static void OPC_6502_6D (void)
1279 /* Opcode $6D: ADC abs */
1283 Addr = MemReadWord (Regs.PC+1);
1284 ADC (MemReadByte (Addr));
1290 static void OPC_6502_6E (void)
1291 /* Opcode $6E: ROR abs */
1296 Addr = MemReadWord (Regs.PC+1);
1297 Val = MemReadByte (Addr);
1299 MemWriteByte (Addr, Val);
1305 static void OPC_6502_70 (void)
1306 /* Opcode $70: BVS */
1313 static void OPC_6502_71 (void)
1314 /* Opcode $71: ADC (zp),y */
1316 unsigned char ZPAddr;
1319 ZPAddr = MemReadByte (Regs.PC+1);
1320 Addr = MemReadZPWord (ZPAddr);
1321 if (PAGE_CROSS (Addr, Regs.YR)) {
1324 ADC (MemReadByte (Addr + Regs.YR));
1330 static void OPC_65SC02_72 (void)
1331 /* Opcode $72: ADC (zp) */
1333 unsigned char ZPAddr;
1336 ZPAddr = MemReadByte (Regs.PC+1);
1337 Addr = MemReadZPWord (ZPAddr);
1338 ADC (MemReadByte (Addr));
1344 static void OPC_65SC02_74 (void)
1345 /* Opcode $74: STZ zp,x */
1347 unsigned char ZPAddr;
1349 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1350 MemWriteByte (ZPAddr, 0);
1356 static void OPC_6502_75 (void)
1357 /* Opcode $75: ADC zp,x */
1359 unsigned char ZPAddr;
1361 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1362 ADC (MemReadByte (ZPAddr));
1368 static void OPC_6502_76 (void)
1369 /* Opcode $76: ROR zp,x */
1371 unsigned char ZPAddr;
1374 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1375 Val = MemReadByte (ZPAddr);
1377 MemWriteByte (ZPAddr, Val);
1383 static void OPC_6502_78 (void)
1384 /* Opcode $78: SEI */
1393 static void OPC_6502_79 (void)
1394 /* Opcode $79: ADC abs,y */
1398 Addr = MemReadWord (Regs.PC+1);
1399 if (PAGE_CROSS (Addr, Regs.YR)) {
1402 ADC (MemReadByte (Addr + Regs.YR));
1408 static void OPC_65SC02_7A (void)
1409 /* Opcode $7A: PLY */
1420 static void OPC_65SC02_7C (void)
1421 /* Opcode $7C: JMP (ind,X) */
1426 Adr = MemReadWord (PC+1);
1427 Regs.PC = MemReadWord(Adr+Regs.XR);
1432 static void OPC_6502_7D (void)
1433 /* Opcode $7D: ADC abs,x */
1437 Addr = MemReadWord (Regs.PC+1);
1438 if (PAGE_CROSS (Addr, Regs.XR)) {
1441 ADC (MemReadByte (Addr + Regs.XR));
1447 static void OPC_6502_7E (void)
1448 /* Opcode $7E: ROR abs,x */
1453 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1454 Val = MemReadByte (Addr);
1456 MemWriteByte (Addr, Val);
1462 static void OPC_65SC02_80 (void)
1463 /* Opcode $80: BRA */
1470 static void OPC_6502_81 (void)
1471 /* Opcode $81: STA (zp,x) */
1473 unsigned char ZPAddr;
1476 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1477 Addr = MemReadZPWord (ZPAddr);
1478 MemWriteByte (Addr, Regs.AC);
1484 static void OPC_6502_84 (void)
1485 /* Opcode $84: STY zp */
1487 unsigned char ZPAddr;
1489 ZPAddr = MemReadByte (Regs.PC+1);
1490 MemWriteByte (ZPAddr, Regs.YR);
1496 static void OPC_6502_85 (void)
1497 /* Opcode $85: STA zp */
1499 unsigned char ZPAddr;
1501 ZPAddr = MemReadByte (Regs.PC+1);
1502 MemWriteByte (ZPAddr, Regs.AC);
1508 static void OPC_6502_86 (void)
1509 /* Opcode $86: STX zp */
1511 unsigned char ZPAddr;
1513 ZPAddr = MemReadByte (Regs.PC+1);
1514 MemWriteByte (ZPAddr, Regs.XR);
1520 static void OPC_6502_88 (void)
1521 /* Opcode $88: DEY */
1524 Regs.YR = (Regs.YR - 1) & 0xFF;
1532 static void OPC_65SC02_89 (void)
1533 /* Opcode $89: BIT #imm */
1537 Val = MemReadByte (Regs.PC+1);
1538 SET_SF (Val & 0x80);
1539 SET_OF (Val & 0x40);
1540 SET_ZF ((Val & Regs.AC) == 0);
1546 static void OPC_6502_8A (void)
1547 /* Opcode $8A: TXA */
1558 static void OPC_6502_8C (void)
1559 /* Opcode $8C: STY abs */
1563 Addr = MemReadWord (Regs.PC+1);
1564 MemWriteByte (Addr, Regs.YR);
1570 static void OPC_6502_8D (void)
1571 /* Opcode $8D: STA abs */
1575 Addr = MemReadWord (Regs.PC+1);
1576 MemWriteByte (Addr, Regs.AC);
1582 static void OPC_6502_8E (void)
1583 /* Opcode $8E: STX abs */
1587 Addr = MemReadWord (Regs.PC+1);
1588 MemWriteByte (Addr, Regs.XR);
1594 static void OPC_6502_90 (void)
1595 /* Opcode $90: BCC */
1597 BRANCH (!GET_CF ());
1602 static void OPC_6502_91 (void)
1603 /* Opcode $91: sta (zp),y */
1605 unsigned char ZPAddr;
1608 ZPAddr = MemReadByte (Regs.PC+1);
1609 Addr = MemReadZPWord (ZPAddr) + Regs.YR;
1610 MemWriteByte (Addr, Regs.AC);
1616 static void OPC_65SC02_92 (void)
1617 /* Opcode $92: sta (zp) */
1619 unsigned char ZPAddr;
1622 ZPAddr = MemReadByte (Regs.PC+1);
1623 Addr = MemReadZPWord (ZPAddr);
1624 MemWriteByte (Addr, Regs.AC);
1630 static void OPC_6502_94 (void)
1631 /* Opcode $94: STY zp,x */
1633 unsigned char ZPAddr;
1635 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1636 MemWriteByte (ZPAddr, Regs.YR);
1642 static void OPC_6502_95 (void)
1643 /* Opcode $95: STA zp,x */
1645 unsigned char ZPAddr;
1647 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1648 MemWriteByte (ZPAddr, Regs.AC);
1654 static void OPC_6502_96 (void)
1655 /* Opcode $96: stx zp,y */
1657 unsigned char ZPAddr;
1659 ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR;
1660 MemWriteByte (ZPAddr, Regs.XR);
1666 static void OPC_6502_98 (void)
1667 /* Opcode $98: TYA */
1678 static void OPC_6502_99 (void)
1679 /* Opcode $99: STA abs,y */
1683 Addr = MemReadWord (Regs.PC+1) + Regs.YR;
1684 MemWriteByte (Addr, Regs.AC);
1690 static void OPC_6502_9A (void)
1691 /* Opcode $9A: TXS */
1700 static void OPC_65SC02_9C (void)
1701 /* Opcode $9C: STZ abs */
1705 Addr = MemReadWord (Regs.PC+1);
1706 MemWriteByte (Addr, 0);
1712 static void OPC_6502_9D (void)
1713 /* Opcode $9D: STA abs,x */
1717 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1718 MemWriteByte (Addr, Regs.AC);
1724 static void OPC_65SC02_9E (void)
1725 /* Opcode $9E: STZ abs,x */
1729 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1730 MemWriteByte (Addr, 0);
1736 static void OPC_6502_A0 (void)
1737 /* Opcode $A0: LDY #imm */
1740 Regs.YR = MemReadByte (Regs.PC+1);
1748 static void OPC_6502_A1 (void)
1749 /* Opcode $A1: LDA (zp,x) */
1751 unsigned char ZPAddr;
1754 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1755 Addr = MemReadZPWord (ZPAddr);
1756 Regs.AC = MemReadByte (Addr);
1764 static void OPC_6502_A2 (void)
1765 /* Opcode $A2: LDX #imm */
1768 Regs.XR = MemReadByte (Regs.PC+1);
1776 static void OPC_6502_A4 (void)
1777 /* Opcode $A4: LDY zp */
1779 unsigned char ZPAddr;
1781 ZPAddr = MemReadByte (Regs.PC+1);
1782 Regs.YR = MemReadByte (ZPAddr);
1790 static void OPC_6502_A5 (void)
1791 /* Opcode $A5: LDA zp */
1793 unsigned char ZPAddr;
1795 ZPAddr = MemReadByte (Regs.PC+1);
1796 Regs.AC = MemReadByte (ZPAddr);
1804 static void OPC_6502_A6 (void)
1805 /* Opcode $A6: LDX zp */
1807 unsigned char ZPAddr;
1809 ZPAddr = MemReadByte (Regs.PC+1);
1810 Regs.XR = MemReadByte (ZPAddr);
1818 static void OPC_6502_A8 (void)
1819 /* Opcode $A8: TAY */
1830 static void OPC_6502_A9 (void)
1831 /* Opcode $A9: LDA #imm */
1834 Regs.AC = MemReadByte (Regs.PC+1);
1842 static void OPC_6502_AA (void)
1843 /* Opcode $AA: TAX */
1854 static void OPC_6502_AC (void)
1855 /* Opcode $Regs.AC: LDY abs */
1859 Addr = MemReadWord (Regs.PC+1);
1860 Regs.YR = MemReadByte (Addr);
1868 static void OPC_6502_AD (void)
1869 /* Opcode $AD: LDA abs */
1873 Addr = MemReadWord (Regs.PC+1);
1874 Regs.AC = MemReadByte (Addr);
1882 static void OPC_6502_AE (void)
1883 /* Opcode $AE: LDX abs */
1887 Addr = MemReadWord (Regs.PC+1);
1888 Regs.XR = MemReadByte (Addr);
1896 static void OPC_6502_B0 (void)
1897 /* Opcode $B0: BCS */
1904 static void OPC_6502_B1 (void)
1905 /* Opcode $B1: LDA (zp),y */
1907 unsigned char ZPAddr;
1910 ZPAddr = MemReadByte (Regs.PC+1);
1911 Addr = MemReadZPWord (ZPAddr);
1912 if (PAGE_CROSS (Addr, Regs.YR)) {
1915 Regs.AC = MemReadByte (Addr + Regs.YR);
1923 static void OPC_65SC02_B2 (void)
1924 /* Opcode $B2: LDA (zp) */
1926 unsigned char ZPAddr;
1929 ZPAddr = MemReadByte (Regs.PC+1);
1930 Addr = MemReadZPWord (ZPAddr);
1931 Regs.AC = MemReadByte (Addr);
1939 static void OPC_6502_B4 (void)
1940 /* Opcode $B4: LDY zp,x */
1942 unsigned char ZPAddr;
1944 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1945 Regs.YR = MemReadByte (ZPAddr);
1953 static void OPC_6502_B5 (void)
1954 /* Opcode $B5: LDA zp,x */
1956 unsigned char ZPAddr;
1958 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1959 Regs.AC = MemReadByte (ZPAddr);
1967 static void OPC_6502_B6 (void)
1968 /* Opcode $B6: LDX zp,y */
1970 unsigned char ZPAddr;
1972 ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR;
1973 Regs.XR = MemReadByte (ZPAddr);
1981 static void OPC_6502_B8 (void)
1982 /* Opcode $B8: CLV */
1991 static void OPC_6502_B9 (void)
1992 /* Opcode $B9: LDA abs,y */
1996 Addr = MemReadWord (Regs.PC+1);
1997 if (PAGE_CROSS (Addr, Regs.YR)) {
2000 Regs.AC = MemReadByte (Addr + Regs.YR);
2008 static void OPC_6502_BA (void)
2009 /* Opcode $BA: TSX */
2020 static void OPC_6502_BC (void)
2021 /* Opcode $BC: LDY abs,x */
2025 Addr = MemReadWord (Regs.PC+1);
2026 if (PAGE_CROSS (Addr, Regs.XR)) {
2029 Regs.YR = MemReadByte (Addr + Regs.XR);
2037 static void OPC_6502_BD (void)
2038 /* Opcode $BD: LDA abs,x */
2042 Addr = MemReadWord (Regs.PC+1);
2043 if (PAGE_CROSS (Addr, Regs.XR)) {
2046 Regs.AC = MemReadByte (Addr + Regs.XR);
2054 static void OPC_6502_BE (void)
2055 /* Opcode $BE: LDX abs,y */
2059 Addr = MemReadWord (Regs.PC+1);
2060 if (PAGE_CROSS (Addr, Regs.YR)) {
2063 Regs.XR = MemReadByte (Addr + Regs.YR);
2071 static void OPC_6502_C0 (void)
2072 /* Opcode $C0: CPY #imm */
2075 CMP (Regs.YR, MemReadByte (Regs.PC+1));
2081 static void OPC_6502_C1 (void)
2082 /* Opcode $C1: CMP (zp,x) */
2084 unsigned char ZPAddr;
2087 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2088 Addr = MemReadZPWord (ZPAddr);
2089 CMP (Regs.AC, MemReadByte (Addr));
2095 static void OPC_6502_C4 (void)
2096 /* Opcode $C4: CPY zp */
2098 unsigned char ZPAddr;
2100 ZPAddr = MemReadByte (Regs.PC+1);
2101 CMP (Regs.YR, MemReadByte (ZPAddr));
2107 static void OPC_6502_C5 (void)
2108 /* Opcode $C5: CMP zp */
2110 unsigned char ZPAddr;
2112 ZPAddr = MemReadByte (Regs.PC+1);
2113 CMP (Regs.AC, MemReadByte (ZPAddr));
2119 static void OPC_6502_C6 (void)
2120 /* Opcode $C6: DEC zp */
2122 unsigned char ZPAddr;
2125 ZPAddr = MemReadByte (Regs.PC+1);
2126 Val = MemReadByte (ZPAddr) - 1;
2127 MemWriteByte (ZPAddr, Val);
2135 static void OPC_6502_C8 (void)
2136 /* Opcode $C8: INY */
2139 Regs.YR = (Regs.YR + 1) & 0xFF;
2147 static void OPC_6502_C9 (void)
2148 /* Opcode $C9: CMP #imm */
2151 CMP (Regs.AC, MemReadByte (Regs.PC+1));
2157 static void OPC_6502_CA (void)
2158 /* Opcode $CA: DEX */
2161 Regs.XR = (Regs.XR - 1) & 0xFF;
2169 static void OPC_6502_CC (void)
2170 /* Opcode $CC: CPY abs */
2174 Addr = MemReadWord (Regs.PC+1);
2175 CMP (Regs.YR, MemReadByte (Addr));
2181 static void OPC_6502_CD (void)
2182 /* Opcode $CD: CMP abs */
2186 Addr = MemReadWord (Regs.PC+1);
2187 CMP (Regs.AC, MemReadByte (Addr));
2193 static void OPC_6502_CE (void)
2194 /* Opcode $CE: DEC abs */
2199 Addr = MemReadWord (Regs.PC+1);
2200 Val = MemReadByte (Addr) - 1;
2201 MemWriteByte (Addr, Val);
2209 static void OPC_6502_D0 (void)
2210 /* Opcode $D0: BNE */
2212 BRANCH (!GET_ZF ());
2217 static void OPC_6502_D1 (void)
2218 /* Opcode $D1: CMP (zp),y */
2223 ZPAddr = MemReadByte (Regs.PC+1);
2224 Addr = MemReadWord (ZPAddr);
2225 if (PAGE_CROSS (Addr, Regs.YR)) {
2228 CMP (Regs.AC, MemReadByte (Addr + Regs.YR));
2234 static void OPC_65SC02_D2 (void)
2235 /* Opcode $D2: CMP (zp) */
2240 ZPAddr = MemReadByte (Regs.PC+1);
2241 Addr = MemReadWord (ZPAddr);
2242 CMP (Regs.AC, MemReadByte (Addr));
2248 static void OPC_6502_D5 (void)
2249 /* Opcode $D5: CMP zp,x */
2251 unsigned char ZPAddr;
2253 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2254 CMP (Regs.AC, MemReadByte (ZPAddr));
2260 static void OPC_6502_D6 (void)
2261 /* Opcode $D6: DEC zp,x */
2263 unsigned char ZPAddr;
2266 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2267 Val = MemReadByte (ZPAddr) - 1;
2268 MemWriteByte (ZPAddr, Val);
2276 static void OPC_6502_D8 (void)
2277 /* Opcode $D8: CLD */
2286 static void OPC_6502_D9 (void)
2287 /* Opcode $D9: CMP abs,y */
2291 Addr = MemReadWord (Regs.PC+1);
2292 if (PAGE_CROSS (Addr, Regs.YR)) {
2295 CMP (Regs.AC, MemReadByte (Addr + Regs.YR));
2301 static void OPC_65SC02_DA (void)
2302 /* Opcode $DA: PHX */
2311 static void OPC_6502_DD (void)
2312 /* Opcode $DD: CMP abs,x */
2316 Addr = MemReadWord (Regs.PC+1);
2317 if (PAGE_CROSS (Addr, Regs.XR)) {
2320 CMP (Regs.AC, MemReadByte (Addr + Regs.XR));
2326 static void OPC_6502_DE (void)
2327 /* Opcode $DE: DEC abs,x */
2332 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
2333 Val = MemReadByte (Addr) - 1;
2334 MemWriteByte (Addr, Val);
2342 static void OPC_6502_E0 (void)
2343 /* Opcode $E0: CPX #imm */
2346 CMP (Regs.XR, MemReadByte (Regs.PC+1));
2352 static void OPC_6502_E1 (void)
2353 /* Opcode $E1: SBC (zp,x) */
2355 unsigned char ZPAddr;
2358 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2359 Addr = MemReadZPWord (ZPAddr);
2360 SBC (MemReadByte (Addr));
2366 static void OPC_6502_E4 (void)
2367 /* Opcode $E4: CPX zp */
2369 unsigned char ZPAddr;
2371 ZPAddr = MemReadByte (Regs.PC+1);
2372 CMP (Regs.XR, MemReadByte (ZPAddr));
2378 static void OPC_6502_E5 (void)
2379 /* Opcode $E5: SBC zp */
2381 unsigned char ZPAddr;
2383 ZPAddr = MemReadByte (Regs.PC+1);
2384 SBC (MemReadByte (ZPAddr));
2390 static void OPC_6502_E6 (void)
2391 /* Opcode $E6: INC zp */
2393 unsigned char ZPAddr;
2396 ZPAddr = MemReadByte (Regs.PC+1);
2397 Val = MemReadByte (ZPAddr) + 1;
2398 MemWriteByte (ZPAddr, Val);
2406 static void OPC_6502_E8 (void)
2407 /* Opcode $E8: INX */
2410 Regs.XR = (Regs.XR + 1) & 0xFF;
2418 static void OPC_6502_E9 (void)
2419 /* Opcode $E9: SBC #imm */
2422 SBC (MemReadByte (Regs.PC+1));
2428 static void OPC_6502_EA (void)
2429 /* Opcode $EA: NOP */
2431 /* This one is easy... */
2438 static void OPC_65C02_NOP11(void)
2439 /* Opcode 'Illegal' 1 cycle NOP */
2447 static void OPC_65C02_NOP22 (void)
2448 /* Opcode 'Illegal' 2 byte 2 cycle NOP */
2456 static void OPC_65C02_NOP24 (void)
2457 /* Opcode 'Illegal' 2 byte 4 cycle NOP */
2465 static void OPC_65C02_NOP34 (void)
2466 /* Opcode 'Illegal' 3 byte 4 cycle NOP */
2474 static void OPC_6502_EC (void)
2475 /* Opcode $EC: CPX abs */
2479 Addr = MemReadWord (Regs.PC+1);
2480 CMP (Regs.XR, MemReadByte (Addr));
2486 static void OPC_6502_ED (void)
2487 /* Opcode $ED: SBC abs */
2491 Addr = MemReadWord (Regs.PC+1);
2492 SBC (MemReadByte (Addr));
2498 static void OPC_6502_EE (void)
2499 /* Opcode $EE: INC abs */
2504 Addr = MemReadWord (Regs.PC+1);
2505 Val = MemReadByte (Addr) + 1;
2506 MemWriteByte (Addr, Val);
2514 static void OPC_6502_F0 (void)
2515 /* Opcode $F0: BEQ */
2522 static void OPC_6502_F1 (void)
2523 /* Opcode $F1: SBC (zp),y */
2525 unsigned char ZPAddr;
2528 ZPAddr = MemReadByte (Regs.PC+1);
2529 Addr = MemReadZPWord (ZPAddr);
2530 if (PAGE_CROSS (Addr, Regs.YR)) {
2533 SBC (MemReadByte (Addr + Regs.YR));
2539 static void OPC_65SC02_F2 (void)
2540 /* Opcode $F2: SBC (zp) */
2542 unsigned char ZPAddr;
2545 ZPAddr = MemReadByte (Regs.PC+1);
2546 Addr = MemReadZPWord (ZPAddr);
2547 SBC (MemReadByte (Addr));
2553 static void OPC_6502_F5 (void)
2554 /* Opcode $F5: SBC zp,x */
2556 unsigned char ZPAddr;
2558 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2559 SBC (MemReadByte (ZPAddr));
2565 static void OPC_6502_F6 (void)
2566 /* Opcode $F6: INC zp,x */
2568 unsigned char ZPAddr;
2571 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2572 Val = MemReadByte (ZPAddr) + 1;
2573 MemWriteByte (ZPAddr, Val);
2581 static void OPC_6502_F8 (void)
2582 /* Opcode $F8: SED */
2589 static void OPC_6502_F9 (void)
2590 /* Opcode $F9: SBC abs,y */
2594 Addr = MemReadWord (Regs.PC+1);
2595 if (PAGE_CROSS (Addr, Regs.YR)) {
2598 SBC (MemReadByte (Addr + Regs.YR));
2604 static void OPC_65SC02_FA (void)
2605 /* Opcode $7A: PLX */
2616 static void OPC_6502_FD (void)
2617 /* Opcode $FD: SBC abs,x */
2621 Addr = MemReadWord (Regs.PC+1);
2622 if (PAGE_CROSS (Addr, Regs.XR)) {
2625 SBC (MemReadByte (Addr + Regs.XR));
2631 static void OPC_6502_FE (void)
2632 /* Opcode $FE: INC abs,x */
2637 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
2638 Val = MemReadByte (Addr) + 1;
2639 MemWriteByte (Addr, Val);
2647 /*****************************************************************************/
2648 /* Opcode handler tables */
2649 /*****************************************************************************/
2653 /* Opcode handler table for the 6502 */
2654 static const OPFunc OP6502Table[256] = {
2915 /* Opcode handler table for the 65C02 */
2916 static const OPFunc OP65C02Table[256] = {
2919 OPC_65C02_NOP22, // $02
2920 OPC_65C02_NOP11, // $03
2924 OPC_Illegal, // $07: RMB0 currently unsupported
2928 OPC_65C02_NOP11, // $0B
2932 OPC_Illegal, // $0F: BBR0 currently unsupported
2936 OPC_65C02_NOP11, // $13
2940 OPC_Illegal, // $17: RMB1 currently unsupported
2944 OPC_65C02_NOP11, // $1B
2948 OPC_Illegal, // $1F: BBR1 currently unsupported
2951 OPC_65C02_NOP22, // $22
2952 OPC_65C02_NOP11, // $23
2956 OPC_Illegal, // $27: RMB2 currently unsupported
2960 OPC_65C02_NOP11, // $2B
2964 OPC_Illegal, // $2F: BBR2 currently unsupported
2968 OPC_65C02_NOP11, // $33
2972 OPC_Illegal, // $37: RMB3 currently unsupported
2976 OPC_65C02_NOP11, // $3B
2980 OPC_Illegal, // $3F: BBR3 currently unsupported
2983 OPC_65C02_NOP22, // $42
2984 OPC_65C02_NOP11, // $43
2985 OPC_65C02_44, // $44
2988 OPC_Illegal, // $47: RMB4 currently unsupported
2992 OPC_65C02_NOP11, // $4B
2996 OPC_Illegal, // $4F: BBR4 currently unsupported
3000 OPC_65C02_NOP11, // $53
3001 OPC_65C02_NOP24, // $54
3004 OPC_Illegal, // $57: RMB5 currently unsupported
3008 OPC_65C02_NOP11, // $5B
3012 OPC_Illegal, // $5F: BBR5 currently unsupported
3015 OPC_65C02_NOP22, // $62
3016 OPC_65C02_NOP11, // $63
3020 OPC_Illegal, // $67: RMB6 currently unsupported
3024 OPC_65C02_NOP11, // $6B
3028 OPC_Illegal, // $6F: BBR6 currently unsupported
3032 OPC_65C02_NOP11, // $73
3036 OPC_Illegal, // $77: RMB7 currently unsupported
3040 OPC_65C02_NOP11, // $7B
3044 OPC_Illegal, // $7F: BBR7 currently unsupported
3047 OPC_65C02_NOP22, // $82
3048 OPC_65C02_NOP11, // $83
3052 OPC_Illegal, // $87: SMB0 currently unsupported
3056 OPC_65C02_NOP11, // $8B
3060 OPC_Illegal, // $8F: BBS0 currently unsupported
3064 OPC_65C02_NOP11, // $93
3068 OPC_Illegal, // $97: SMB1 currently unsupported
3072 OPC_65C02_NOP11, // $9B
3076 OPC_Illegal, // $9F: BBS1 currently unsupported
3080 OPC_65C02_NOP11, // $A3
3084 OPC_Illegal, // $A7: SMB2 currently unsupported
3088 OPC_65C02_NOP11, // $AB
3092 OPC_Illegal, // $AF: BBS2 currently unsupported
3096 OPC_65C02_NOP11, // $B3
3100 OPC_Illegal, // $B7: SMB3 currently unsupported
3104 OPC_65C02_NOP11, // $BB
3108 OPC_Illegal, // $BF: BBS3 currently unsupported
3111 OPC_65C02_NOP22, // $C2
3112 OPC_65C02_NOP11, // $C3
3116 OPC_Illegal, // $C7: SMB4 currently unsupported
3120 OPC_Illegal, // $CB: WAI currently unsupported
3124 OPC_Illegal, // $CF: BBS4 currently unsupported
3128 OPC_65C02_NOP11, // $D3
3129 OPC_65C02_NOP24, // $D4
3132 OPC_Illegal, // $D7: SMB5 currently unsupported
3136 OPC_Illegal, // $DB: STP currently unsupported
3137 OPC_65C02_NOP34, // $DC
3140 OPC_Illegal, // $DF: BBS5 currently unsupported
3143 OPC_65C02_NOP22, // $E2
3144 OPC_65C02_NOP11, // $E3
3148 OPC_Illegal, // $E7: SMB6 currently unsupported
3152 OPC_65C02_NOP11, // $EB
3156 OPC_Illegal, // $EF: BBS6 currently unsupported
3160 OPC_65C02_NOP11, // $F3
3161 OPC_65C02_NOP24, // $F4
3164 OPC_Illegal, // $F7: SMB7 currently unsupported
3168 OPC_65C02_NOP11, // $FB
3169 OPC_65C02_NOP34, // $FC
3172 OPC_Illegal, // $FF: BBS7 currently unsupported
3177 /* Tables with opcode handlers */
3178 static const OPFunc* Handlers[2] = {OP6502Table, OP65C02Table};
3182 /*****************************************************************************/
3184 /*****************************************************************************/
3188 void IRQRequest (void)
3189 /* Generate an IRQ */
3191 /* Remember the request */
3197 void NMIRequest (void)
3198 /* Generate an NMI */
3200 /* Remember the request */
3207 /* Generate a CPU RESET */
3213 Regs.PC = MemReadWord (0xFFFC);
3218 unsigned ExecuteInsn (void)
3219 /* Execute one CPU instruction */
3221 /* If we have an NMI request, handle it */
3222 if (HaveNMIRequest) {
3229 Regs.PC = MemReadWord (0xFFFA);
3232 } else if (HaveIRQRequest && GET_IF () == 0) {
3239 Regs.PC = MemReadWord (0xFFFE);
3244 /* Normal instruction - read the next opcode */
3245 unsigned char OPC = MemReadByte (Regs.PC);
3248 Handlers[CPU][OPC] ();
3252 TotalCycles += Cycles;
3254 /* Return the number of clock cycles needed by this insn */
3260 unsigned long GetCycles (void)
3261 /* Return the total number of cycles executed */
3263 /* Return the total number of cycles */