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)) \
220 Regs.AC = Regs.AC op MemReadByte (Addr); \
226 #define AC_OP_ZPIND(op) \
227 unsigned char ZPAddr; \
230 ZPAddr = MemReadByte (Regs.PC+1); \
231 Addr = MemReadZPWord (ZPAddr); \
232 Regs.AC = Regs.AC op MemReadByte (Addr); \
240 unsigned old = Regs.AC; \
241 unsigned rhs = (v & 0xFF); \
245 lo = (old & 0x0F) + (rhs & 0x0F) + GET_CF (); \
247 lo = ((lo + 0x06) & 0x0F) + 0x10; \
249 Regs.AC = (old & 0xF0) + (rhs & 0xF0) + lo; \
250 res = (signed char)(old & 0xF0) + \
251 (signed char)(rhs & 0xF0) + \
253 TEST_ZF (old + rhs + GET_CF ()); \
255 if (Regs.AC >= 0xA0) { \
259 SET_OF ((res < -128) || (res > 127)); \
263 Regs.AC += rhs + GET_CF (); \
267 SET_OF (!((old ^ rhs) & 0x80) && \
268 ((old ^ Regs.AC) & 0x80)); \
274 #define BRANCH(cond) \
278 unsigned char OldPCH; \
280 Offs = (signed char) MemReadByte (Regs.PC+1); \
282 Regs.PC += 2 + (int) Offs; \
283 if (PCH != OldPCH) { \
291 #define CMP(v1, v2) \
293 unsigned Result = v1 - v2; \
294 TEST_ZF (Result & 0xFF); \
296 SET_CF (Result <= 0xFF); \
315 SET_CF (Val & 0x01); \
323 unsigned old = Regs.AC; \
324 unsigned rhs = (v & 0xFF); \
328 lo = (old & 0x0F) - (rhs & 0x0F) + GET_CF () - 1; \
330 lo = ((lo - 0x06) & 0x0F) - 0x10; \
332 Regs.AC = (old & 0xF0) - (rhs & 0xF0) + lo; \
333 if (Regs.AC & 0x80) { \
336 res = Regs.AC - rhs + (!GET_CF ()); \
339 SET_CF (res <= 0xFF); \
340 SET_OF (((old^rhs) & (old^res) & 0x80)); \
344 Regs.AC -= rhs + (!GET_CF ()); \
347 SET_CF (Regs.AC <= 0xFF); \
348 SET_OF (((old^rhs) & (old^Regs.AC) & 0x80)); \
355 /*****************************************************************************/
356 /* Opcode handling functions */
357 /*****************************************************************************/
361 static void OPC_Illegal (void)
363 Error ("Illegal opcode $%02X at address $%04X",
364 MemReadByte (Regs.PC), Regs.PC);
369 static void OPC_6502_00 (void)
370 /* Opcode $00: BRK */
379 Regs.PC = MemReadWord (0xFFFE);
384 static void OPC_6502_01 (void)
385 /* Opcode $01: ORA (ind,x) */
392 static void OPC_65SC02_04 (void)
393 /* Opcode $04: TSB zp */
395 unsigned char ZPAddr;
398 ZPAddr = MemReadByte (Regs.PC+1);
399 Val = MemReadByte (ZPAddr);
400 SET_ZF ((Val & Regs.AC) == 0);
401 MemWriteByte (ZPAddr, (unsigned char)(Val | Regs.AC));
407 static void OPC_6502_05 (void)
408 /* Opcode $05: ORA zp */
415 static void OPC_6502_06 (void)
416 /* Opcode $06: ASL zp */
418 unsigned char ZPAddr;
421 ZPAddr = MemReadByte (Regs.PC+1);
422 Val = MemReadByte (ZPAddr) << 1;
423 MemWriteByte (ZPAddr, (unsigned char) Val);
424 TEST_ZF (Val & 0xFF);
426 SET_CF (Val & 0x100);
432 static void OPC_6502_08 (void)
433 /* Opcode $08: PHP */
436 PUSH (Regs.SR & ~BF);
442 static void OPC_6502_09 (void)
443 /* Opcode $09: ORA #imm */
450 static void OPC_6502_0A (void)
451 /* Opcode $0A: ASL a */
455 TEST_ZF (Regs.AC & 0xFF);
457 SET_CF (Regs.AC & 0x100);
464 static void OPC_65SC02_0C (void)
465 /* Opcode $0C: TSB abs */
470 Addr = MemReadByte (Regs.PC+1);
471 Val = MemReadByte (Addr);
472 SET_ZF ((Val & Regs.AC) == 0);
473 MemWriteByte (Addr, (unsigned char) (Val | Regs.AC));
479 static void OPC_6502_0D (void)
480 /* Opcode $0D: ORA abs */
487 static void OPC_6502_0E (void)
488 /* Opcode $0E: ALS abs */
493 Addr = MemReadWord (Regs.PC+1);
494 Val = MemReadByte (Addr) << 1;
495 MemWriteByte (Addr, (unsigned char) Val);
496 TEST_ZF (Val & 0xFF);
498 SET_CF (Val & 0x100);
504 static void OPC_6502_10 (void)
505 /* Opcode $10: BPL */
512 static void OPC_6502_11 (void)
513 /* Opcode $11: ORA (zp),y */
520 static void OPC_65SC02_12 (void)
521 /* Opcode $12: ORA (zp) */
528 static void OPC_65SC02_14 (void)
529 /* Opcode $14: TRB zp */
531 unsigned char ZPAddr;
534 ZPAddr = MemReadByte (Regs.PC+1);
535 Val = MemReadByte (ZPAddr);
536 SET_ZF ((Val & Regs.AC) == 0);
537 MemWriteByte (ZPAddr, (unsigned char)(Val & ~Regs.AC));
543 static void OPC_6502_15 (void)
544 /* Opcode $15: ORA zp,x */
551 static void OPC_6502_16 (void)
552 /* Opcode $16: ASL zp,x */
554 unsigned char ZPAddr;
557 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
558 Val = MemReadByte (ZPAddr) << 1;
559 MemWriteByte (ZPAddr, (unsigned char) Val);
560 TEST_ZF (Val & 0xFF);
562 SET_CF (Val & 0x100);
568 static void OPC_6502_18 (void)
569 /* Opcode $18: CLC */
578 static void OPC_6502_19 (void)
579 /* Opcode $19: ORA abs,y */
586 static void OPC_65SC02_1A (void)
587 /* Opcode $1A: INC a */
590 Regs.AC = (Regs.AC + 1) & 0xFF;
598 static void OPC_65SC02_1C (void)
599 /* Opcode $1C: TRB abs */
604 Addr = MemReadByte (Regs.PC+1);
605 Val = MemReadByte (Addr);
606 SET_ZF ((Val & Regs.AC) == 0);
607 MemWriteByte (Addr, (unsigned char) (Val & ~Regs.AC));
613 static void OPC_6502_1D (void)
614 /* Opcode $1D: ORA abs,x */
621 static void OPC_6502_1E (void)
622 /* Opcode $1E: ASL abs,x */
627 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
628 Val = MemReadByte (Addr) << 1;
629 MemWriteByte (Addr, (unsigned char) Val);
630 TEST_ZF (Val & 0xFF);
632 SET_CF (Val & 0x100);
638 static void OPC_6502_20 (void)
639 /* Opcode $20: JSR */
643 Addr = MemReadWord (Regs.PC+1);
649 ParaVirtHooks (&Regs);
654 static void OPC_6502_21 (void)
655 /* Opcode $21: AND (zp,x) */
662 static void OPC_6502_24 (void)
663 /* Opcode $24: BIT zp */
665 unsigned char ZPAddr;
668 ZPAddr = MemReadByte (Regs.PC+1);
669 Val = MemReadByte (ZPAddr);
672 SET_ZF ((Val & Regs.AC) == 0);
678 static void OPC_6502_25 (void)
679 /* Opcode $25: AND zp */
686 static void OPC_6502_26 (void)
687 /* Opcode $26: ROL zp */
689 unsigned char ZPAddr;
692 ZPAddr = MemReadByte (Regs.PC+1);
693 Val = MemReadByte (ZPAddr);
695 MemWriteByte (ZPAddr, Val);
701 static void OPC_6502_28 (void)
702 /* Opcode $28: PLP */
705 Regs.SR = (POP () & ~BF);
711 static void OPC_6502_29 (void)
712 /* Opcode $29: AND #imm */
719 static void OPC_6502_2A (void)
720 /* Opcode $2A: ROL a */
730 static void OPC_6502_2C (void)
731 /* Opcode $2C: BIT abs */
736 Addr = MemReadByte (Regs.PC+1);
737 Val = MemReadByte (Addr);
740 SET_ZF ((Val & Regs.AC) == 0);
746 static void OPC_6502_2D (void)
747 /* Opcode $2D: AND abs */
754 static void OPC_6502_2E (void)
755 /* Opcode $2E: ROL abs */
760 Addr = MemReadWord (Regs.PC+1);
761 Val = MemReadByte (Addr);
763 MemWriteByte (Addr, Val);
769 static void OPC_6502_30 (void)
770 /* Opcode $30: BMI */
777 static void OPC_6502_31 (void)
778 /* Opcode $31: AND (zp),y */
785 static void OPC_65SC02_32 (void)
786 /* Opcode $32: AND (zp) */
793 static void OPC_65SC02_34 (void)
794 /* Opcode $34: BIT zp,x */
796 unsigned char ZPAddr;
799 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
800 Val = MemReadByte (ZPAddr);
803 SET_ZF ((Val & Regs.AC) == 0);
809 static void OPC_6502_35 (void)
810 /* Opcode $35: AND zp,x */
817 static void OPC_6502_36 (void)
818 /* Opcode $36: ROL zp,x */
820 unsigned char ZPAddr;
823 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
824 Val = MemReadByte (ZPAddr);
826 MemWriteByte (ZPAddr, Val);
832 static void OPC_6502_38 (void)
833 /* Opcode $38: SEC */
842 static void OPC_6502_39 (void)
843 /* Opcode $39: AND abs,y */
850 static void OPC_65SC02_3A (void)
851 /* Opcode $3A: DEC a */
854 Regs.AC = (Regs.AC - 1) & 0xFF;
862 static void OPC_65SC02_3C (void)
863 /* Opcode $3C: BIT abs,x */
868 Addr = MemReadByte (Regs.PC+1);
869 if (PAGE_CROSS (Addr, Regs.XR))
871 Val = MemReadByte (Addr + Regs.XR);
874 SET_ZF ((Val & Regs.AC) == 0);
880 static void OPC_6502_3D (void)
881 /* Opcode $3D: AND abs,x */
888 static void OPC_6502_3E (void)
889 /* Opcode $3E: ROL abs,x */
894 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
895 Val = MemReadByte (Addr);
897 MemWriteByte (Addr, Val);
903 static void OPC_6502_40 (void)
904 /* Opcode $40: RTI */
908 Regs.PC = POP (); /* PCL */
909 Regs.PC |= (POP () << 8); /* PCH */
914 static void OPC_6502_41 (void)
915 /* Opcode $41: EOR (zp,x) */
922 static void OPC_65C02_44 (void)
923 /* Opcode $44: 'zp' 3 cycle NOP */
931 static void OPC_6502_45 (void)
932 /* Opcode $45: EOR zp */
939 static void OPC_6502_46 (void)
940 /* Opcode $46: LSR zp */
942 unsigned char ZPAddr;
945 ZPAddr = MemReadByte (Regs.PC+1);
946 Val = MemReadByte (ZPAddr);
949 MemWriteByte (ZPAddr, Val);
957 static void OPC_6502_48 (void)
958 /* Opcode $48: PHA */
967 static void OPC_6502_49 (void)
968 /* Opcode $49: EOR #imm */
975 static void OPC_6502_4A (void)
976 /* Opcode $4A: LSR a */
979 SET_CF (Regs.AC & 0x01);
988 static void OPC_6502_4C (void)
989 /* Opcode $4C: JMP abs */
992 Regs.PC = MemReadWord (Regs.PC+1);
994 ParaVirtHooks (&Regs);
999 static void OPC_6502_4D (void)
1000 /* Opcode $4D: EOR abs */
1007 static void OPC_6502_4E (void)
1008 /* Opcode $4E: LSR abs */
1013 Addr = MemReadWord (Regs.PC+1);
1014 Val = MemReadByte (Addr);
1015 SET_CF (Val & 0x01);
1017 MemWriteByte (Addr, Val);
1025 static void OPC_6502_50 (void)
1026 /* Opcode $50: BVC */
1028 BRANCH (!GET_OF ());
1033 static void OPC_6502_51 (void)
1034 /* Opcode $51: EOR (zp),y */
1041 static void OPC_65SC02_52 (void)
1042 /* Opcode $52: EOR (zp) */
1049 static void OPC_6502_55 (void)
1050 /* Opcode $55: EOR zp,x */
1057 static void OPC_6502_56 (void)
1058 /* Opcode $56: LSR zp,x */
1060 unsigned char ZPAddr;
1063 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1064 Val = MemReadByte (ZPAddr);
1065 SET_CF (Val & 0x01);
1067 MemWriteByte (ZPAddr, Val);
1075 static void OPC_6502_58 (void)
1076 /* Opcode $58: CLI */
1085 static void OPC_6502_59 (void)
1086 /* Opcode $59: EOR abs,y */
1093 static void OPC_65SC02_5A (void)
1094 /* Opcode $5A: PHY */
1103 static void OPC_65C02_5C (void)
1104 /* Opcode $5C: 'Absolute' 8 cycle NOP */
1112 static void OPC_6502_5D (void)
1113 /* Opcode $5D: EOR abs,x */
1120 static void OPC_6502_5E (void)
1121 /* Opcode $5E: LSR abs,x */
1126 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1127 Val = MemReadByte (Addr);
1128 SET_CF (Val & 0x01);
1130 MemWriteByte (Addr, Val);
1138 static void OPC_6502_60 (void)
1139 /* Opcode $60: RTS */
1142 Regs.PC = POP (); /* PCL */
1143 Regs.PC |= (POP () << 8); /* PCH */
1149 static void OPC_6502_61 (void)
1150 /* Opcode $61: ADC (zp,x) */
1152 unsigned char ZPAddr;
1155 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1156 Addr = MemReadZPWord (ZPAddr);
1157 ADC (MemReadByte (Addr));
1163 static void OPC_65SC02_64 (void)
1164 /* Opcode $64: STZ zp */
1166 unsigned char ZPAddr;
1168 ZPAddr = MemReadByte (Regs.PC+1);
1169 MemWriteByte (ZPAddr, 0);
1175 static void OPC_6502_65 (void)
1176 /* Opcode $65: ADC zp */
1178 unsigned char ZPAddr;
1180 ZPAddr = MemReadByte (Regs.PC+1);
1181 ADC (MemReadByte (ZPAddr));
1187 static void OPC_6502_66 (void)
1188 /* Opcode $66: ROR zp */
1190 unsigned char ZPAddr;
1193 ZPAddr = MemReadByte (Regs.PC+1);
1194 Val = MemReadByte (ZPAddr);
1196 MemWriteByte (ZPAddr, Val);
1202 static void OPC_6502_68 (void)
1203 /* Opcode $68: PLA */
1214 static void OPC_6502_69 (void)
1215 /* Opcode $69: ADC #imm */
1218 ADC (MemReadByte (Regs.PC+1));
1224 static void OPC_6502_6A (void)
1225 /* Opcode $6A: ROR a */
1234 static void OPC_6502_6C (void)
1235 /* Opcode $6C: JMP (ind) */
1237 unsigned PC, Lo, Hi;
1239 Lo = MemReadWord (PC+1);
1243 /* Emulate the 6502 bug */
1245 Regs.PC = MemReadByte (Lo);
1246 Hi = (Lo & 0xFF00) | ((Lo + 1) & 0xFF);
1247 Regs.PC |= (MemReadByte (Hi) << 8);
1249 /* Output a warning if the bug is triggered */
1252 Warning ("6502 indirect jump bug triggered at $%04X, ind addr = $%04X",
1259 Regs.PC = MemReadWord(Lo);
1265 static void OPC_65C02_6C (void)
1266 /* Opcode $6C: JMP (ind) */
1268 /* 6502 bug fixed here */
1270 Regs.PC = MemReadWord (MemReadWord (Regs.PC+1));
1275 static void OPC_6502_6D (void)
1276 /* Opcode $6D: ADC abs */
1280 Addr = MemReadWord (Regs.PC+1);
1281 ADC (MemReadByte (Addr));
1287 static void OPC_6502_6E (void)
1288 /* Opcode $6E: ROR abs */
1293 Addr = MemReadWord (Regs.PC+1);
1294 Val = MemReadByte (Addr);
1296 MemWriteByte (Addr, Val);
1302 static void OPC_6502_70 (void)
1303 /* Opcode $70: BVS */
1310 static void OPC_6502_71 (void)
1311 /* Opcode $71: ADC (zp),y */
1313 unsigned char ZPAddr;
1316 ZPAddr = MemReadByte (Regs.PC+1);
1317 Addr = MemReadZPWord (ZPAddr);
1318 if (PAGE_CROSS (Addr, Regs.YR)) {
1321 ADC (MemReadByte (Addr + Regs.YR));
1327 static void OPC_65SC02_72 (void)
1328 /* Opcode $72: ADC (zp) */
1330 unsigned char ZPAddr;
1333 ZPAddr = MemReadByte (Regs.PC+1);
1334 Addr = MemReadZPWord (ZPAddr);
1335 ADC (MemReadByte (Addr));
1341 static void OPC_65SC02_74 (void)
1342 /* Opcode $74: STZ zp,x */
1344 unsigned char ZPAddr;
1346 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1347 MemWriteByte (ZPAddr, 0);
1353 static void OPC_6502_75 (void)
1354 /* Opcode $75: ADC zp,x */
1356 unsigned char ZPAddr;
1358 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1359 ADC (MemReadByte (ZPAddr));
1365 static void OPC_6502_76 (void)
1366 /* Opcode $76: ROR zp,x */
1368 unsigned char ZPAddr;
1371 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1372 Val = MemReadByte (ZPAddr);
1374 MemWriteByte (ZPAddr, Val);
1380 static void OPC_6502_78 (void)
1381 /* Opcode $78: SEI */
1390 static void OPC_6502_79 (void)
1391 /* Opcode $79: ADC abs,y */
1395 Addr = MemReadWord (Regs.PC+1);
1396 if (PAGE_CROSS (Addr, Regs.YR)) {
1399 ADC (MemReadByte (Addr + Regs.YR));
1405 static void OPC_65SC02_7A (void)
1406 /* Opcode $7A: PLY */
1417 static void OPC_65SC02_7C (void)
1418 /* Opcode $7C: JMP (ind,X) */
1423 Adr = MemReadWord (PC+1);
1424 Regs.PC = MemReadWord(Adr+Regs.XR);
1429 static void OPC_6502_7D (void)
1430 /* Opcode $7D: ADC abs,x */
1434 Addr = MemReadWord (Regs.PC+1);
1435 if (PAGE_CROSS (Addr, Regs.XR)) {
1438 ADC (MemReadByte (Addr + Regs.XR));
1444 static void OPC_6502_7E (void)
1445 /* Opcode $7E: ROR abs,x */
1450 Addr = MemReadByte (Regs.PC+1) + Regs.XR;
1451 Val = MemReadByte (Addr);
1453 MemWriteByte (Addr, Val);
1459 static void OPC_65SC02_80 (void)
1460 /* Opcode $80: BRA */
1467 static void OPC_6502_81 (void)
1468 /* Opcode $81: STA (zp,x) */
1470 unsigned char ZPAddr;
1473 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1474 Addr = MemReadZPWord (ZPAddr);
1475 MemWriteByte (Addr, Regs.AC);
1481 static void OPC_6502_84 (void)
1482 /* Opcode $84: STY zp */
1484 unsigned char ZPAddr;
1486 ZPAddr = MemReadByte (Regs.PC+1);
1487 MemWriteByte (ZPAddr, Regs.YR);
1493 static void OPC_6502_85 (void)
1494 /* Opcode $85: STA zp */
1496 unsigned char ZPAddr;
1498 ZPAddr = MemReadByte (Regs.PC+1);
1499 MemWriteByte (ZPAddr, Regs.AC);
1505 static void OPC_6502_86 (void)
1506 /* Opcode $86: STX zp */
1508 unsigned char ZPAddr;
1510 ZPAddr = MemReadByte (Regs.PC+1);
1511 MemWriteByte (ZPAddr, Regs.XR);
1517 static void OPC_6502_88 (void)
1518 /* Opcode $88: DEY */
1521 Regs.YR = (Regs.YR - 1) & 0xFF;
1529 static void OPC_65SC02_89 (void)
1530 /* Opcode $89: BIT #imm */
1534 Val = MemReadByte (Regs.PC+1);
1535 SET_SF (Val & 0x80);
1536 SET_OF (Val & 0x40);
1537 SET_ZF ((Val & Regs.AC) == 0);
1543 static void OPC_6502_8A (void)
1544 /* Opcode $8A: TXA */
1555 static void OPC_6502_8C (void)
1556 /* Opcode $8C: STY abs */
1560 Addr = MemReadWord (Regs.PC+1);
1561 MemWriteByte (Addr, Regs.YR);
1567 static void OPC_6502_8D (void)
1568 /* Opcode $8D: STA abs */
1572 Addr = MemReadWord (Regs.PC+1);
1573 MemWriteByte (Addr, Regs.AC);
1579 static void OPC_6502_8E (void)
1580 /* Opcode $8E: STX abs */
1584 Addr = MemReadWord (Regs.PC+1);
1585 MemWriteByte (Addr, Regs.XR);
1591 static void OPC_6502_90 (void)
1592 /* Opcode $90: BCC */
1594 BRANCH (!GET_CF ());
1599 static void OPC_6502_91 (void)
1600 /* Opcode $91: sta (zp),y */
1602 unsigned char ZPAddr;
1605 ZPAddr = MemReadByte (Regs.PC+1);
1606 Addr = MemReadZPWord (ZPAddr) + Regs.YR;
1607 MemWriteByte (Addr, Regs.AC);
1613 static void OPC_65SC02_92 (void)
1614 /* Opcode $92: sta (zp) */
1616 unsigned char ZPAddr;
1619 ZPAddr = MemReadByte (Regs.PC+1);
1620 Addr = MemReadZPWord (ZPAddr);
1621 MemWriteByte (Addr, Regs.AC);
1627 static void OPC_6502_94 (void)
1628 /* Opcode $94: STY zp,x */
1630 unsigned char ZPAddr;
1632 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1633 MemWriteByte (ZPAddr, Regs.YR);
1639 static void OPC_6502_95 (void)
1640 /* Opcode $95: STA zp,x */
1642 unsigned char ZPAddr;
1644 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1645 MemWriteByte (ZPAddr, Regs.AC);
1651 static void OPC_6502_96 (void)
1652 /* Opcode $96: stx zp,y */
1654 unsigned char ZPAddr;
1656 ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR;
1657 MemWriteByte (ZPAddr, Regs.XR);
1663 static void OPC_6502_98 (void)
1664 /* Opcode $98: TYA */
1675 static void OPC_6502_99 (void)
1676 /* Opcode $99: STA abs,y */
1680 Addr = MemReadWord (Regs.PC+1) + Regs.YR;
1681 MemWriteByte (Addr, Regs.AC);
1687 static void OPC_6502_9A (void)
1688 /* Opcode $9A: TXS */
1697 static void OPC_65SC02_9C (void)
1698 /* Opcode $9C: STZ abs */
1702 Addr = MemReadWord (Regs.PC+1);
1703 MemWriteByte (Addr, 0);
1709 static void OPC_6502_9D (void)
1710 /* Opcode $9D: STA abs,x */
1714 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1715 MemWriteByte (Addr, Regs.AC);
1721 static void OPC_65SC02_9E (void)
1722 /* Opcode $9E: STZ abs,x */
1726 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
1727 MemWriteByte (Addr, 0);
1733 static void OPC_6502_A0 (void)
1734 /* Opcode $A0: LDY #imm */
1737 Regs.YR = MemReadByte (Regs.PC+1);
1745 static void OPC_6502_A1 (void)
1746 /* Opcode $A1: LDA (zp,x) */
1748 unsigned char ZPAddr;
1751 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1752 Addr = MemReadZPWord (ZPAddr);
1753 Regs.AC = MemReadByte (Addr);
1761 static void OPC_6502_A2 (void)
1762 /* Opcode $A2: LDX #imm */
1765 Regs.XR = MemReadByte (Regs.PC+1);
1773 static void OPC_6502_A4 (void)
1774 /* Opcode $A4: LDY zp */
1776 unsigned char ZPAddr;
1778 ZPAddr = MemReadByte (Regs.PC+1);
1779 Regs.YR = MemReadByte (ZPAddr);
1787 static void OPC_6502_A5 (void)
1788 /* Opcode $A5: LDA zp */
1790 unsigned char ZPAddr;
1792 ZPAddr = MemReadByte (Regs.PC+1);
1793 Regs.AC = MemReadByte (ZPAddr);
1801 static void OPC_6502_A6 (void)
1802 /* Opcode $A6: LDX zp */
1804 unsigned char ZPAddr;
1806 ZPAddr = MemReadByte (Regs.PC+1);
1807 Regs.XR = MemReadByte (ZPAddr);
1815 static void OPC_6502_A8 (void)
1816 /* Opcode $A8: TAY */
1827 static void OPC_6502_A9 (void)
1828 /* Opcode $A9: LDA #imm */
1831 Regs.AC = MemReadByte (Regs.PC+1);
1839 static void OPC_6502_AA (void)
1840 /* Opcode $AA: TAX */
1851 static void OPC_6502_AC (void)
1852 /* Opcode $Regs.AC: LDY abs */
1856 Addr = MemReadWord (Regs.PC+1);
1857 Regs.YR = MemReadByte (Addr);
1865 static void OPC_6502_AD (void)
1866 /* Opcode $AD: LDA abs */
1870 Addr = MemReadWord (Regs.PC+1);
1871 Regs.AC = MemReadByte (Addr);
1879 static void OPC_6502_AE (void)
1880 /* Opcode $AE: LDX abs */
1884 Addr = MemReadWord (Regs.PC+1);
1885 Regs.XR = MemReadByte (Addr);
1893 static void OPC_6502_B0 (void)
1894 /* Opcode $B0: BCS */
1901 static void OPC_6502_B1 (void)
1902 /* Opcode $B1: LDA (zp),y */
1904 unsigned char ZPAddr;
1907 ZPAddr = MemReadByte (Regs.PC+1);
1908 Addr = MemReadZPWord (ZPAddr);
1909 if (PAGE_CROSS (Addr, Regs.YR)) {
1912 Regs.AC = MemReadByte (Addr + Regs.YR);
1920 static void OPC_65SC02_B2 (void)
1921 /* Opcode $B2: LDA (zp) */
1923 unsigned char ZPAddr;
1926 ZPAddr = MemReadByte (Regs.PC+1);
1927 Addr = MemReadZPWord (ZPAddr);
1928 Regs.AC = MemReadByte (Addr);
1936 static void OPC_6502_B4 (void)
1937 /* Opcode $B4: LDY zp,x */
1939 unsigned char ZPAddr;
1941 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1942 Regs.YR = MemReadByte (ZPAddr);
1950 static void OPC_6502_B5 (void)
1951 /* Opcode $B5: LDA zp,x */
1953 unsigned char ZPAddr;
1955 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
1956 Regs.AC = MemReadByte (ZPAddr);
1964 static void OPC_6502_B6 (void)
1965 /* Opcode $B6: LDX zp,y */
1967 unsigned char ZPAddr;
1969 ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR;
1970 Regs.XR = MemReadByte (ZPAddr);
1978 static void OPC_6502_B8 (void)
1979 /* Opcode $B8: CLV */
1988 static void OPC_6502_B9 (void)
1989 /* Opcode $B9: LDA abs,y */
1993 Addr = MemReadWord (Regs.PC+1);
1994 if (PAGE_CROSS (Addr, Regs.YR)) {
1997 Regs.AC = MemReadByte (Addr + Regs.YR);
2005 static void OPC_6502_BA (void)
2006 /* Opcode $BA: TSX */
2017 static void OPC_6502_BC (void)
2018 /* Opcode $BC: LDY abs,x */
2022 Addr = MemReadWord (Regs.PC+1);
2023 if (PAGE_CROSS (Addr, Regs.XR)) {
2026 Regs.YR = MemReadByte (Addr + Regs.XR);
2034 static void OPC_6502_BD (void)
2035 /* Opcode $BD: LDA abs,x */
2039 Addr = MemReadWord (Regs.PC+1);
2040 if (PAGE_CROSS (Addr, Regs.XR)) {
2043 Regs.AC = MemReadByte (Addr + Regs.XR);
2051 static void OPC_6502_BE (void)
2052 /* Opcode $BE: LDX abs,y */
2056 Addr = MemReadWord (Regs.PC+1);
2057 if (PAGE_CROSS (Addr, Regs.YR)) {
2060 Regs.XR = MemReadByte (Addr + Regs.YR);
2068 static void OPC_6502_C0 (void)
2069 /* Opcode $C0: CPY #imm */
2072 CMP (Regs.YR, MemReadByte (Regs.PC+1));
2078 static void OPC_6502_C1 (void)
2079 /* Opcode $C1: CMP (zp,x) */
2081 unsigned char ZPAddr;
2084 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2085 Addr = MemReadZPWord (ZPAddr);
2086 CMP (Regs.AC, MemReadByte (Addr));
2092 static void OPC_6502_C4 (void)
2093 /* Opcode $C4: CPY zp */
2095 unsigned char ZPAddr;
2097 ZPAddr = MemReadByte (Regs.PC+1);
2098 CMP (Regs.YR, MemReadByte (ZPAddr));
2104 static void OPC_6502_C5 (void)
2105 /* Opcode $C5: CMP zp */
2107 unsigned char ZPAddr;
2109 ZPAddr = MemReadByte (Regs.PC+1);
2110 CMP (Regs.AC, MemReadByte (ZPAddr));
2116 static void OPC_6502_C6 (void)
2117 /* Opcode $C6: DEC zp */
2119 unsigned char ZPAddr;
2122 ZPAddr = MemReadByte (Regs.PC+1);
2123 Val = MemReadByte (ZPAddr) - 1;
2124 MemWriteByte (ZPAddr, Val);
2132 static void OPC_6502_C8 (void)
2133 /* Opcode $C8: INY */
2136 Regs.YR = (Regs.YR + 1) & 0xFF;
2144 static void OPC_6502_C9 (void)
2145 /* Opcode $C9: CMP #imm */
2148 CMP (Regs.AC, MemReadByte (Regs.PC+1));
2154 static void OPC_6502_CA (void)
2155 /* Opcode $CA: DEX */
2158 Regs.XR = (Regs.XR - 1) & 0xFF;
2166 static void OPC_6502_CC (void)
2167 /* Opcode $CC: CPY abs */
2171 Addr = MemReadWord (Regs.PC+1);
2172 CMP (Regs.YR, MemReadByte (Addr));
2178 static void OPC_6502_CD (void)
2179 /* Opcode $CD: CMP abs */
2183 Addr = MemReadWord (Regs.PC+1);
2184 CMP (Regs.AC, MemReadByte (Addr));
2190 static void OPC_6502_CE (void)
2191 /* Opcode $CE: DEC abs */
2196 Addr = MemReadWord (Regs.PC+1);
2197 Val = MemReadByte (Addr) - 1;
2198 MemWriteByte (Addr, Val);
2206 static void OPC_6502_D0 (void)
2207 /* Opcode $D0: BNE */
2209 BRANCH (!GET_ZF ());
2214 static void OPC_6502_D1 (void)
2215 /* Opcode $D1: CMP (zp),y */
2220 ZPAddr = MemReadByte (Regs.PC+1);
2221 Addr = MemReadWord (ZPAddr);
2222 if (PAGE_CROSS (Addr, Regs.YR)) {
2225 CMP (Regs.AC, MemReadByte (Addr + Regs.YR));
2231 static void OPC_65SC02_D2 (void)
2232 /* Opcode $D2: CMP (zp) */
2237 ZPAddr = MemReadByte (Regs.PC+1);
2238 Addr = MemReadWord (ZPAddr);
2239 CMP (Regs.AC, MemReadByte (Addr));
2245 static void OPC_6502_D5 (void)
2246 /* Opcode $D5: CMP zp,x */
2248 unsigned char ZPAddr;
2250 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2251 CMP (Regs.AC, MemReadByte (ZPAddr));
2257 static void OPC_6502_D6 (void)
2258 /* Opcode $D6: DEC zp,x */
2260 unsigned char ZPAddr;
2263 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2264 Val = MemReadByte (ZPAddr) - 1;
2265 MemWriteByte (ZPAddr, Val);
2273 static void OPC_6502_D8 (void)
2274 /* Opcode $D8: CLD */
2283 static void OPC_6502_D9 (void)
2284 /* Opcode $D9: CMP abs,y */
2288 Addr = MemReadWord (Regs.PC+1);
2289 if (PAGE_CROSS (Addr, Regs.YR)) {
2292 CMP (Regs.AC, MemReadByte (Addr + Regs.YR));
2298 static void OPC_65SC02_DA (void)
2299 /* Opcode $DA: PHX */
2308 static void OPC_6502_DD (void)
2309 /* Opcode $DD: CMP abs,x */
2313 Addr = MemReadWord (Regs.PC+1);
2314 if (PAGE_CROSS (Addr, Regs.XR)) {
2317 CMP (Regs.AC, MemReadByte (Addr + Regs.XR));
2323 static void OPC_6502_DE (void)
2324 /* Opcode $DE: DEC abs,x */
2329 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
2330 Val = MemReadByte (Addr) - 1;
2331 MemWriteByte (Addr, Val);
2339 static void OPC_6502_E0 (void)
2340 /* Opcode $E0: CPX #imm */
2343 CMP (Regs.XR, MemReadByte (Regs.PC+1));
2349 static void OPC_6502_E1 (void)
2350 /* Opcode $E1: SBC (zp,x) */
2352 unsigned char ZPAddr;
2355 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2356 Addr = MemReadZPWord (ZPAddr);
2357 SBC (MemReadByte (Addr));
2363 static void OPC_6502_E4 (void)
2364 /* Opcode $E4: CPX zp */
2366 unsigned char ZPAddr;
2368 ZPAddr = MemReadByte (Regs.PC+1);
2369 CMP (Regs.XR, MemReadByte (ZPAddr));
2375 static void OPC_6502_E5 (void)
2376 /* Opcode $E5: SBC zp */
2378 unsigned char ZPAddr;
2380 ZPAddr = MemReadByte (Regs.PC+1);
2381 SBC (MemReadByte (ZPAddr));
2387 static void OPC_6502_E6 (void)
2388 /* Opcode $E6: INC zp */
2390 unsigned char ZPAddr;
2393 ZPAddr = MemReadByte (Regs.PC+1);
2394 Val = MemReadByte (ZPAddr) + 1;
2395 MemWriteByte (ZPAddr, Val);
2403 static void OPC_6502_E8 (void)
2404 /* Opcode $E8: INX */
2407 Regs.XR = (Regs.XR + 1) & 0xFF;
2415 static void OPC_6502_E9 (void)
2416 /* Opcode $E9: SBC #imm */
2419 SBC (MemReadByte (Regs.PC+1));
2425 static void OPC_6502_EA (void)
2426 /* Opcode $EA: NOP */
2428 /* This one is easy... */
2435 static void OPC_65C02_NOP11(void)
2436 /* Opcode 'Illegal' 1 cycle NOP */
2444 static void OPC_65C02_NOP22 (void)
2445 /* Opcode 'Illegal' 2 byte 2 cycle NOP */
2453 static void OPC_65C02_NOP24 (void)
2454 /* Opcode 'Illegal' 2 byte 4 cycle NOP */
2462 static void OPC_65C02_NOP34 (void)
2463 /* Opcode 'Illegal' 3 byte 4 cycle NOP */
2471 static void OPC_6502_EC (void)
2472 /* Opcode $EC: CPX abs */
2476 Addr = MemReadWord (Regs.PC+1);
2477 CMP (Regs.XR, MemReadByte (Addr));
2483 static void OPC_6502_ED (void)
2484 /* Opcode $ED: SBC abs */
2488 Addr = MemReadWord (Regs.PC+1);
2489 SBC (MemReadByte (Addr));
2495 static void OPC_6502_EE (void)
2496 /* Opcode $EE: INC abs */
2501 Addr = MemReadWord (Regs.PC+1);
2502 Val = MemReadByte (Addr) + 1;
2503 MemWriteByte (Addr, Val);
2511 static void OPC_6502_F0 (void)
2512 /* Opcode $F0: BEQ */
2519 static void OPC_6502_F1 (void)
2520 /* Opcode $F1: SBC (zp),y */
2522 unsigned char ZPAddr;
2525 ZPAddr = MemReadByte (Regs.PC+1);
2526 Addr = MemReadZPWord (ZPAddr);
2527 if (PAGE_CROSS (Addr, Regs.YR)) {
2530 SBC (MemReadByte (Addr + Regs.YR));
2536 static void OPC_65SC02_F2 (void)
2537 /* Opcode $F2: SBC (zp) */
2539 unsigned char ZPAddr;
2542 ZPAddr = MemReadByte (Regs.PC+1);
2543 Addr = MemReadZPWord (ZPAddr);
2544 SBC (MemReadByte (Addr));
2550 static void OPC_6502_F5 (void)
2551 /* Opcode $F5: SBC zp,x */
2553 unsigned char ZPAddr;
2555 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2556 SBC (MemReadByte (ZPAddr));
2562 static void OPC_6502_F6 (void)
2563 /* Opcode $F6: INC zp,x */
2565 unsigned char ZPAddr;
2568 ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
2569 Val = MemReadByte (ZPAddr) + 1;
2570 MemWriteByte (ZPAddr, Val);
2578 static void OPC_6502_F8 (void)
2579 /* Opcode $F8: SED */
2586 static void OPC_6502_F9 (void)
2587 /* Opcode $F9: SBC abs,y */
2591 Addr = MemReadWord (Regs.PC+1);
2592 if (PAGE_CROSS (Addr, Regs.YR)) {
2595 SBC (MemReadByte (Addr + Regs.YR));
2601 static void OPC_65SC02_FA (void)
2602 /* Opcode $7A: PLX */
2613 static void OPC_6502_FD (void)
2614 /* Opcode $FD: SBC abs,x */
2618 Addr = MemReadWord (Regs.PC+1);
2619 if (PAGE_CROSS (Addr, Regs.XR)) {
2622 SBC (MemReadByte (Addr + Regs.XR));
2628 static void OPC_6502_FE (void)
2629 /* Opcode $FE: INC abs,x */
2634 Addr = MemReadWord (Regs.PC+1) + Regs.XR;
2635 Val = MemReadByte (Addr) + 1;
2636 MemWriteByte (Addr, Val);
2644 /*****************************************************************************/
2645 /* Opcode handler tables */
2646 /*****************************************************************************/
2650 /* Opcode handler table for the 6502 */
2651 static const OPFunc OP6502Table[256] = {
2912 /* Opcode handler table for the 65C02 */
2913 static const OPFunc OP65C02Table[256] = {
2916 OPC_65C02_NOP22, // $02
2917 OPC_65C02_NOP11, // $03
2921 OPC_Illegal, // $07: RMB0 currently unsupported
2925 OPC_65C02_NOP11, // $0B
2929 OPC_Illegal, // $0F: BBR0 currently unsupported
2933 OPC_65C02_NOP11, // $13
2937 OPC_Illegal, // $17: RMB1 currently unsupported
2941 OPC_65C02_NOP11, // $1B
2945 OPC_Illegal, // $1F: BBR1 currently unsupported
2948 OPC_65C02_NOP22, // $22
2949 OPC_65C02_NOP11, // $23
2953 OPC_Illegal, // $27: RMB2 currently unsupported
2957 OPC_65C02_NOP11, // $2B
2961 OPC_Illegal, // $2F: BBR2 currently unsupported
2965 OPC_65C02_NOP11, // $33
2969 OPC_Illegal, // $37: RMB3 currently unsupported
2973 OPC_65C02_NOP11, // $3B
2977 OPC_Illegal, // $3F: BBR3 currently unsupported
2980 OPC_65C02_NOP22, // $42
2981 OPC_65C02_NOP11, // $43
2982 OPC_65C02_44, // $44
2985 OPC_Illegal, // $47: RMB4 currently unsupported
2989 OPC_65C02_NOP11, // $4B
2993 OPC_Illegal, // $4F: BBR4 currently unsupported
2997 OPC_65C02_NOP11, // $53
2998 OPC_65C02_NOP24, // $54
3001 OPC_Illegal, // $57: RMB5 currently unsupported
3005 OPC_65C02_NOP11, // $5B
3009 OPC_Illegal, // $5F: BBR5 currently unsupported
3012 OPC_65C02_NOP22, // $62
3013 OPC_65C02_NOP11, // $63
3017 OPC_Illegal, // $67: RMB6 currently unsupported
3021 OPC_65C02_NOP11, // $6B
3025 OPC_Illegal, // $6F: BBR6 currently unsupported
3029 OPC_65C02_NOP11, // $73
3033 OPC_Illegal, // $77: RMB7 currently unsupported
3037 OPC_65C02_NOP11, // $7B
3041 OPC_Illegal, // $7F: BBR7 currently unsupported
3044 OPC_65C02_NOP22, // $82
3045 OPC_65C02_NOP11, // $83
3049 OPC_Illegal, // $87: SMB0 currently unsupported
3053 OPC_65C02_NOP11, // $8B
3057 OPC_Illegal, // $8F: BBS0 currently unsupported
3061 OPC_65C02_NOP11, // $93
3065 OPC_Illegal, // $97: SMB1 currently unsupported
3069 OPC_65C02_NOP11, // $9B
3073 OPC_Illegal, // $9F: BBS1 currently unsupported
3077 OPC_65C02_NOP11, // $A3
3081 OPC_Illegal, // $A7: SMB2 currently unsupported
3085 OPC_65C02_NOP11, // $AB
3089 OPC_Illegal, // $AF: BBS2 currently unsupported
3093 OPC_65C02_NOP11, // $B3
3097 OPC_Illegal, // $B7: SMB3 currently unsupported
3101 OPC_65C02_NOP11, // $BB
3105 OPC_Illegal, // $BF: BBS3 currently unsupported
3108 OPC_65C02_NOP22, // $C2
3109 OPC_65C02_NOP11, // $C3
3113 OPC_Illegal, // $C7: SMB4 currently unsupported
3117 OPC_Illegal, // $CB: WAI currently unsupported
3121 OPC_Illegal, // $CF: BBS4 currently unsupported
3125 OPC_65C02_NOP11, // $D3
3126 OPC_65C02_NOP24, // $D4
3129 OPC_Illegal, // $D7: SMB5 currently unsupported
3133 OPC_Illegal, // $DB: STP currently unsupported
3134 OPC_65C02_NOP34, // $DC
3137 OPC_Illegal, // $DF: BBS5 currently unsupported
3140 OPC_65C02_NOP22, // $E2
3141 OPC_65C02_NOP11, // $E3
3145 OPC_Illegal, // $E7: SMB6 currently unsupported
3149 OPC_65C02_NOP11, // $EB
3153 OPC_Illegal, // $EF: BBS6 currently unsupported
3157 OPC_65C02_NOP11, // $F3
3158 OPC_65C02_NOP24, // $F4
3161 OPC_Illegal, // $F7: SMB7 currently unsupported
3165 OPC_65C02_NOP11, // $FB
3166 OPC_65C02_NOP34, // $FC
3169 OPC_Illegal, // $FF: BBS7 currently unsupported
3174 /* Tables with opcode handlers */
3175 static const OPFunc* Handlers[2] = {OP6502Table, OP65C02Table};
3179 /*****************************************************************************/
3181 /*****************************************************************************/
3185 void IRQRequest (void)
3186 /* Generate an IRQ */
3188 /* Remember the request */
3194 void NMIRequest (void)
3195 /* Generate an NMI */
3197 /* Remember the request */
3204 /* Generate a CPU RESET */
3210 Regs.PC = MemReadWord (0xFFFC);
3215 unsigned ExecuteInsn (void)
3216 /* Execute one CPU instruction */
3218 /* If we have an NMI request, handle it */
3219 if (HaveNMIRequest) {
3226 Regs.PC = MemReadWord (0xFFFA);
3229 } else if (HaveIRQRequest && GET_IF () == 0) {
3236 Regs.PC = MemReadWord (0xFFFE);
3241 /* Normal instruction - read the next opcode */
3242 unsigned char OPC = MemReadByte (Regs.PC);
3245 Handlers[CPU][OPC] ();
3249 TotalCycles += Cycles;
3251 /* Return the number of clock cycles needed by this insn */
3257 unsigned long GetCycles (void)
3258 /* Return the total number of cycles executed */
3260 /* Return the total number of cycles */