aboutsummaryrefslogtreecommitdiff
path: root/source/cpuaddr.h
diff options
context:
space:
mode:
authorNebuleon Fumika2012-12-23 16:13:54 -0500
committerNebuleon Fumika2012-12-23 16:13:54 -0500
commitd1fe64aef0298514150e543b1b13fbf03f33c3e1 (patch)
treec72a28ecbfb93c65ce39ca28d9853251453c1b16 /source/cpuaddr.h
parente7f7d0282a7126f9e1095481b39c43e3e24909bf (diff)
downloadsnes9x2005-d1fe64aef0298514150e543b1b13fbf03f33c3e1.tar.gz
snes9x2005-d1fe64aef0298514150e543b1b13fbf03f33c3e1.tar.bz2
snes9x2005-d1fe64aef0298514150e543b1b13fbf03f33c3e1.zip
Various optimisations in the CPU emulation.
Run the opcode as a tail call from the address calculation. This cuts on the needed return instructions. Pass the opcode address as a parameter; this keeps it in a register most of the time and avoids memory stores.
Diffstat (limited to 'source/cpuaddr.h')
-rw-r--r--source/cpuaddr.h213
1 files changed, 131 insertions, 82 deletions
diff --git a/source/cpuaddr.h b/source/cpuaddr.h
index 4f5febf..84ee45b 100644
--- a/source/cpuaddr.h
+++ b/source/cpuaddr.h
@@ -90,8 +90,6 @@
#ifndef _CPUADDR_H_
#define _CPUADDR_H_
-EXTERN_C long OpAddress;
-
typedef enum {
NONE = 0,
READ = 1,
@@ -100,48 +98,74 @@ typedef enum {
JUMP = 4
} AccessMode;
-void Immediate8 (AccessMode a)
+EXTERN_C long OpAddress;
+
+// The type for a function that can run after the addressing mode is resolved:
+// void NAME (long Addr) {...}
+typedef void (*InternalOp) (long);
+
+/*
+ * The addressing modes in this file do not update the OpAddress variable.
+ * Rather, they pass the address they calculate to the operation that needs to
+ * be done with it. If you need the calculated value, set a passthrough
+ * that gets the calculated address from the internal op and then updates the
+ * OpAddress variable.
+ *
+ * Not updating the OpAddress variable saves a few memory storage instructions
+ * per SNES instruction.
+ * Calling the operation at the end of the addressing mode calculation saves
+ * one return instruction per SNES instruction, because the code can just
+ * jump from one to the other.
+ */
+
+static void Immediate8 (AccessMode a, InternalOp op)
{
- OpAddress = ICPU.ShiftedPB + CPU.PC - CPU.PCBase;
+ long Addr = ICPU.ShiftedPB + CPU.PC - CPU.PCBase;
CPU.PC++;
+ (*op)(Addr);
}
-void Immediate16 (AccessMode a)
+static void Immediate16 (AccessMode a, InternalOp op)
{
- OpAddress = ICPU.ShiftedPB + CPU.PC - CPU.PCBase;
+ long Addr = ICPU.ShiftedPB + CPU.PC - CPU.PCBase;
CPU.PC += 2;
+ (*op)(Addr);
}
-void Relative (AccessMode a)
+static void Relative (AccessMode a, InternalOp op)
{
Int8 = *CPU.PC++;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
- OpAddress = ((int) (CPU.PC - CPU.PCBase) + Int8) & 0xffff;
+ long Addr = ((int) (CPU.PC - CPU.PCBase) + Int8) & 0xffff;
+ (*op)(Addr);
}
-void RelativeLong (AccessMode a)
+static void RelativeLong (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = *(uint16 *) CPU.PC;
+ Addr = *(uint16 *) CPU.PC;
#else
- OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8);
+ Addr = *CPU.PC + (*(CPU.PC + 1) << 8);
#endif
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE;
#endif
CPU.PC += 2;
- OpAddress += (CPU.PC - CPU.PCBase);
- OpAddress &= 0xffff;
+ Addr += (CPU.PC - CPU.PCBase);
+ Addr &= 0xffff;
+ (*op)(Addr);
}
-void AbsoluteIndexedIndirect (AccessMode a)
+static void AbsoluteIndexedIndirect (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = (Registers.X.W + *(uint16 *) CPU.PC) & 0xffff;
+ Addr = (Registers.X.W + *(uint16 *) CPU.PC) & 0xffff;
#else
- OpAddress = (Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff;
+ Addr = (Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff;
#endif
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeedx2;
@@ -150,18 +174,20 @@ void AbsoluteIndexedIndirect (AccessMode a)
OpenBus = *(CPU.PC + 1);
#endif
CPU.PC += 2;
- OpAddress = S9xGetWord (ICPU.ShiftedPB + OpAddress);
+ Addr = S9xGetWord (ICPU.ShiftedPB + Addr);
#ifndef NO_OPEN_BUS
- if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ if(a&READ) OpenBus = (uint8)(Addr>>8);
#endif
+ (*op)(Addr);
}
-void AbsoluteIndirectLong (AccessMode a)
+static void AbsoluteIndirectLong (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = *(uint16 *) CPU.PC;
+ Addr = *(uint16 *) CPU.PC;
#else
- OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8);
+ Addr = *CPU.PC + (*(CPU.PC + 1) << 8);
#endif
#ifndef SA1_OPCODES
@@ -173,21 +199,23 @@ void AbsoluteIndirectLong (AccessMode a)
CPU.PC += 2;
#ifndef NO_OPEN_BUS
if(a&READ) {
- OpAddress = S9xGetWord (OpAddress) | ((OpenBus=S9xGetByte (OpAddress + 2)) << 16);
+ Addr = S9xGetWord (Addr) | ((OpenBus=S9xGetByte (Addr + 2)) << 16);
} else {
#endif
- OpAddress = S9xGetWord (OpAddress) | (S9xGetByte (OpAddress + 2) << 16);
+ Addr = S9xGetWord (Addr) | (S9xGetByte (Addr + 2) << 16);
#ifndef NO_OPEN_BUS
}
#endif
+ (*op)(Addr);
}
-void AbsoluteIndirect (AccessMode a)
+static void AbsoluteIndirect (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = *(uint16 *) CPU.PC;
+ Addr = *(uint16 *) CPU.PC;
#else
- OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8);
+ Addr = *CPU.PC + (*(CPU.PC + 1) << 8);
#endif
#ifndef SA1_OPCODES
@@ -197,19 +225,21 @@ void AbsoluteIndirect (AccessMode a)
OpenBus = *(CPU.PC + 1);
#endif
CPU.PC += 2;
- OpAddress = S9xGetWord (OpAddress);
+ Addr = S9xGetWord (Addr);
#ifndef NO_OPEN_BUS
- if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ if(a&READ) OpenBus = (uint8)(Addr>>8);
#endif
- OpAddress += ICPU.ShiftedPB;
+ Addr += ICPU.ShiftedPB;
+ (*op)(Addr);
}
-void Absolute (AccessMode a)
+static void Absolute (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = *(uint16 *) CPU.PC + ICPU.ShiftedDB;
+ Addr = *(uint16 *) CPU.PC + ICPU.ShiftedDB;
#else
- OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB;
+ Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB;
#endif
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *(CPU.PC+1);
@@ -218,14 +248,16 @@ void Absolute (AccessMode a)
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeedx2;
#endif
+ (*op)(Addr);
}
-void AbsoluteLong (AccessMode a)
+static void AbsoluteLong (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = (*(uint32 *) CPU.PC) & 0xffffff;
+ Addr = (*(uint32 *) CPU.PC) & 0xffffff;
#else
- OpAddress = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16);
+ Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16);
#endif
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *(CPU.PC+2);
@@ -234,78 +266,82 @@ void AbsoluteLong (AccessMode a)
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed;
#endif
+ (*op)(Addr);
}
-void Direct(AccessMode a)
+static void Direct(AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+ (*op)(Addr);
}
-void DirectIndirectIndexed (AccessMode a)
+static void DirectIndirectIndexed (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
- OpAddress = S9xGetWord (OpAddress);
+ Addr = S9xGetWord (Addr);
#ifndef NO_OPEN_BUS
- if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ if(a&READ) OpenBus = (uint8)(Addr>>8);
#endif
- OpAddress += ICPU.ShiftedDB + Registers.Y.W;
+ Addr += ICPU.ShiftedDB + Registers.Y.W;
// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
// XXX: always add one if STA
// XXX: else Add one cycle if crosses page boundary
+ (*op)(Addr);
}
-void DirectIndirectIndexedLong (AccessMode a)
+static void DirectIndirectIndexedLong (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
#ifndef NO_OPEN_BUS
if(a&READ){
- OpAddress = S9xGetWord (OpAddress) + ((OpenBus = S9xGetByte (OpAddress + 2)) << 16) + Registers.Y.W;
+ Addr = S9xGetWord (Addr) + ((OpenBus = S9xGetByte (Addr + 2)) << 16) + Registers.Y.W;
} else {
#endif
- OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16) + Registers.Y.W;
+ Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16) + Registers.Y.W;
#ifndef NO_OPEN_BUS
}
#endif
// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+ (*op)(Addr);
}
-void DirectIndexedIndirect(AccessMode a)
+static void DirectIndexedIndirect(AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W + Registers.X.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
- OpAddress = S9xGetWord (OpAddress);
+ Addr = S9xGetWord (Addr);
#ifndef NO_OPEN_BUS
- if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ if(a&READ) OpenBus = (uint8)(Addr>>8);
#endif
- OpAddress += ICPU.ShiftedDB;
+ Addr += ICPU.ShiftedDB;
#ifndef SA1_OPCODES
// if (Registers.DL != 0)
@@ -313,15 +349,16 @@ void DirectIndexedIndirect(AccessMode a)
// else
CPU.Cycles += ONE_CYCLE;
#endif
+ (*op)(Addr);
}
-void DirectIndexedX (AccessMode a)
+static void DirectIndexedX (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W + Registers.X.W);
- OpAddress &= CheckEmulation() ? 0xff : 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W + Registers.X.W);
+ Addr &= CheckEmulation() ? 0xff : 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed + ONE_CYCLE;
@@ -330,15 +367,16 @@ void DirectIndexedX (AccessMode a)
// else
// CPU.Cycles += ONE_CYCLE;
#endif
+ (*op)(Addr);
}
-void DirectIndexedY (AccessMode a)
+static void DirectIndexedY (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W + Registers.Y.W);
- OpAddress &= CheckEmulation() ? 0xff : 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W + Registers.Y.W);
+ Addr &= CheckEmulation() ? 0xff : 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed + ONE_CYCLE;
// if (Registers.DL != 0)
@@ -346,14 +384,16 @@ void DirectIndexedY (AccessMode a)
// else
// CPU.Cycles += ONE_CYCLE;
#endif
+ (*op)(Addr);
}
-void AbsoluteIndexedX (AccessMode a)
+static void AbsoluteIndexedX (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W;
+ Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.X.W;
#else
- OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) +
+ Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) +
Registers.X.W;
#endif
#ifndef NO_OPEN_BUS
@@ -365,14 +405,16 @@ void AbsoluteIndexedX (AccessMode a)
#endif
// XXX: always add one cycle for ROL, LSR, etc
// XXX: else is cross page boundary add one cycle
+ (*op)(Addr);
}
-void AbsoluteIndexedY (AccessMode a)
+static void AbsoluteIndexedY (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W;
+ Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + Registers.Y.W;
#else
- OpAddress = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) +
+ Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) +
Registers.Y.W;
#endif
#ifndef NO_OPEN_BUS
@@ -384,14 +426,16 @@ void AbsoluteIndexedY (AccessMode a)
#endif
// XXX: always add cycle for STA
// XXX: else is cross page boundary add one cycle
+ (*op)(Addr);
}
-void AbsoluteLongIndexedX (AccessMode a)
+static void AbsoluteLongIndexedX (AccessMode a, InternalOp op)
{
+ long Addr;
#ifdef FAST_LSB_WORD_ACCESS
- OpAddress = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff;
+ Addr = (*(uint32 *) CPU.PC + Registers.X.W) & 0xffffff;
#else
- OpAddress = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff;
+ Addr = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + Registers.X.W) & 0xffffff;
#endif
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *(CPU.PC+2);
@@ -400,73 +444,78 @@ void AbsoluteLongIndexedX (AccessMode a)
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed;
#endif
+ (*op)(Addr);
}
-void DirectIndirect (AccessMode a)
+static void DirectIndirect (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
- OpAddress = S9xGetWord (OpAddress);
+ Addr = S9xGetWord (Addr);
#ifndef NO_OPEN_BUS
- if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ if(a&READ) OpenBus = (uint8)(Addr>>8);
#endif
- OpAddress += ICPU.ShiftedDB;
+ Addr += ICPU.ShiftedDB;
// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+ (*op)(Addr);
}
-void DirectIndirectLong (AccessMode a)
+static void DirectIndirectLong (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.D.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.D.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed;
#endif
#ifndef NO_OPEN_BUS
if(a&READ){
- OpAddress = S9xGetWord (OpAddress) + ((OpenBus=S9xGetByte (OpAddress + 2)) << 16);
+ Addr = S9xGetWord (Addr) + ((OpenBus=S9xGetByte (Addr + 2)) << 16);
} else {
#endif
- OpAddress = S9xGetWord (OpAddress) + (S9xGetByte (OpAddress + 2) << 16);
+ Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16);
#ifndef NO_OPEN_BUS
}
#endif
// if (Registers.DL != 0) CPU.Cycles += ONE_CYCLE;
+ (*op)(Addr);
}
-void StackRelative (AccessMode a)
+static void StackRelative (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
if(a&READ) OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.S.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed + ONE_CYCLE;
#endif
+ (*op)(Addr);
}
-void StackRelativeIndirectIndexed (AccessMode a)
+static void StackRelativeIndirectIndexed (AccessMode a, InternalOp op)
{
#ifndef NO_OPEN_BUS
OpenBus = *CPU.PC;
#endif
- OpAddress = (*CPU.PC++ + Registers.S.W) & 0xffff;
+ long Addr = (*CPU.PC++ + Registers.S.W) & 0xffff;
#ifndef SA1_OPCODES
CPU.Cycles += CPU.MemSpeed + TWO_CYCLES;
#endif
- OpAddress = S9xGetWord (OpAddress);
+ Addr = S9xGetWord (Addr);
#ifndef NO_OPEN_BUS
- if(a&READ) OpenBus = (uint8)(OpAddress>>8);
+ if(a&READ) OpenBus = (uint8)(Addr>>8);
#endif
- OpAddress = (OpAddress + ICPU.ShiftedDB +
+ Addr = (Addr + ICPU.ShiftedDB +
Registers.Y.W) & 0xffffff;
+ (*op)(Addr);
}
#endif