--- /dev/null
+/*****************************************************************************/
+/* */
+/* cpucore.c */
+/* */
+/* CPU core for the 6502 simulator */
+/* */
+/* */
+/* */
+/* (C) 2002 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#include <stdlib.h>
+
+/* common */
+#include "abend.h"
+#include "print.h"
+
+/* sim65 */
+#include "cputype.h"
+#include "global.h"
+#include "memory.h"
+#include "cpucore.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Registers */
+unsigned char AC; /* Accumulator */
+unsigned char XR; /* X register */
+unsigned char YR; /* Y register */
+unsigned char SR; /* Status register */
+unsigned char SP; /* Stackpointer */
+unsigned PC; /* Program counter */
+
+/* Count the total number of cylcles */
+unsigned Cycles; /* Cycles per insn */
+unsigned long TotalCycles; /* Total cycles */
+
+/* Allow the stack page to be changed */
+static unsigned StackPage = 0x100;
+
+/* Status register bits */
+#define CF 0x01 /* Carry flag */
+#define ZF 0x02 /* Zero flag */
+#define IF 0x04 /* Interrupt flag */
+#define DF 0x08 /* Decimal flag */
+#define BF 0x10 /* Break flag */
+#define OF 0x40 /* Overflow flag */
+#define SF 0x80 /* Sign flag */
+
+/* */
+int CPUHalted;
+
+
+
+/*****************************************************************************/
+/* Helper functions and macros */
+/*****************************************************************************/
+
+
+
+/* Set flags */
+#define SET_CF() (SR |= CF)
+#define SET_ZF() (SR |= ZF)
+#define SET_IF() (SR |= IF)
+#define SET_DF() (SR |= DF)
+#define SET_BF() (SR |= BF)
+#define SET_OF() (SR |= OF)
+#define SET_SF() (SR |= SF)
+
+/* Reset flags */
+#define CLR_CF() (SR &= ~CF)
+#define CLR_ZF() (SR &= ~ZF)
+#define CLR_IF() (SR &= ~IF)
+#define CLR_DF() (SR &= ~DF)
+#define CLR_BF() (SR &= ~BF)
+#define CLR_OF() (SR &= ~OF)
+#define CLR_SF() (SR &= ~SF)
+
+/* Test for the flags */
+#define CF_IS_SET() (SR & CF)
+#define ZF_IS_SET() (SR & ZF)
+#define IF_IS_SET() (SR & IF)
+#define DF_IS_SET() (SR & DF)
+#define BF_IS_SET() (SR & BF)
+#define OF_IS_SET() (SR & OF)
+#define SF_IS_SET() (SR & SF)
+
+/* Set the flags according to a given value */
+#define TEST_ZF(v) do { if ((v) == 0) { SET_ZF(); } else { CLR_ZF(); } } while (0)
+#define TEST_SF(v) do { if ((v) & 0x80) { SET_SF(); } else { CLR_SF(); } } while (0)
+#define TEST_CF(v) do { if (v) { SET_CF (); } else { CLR_CF (); } } while (0)
+
+/* Program counter halves */
+#define PCL (PC & 0xFF)
+#define PCH ((PC >> 8) & 0xFF)
+
+/* Stack operations */
+#define PUSH(Val) WriteMem (StackPage + SP--, Val)
+#define POP() ReadMem (StackPage + ++SP)
+
+/* Test for page cross */
+#define PAGE_CROSS(addr,offs) ((((addr) & 0xFF) + offs) >= 0x100)
+
+/* #imm */
+#define AC_OP_IMM(op) \
+ Cycles = 2; \
+ AC = AC op ReadMem (PC+1); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 2
+
+/* zp */
+#define AC_OP_ZP(op) \
+ Cycles = 3; \
+ AC = AC op ReadMem (ReadMem (PC+1)); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 2
+
+/* zp,x */
+#define AC_OP_ZPX(op) \
+ unsigned char ZPAddr; \
+ Cycles = 4; \
+ ZPAddr = ReadMem (PC+1) + XR; \
+ AC = AC op ReadMem (ZPAddr); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 2
+
+/* zp,y */
+#define AC_OP_ZPY(op) \
+ unsigned char ZPAddr; \
+ Cycles = 4; \
+ ZPAddr = ReadMem (PC+1) + YR; \
+ AC = AC op ReadMem (ZPAddr); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 2
+
+/* abs */
+#define AC_OP_ABS(op) \
+ unsigned Addr; \
+ Cycles = 4; \
+ Addr = ReadMemW (PC+1); \
+ AC = AC op ReadMem (Addr); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 3
+
+/* abs,x */
+#define AC_OP_ABSX(op) \
+ unsigned Addr; \
+ Cycles = 4; \
+ Addr = ReadMemW (PC+1); \
+ if (PAGE_CROSS (Addr, XR)) { \
+ ++Cycles; \
+ } \
+ AC = AC | ReadMem (Addr + XR); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 3
+
+/* abs,y */
+#define AC_OP_ABSY(op) \
+ unsigned Addr; \
+ Cycles = 4; \
+ Addr = ReadMemW (PC+1); \
+ if (PAGE_CROSS (Addr, YR)) { \
+ ++Cycles; \
+ } \
+ AC = AC | ReadMem (Addr + YR); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 3
+
+/* (zp,x) */
+#define AC_OP_ZPXIND(op) \
+ unsigned char ZPAddr; \
+ unsigned Addr; \
+ Cycles = 6; \
+ ZPAddr = ReadMem (PC+1) + XR; \
+ Addr = ReadZeroPageW (ZPAddr); \
+ AC = AC op ReadMem (Addr); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 2
+
+/* (zp),y */
+#define AC_OP_ZPINDY(op) \
+ unsigned char ZPAddr; \
+ unsigned Addr; \
+ Cycles = 5; \
+ ZPAddr = ReadMem (PC+1); \
+ Addr = ReadZeroPageW (ZPAddr) + YR; \
+ AC = AC op ReadMem (Addr); \
+ TEST_ZF (AC); \
+ TEST_SF (AC); \
+ PC += 2
+
+/* branches */
+#define BRANCH(cond) \
+ Cycles = 2; \
+ if (cond) { \
+ signed char Offs; \
+ unsigned char OldPCH; \
+ ++Cycles; \
+ Offs = (signed char) ReadMem (PC+1); \
+ OldPCH = PCH; \
+ PC += (int) Offs; \
+ if (PCH != OldPCH) { \
+ ++Cycles; \
+ } \
+ } else { \
+ PC += 2; \
+ }
+
+/* compares */
+#define CMP(v1,v2) \
+ { \
+ unsigned Result = v1 - v2; \
+ TEST_ZF (Result & 0xFF); \
+ TEST_SF (Result); \
+ TEST_CF (Result <= 0xFF); \
+ }
+
+
+
+/*****************************************************************************/
+/* Helper functions */
+/*****************************************************************************/
+
+
+
+static void Illegal (void)
+{
+ fprintf (stderr, "Illegal: $%02X\n", ReadMem (PC));
+ exit (EXIT_FAILURE);
+}
+
+
+
+static void NotImplemented (void)
+{
+ fprintf (stderr, "Not implemented: $%02X\n", ReadMem (PC));
+ exit (EXIT_FAILURE);
+}
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+static void OPC_6502_00 (void)
+/* Opcode $00: BRK */
+{
+ Cycles = 7;
+ PC += 2;
+ SET_BF ();
+ PUSH (PCH);
+ PUSH (PCL);
+ PUSH (SR);
+ SET_IF ();
+ PC = ReadMemW (0xFFFE);
+}
+
+
+
+static void OPC_6502_01 (void)
+/* Opcode $01: ORA (ind,x) */
+{
+ AC_OP_ZPXIND (|);
+}
+
+
+
+static void OPC_6502_02 (void)
+/* Opcode $02 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_03 (void)
+/* Opcode $03 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_04 (void)
+/* Opcode $04 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_05 (void)
+/* Opcode $05: ORA zp */
+{
+ AC_OP_ZP (|);
+}
+
+
+
+static void OPC_6502_06 (void)
+/* Opcode $06: ASL zp */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_07 (void)
+/* Opcode $07 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_08 (void)
+/* Opcode $08: PHP */
+{
+ Cycles = 3;
+ PUSH (SR & ~BF);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_09 (void)
+/* Opcode $09: ORA #imm */
+{
+ AC_OP_IMM (|);
+}
+
+
+
+static void OPC_6502_0A (void)
+/* Opcode $0A: ASL a */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_0B (void)
+/* Opcode $0B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_0C (void)
+/* Opcode $0C */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_0D (void)
+/* Opcode $0D: ORA abs */
+{
+ AC_OP_ABS (|);
+}
+
+
+
+static void OPC_6502_0E (void)
+/* Opcode $0E: ALS abs */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_0F (void)
+/* Opcode $0F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_10 (void)
+/* Opcode $10: BPL */
+{
+ BRANCH (!SF_IS_SET ());
+}
+
+
+
+static void OPC_6502_11 (void)
+/* Opcode $11: ORA (zp),y */
+{
+ AC_OP_ZPINDY (|);
+}
+
+
+
+static void OPC_6502_12 (void)
+/* Opcode $12 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_13 (void)
+/* Opcode $13 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_14 (void)
+/* Opcode $14 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_15 (void)
+/* Opcode $15: ORA zp,x */
+{
+ AC_OP_ZPX (|);
+}
+
+
+
+static void OPC_6502_16 (void)
+/* Opcode $16: ASL zp,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_17 (void)
+/* Opcode $17 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_18 (void)
+/* Opcode $18: CLC */
+{
+ Cycles = 2;
+ CLR_CF ();
+ PC += 1;
+}
+
+
+
+static void OPC_6502_19 (void)
+/* Opcode $19: ORA abs,y */
+{
+ AC_OP_ABSY (|);
+}
+
+
+
+static void OPC_6502_1A (void)
+/* Opcode $1A */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_1B (void)
+/* Opcode $1B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_1C (void)
+/* Opcode $1C */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_1D (void)
+/* Opcode $1D: ORA abs,x */
+{
+ AC_OP_ABSX (|);
+}
+
+
+
+static void OPC_6502_1E (void)
+/* Opcode $1E: ASL abs,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_1F (void)
+/* Opcode $1F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_20 (void)
+/* Opcode $20: JSR */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_21 (void)
+/* Opcode $21: AND (zp,x) */
+{
+ AC_OP_ZPXIND (&);
+}
+
+
+
+static void OPC_6502_22 (void)
+/* Opcode $22 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_23 (void)
+/* Opcode $23 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_24 (void)
+/* Opcode $24: BIT zp */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_25 (void)
+/* Opcode $25: AND zp */
+{
+ AC_OP_ZP (&);
+}
+
+
+
+static void OPC_6502_26 (void)
+/* Opcode $26: ROL zp */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_27 (void)
+/* Opcode $27 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_28 (void)
+/* Opcode $28: PLP */
+{
+ Cycles = 4;
+ SR = (POP () & ~BF);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_29 (void)
+/* Opcode $29: AND #imm */
+{
+ AC_OP_IMM (&);
+}
+
+
+
+static void OPC_6502_2A (void)
+/* Opcode $2A: ROL a */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_2B (void)
+/* Opcode $2B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_2C (void)
+/* Opcode $2C: BIT abs */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_2D (void)
+/* Opcode $2D: AND abs */
+{
+ AC_OP_ABS (&);
+}
+
+
+
+static void OPC_6502_2E (void)
+/* Opcode $2E: ROL abs */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_2F (void)
+/* Opcode $2F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_30 (void)
+/* Opcode $30: BMI */
+{
+ BRANCH (SF_IS_SET ());
+}
+
+
+
+static void OPC_6502_31 (void)
+/* Opcode $31: AND (zp),y */
+{
+ AC_OP_ZPINDY (&);
+}
+
+
+
+static void OPC_6502_32 (void)
+/* Opcode $32 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_33 (void)
+/* Opcode $33 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_34 (void)
+/* Opcode $34 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_35 (void)
+/* Opcode $35: AND zp,x */
+{
+ AC_OP_ZPX (&);
+}
+
+
+
+static void OPC_6502_36 (void)
+/* Opcode $36: ROL zp,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_37 (void)
+/* Opcode $37 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_38 (void)
+/* Opcode $38: SEC */
+{
+ Cycles = 2;
+ SET_CF ();
+ PC += 1;
+}
+
+
+
+static void OPC_6502_39 (void)
+/* Opcode $39: AND abs,y */
+{
+ AC_OP_ABSY (&);
+}
+
+
+
+static void OPC_6502_3A (void)
+/* Opcode $3A */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_3B (void)
+/* Opcode $3B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_3C (void)
+/* Opcode $3C */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_3D (void)
+/* Opcode $3D: AND abs,x */
+{
+ AC_OP_ABSX (&);
+}
+
+
+
+static void OPC_6502_3E (void)
+/* Opcode $3E: ROL abs,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_3F (void)
+/* Opcode $3F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_40 (void)
+/* Opcode $40: RTI */
+{
+ Cycles = 6;
+ SR = POP ();
+ PC = POP (); /* PCL */
+ PC |= (POP () << 8); /* PCH */
+}
+
+
+
+static void OPC_6502_41 (void)
+/* Opcode $41: EOR (zp,x) */
+{
+ AC_OP_ZPXIND (^);
+}
+
+
+
+static void OPC_6502_42 (void)
+/* Opcode $42 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_43 (void)
+/* Opcode $43 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_44 (void)
+/* Opcode $44 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_45 (void)
+/* Opcode $45: EOR zp */
+{
+ AC_OP_ZP (^);
+}
+
+
+
+static void OPC_6502_46 (void)
+/* Opcode $46: LSR zp */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_47 (void)
+/* Opcode $47 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_48 (void)
+/* Opcode $48: PHA */
+{
+ Cycles = 3;
+ PUSH (AC);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_49 (void)
+/* Opcode $49: EOR #imm */
+{
+ AC_OP_IMM (^);
+}
+
+
+
+static void OPC_6502_4A (void)
+/* Opcode $4A: LSR a */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_4B (void)
+/* Opcode $4B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_4C (void)
+/* Opcode $4C: JMP abs */
+{
+ Cycles = 3;
+ PC = ReadMemW (PC+1);
+}
+
+
+
+static void OPC_6502_4D (void)
+/* Opcode $4D: EOR abs */
+{
+ AC_OP_ABS (^);
+}
+
+
+
+static void OPC_6502_4E (void)
+/* Opcode $4E: LSR abs */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_4F (void)
+/* Opcode $4F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_50 (void)
+/* Opcode $50: BVC */
+{
+ BRANCH (!OF_IS_SET());
+}
+
+
+
+static void OPC_6502_51 (void)
+/* Opcode $51: EOR (zp),y */
+{
+ AC_OP_ZPINDY (^);
+}
+
+
+
+static void OPC_6502_52 (void)
+/* Opcode $52 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_53 (void)
+/* Opcode $53 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_54 (void)
+/* Opcode $54 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_55 (void)
+/* Opcode $55: EOR zp,x */
+{
+ AC_OP_ZPX (^);
+}
+
+
+
+static void OPC_6502_56 (void)
+/* Opcode $56: LSR zp,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_57 (void)
+/* Opcode $57 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_58 (void)
+/* Opcode $58: CLI */
+{
+ Cycles = 2;
+ CLR_IF ();
+ PC += 1;
+}
+
+
+
+static void OPC_6502_59 (void)
+/* Opcode $59: EOR abs,y */
+{
+ AC_OP_ABSY (^);
+}
+
+
+
+static void OPC_6502_5A (void)
+/* Opcode $5A */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_5B (void)
+/* Opcode $5B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_5C (void)
+/* Opcode $5C */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_5D (void)
+/* Opcode $5D: EOR abs,x */
+{
+ AC_OP_ABSX (^);
+}
+
+
+
+static void OPC_6502_5E (void)
+/* Opcode $5E: LSR abs,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_5F (void)
+/* Opcode $5F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_60 (void)
+/* Opcode $60: RTS */
+{
+ Cycles = 6;
+ PC = POP (); /* PCL */
+ PC |= (POP () << 8); /* PCH */
+ PC += 1;
+}
+
+
+
+static void OPC_6502_61 (void)
+/* Opcode $61: ADC (zp,x) */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_62 (void)
+/* Opcode $62 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_63 (void)
+/* Opcode $63 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_64 (void)
+/* Opcode $64 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_65 (void)
+/* Opcode $65: ADC zp */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_66 (void)
+/* Opcode $66: ROR zp */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_67 (void)
+/* Opcode $67 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_68 (void)
+/* Opcode $68: PLA */
+{
+ Cycles = 4;
+ AC = POP ();
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_69 (void)
+/* Opcode $69: ADC #imm */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_6A (void)
+/* Opcode $6A: ROR a */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_6B (void)
+/* Opcode $6B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_6C (void)
+/* Opcode $6C: JMP (ind) */
+{
+ unsigned Addr;
+ Cycles = 5;
+ Addr = ReadMemW (PC+1);
+ if (CPU == CPU_6502) {
+ /* Emulate the 6502 bug */
+ PC = ReadMem (Addr);
+ Addr = (Addr & 0xFF00) | ((Addr + 1) & 0xFF);
+ PC |= (ReadMem (Addr) << 8);
+ } else {
+ /* 65C02 and above have this bug fixed */
+ PC = ReadMemW (Addr);
+ }
+ PC += 3;
+}
+
+
+
+static void OPC_6502_6D (void)
+/* Opcode $6D: ADC abs */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_6E (void)
+/* Opcode $6E: ROR abs */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_6F (void)
+/* Opcode $6F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_70 (void)
+/* Opcode $70: BVS */
+{
+ BRANCH (OF_IS_SET ());
+}
+
+
+
+static void OPC_6502_71 (void)
+/* Opcode $71: ADC (zp),y */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_72 (void)
+/* Opcode $72 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_73 (void)
+/* Opcode $73 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_74 (void)
+/* Opcode $74 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_75 (void)
+/* Opcode $75: ADC zp,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_76 (void)
+/* Opcode $76: ROR zp,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_77 (void)
+/* Opcode $77 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_78 (void)
+/* Opcode $78: SEI */
+{
+ Cycles = 2;
+ SET_IF ();
+ PC += 1;
+}
+
+
+
+static void OPC_6502_79 (void)
+/* Opcode $79: ADC abs,y */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_7A (void)
+/* Opcode $7A */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_7B (void)
+/* Opcode $7B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_7C (void)
+/* Opcode $7C */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_7D (void)
+/* Opcode $7D: ADC abs,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_7E (void)
+/* Opcode $7E: ROR abs,x */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_7F (void)
+/* Opcode $7F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_80 (void)
+/* Opcode $80 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_81 (void)
+/* Opcode $81: STA (zp,x) */
+{
+ NotImplemented ();
+}
+
+
+
+static void OPC_6502_82 (void)
+/* Opcode $82 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_83 (void)
+/* Opcode $83 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_84 (void)
+/* Opcode $84: STY zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ WriteMem (ZPAddr, YR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_85 (void)
+/* Opcode $85: STA zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ WriteMem (ZPAddr, AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_86 (void)
+/* Opcode $86: STX zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ WriteMem (ZPAddr, XR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_87 (void)
+/* Opcode $87 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_88 (void)
+/* Opcode $88: DEY */
+{
+ Cycles = 2;
+ --YR;
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_89 (void)
+/* Opcode $89 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_8A (void)
+/* Opcode $8A: TXA */
+{
+ Cycles = 2;
+ AC = XR;
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_8B (void)
+/* Opcode $8B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_8C (void)
+/* Opcode $8C: STY abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ WriteMem (Addr, YR);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_8D (void)
+/* Opcode $8D: STA abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ WriteMem (Addr, AC);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_8E (void)
+/* Opcode $8E: STX abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ WriteMem (Addr, XR);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_8F (void)
+/* Opcode $8F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_90 (void)
+/* Opcode $90: BCC */
+{
+ BRANCH (!CF_IS_SET ());
+}
+
+
+
+static void OPC_6502_91 (void)
+/* Opcode $91: sta (zp),y */
+{
+ unsigned char ZPAddr;
+ unsigned Addr;
+ Cycles = 6;
+ ZPAddr = ReadMem (PC+1);
+ Addr = ReadZeroPageW (ZPAddr) + YR;
+ WriteMem (Addr, AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_92 (void)
+/* Opcode $92 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_93 (void)
+/* Opcode $93 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_94 (void)
+/* Opcode $94: STY zp,x */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + XR;
+ WriteMem (ZPAddr, YR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_95 (void)
+/* Opcode $95: STA zp,x */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + XR;
+ WriteMem (ZPAddr, AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_96 (void)
+/* Opcode $96: stx zp,y */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + YR;
+ WriteMem (ZPAddr, XR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_97 (void)
+/* Opcode $97 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_98 (void)
+/* Opcode $98: TYA */
+{
+ Cycles = 2;
+ AC = YR;
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_99 (void)
+/* Opcode $99: STA abs,y */
+{
+ unsigned Addr;
+ Cycles = 5;
+ Addr = ReadMemW (PC+1) + YR;
+ WriteMem (Addr, AC);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_9A (void)
+/* Opcode $9A: TXS */
+{
+ Cycles = 2;
+ SP = XR;
+ PC += 1;
+}
+
+
+
+static void OPC_6502_9B (void)
+/* Opcode $9B */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_9C (void)
+/* Opcode $9C */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_9D (void)
+/* Opcode $9D: STA abs,x */
+{
+ unsigned Addr;
+ Cycles = 5;
+ Addr = ReadMemW (PC+1) + XR;
+ WriteMem (Addr, AC);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_9E (void)
+/* Opcode $9E */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_9F (void)
+/* Opcode $9F */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_A0 (void)
+/* Opcode $A0: LDY #imm */
+{
+ Cycles = 2;
+ YR = ReadMem (PC+1);
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_A1 (void)
+/* Opcode $A1: LDA (zp,x) */
+{
+ unsigned char ZPAddr;
+ unsigned Addr;
+ Cycles = 6;
+ ZPAddr = ReadMem (PC+1) + XR;
+ Addr = ReadZeroPageW (ZPAddr);
+ AC = ReadMem (Addr);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_A2 (void)
+/* Opcode $A2: LDX #imm */
+{
+ Cycles = 2;
+ XR = ReadMem (PC+1);
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_A3 (void)
+/* Opcode $A3 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_A4 (void)
+/* Opcode $A4: LDY zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ YR = ReadMem (ZPAddr);
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_A5 (void)
+/* Opcode $A5: LDA zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ AC = ReadMem (ZPAddr);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_A6 (void)
+/* Opcode $A6: LDX zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ XR = ReadMem (ZPAddr);
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_A7 (void)
+/* Opcode $A7 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_A8 (void)
+/* Opcode $A8: TAY */
+{
+ Cycles = 2;
+ YR = AC;
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_A9 (void)
+/* Opcode $A9: LDA #imm */
+{
+ Cycles = 2;
+ AC = ReadMem (PC+1);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_AA (void)
+/* Opcode $AA: TAX */
+{
+ Cycles = 2;
+ XR = AC;
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_AB (void)
+/* Opcode $AB */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_AC (void)
+/* Opcode $AC: LDY abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ YR = ReadMem (Addr);
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_AD (void)
+/* Opcode $AD: LDA abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ AC = ReadMem (Addr);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_AE (void)
+/* Opcode $AE: LDX abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ XR = ReadMem (Addr);
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_AF (void)
+/* Opcode $AF */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_B0 (void)
+/* Opcode $B0: BCS */
+{
+ BRANCH (CF_IS_SET ());
+}
+
+
+
+static void OPC_6502_B1 (void)
+/* Opcode $B1: LDA (zp),y */
+{
+ unsigned char ZPAddr;
+ unsigned Addr;
+ Cycles = 5;
+ ZPAddr = ReadMem (PC+1);
+ Addr = ReadZeroPageW (ZPAddr);
+ if (PAGE_CROSS (Addr, YR)) {
+ ++Cycles;
+ }
+ AC = ReadMem (Addr + YR);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_B2 (void)
+/* Opcode $B2 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_B3 (void)
+/* Opcode $B3 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_B4 (void)
+/* Opcode $B4: LDY zp,x */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + XR;
+ YR = ReadMem (ZPAddr);
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_B5 (void)
+/* Opcode $B5: LDA zp,x */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + XR;
+ AC = ReadMem (ZPAddr);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_B6 (void)
+/* Opcode $B6: LDX zp,y */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + YR;
+ XR = ReadMem (ZPAddr);
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_B7 (void)
+/* Opcode $B7 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_B8 (void)
+/* Opcode $B8: CLV */
+{
+ Cycles = 2;
+ CLR_OF ();
+ PC += 1;
+}
+
+
+
+static void OPC_6502_B9 (void)
+/* Opcode $B9: LDA abs,y */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ if (PAGE_CROSS (Addr, YR)) {
+ ++Cycles;
+ }
+ AC = ReadMem (Addr + YR);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_BA (void)
+/* Opcode $BA: TSX */
+{
+ Cycles = 2;
+ XR = SP;
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_BB (void)
+/* Opcode $BB */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_BC (void)
+/* Opcode $BC: LDY abs,x */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ if (PAGE_CROSS (Addr, XR)) {
+ ++Cycles;
+ }
+ YR = ReadMem (Addr + XR);
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_BD (void)
+/* Opcode $BD: LDA abs,x */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ if (PAGE_CROSS (Addr, XR)) {
+ ++Cycles;
+ }
+ AC = ReadMem (Addr + XR);
+ TEST_ZF (AC);
+ TEST_SF (AC);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_BE (void)
+/* Opcode $BE: LDX abs,y */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ if (PAGE_CROSS (Addr, YR)) {
+ ++Cycles;
+ }
+ XR = ReadMem (Addr + YR);
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_BF (void)
+/* Opcode $BF */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_C0 (void)
+/* Opcode $C0: CPY #imm */
+{
+ Cycles = 2;
+ CMP (YR, ReadMem (PC+1));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_C1 (void)
+/* Opcode $C1: CMP (zp,x) */
+{
+ unsigned char ZPAddr;
+ unsigned Addr;
+ Cycles = 6;
+ ZPAddr = ReadMem (PC+1) + XR;
+ Addr = ReadZeroPageW (ZPAddr);
+ CMP (AC, ReadMem (Addr));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_C2 (void)
+/* Opcode $C2 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_C3 (void)
+/* Opcode $C3 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_C4 (void)
+/* Opcode $C4: CPY zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ CMP (YR, ReadMem (ZPAddr));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_C5 (void)
+/* Opcode $C5: CMP zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ CMP (AC, ReadMem (ZPAddr));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_C6 (void)
+/* Opcode $C6: DEC zp */
+{
+ unsigned char ZPAddr;
+ unsigned char Val;
+ Cycles = 5;
+ ZPAddr = ReadMem (PC+1);
+ Val = ReadMem (ZPAddr) - 1;
+ WriteMem (ZPAddr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_C7 (void)
+/* Opcode $C7 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_C8 (void)
+/* Opcode $C8: INY */
+{
+ Cycles = 2;
+ ++YR;
+ TEST_ZF (YR);
+ TEST_SF (YR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_C9 (void)
+/* Opcode $C9: CMP #imm */
+{
+ Cycles = 2;
+ CMP (AC, ReadMem (PC+1));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_CA (void)
+/* Opcode $CA: DEX */
+{
+ Cycles = 2;
+ --XR;
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_CB (void)
+/* Opcode $CB */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_CC (void)
+/* Opcode $CC: CPY abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ CMP (YR, ReadMem (Addr));
+ PC += 3;
+}
+
+
+
+static void OPC_6502_CD (void)
+/* Opcode $CD: CMP abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ CMP (AC, ReadMem (Addr));
+ PC += 3;
+}
+
+
+
+static void OPC_6502_CE (void)
+/* Opcode $CE: DEC abs */
+{
+ unsigned Addr;
+ unsigned char Val;
+ Cycles = 6;
+ Addr = ReadMemW (PC+1);
+ Val = ReadMem (Addr) - 1;
+ WriteMem (Addr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_CF (void)
+/* Opcode $CF */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_D0 (void)
+/* Opcode $D0: BNE */
+{
+ BRANCH (!ZF_IS_SET ());
+}
+
+
+
+static void OPC_6502_D1 (void)
+/* Opcode $D1: CMP (zp),y */
+{
+ unsigned ZPAddr;
+ unsigned Addr;
+ Cycles = 5;
+ ZPAddr = ReadMem (PC+1);
+ Addr = ReadMemW (ZPAddr);
+ if (PAGE_CROSS (Addr, YR)) {
+ ++Cycles;
+ }
+ CMP (AC, ReadMem (Addr + YR));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_D2 (void)
+/* Opcode $D2 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_D3 (void)
+/* Opcode $D3 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_D4 (void)
+/* Opcode $D4 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_D5 (void)
+/* Opcode $D5: CMP zp,x */
+{
+ unsigned char ZPAddr;
+ Cycles = 4;
+ ZPAddr = ReadMem (PC+1) + XR;
+ CMP (AC, ReadMem (ZPAddr));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_D6 (void)
+/* Opcode $D6: DEC zp,x */
+{
+ unsigned char ZPAddr;
+ unsigned char Val;
+ Cycles = 6;
+ ZPAddr = ReadMem (PC+1) + XR;
+ Val = ReadMem (ZPAddr) - 1;
+ WriteMem (ZPAddr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_D7 (void)
+/* Opcode $D7 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_D8 (void)
+/* Opcode $D8: CLD */
+{
+ CLR_DF ();
+}
+
+
+
+static void OPC_6502_D9 (void)
+/* Opcode $D9: CMP abs,y */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ if (PAGE_CROSS (Addr, YR)) {
+ ++Cycles;
+ }
+ CMP (AC, ReadMem (Addr + YR));
+ PC += 3;
+}
+
+
+
+static void OPC_6502_DA (void)
+/* Opcode $DA */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_DB (void)
+/* Opcode $DB */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_DC (void)
+/* Opcode $DC */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_DD (void)
+/* Opcode $DD: CMP abs,x */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ if (PAGE_CROSS (Addr, XR)) {
+ ++Cycles;
+ }
+ CMP (AC, ReadMem (Addr + XR));
+ PC += 3;
+}
+
+
+
+static void OPC_6502_DE (void)
+/* Opcode $DE: DEC abs,x */
+{
+ unsigned Addr;
+ unsigned char Val;
+ Cycles = 7;
+ Addr = ReadMemW (PC+1) + XR;
+ Val = ReadMem (Addr) - 1;
+ WriteMem (Addr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_DF (void)
+/* Opcode $DF */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_E0 (void)
+/* Opcode $E0: CPX #imm */
+{
+ Cycles = 2;
+ CMP (XR, ReadMem (PC+1));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_E1 (void)
+/* Opcode $E1 */
+{
+}
+
+
+
+static void OPC_6502_E2 (void)
+/* Opcode $E2 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_E3 (void)
+/* Opcode $E3 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_E4 (void)
+/* Opcode $E4: CPX zp */
+{
+ unsigned char ZPAddr;
+ Cycles = 3;
+ ZPAddr = ReadMem (PC+1);
+ CMP (XR, ReadMem (ZPAddr));
+ PC += 2;
+}
+
+
+
+static void OPC_6502_E5 (void)
+/* Opcode $E5 */
+{
+}
+
+
+
+static void OPC_6502_E6 (void)
+/* Opcode $E6: INC zp */
+{
+ unsigned char ZPAddr;
+ unsigned char Val;
+ Cycles = 5;
+ ZPAddr = ReadMem (PC+1);
+ Val = ReadMem (ZPAddr) + 1;
+ WriteMem (ZPAddr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_E7 (void)
+/* Opcode $E7 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_E8 (void)
+/* Opcode $E8: INX */
+{
+ Cycles = 2;
+ ++XR;
+ TEST_ZF (XR);
+ TEST_SF (XR);
+ PC += 1;
+}
+
+
+
+static void OPC_6502_E9 (void)
+/* Opcode $E9 */
+{
+}
+
+
+
+static void OPC_6502_EA (void)
+/* Opcode $EA: NOP */
+{
+ /* This one is easy... */
+ Cycles = 2;
+ PC += 1;
+}
+
+
+
+static void OPC_6502_EB (void)
+/* Opcode $EB */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_EC (void)
+/* Opcode $EC: CPX abs */
+{
+ unsigned Addr;
+ Cycles = 4;
+ Addr = ReadMemW (PC+1);
+ CMP (XR, ReadMem (Addr));
+ PC += 3;
+}
+
+
+
+static void OPC_6502_ED (void)
+/* Opcode $ED */
+{
+}
+
+
+
+static void OPC_6502_EE (void)
+/* Opcode $EE: INC abs */
+{
+ unsigned Addr;
+ unsigned char Val;
+ Cycles = 6;
+ Addr = ReadMemW (PC+1);
+ Val = ReadMem (Addr) + 1;
+ WriteMem (Addr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_EF (void)
+/* Opcode $EF */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_F0 (void)
+/* Opcode $F0: BEQ */
+{
+ BRANCH (ZF_IS_SET ());
+}
+
+
+
+static void OPC_6502_F1 (void)
+/* Opcode $F1 */
+{
+}
+
+
+
+static void OPC_6502_F2 (void)
+/* Opcode $F2 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_F3 (void)
+/* Opcode $F3 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_F4 (void)
+/* Opcode $F4 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_F5 (void)
+/* Opcode $F5 */
+{
+}
+
+
+
+static void OPC_6502_F6 (void)
+/* Opcode $F6: INC zp,x */
+{
+ unsigned char ZPAddr;
+ unsigned char Val;
+ Cycles = 6;
+ ZPAddr = ReadMem (PC+1) + XR;
+ Val = ReadMem (ZPAddr) + 1;
+ WriteMem (ZPAddr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 2;
+}
+
+
+
+static void OPC_6502_F7 (void)
+/* Opcode $F7 */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_F8 (void)
+/* Opcode $F8: SED */
+{
+ SET_DF ();
+}
+
+
+
+static void OPC_6502_F9 (void)
+/* Opcode $F9 */
+{
+}
+
+
+
+static void OPC_6502_FA (void)
+/* Opcode $FA */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_FB (void)
+/* Opcode $FB */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_FC (void)
+/* Opcode $FC */
+{
+ Illegal ();
+}
+
+
+
+static void OPC_6502_FD (void)
+/* Opcode $FD */
+{
+}
+
+
+
+static void OPC_6502_FE (void)
+/* Opcode $FE: INC abs,x */
+{
+ unsigned Addr;
+ unsigned char Val;
+ Cycles = 7;
+ Addr = ReadMemW (PC+1) + XR;
+ Val = ReadMem (Addr) + 1;
+ WriteMem (Addr, Val);
+ TEST_ZF (Val);
+ TEST_SF (Val);
+ PC += 3;
+}
+
+
+
+static void OPC_6502_FF (void)
+/* Opcode $FF */
+{
+ Illegal ();
+}
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Opcode handler table */
+typedef void (*OPCFunc) (void);
+static OPCFunc OPCTable[256] = {
+ OPC_6502_00,
+ OPC_6502_01,
+ OPC_6502_02,
+ OPC_6502_03,
+ OPC_6502_04,
+ OPC_6502_05,
+ OPC_6502_06,
+ OPC_6502_07,
+ OPC_6502_08,
+ OPC_6502_09,
+ OPC_6502_0A,
+ OPC_6502_0B,
+ OPC_6502_0C,
+ OPC_6502_0D,
+ OPC_6502_0E,
+ OPC_6502_0F,
+ OPC_6502_10,
+ OPC_6502_11,
+ OPC_6502_12,
+ OPC_6502_13,
+ OPC_6502_14,
+ OPC_6502_15,
+ OPC_6502_16,
+ OPC_6502_17,
+ OPC_6502_18,
+ OPC_6502_19,
+ OPC_6502_1A,
+ OPC_6502_1B,
+ OPC_6502_1C,
+ OPC_6502_1D,
+ OPC_6502_1E,
+ OPC_6502_1F,
+ OPC_6502_20,
+ OPC_6502_21,
+ OPC_6502_22,
+ OPC_6502_23,
+ OPC_6502_24,
+ OPC_6502_25,
+ OPC_6502_26,
+ OPC_6502_27,
+ OPC_6502_28,
+ OPC_6502_29,
+ OPC_6502_2A,
+ OPC_6502_2B,
+ OPC_6502_2C,
+ OPC_6502_2D,
+ OPC_6502_2E,
+ OPC_6502_2F,
+ OPC_6502_30,
+ OPC_6502_31,
+ OPC_6502_32,
+ OPC_6502_33,
+ OPC_6502_34,
+ OPC_6502_35,
+ OPC_6502_36,
+ OPC_6502_37,
+ OPC_6502_38,
+ OPC_6502_39,
+ OPC_6502_3A,
+ OPC_6502_3B,
+ OPC_6502_3C,
+ OPC_6502_3D,
+ OPC_6502_3E,
+ OPC_6502_3F,
+ OPC_6502_40,
+ OPC_6502_41,
+ OPC_6502_42,
+ OPC_6502_43,
+ OPC_6502_44,
+ OPC_6502_45,
+ OPC_6502_46,
+ OPC_6502_47,
+ OPC_6502_48,
+ OPC_6502_49,
+ OPC_6502_4A,
+ OPC_6502_4B,
+ OPC_6502_4C,
+ OPC_6502_4D,
+ OPC_6502_4E,
+ OPC_6502_4F,
+ OPC_6502_50,
+ OPC_6502_51,
+ OPC_6502_52,
+ OPC_6502_53,
+ OPC_6502_54,
+ OPC_6502_55,
+ OPC_6502_56,
+ OPC_6502_57,
+ OPC_6502_58,
+ OPC_6502_59,
+ OPC_6502_5A,
+ OPC_6502_5B,
+ OPC_6502_5C,
+ OPC_6502_5D,
+ OPC_6502_5E,
+ OPC_6502_5F,
+ OPC_6502_60,
+ OPC_6502_61,
+ OPC_6502_62,
+ OPC_6502_63,
+ OPC_6502_64,
+ OPC_6502_65,
+ OPC_6502_66,
+ OPC_6502_67,
+ OPC_6502_68,
+ OPC_6502_69,
+ OPC_6502_6A,
+ OPC_6502_6B,
+ OPC_6502_6C,
+ OPC_6502_6D,
+ OPC_6502_6E,
+ OPC_6502_6F,
+ OPC_6502_70,
+ OPC_6502_71,
+ OPC_6502_72,
+ OPC_6502_73,
+ OPC_6502_74,
+ OPC_6502_75,
+ OPC_6502_76,
+ OPC_6502_77,
+ OPC_6502_78,
+ OPC_6502_79,
+ OPC_6502_7A,
+ OPC_6502_7B,
+ OPC_6502_7C,
+ OPC_6502_7D,
+ OPC_6502_7E,
+ OPC_6502_7F,
+ OPC_6502_80,
+ OPC_6502_81,
+ OPC_6502_82,
+ OPC_6502_83,
+ OPC_6502_84,
+ OPC_6502_85,
+ OPC_6502_86,
+ OPC_6502_87,
+ OPC_6502_88,
+ OPC_6502_89,
+ OPC_6502_8A,
+ OPC_6502_8B,
+ OPC_6502_8C,
+ OPC_6502_8D,
+ OPC_6502_8E,
+ OPC_6502_8F,
+ OPC_6502_90,
+ OPC_6502_91,
+ OPC_6502_92,
+ OPC_6502_93,
+ OPC_6502_94,
+ OPC_6502_95,
+ OPC_6502_96,
+ OPC_6502_97,
+ OPC_6502_98,
+ OPC_6502_99,
+ OPC_6502_9A,
+ OPC_6502_9B,
+ OPC_6502_9C,
+ OPC_6502_9D,
+ OPC_6502_9E,
+ OPC_6502_9F,
+ OPC_6502_A0,
+ OPC_6502_A1,
+ OPC_6502_A2,
+ OPC_6502_A3,
+ OPC_6502_A4,
+ OPC_6502_A5,
+ OPC_6502_A6,
+ OPC_6502_A7,
+ OPC_6502_A8,
+ OPC_6502_A9,
+ OPC_6502_AA,
+ OPC_6502_AB,
+ OPC_6502_AC,
+ OPC_6502_AD,
+ OPC_6502_AE,
+ OPC_6502_AF,
+ OPC_6502_B0,
+ OPC_6502_B1,
+ OPC_6502_B2,
+ OPC_6502_B3,
+ OPC_6502_B4,
+ OPC_6502_B5,
+ OPC_6502_B6,
+ OPC_6502_B7,
+ OPC_6502_B8,
+ OPC_6502_B9,
+ OPC_6502_BA,
+ OPC_6502_BB,
+ OPC_6502_BC,
+ OPC_6502_BD,
+ OPC_6502_BE,
+ OPC_6502_BF,
+ OPC_6502_C0,
+ OPC_6502_C1,
+ OPC_6502_C2,
+ OPC_6502_C3,
+ OPC_6502_C4,
+ OPC_6502_C5,
+ OPC_6502_C6,
+ OPC_6502_C7,
+ OPC_6502_C8,
+ OPC_6502_C9,
+ OPC_6502_CA,
+ OPC_6502_CB,
+ OPC_6502_CC,
+ OPC_6502_CD,
+ OPC_6502_CE,
+ OPC_6502_CF,
+ OPC_6502_D0,
+ OPC_6502_D1,
+ OPC_6502_D2,
+ OPC_6502_D3,
+ OPC_6502_D4,
+ OPC_6502_D5,
+ OPC_6502_D6,
+ OPC_6502_D7,
+ OPC_6502_D8,
+ OPC_6502_D9,
+ OPC_6502_DA,
+ OPC_6502_DB,
+ OPC_6502_DC,
+ OPC_6502_DD,
+ OPC_6502_DE,
+ OPC_6502_DF,
+ OPC_6502_E0,
+ OPC_6502_E1,
+ OPC_6502_E2,
+ OPC_6502_E3,
+ OPC_6502_E4,
+ OPC_6502_E5,
+ OPC_6502_E6,
+ OPC_6502_E7,
+ OPC_6502_E8,
+ OPC_6502_E9,
+ OPC_6502_EA,
+ OPC_6502_EB,
+ OPC_6502_EC,
+ OPC_6502_ED,
+ OPC_6502_EE,
+ OPC_6502_EF,
+ OPC_6502_F0,
+ OPC_6502_F1,
+ OPC_6502_F2,
+ OPC_6502_F3,
+ OPC_6502_F4,
+ OPC_6502_F5,
+ OPC_6502_F6,
+ OPC_6502_F7,
+ OPC_6502_F8,
+ OPC_6502_F9,
+ OPC_6502_FA,
+ OPC_6502_FB,
+ OPC_6502_FC,
+ OPC_6502_FD,
+ OPC_6502_FE,
+ OPC_6502_FF,
+};
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void RunCPU (void)
+/* Run the CPU */
+{
+ while (!CPUHalted) {
+
+ /* Get the next opcode */
+ unsigned char B = 0x00;
+
+ /* Execute it */
+ OPCTable[B] ();
+ }
+}
+
+
+