#include "xsprintf.h"
/* sim65 */
+#include "cpuregs.h"
#include "cputype.h"
#include "error.h"
#include "global.h"
/*****************************************************************************/
-/* Data */
+/* 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 */
+CPURegs Regs;
/* Count the total number of cylcles */
unsigned Cycles; /* Cycles per insn */
/* 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;
+/* CPU flags */
+int HaveNMIRequest = 0;
+int HaveIRQRequest = 0;
+int CPUHalted = 0;
/* Break message */
static char BreakMsg[1024];
/* Return the flags as a boolean value (0/1) */
-#define GET_CF() ((SR & CF) != 0)
-#define GET_ZF() ((SR & ZF) != 0)
-#define GET_IF() ((SR & IF) != 0)
-#define GET_DF() ((SR & DF) != 0)
-#define GET_BF() ((SR & BF) != 0)
-#define GET_OF() ((SR & OF) != 0)
-#define GET_SF() ((SR & SF) != 0)
+#define GET_CF() ((Regs.SR & CF) != 0)
+#define GET_ZF() ((Regs.SR & ZF) != 0)
+#define GET_IF() ((Regs.SR & IF) != 0)
+#define GET_DF() ((Regs.SR & DF) != 0)
+#define GET_BF() ((Regs.SR & BF) != 0)
+#define GET_OF() ((Regs.SR & OF) != 0)
+#define GET_SF() ((Regs.SR & SF) != 0)
/* Set the flags. The parameter is a boolean flag that says if the flag should be
* set or reset.
*/
-#define SET_CF(f) do { if (f) { SR |= CF; } else { SR &= ~CF; } } while (0)
-#define SET_ZF(f) do { if (f) { SR |= ZF; } else { SR &= ~ZF; } } while (0)
-#define SET_IF(f) do { if (f) { SR |= IF; } else { SR &= ~IF; } } while (0)
-#define SET_DF(f) do { if (f) { SR |= DF; } else { SR &= ~DF; } } while (0)
-#define SET_BF(f) do { if (f) { SR |= BF; } else { SR &= ~BF; } } while (0)
-#define SET_OF(f) do { if (f) { SR |= OF; } else { SR &= ~OF; } } while (0)
-#define SET_SF(f) do { if (f) { SR |= SF; } else { SR &= ~SF; } } while (0)
+#define SET_CF(f) do { if (f) { Regs.SR |= CF; } else { Regs.SR &= ~CF; } } while (0)
+#define SET_ZF(f) do { if (f) { Regs.SR |= ZF; } else { Regs.SR &= ~ZF; } } while (0)
+#define SET_IF(f) do { if (f) { Regs.SR |= IF; } else { Regs.SR &= ~IF; } } while (0)
+#define SET_DF(f) do { if (f) { Regs.SR |= DF; } else { Regs.SR &= ~DF; } } while (0)
+#define SET_BF(f) do { if (f) { Regs.SR |= BF; } else { Regs.SR &= ~BF; } } while (0)
+#define SET_OF(f) do { if (f) { Regs.SR |= OF; } else { Regs.SR &= ~OF; } } while (0)
+#define SET_SF(f) do { if (f) { Regs.SR |= SF; } else { Regs.SR &= ~SF; } } while (0)
/* Special test and set macros. The meaning of the parameter depends on the
* actual flag that should be set or reset.
#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0)
/* Program counter halves */
-#define PCL (PC & 0xFF)
-#define PCH ((PC >> 8) & 0xFF)
+#define PCL (Regs.PC & 0xFF)
+#define PCH ((Regs.PC >> 8) & 0xFF)
/* Stack operations */
-#define PUSH(Val) MemWriteByte (StackPage + SP--, Val)
-#define POP() MemReadByte (StackPage + ++SP)
+#define PUSH(Val) MemWriteByte (StackPage + Regs.SP--, Val)
+#define POP() MemReadByte (StackPage + ++Regs.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 MemReadByte (PC+1); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 2
+#define AC_OP_IMM(op) \
+ Cycles = 2; \
+ Regs.AC = Regs.AC op MemReadByte (Regs.PC+1); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 2
/* zp */
-#define AC_OP_ZP(op) \
- Cycles = 3; \
- AC = AC op MemReadByte (MemReadByte (PC+1));\
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 2
+#define AC_OP_ZP(op) \
+ Cycles = 3; \
+ Regs.AC = Regs.AC op MemReadByte (MemReadByte (Regs.PC+1)); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 2
/* zp,x */
-#define AC_OP_ZPX(op) \
- unsigned char ZPAddr; \
- Cycles = 4; \
- ZPAddr = MemReadByte (PC+1) + XR; \
- AC = AC op MemReadByte (ZPAddr); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 2
+#define AC_OP_ZPX(op) \
+ unsigned char ZPAddr; \
+ Cycles = 4; \
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \
+ Regs.AC = Regs.AC op MemReadByte (ZPAddr); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 2
/* zp,y */
-#define AC_OP_ZPY(op) \
- unsigned char ZPAddr; \
- Cycles = 4; \
- ZPAddr = MemReadByte (PC+1) + YR; \
- AC = AC op MemReadByte (ZPAddr); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 2
+#define AC_OP_ZPY(op) \
+ unsigned char ZPAddr; \
+ Cycles = 4; \
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR; \
+ Regs.AC = Regs.AC op MemReadByte (ZPAddr); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 2
/* abs */
-#define AC_OP_ABS(op) \
- unsigned Addr; \
- Cycles = 4; \
- Addr = MemReadWord (PC+1); \
- AC = AC op MemReadByte (Addr); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 3
+#define AC_OP_ABS(op) \
+ unsigned Addr; \
+ Cycles = 4; \
+ Addr = MemReadWord (Regs.PC+1); \
+ Regs.AC = Regs.AC op MemReadByte (Addr); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 3
/* abs,x */
-#define AC_OP_ABSX(op) \
- unsigned Addr; \
- Cycles = 4; \
- Addr = MemReadWord (PC+1); \
- if (PAGE_CROSS (Addr, XR)) { \
- ++Cycles; \
- } \
- AC = AC | MemReadByte (Addr + XR); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 3
+#define AC_OP_ABSX(op) \
+ unsigned Addr; \
+ Cycles = 4; \
+ Addr = MemReadWord (Regs.PC+1); \
+ if (PAGE_CROSS (Addr, Regs.XR)) { \
+ ++Cycles; \
+ } \
+ Regs.AC = Regs.AC op MemReadByte (Addr + Regs.XR); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 3
/* abs,y */
-#define AC_OP_ABSY(op) \
- unsigned Addr; \
- Cycles = 4; \
- Addr = MemReadWord (PC+1); \
- if (PAGE_CROSS (Addr, YR)) { \
- ++Cycles; \
- } \
- AC = AC | MemReadByte (Addr + YR); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 3
+#define AC_OP_ABSY(op) \
+ unsigned Addr; \
+ Cycles = 4; \
+ Addr = MemReadWord (Regs.PC+1); \
+ if (PAGE_CROSS (Addr, Regs.YR)) { \
+ ++Cycles; \
+ } \
+ Regs.AC = Regs.AC op MemReadByte (Addr + Regs.YR); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 3
/* (zp,x) */
-#define AC_OP_ZPXIND(op) \
- unsigned char ZPAddr; \
- unsigned Addr; \
- Cycles = 6; \
- ZPAddr = MemReadByte (PC+1) + XR; \
- Addr = MemReadZPWord (ZPAddr); \
- AC = AC op MemReadByte (Addr); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 2
+#define AC_OP_ZPXIND(op) \
+ unsigned char ZPAddr; \
+ unsigned Addr; \
+ Cycles = 6; \
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR; \
+ Addr = MemReadZPWord (ZPAddr); \
+ Regs.AC = Regs.AC op MemReadByte (Addr); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 2
/* (zp),y */
-#define AC_OP_ZPINDY(op) \
- unsigned char ZPAddr; \
- unsigned Addr; \
- Cycles = 5; \
- ZPAddr = MemReadByte (PC+1); \
- Addr = MemReadZPWord (ZPAddr) + YR; \
- AC = AC op MemReadByte (Addr); \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- PC += 2
+#define AC_OP_ZPINDY(op) \
+ unsigned char ZPAddr; \
+ unsigned Addr; \
+ Cycles = 5; \
+ ZPAddr = MemReadByte (Regs.PC+1); \
+ Addr = MemReadZPWord (ZPAddr) + Regs.YR; \
+ Regs.AC = Regs.AC op MemReadByte (Addr); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ Regs.PC += 2
/* ADC */
-#define ADC(v) \
- if (GET_DF ()) { \
- Warning ("Decimal mode not available"); \
- } else { \
- unsigned Val; \
- unsigned char rhs = v; \
- Val = AC + rhs + GET_CF (); \
- AC = (unsigned char) Val; \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- TEST_CF (Val); \
- SET_OF (!((AC ^ rhs) & 0x80) && \
- ((AC ^ Val) & 0x80)); \
+#define ADC(v) \
+ if (GET_DF ()) { \
+ Warning ("Decimal mode not available"); \
+ } else { \
+ unsigned old = Regs.AC; \
+ unsigned rhs = (v & 0xFF); \
+ Regs.AC += rhs + GET_CF (); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ TEST_CF (Regs.AC); \
+ SET_OF (!((old ^ rhs) & 0x80) && \
+ ((old ^ Regs.AC) & 0x80)); \
+ Regs.AC &= 0xFF; \
}
/* branches */
-#define BRANCH(cond) \
- Cycles = 2; \
- if (cond) { \
- signed char Offs; \
- unsigned char OldPCH; \
- ++Cycles; \
- Offs = (signed char) MemReadByte (PC+1);\
- OldPCH = PCH; \
- PC += 2 + (int) Offs; \
- if (PCH != OldPCH) { \
- ++Cycles; \
- } \
- } else { \
- PC += 2; \
+#define BRANCH(cond) \
+ Cycles = 2; \
+ if (cond) { \
+ signed char Offs; \
+ unsigned char OldPCH; \
+ ++Cycles; \
+ Offs = (signed char) MemReadByte (Regs.PC+1); \
+ OldPCH = PCH; \
+ Regs.PC += 2 + (int) Offs; \
+ if (PCH != OldPCH) { \
+ ++Cycles; \
+ } \
+ } else { \
+ Regs.PC += 2; \
}
/* compares */
-#define CMP(v1,v2) \
- { \
- unsigned Result = v1 - v2; \
- TEST_ZF (Result & 0xFF); \
- TEST_SF (Result); \
- SET_CF (Result <= 0xFF); \
+#define CMP(v1,v2) \
+ { \
+ unsigned Result = v1 - v2; \
+ TEST_ZF (Result & 0xFF); \
+ TEST_SF (Result); \
+ SET_CF (Result <= 0xFF); \
}
/* ROL */
-#define ROL(Val) \
- Val <<= 1; \
- if (GET_CF ()) { \
- Val |= 0x01; \
- } \
- TEST_ZF (Val); \
- TEST_SF (Val); \
+#define ROL(Val) \
+ Val <<= 1; \
+ if (GET_CF ()) { \
+ Val |= 0x01; \
+ } \
+ TEST_ZF (Val); \
+ TEST_SF (Val); \
TEST_CF (Val)
/* ROR */
-#define ROR(Val) \
- if (GET_CF ()) { \
- Val |= 0x100; \
- } \
- SET_CF (Val & 0x01); \
- Val >>= 1; \
- TEST_ZF (Val); \
+#define ROR(Val) \
+ if (GET_CF ()) { \
+ Val |= 0x100; \
+ } \
+ SET_CF (Val & 0x01); \
+ Val >>= 1; \
+ TEST_ZF (Val); \
TEST_SF (Val)
/* SBC */
-#define SBC(v) \
- if (GET_DF ()) { \
- Warning ("Decimal mode not available"); \
- } else { \
- unsigned Val; \
- unsigned char rhs = v; \
- Val = AC - rhs - (!GET_CF ()); \
- AC = (unsigned char) Val; \
- TEST_ZF (AC); \
- TEST_SF (AC); \
- SET_CF (Val <= 0xFF); \
- SET_OF (((AC^rhs) & (AC^Val) & 0x80)); \
+#define SBC(v) \
+ if (GET_DF ()) { \
+ Warning ("Decimal mode not available"); \
+ } else { \
+ unsigned old = Regs.AC; \
+ unsigned rhs = (v & 0xFF); \
+ Regs.AC -= rhs - (!GET_CF ()); \
+ TEST_ZF (Regs.AC); \
+ TEST_SF (Regs.AC); \
+ SET_CF (Regs.AC <= 0xFF); \
+ SET_OF (((old^rhs) & (old^Regs.AC) & 0x80)); \
+ Regs.AC &= 0xFF; \
}
static void OPC_Illegal (void)
{
- Warning ("Illegal opcode $%02X at address $%04X\n", MemReadByte (PC), PC);
+ Warning ("Illegal opcode $%02X at address $%04X\n", MemReadByte (Regs.PC), Regs.PC);
}
/* Opcode $00: BRK */
{
Cycles = 7;
- PC += 2;
+ Regs.PC += 2;
SET_BF (1);
PUSH (PCH);
PUSH (PCL);
- PUSH (SR);
+ PUSH (Regs.SR);
SET_IF (1);
- PC = MemReadWord (0xFFFE);
+ Regs.PC = MemReadWord (0xFFFE);
CPUHalted = 1;
}
unsigned char ZPAddr;
unsigned Val;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr) << 1;
MemWriteByte (ZPAddr, (unsigned char) Val);
TEST_ZF (Val & 0xFF);
TEST_SF (Val);
SET_CF (Val & 0x100);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $08: PHP */
{
Cycles = 3;
- PUSH (SR & ~BF);
- PC += 1;
+ PUSH (Regs.SR & ~BF);
+ Regs.PC += 1;
}
static void OPC_6502_0A (void)
/* Opcode $0A: ASL a */
{
- unsigned Val;
Cycles = 2;
- Val = AC << 1;
- AC = (unsigned char) Val;
- TEST_ZF (Val & 0xFF);
- TEST_SF (Val);
- SET_CF (Val & 0x100);
- PC += 1;
+ Regs.AC <<= 1;
+ TEST_ZF (Regs.AC & 0xFF);
+ TEST_SF (Regs.AC);
+ SET_CF (Regs.AC & 0x100);
+ Regs.AC &= 0xFF;
+ Regs.PC += 1;
}
unsigned Addr;
unsigned Val;
Cycles = 6;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr) << 1;
MemWriteByte (Addr, (unsigned char) Val);
TEST_ZF (Val & 0xFF);
TEST_SF (Val);
SET_CF (Val & 0x100);
- PC += 3;
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Val;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (ZPAddr) << 1;
MemWriteByte (ZPAddr, (unsigned char) Val);
TEST_ZF (Val & 0xFF);
TEST_SF (Val);
SET_CF (Val & 0x100);
- PC += 2;
+ Regs.PC += 2;
}
{
Cycles = 2;
SET_CF (0);
- PC += 1;
+ Regs.PC += 1;
}
unsigned Addr;
unsigned Val;
Cycles = 7;
- Addr = MemReadWord (PC+1) + XR;
+ Addr = MemReadWord (Regs.PC+1) + Regs.XR;
Val = MemReadByte (Addr) << 1;
MemWriteByte (Addr, (unsigned char) Val);
TEST_ZF (Val & 0xFF);
TEST_SF (Val);
SET_CF (Val & 0x100);
- PC += 3;
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 6;
- Addr = MemReadWord (PC+1);
- PC += 2;
+ Addr = MemReadWord (Regs.PC+1);
+ Regs.PC += 2;
PUSH (PCH);
PUSH (PCL);
- PC = Addr;
+ Regs.PC = Addr;
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr);
SET_SF (Val & 0x80);
SET_OF (Val & 0x40);
- SET_ZF ((Val & AC) == 0);
- PC += 2;
+ SET_ZF ((Val & Regs.AC) == 0);
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned Val;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr);
ROL (Val);
MemWriteByte (ZPAddr, Val);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $28: PLP */
{
Cycles = 4;
- SR = (POP () & ~BF);
- PC += 1;
+ Regs.SR = (POP () & ~BF);
+ Regs.PC += 1;
}
static void OPC_6502_2A (void)
/* Opcode $2A: ROL a */
{
- unsigned Val;
Cycles = 2;
- Val = AC;
- ROL (Val);
- AC = (unsigned char) Val;
- PC += 1;
+ ROL (Regs.AC);
+ Regs.AC &= 0xFF;
+ Regs.PC += 1;
}
unsigned Addr;
unsigned char Val;
Cycles = 4;
- Addr = MemReadByte (PC+1);
+ Addr = MemReadByte (Regs.PC+1);
Val = MemReadByte (Addr);
SET_SF (Val & 0x80);
SET_OF (Val & 0x40);
- SET_ZF ((Val & AC) == 0);
- PC += 3;
+ SET_ZF ((Val & Regs.AC) == 0);
+ Regs.PC += 3;
}
unsigned Addr;
unsigned Val;
Cycles = 6;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr);
ROL (Val);
MemWriteByte (Addr, Val);
- PC += 3;
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Val;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (ZPAddr);
ROL (Val);
MemWriteByte (ZPAddr, Val);
- PC += 2;
+ Regs.PC += 2;
}
{
Cycles = 2;
SET_CF (1);
- PC += 1;
+ Regs.PC += 1;
}
unsigned Addr;
unsigned Val;
Cycles = 7;
- Addr = MemReadWord (PC+1) + XR;
+ Addr = MemReadWord (Regs.PC+1) + Regs.XR;
Val = MemReadByte (Addr);
ROL (Val);
MemWriteByte (Addr, Val);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $40: RTI */
{
Cycles = 6;
- SR = POP ();
- PC = POP (); /* PCL */
- PC |= (POP () << 8); /* PCH */
+ Regs.SR = POP ();
+ Regs.PC = POP (); /* PCL */
+ Regs.PC |= (POP () << 8); /* PCH */
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr);
SET_CF (Val & 0x01);
Val >>= 1;
MemWriteByte (ZPAddr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $48: PHA */
{
Cycles = 3;
- PUSH (AC);
- PC += 1;
+ PUSH (Regs.AC);
+ Regs.PC += 1;
}
/* Opcode $4A: LSR a */
{
Cycles = 2;
- SET_CF (AC & 0x01);
- AC >>= 1;
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 1;
+ SET_CF (Regs.AC & 0x01);
+ Regs.AC >>= 1;
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 1;
}
/* Opcode $4C: JMP abs */
{
Cycles = 3;
- PC = MemReadWord (PC+1);
+ Regs.PC = MemReadWord (Regs.PC+1);
}
unsigned Addr;
unsigned char Val;
Cycles = 6;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr);
SET_CF (Val & 0x01);
Val >>= 1;
MemWriteByte (Addr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 3;
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (ZPAddr);
SET_CF (Val & 0x01);
Val >>= 1;
MemWriteByte (ZPAddr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 2;
+ Regs.PC += 2;
}
{
Cycles = 2;
SET_IF (0);
- PC += 1;
+ Regs.PC += 1;
}
unsigned Addr;
unsigned char Val;
Cycles = 7;
- Addr = MemReadWord (PC+1) + XR;
+ Addr = MemReadWord (Regs.PC+1) + Regs.XR;
Val = MemReadByte (Addr);
SET_CF (Val & 0x01);
Val >>= 1;
MemWriteByte (Addr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 3;
+ Regs.PC += 3;
}
/* Opcode $60: RTS */
{
Cycles = 6;
- PC = POP (); /* PCL */
- PC |= (POP () << 8); /* PCH */
- PC += 1;
+ Regs.PC = POP (); /* PCL */
+ Regs.PC |= (POP () << 8); /* PCH */
+ Regs.PC += 1;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Addr = MemReadZPWord (ZPAddr);
ADC (MemReadByte (Addr));
- PC += 2;
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
ADC (MemReadByte (ZPAddr));
- PC += 2;
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned Val;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr);
ROR (Val);
MemWriteByte (ZPAddr, Val);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $68: PLA */
{
Cycles = 4;
- AC = POP ();
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 1;
+ Regs.AC = POP ();
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 1;
}
/* Opcode $69: ADC #imm */
{
Cycles = 2;
- ADC (MemReadByte (PC+1));
- PC += 2;
+ ADC (MemReadByte (Regs.PC+1));
+ Regs.PC += 2;
}
static void OPC_6502_6A (void)
/* Opcode $6A: ROR a */
{
- unsigned Val;
Cycles = 2;
- Val = AC;
- ROR (Val);
- AC = (unsigned char) Val;
- PC += 1;
+ ROR (Regs.AC);
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 5;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
if (CPU == CPU_6502) {
/* Emulate the 6502 bug */
- PC = MemReadByte (Addr);
+ Regs.PC = MemReadByte (Addr);
Addr = (Addr & 0xFF00) | ((Addr + 1) & 0xFF);
- PC |= (MemReadByte (Addr) << 8);
+ Regs.PC |= (MemReadByte (Addr) << 8);
} else {
/* 65C02 and above have this bug fixed */
- PC = MemReadWord (Addr);
+ Regs.PC = MemReadWord (Addr);
}
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
ADC (MemReadByte (Addr));
- PC += 3;
+ Regs.PC += 3;
}
unsigned Addr;
unsigned Val;
Cycles = 6;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr);
ROR (Val);
MemWriteByte (Addr, Val);
- PC += 3;
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Addr = MemReadZPWord (ZPAddr);
- if (PAGE_CROSS (Addr, YR)) {
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- ADC (MemReadByte (Addr + YR));
- PC += 2;
+ ADC (MemReadByte (Addr + Regs.YR));
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
ADC (MemReadByte (ZPAddr));
- PC += 2;
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned Val;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (ZPAddr);
ROR (Val);
MemWriteByte (ZPAddr, Val);
- PC += 2;
+ Regs.PC += 2;
}
{
Cycles = 2;
SET_IF (1);
- PC += 1;
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, YR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- ADC (MemReadByte (Addr + YR));
- PC += 3;
+ ADC (MemReadByte (Addr + Regs.YR));
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, XR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.XR)) {
++Cycles;
}
- ADC (MemReadByte (Addr + XR));
- PC += 3;
+ ADC (MemReadByte (Addr + Regs.XR));
+ Regs.PC += 3;
}
unsigned Addr;
unsigned Val;
Cycles = 7;
- Addr = MemReadByte (PC+1) + XR;
+ Addr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (Addr);
ROR (Val);
MemWriteByte (Addr, Val);
- PC += 3;
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Addr = MemReadZPWord (ZPAddr);
- MemWriteByte (Addr, AC);
- PC += 2;
+ MemWriteByte (Addr, Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- MemWriteByte (ZPAddr, YR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ MemWriteByte (ZPAddr, Regs.YR);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- MemWriteByte (ZPAddr, AC);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ MemWriteByte (ZPAddr, Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- MemWriteByte (ZPAddr, XR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ MemWriteByte (ZPAddr, Regs.XR);
+ Regs.PC += 2;
}
/* Opcode $88: DEY */
{
Cycles = 2;
- --YR;
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 1;
+ Regs.YR = (Regs.YR - 1) & 0xFF;
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 1;
}
/* Opcode $8A: TXA */
{
Cycles = 2;
- AC = XR;
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 1;
+ Regs.AC = Regs.XR;
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- MemWriteByte (Addr, YR);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ MemWriteByte (Addr, Regs.YR);
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- MemWriteByte (Addr, AC);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ MemWriteByte (Addr, Regs.AC);
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- MemWriteByte (Addr, XR);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ MemWriteByte (Addr, Regs.XR);
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1);
- Addr = MemReadZPWord (ZPAddr) + YR;
- MemWriteByte (Addr, AC);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ Addr = MemReadZPWord (ZPAddr) + Regs.YR;
+ MemWriteByte (Addr, Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
- MemWriteByte (ZPAddr, YR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
+ MemWriteByte (ZPAddr, Regs.YR);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
- MemWriteByte (ZPAddr, AC);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
+ MemWriteByte (ZPAddr, Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + YR;
- MemWriteByte (ZPAddr, XR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR;
+ MemWriteByte (ZPAddr, Regs.XR);
+ Regs.PC += 2;
}
/* Opcode $98: TYA */
{
Cycles = 2;
- AC = YR;
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 1;
+ Regs.AC = Regs.YR;
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 5;
- Addr = MemReadWord (PC+1) + YR;
- MemWriteByte (Addr, AC);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1) + Regs.YR;
+ MemWriteByte (Addr, Regs.AC);
+ Regs.PC += 3;
}
/* Opcode $9A: TXS */
{
Cycles = 2;
- SP = XR;
- PC += 1;
+ Regs.SP = Regs.XR;
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 5;
- Addr = MemReadWord (PC+1) + XR;
- MemWriteByte (Addr, AC);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1) + Regs.XR;
+ MemWriteByte (Addr, Regs.AC);
+ Regs.PC += 3;
}
/* Opcode $A0: LDY #imm */
{
Cycles = 2;
- YR = MemReadByte (PC+1);
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 2;
+ Regs.YR = MemReadByte (Regs.PC+1);
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Addr = MemReadZPWord (ZPAddr);
- AC = MemReadByte (Addr);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 2;
+ Regs.AC = MemReadByte (Addr);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 2;
}
/* Opcode $A2: LDX #imm */
{
Cycles = 2;
- XR = MemReadByte (PC+1);
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 2;
+ Regs.XR = MemReadByte (Regs.PC+1);
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- YR = MemReadByte (ZPAddr);
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ Regs.YR = MemReadByte (ZPAddr);
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- AC = MemReadByte (ZPAddr);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ Regs.AC = MemReadByte (ZPAddr);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- XR = MemReadByte (ZPAddr);
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ Regs.XR = MemReadByte (ZPAddr);
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 2;
}
/* Opcode $A8: TAY */
{
Cycles = 2;
- YR = AC;
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 1;
+ Regs.YR = Regs.AC;
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 1;
}
/* Opcode $A9: LDA #imm */
{
Cycles = 2;
- AC = MemReadByte (PC+1);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 2;
+ Regs.AC = MemReadByte (Regs.PC+1);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 2;
}
/* Opcode $AA: TAX */
{
Cycles = 2;
- XR = AC;
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 1;
+ Regs.XR = Regs.AC;
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 1;
}
static void OPC_6502_AC (void)
-/* Opcode $AC: LDY abs */
+/* Opcode $Regs.AC: LDY abs */
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- YR = MemReadByte (Addr);
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ Regs.YR = MemReadByte (Addr);
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- AC = MemReadByte (Addr);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ Regs.AC = MemReadByte (Addr);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- XR = MemReadByte (Addr);
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ Regs.XR = MemReadByte (Addr);
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Addr = MemReadZPWord (ZPAddr);
- if (PAGE_CROSS (Addr, YR)) {
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- AC = MemReadByte (Addr + YR);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 2;
+ Regs.AC = MemReadByte (Addr + Regs.YR);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
- YR = MemReadByte (ZPAddr);
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
+ Regs.YR = MemReadByte (ZPAddr);
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
- AC = MemReadByte (ZPAddr);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
+ Regs.AC = MemReadByte (ZPAddr);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + YR;
- XR = MemReadByte (ZPAddr);
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.YR;
+ Regs.XR = MemReadByte (ZPAddr);
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 2;
}
{
Cycles = 2;
SET_OF (0);
- PC += 1;
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, YR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- AC = MemReadByte (Addr + YR);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 3;
+ Regs.AC = MemReadByte (Addr + Regs.YR);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 3;
}
/* Opcode $BA: TSX */
{
Cycles = 2;
- XR = SP;
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 1;
+ Regs.XR = Regs.SP;
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, XR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.XR)) {
++Cycles;
}
- YR = MemReadByte (Addr + XR);
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 3;
+ Regs.YR = MemReadByte (Addr + Regs.XR);
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, XR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.XR)) {
++Cycles;
}
- AC = MemReadByte (Addr + XR);
- TEST_ZF (AC);
- TEST_SF (AC);
- PC += 3;
+ Regs.AC = MemReadByte (Addr + Regs.XR);
+ TEST_ZF (Regs.AC);
+ TEST_SF (Regs.AC);
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, YR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- XR = MemReadByte (Addr + YR);
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 3;
+ Regs.XR = MemReadByte (Addr + Regs.YR);
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 3;
}
/* Opcode $C0: CPY #imm */
{
Cycles = 2;
- CMP (YR, MemReadByte (PC+1));
- PC += 2;
+ CMP (Regs.YR, MemReadByte (Regs.PC+1));
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Addr = MemReadZPWord (ZPAddr);
- CMP (AC, MemReadByte (Addr));
- PC += 2;
+ CMP (Regs.AC, MemReadByte (Addr));
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- CMP (YR, MemReadByte (ZPAddr));
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ CMP (Regs.YR, MemReadByte (ZPAddr));
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- CMP (AC, MemReadByte (ZPAddr));
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ CMP (Regs.AC, MemReadByte (ZPAddr));
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr) - 1;
MemWriteByte (ZPAddr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $C8: INY */
{
Cycles = 2;
- ++YR;
- TEST_ZF (YR);
- TEST_SF (YR);
- PC += 1;
+ Regs.YR = (Regs.YR + 1) & 0xFF;
+ TEST_ZF (Regs.YR);
+ TEST_SF (Regs.YR);
+ Regs.PC += 1;
}
/* Opcode $C9: CMP #imm */
{
Cycles = 2;
- CMP (AC, MemReadByte (PC+1));
- PC += 2;
+ CMP (Regs.AC, MemReadByte (Regs.PC+1));
+ Regs.PC += 2;
}
/* Opcode $CA: DEX */
{
Cycles = 2;
- --XR;
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 1;
+ Regs.XR = (Regs.XR - 1) & 0xFF;
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- CMP (YR, MemReadByte (Addr));
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ CMP (Regs.YR, MemReadByte (Addr));
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- CMP (AC, MemReadByte (Addr));
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ CMP (Regs.AC, MemReadByte (Addr));
+ Regs.PC += 3;
}
unsigned Addr;
unsigned char Val;
Cycles = 6;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr) - 1;
MemWriteByte (Addr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 3;
+ Regs.PC += 3;
}
unsigned ZPAddr;
unsigned Addr;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Addr = MemReadWord (ZPAddr);
- if (PAGE_CROSS (Addr, YR)) {
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- CMP (AC, MemReadByte (Addr + YR));
- PC += 2;
+ CMP (Regs.AC, MemReadByte (Addr + Regs.YR));
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
- CMP (AC, MemReadByte (ZPAddr));
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
+ CMP (Regs.AC, MemReadByte (ZPAddr));
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (ZPAddr) - 1;
MemWriteByte (ZPAddr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 2;
+ Regs.PC += 2;
}
{
Cycles = 2;
SET_DF (0);
- PC += 1;
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, YR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- CMP (AC, MemReadByte (Addr + YR));
- PC += 3;
+ CMP (Regs.AC, MemReadByte (Addr + Regs.YR));
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, XR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.XR)) {
++Cycles;
}
- CMP (AC, MemReadByte (Addr + XR));
- PC += 3;
+ CMP (Regs.AC, MemReadByte (Addr + Regs.XR));
+ Regs.PC += 3;
}
unsigned Addr;
unsigned char Val;
Cycles = 7;
- Addr = MemReadWord (PC+1) + XR;
+ Addr = MemReadWord (Regs.PC+1) + Regs.XR;
Val = MemReadByte (Addr) - 1;
MemWriteByte (Addr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 3;
+ Regs.PC += 3;
}
/* Opcode $E0: CPX #imm */
{
Cycles = 2;
- CMP (XR, MemReadByte (PC+1));
- PC += 2;
+ CMP (Regs.XR, MemReadByte (Regs.PC+1));
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Addr = MemReadZPWord (ZPAddr);
SBC (MemReadByte (Addr));
- PC += 2;
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
- CMP (XR, MemReadByte (ZPAddr));
- PC += 2;
+ ZPAddr = MemReadByte (Regs.PC+1);
+ CMP (Regs.XR, MemReadByte (ZPAddr));
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 3;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
SBC (MemReadByte (ZPAddr));
- PC += 2;
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Val = MemReadByte (ZPAddr) + 1;
MemWriteByte (ZPAddr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 2;
+ Regs.PC += 2;
}
/* Opcode $E8: INX */
{
Cycles = 2;
- ++XR;
- TEST_ZF (XR);
- TEST_SF (XR);
- PC += 1;
+ Regs.XR = (Regs.XR + 1) & 0xFF;
+ TEST_ZF (Regs.XR);
+ TEST_SF (Regs.XR);
+ Regs.PC += 1;
}
/* Opcode $E9: SBC #imm */
{
Cycles = 2;
- SBC (MemReadByte (PC+1));
- PC += 2;
+ SBC (MemReadByte (Regs.PC+1));
+ Regs.PC += 2;
}
{
/* This one is easy... */
Cycles = 2;
- PC += 1;
+ Regs.PC += 1;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- CMP (XR, MemReadByte (Addr));
- PC += 3;
+ Addr = MemReadWord (Regs.PC+1);
+ CMP (Regs.XR, MemReadByte (Addr));
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
SBC (MemReadByte (Addr));
- PC += 3;
+ Regs.PC += 3;
}
unsigned Addr;
unsigned char Val;
Cycles = 6;
- Addr = MemReadWord (PC+1);
+ Addr = MemReadWord (Regs.PC+1);
Val = MemReadByte (Addr) + 1;
MemWriteByte (Addr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 3;
+ Regs.PC += 3;
}
unsigned char ZPAddr;
unsigned Addr;
Cycles = 5;
- ZPAddr = MemReadByte (PC+1);
+ ZPAddr = MemReadByte (Regs.PC+1);
Addr = MemReadZPWord (ZPAddr);
- if (PAGE_CROSS (Addr, YR)) {
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- SBC (MemReadByte (Addr + YR));
- PC += 2;
+ SBC (MemReadByte (Addr + Regs.YR));
+ Regs.PC += 2;
}
{
unsigned char ZPAddr;
Cycles = 4;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
SBC (MemReadByte (ZPAddr));
- PC += 2;
+ Regs.PC += 2;
}
unsigned char ZPAddr;
unsigned char Val;
Cycles = 6;
- ZPAddr = MemReadByte (PC+1) + XR;
+ ZPAddr = MemReadByte (Regs.PC+1) + Regs.XR;
Val = MemReadByte (ZPAddr) + 1;
MemWriteByte (ZPAddr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 2;
+ Regs.PC += 2;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, YR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.YR)) {
++Cycles;
}
- SBC (MemReadByte (Addr + YR));
- PC += 3;
+ SBC (MemReadByte (Addr + Regs.YR));
+ Regs.PC += 3;
}
{
unsigned Addr;
Cycles = 4;
- Addr = MemReadWord (PC+1);
- if (PAGE_CROSS (Addr, XR)) {
+ Addr = MemReadWord (Regs.PC+1);
+ if (PAGE_CROSS (Addr, Regs.XR)) {
++Cycles;
}
- SBC (MemReadByte (Addr + XR));
- PC += 3;
+ SBC (MemReadByte (Addr + Regs.XR));
+ Regs.PC += 3;
}
unsigned Addr;
unsigned char Val;
Cycles = 7;
- Addr = MemReadWord (PC+1) + XR;
+ Addr = MemReadWord (Regs.PC+1) + Regs.XR;
Val = MemReadByte (Addr) + 1;
MemWriteByte (Addr, Val);
TEST_ZF (Val);
TEST_SF (Val);
- PC += 3;
+ Regs.PC += 3;
}
void CPUInit (void)
/* Initialize the CPU */
{
- PC = MemReadWord (0xFFFC);
+ RESET ();
}
-void Reset (void)
-/* Reset the CPU */
+void IRQRequest (void)
+/* Generate an IRQ */
{
+ HaveIRQRequest = 1;
}
-void IRQ (void)
-/* Generate an IRQ */
+void NMIRequest (void)
+/* Generate an NMI */
{
+ HaveNMIRequest = 1;
}
-void NMI (void)
-/* Generate an NMI */
+void RESET (void)
+/* Generate a CPU RESET */
{
+ CPUHalted = HaveIRQRequest = HaveNMIRequest = 0;
+ Regs.PC = MemReadWord (0xFFFC);
}
void CPURun (void)
-/* Run the CPU */
+/* Run one CPU instruction */
{
- unsigned long I = 0;
+ /* If the CPU is halted, do nothing */
+ if (CPUHalted) {
+ return;
+ }
+ /* If we have an NMI request, handle it */
+ if (HaveNMIRequest) {
- while (!CPUHalted) {
+ HaveNMIRequest = 0;
+ PUSH (PCH);
+ PUSH (PCL);
+ PUSH (Regs.SR);
+ SET_IF (1);
+ Regs.PC = MemReadWord (0xFFFA);
+ Cycles = 7;
- /* Get the next opcode */
- unsigned char OPC = MemReadByte (PC);
+ } else if (HaveIRQRequest && GET_IF () == 0) {
-#if 0
- if ((++I & 0xFF) == 0)
- printf ("%9lu %06X %02X A=%02X X=%02X Y=%02X %c%c%c%c%c%c%c\n",
- TotalCycles, PC, OPC, AC, XR, YR,
- GET_SF()? 'S' : '-',
- GET_ZF()? 'Z' : '-',
- GET_CF()? 'C' : '-',
- GET_IF()? 'I' : '-',
- GET_BF()? 'B' : '-',
- GET_DF()? 'D' : '-',
- GET_OF()? 'V' : '-');
-#endif
+ HaveIRQRequest = 0;
+ PUSH (PCH);
+ PUSH (PCL);
+ PUSH (Regs.SR);
+ SET_IF (1);
+ Regs.PC = MemReadWord (0xFFFE);
+ Cycles = 7;
+
+ } else {
+
+ /* Normal instruction - read the next opcode */
+ unsigned char OPC = MemReadByte (Regs.PC);
- /* Execute it */
- OPCTable[OPC] ();
+ /* Execute it */
+ OPCTable[OPC] ();
- /* Count cycles */
- TotalCycles += Cycles;
+ }
+
+ /* Count cycles */
+ TotalCycles += Cycles;
- if (BreakMsg[0]) {
- printf ("%s\n", BreakMsg);
- BreakMsg[0] = '\0';
- }
+ if (BreakMsg[0]) {
+ printf ("%s\n", BreakMsg);
+ BreakMsg[0] = '\0';
}
}
+#if 0
+ if ((++I & 0xFF) == 0)
+ printf ("%9lu %06X %02X A=%02X X=%02X Y=%02X %c%c%c%c%c%c%c\n",
+ TotalCycles, Regs.PC, OPC, Regs.AC, Regs.XR, Regs.YR,
+ GET_SF()? 'S' : '-',
+ GET_ZF()? 'Z' : '-',
+ GET_CF()? 'C' : '-',
+ GET_IF()? 'I' : '-',
+ GET_BF()? 'B' : '-',
+ GET_DF()? 'D' : '-',
+ GET_OF()? 'V' : '-');
+#endif
+
+