diff options
Diffstat (limited to 'source/cpuaddr.h')
-rw-r--r-- | source/cpuaddr.h | 213 |
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 |