diff --git a/Core/SNES/Coprocessors/SA1/Sa1Cpu.h b/Core/SNES/Coprocessors/SA1/Sa1Cpu.h index 1f60c9bb9..1d00de9e6 100644 --- a/Core/SNES/Coprocessors/SA1/Sa1Cpu.h +++ b/Core/SNES/Coprocessors/SA1/Sa1Cpu.h @@ -37,8 +37,8 @@ class Sa1Cpu : public ISerializable uint16_t GetDirectAddress(uint16_t offset, bool allowEmulationMode = true); - uint16_t GetDirectAddressIndirectWord(uint16_t offset, bool allowEmulationMode = true); - uint32_t GetDirectAddressIndirectLong(uint16_t offset, bool allowEmulationMode = true); + uint16_t GetDirectAddressIndirectWord(uint16_t offset); + uint32_t GetDirectAddressIndirectLong(uint16_t offset); uint8_t GetOpCode(); @@ -64,7 +64,8 @@ class Sa1Cpu : public ISerializable uint8_t Read(uint32_t addr, MemoryOperationType type); - void SetSP(uint16_t sp); + void SetSP(uint16_t sp, bool allowEmulationMode = true); + __forceinline void RestrictStackPointerValue(); void SetPS(uint8_t ps); void SetRegister(uint8_t ®, uint8_t value); @@ -92,11 +93,11 @@ class Sa1Cpu : public ISerializable uint16_t GetWordValue(); - void PushByte(uint8_t value); - uint8_t PopByte(); + void PushByte(uint8_t value, bool allowEmulationMode = true); + uint8_t PopByte(bool allowEmulationMode = true); - void PushWord(uint16_t value); - uint16_t PopWord(); + void PushWord(uint16_t value, bool allowEmulationMode = true); + uint16_t PopWord(bool allowEmulationMode = true); //Add/subtract instructions void Add8(uint8_t value); diff --git a/Core/SNES/SnesCpu.Instructions.h b/Core/SNES/SnesCpu.Instructions.h index 53ba0b1f0..b9627e606 100644 --- a/Core/SNES/SnesCpu.Instructions.h +++ b/Core/SNES/SnesCpu.Instructions.h @@ -411,15 +411,16 @@ void SnesCpu::JSL() uint8_t b1 = ReadOperandByte(); uint8_t b2 = ReadOperandByte(); - PushByte(_state.K); + PushByte(_state.K, false); Idle(); uint8_t b3 = ReadOperandByte(); - PushWord(_state.PC - 1); + PushWord(_state.PC - 1, false); _state.K = b3; _state.PC = b1 | (b2 << 8); + RestrictStackPointerValue(); IdleEndJump(); } @@ -445,7 +446,7 @@ void SnesCpu::JMP_AbsIdxXInd() void SnesCpu::JSR_AbsIdxXInd() { uint8_t lsb = ReadOperandByte(); - PushWord(_state.PC); + PushWord(_state.PC, false); uint8_t msb = ReadOperandByte(); uint16_t baseAddr = (lsb | (msb << 8)) + _state.X; @@ -455,6 +456,7 @@ void SnesCpu::JSR_AbsIdxXInd() msb = ReadData(GetProgramAddress(baseAddr + 1)); _state.PC = (uint16_t)GetProgramAddress(lsb | (msb << 8)); + RestrictStackPointerValue(); IdleEndJump(); } @@ -479,9 +481,10 @@ void SnesCpu::RTL() Idle(); Idle(); - _state.PC = PopWord(); + _state.PC = PopWord(false); _state.PC++; - _state.K = PopByte(); + _state.K = PopByte(false); + RestrictStackPointerValue(); IdleEndJump(); } @@ -771,19 +774,22 @@ Push/pull operations void SnesCpu::PEA() { //Push Effective Address - PushWord((uint16_t)_operand); + PushWord((uint16_t)_operand, false); + RestrictStackPointerValue(); } void SnesCpu::PEI() { //Push Effective Indirect address - PushWord(ReadDataWord(_operand)); + PushWord(ReadDataWord(_operand), false); + RestrictStackPointerValue(); } void SnesCpu::PER() { //Push Effective Relative address - PushWord((uint16_t)((int16_t)_operand + _state.PC)); + PushWord((uint16_t)((int16_t)_operand + _state.PC), false); + RestrictStackPointerValue(); } void SnesCpu::PHB() @@ -795,7 +801,8 @@ void SnesCpu::PHB() void SnesCpu::PHD() { Idle(); - PushWord(_state.D); + PushWord(_state.D, false); + RestrictStackPointerValue(); } void SnesCpu::PHK() @@ -817,7 +824,8 @@ void SnesCpu::PLB() //"PHP, PHK, PHP, PLB, and PLP push and pull one byte from the stack" Idle(); Idle(); - SetRegister(_state.DBR, PopByte()); + SetRegister(_state.DBR, PopByte(false)); + RestrictStackPointerValue(); } void SnesCpu::PLD() @@ -825,7 +833,8 @@ void SnesCpu::PLD() //"PHD and PLD push and pull two bytes from the stack." Idle(); Idle(); - SetRegister(_state.D, PopWord(), false); + SetRegister(_state.D, PopWord(false), false); + RestrictStackPointerValue(); } void SnesCpu::PLP() @@ -1286,7 +1295,7 @@ void SnesCpu::AddrMode_DirIndIdxY(bool isWrite) void SnesCpu::AddrMode_DirIndLng() { - _operand = GetDirectAddressIndirectLong(ReadDirectOperandByte(), false); + _operand = GetDirectAddressIndirectLong(ReadDirectOperandByte()); } void SnesCpu::AddrMode_DirIndLngIdxY() diff --git a/Core/SNES/SnesCpu.Shared.h b/Core/SNES/SnesCpu.Shared.h index b46ac5371..2802257c5 100644 --- a/Core/SNES/SnesCpu.Shared.h +++ b/Core/SNES/SnesCpu.Shared.h @@ -466,65 +466,71 @@ uint16_t SnesCpu::GetWordValue() } } -void SnesCpu::PushByte(uint8_t value) +void SnesCpu::PushByte(uint8_t value, bool allowEmulationMode) { Write(_state.SP, value); - SetSP(_state.SP - 1); + SetSP(_state.SP - 1, allowEmulationMode); } -uint8_t SnesCpu::PopByte() +uint8_t SnesCpu::PopByte(bool allowEmulationMode) { - SetSP(_state.SP + 1); + SetSP(_state.SP + 1, allowEmulationMode); return ReadData(_state.SP); } -void SnesCpu::PushWord(uint16_t value) +void SnesCpu::PushWord(uint16_t value, bool allowEmulationMode) { - PushByte(value >> 8); - PushByte((uint8_t)value); + PushByte(value >> 8, allowEmulationMode); + PushByte((uint8_t)value, allowEmulationMode); } -uint16_t SnesCpu::PopWord() +uint16_t SnesCpu::PopWord(bool allowEmulationMode) { - uint8_t lo = PopByte(); - uint8_t hi = PopByte(); + uint8_t lo = PopByte(allowEmulationMode); + uint8_t hi = PopByte(allowEmulationMode); return lo | hi << 8; } uint16_t SnesCpu::GetDirectAddress(uint16_t offset, bool allowEmulationMode) { if(allowEmulationMode && _state.EmulationMode && (_state.D & 0xFF) == 0) { - //TODO: Check if new instruction or not (PEI) return (uint16_t)((_state.D & 0xFF00) | (offset & 0xFF)); } else { return (uint16_t)(_state.D + offset); } } -uint16_t SnesCpu::GetDirectAddressIndirectWord(uint16_t offset, bool allowEmulationMode) +uint16_t SnesCpu::GetDirectAddressIndirectWord(uint16_t offset) { uint8_t lsb = ReadData(GetDirectAddress(offset + 0)); uint8_t msb = ReadData(GetDirectAddress(offset + 1)); return (msb << 8) | lsb; } -uint32_t SnesCpu::GetDirectAddressIndirectLong(uint16_t offset, bool allowEmulationMode) +uint32_t SnesCpu::GetDirectAddressIndirectLong(uint16_t offset) { - uint8_t b1 = ReadData(GetDirectAddress(offset + 0, allowEmulationMode)); - uint8_t b2 = ReadData(GetDirectAddress(offset + 1, allowEmulationMode)); - uint8_t b3 = ReadData(GetDirectAddress(offset + 2, allowEmulationMode)); + uint8_t b1 = ReadData(GetDirectAddress(offset + 0, false)); + uint8_t b2 = ReadData(GetDirectAddress(offset + 1, false)); + uint8_t b3 = ReadData(GetDirectAddress(offset + 2, false)); return (b3 << 16) | (b2 << 8) | b1; } -void SnesCpu::SetSP(uint16_t sp) +void SnesCpu::SetSP(uint16_t sp, bool allowEmulationMode) { - if(_state.EmulationMode) { + if(allowEmulationMode && _state.EmulationMode) { _state.SP = 0x100 | (sp & 0xFF); } else { _state.SP = sp; } } +void SnesCpu::RestrictStackPointerValue() +{ + if(_state.EmulationMode) { + _state.SP = 0x100 | (_state.SP & 0xFF); + } +} + void SnesCpu::SetPS(uint8_t ps) { _state.PS = ps; diff --git a/Core/SNES/SnesCpu.h b/Core/SNES/SnesCpu.h index 82b42ce7c..9e2a53381 100644 --- a/Core/SNES/SnesCpu.h +++ b/Core/SNES/SnesCpu.h @@ -48,8 +48,8 @@ class SnesCpu : public ISerializable uint16_t GetDirectAddress(uint16_t offset, bool allowEmulationMode = true); - uint16_t GetDirectAddressIndirectWord(uint16_t offset, bool allowEmulationMode = true); - uint32_t GetDirectAddressIndirectLong(uint16_t offset, bool allowEmulationMode = true); + uint16_t GetDirectAddressIndirectWord(uint16_t offset); + uint32_t GetDirectAddressIndirectLong(uint16_t offset); uint8_t GetOpCode(); @@ -72,7 +72,8 @@ class SnesCpu : public ISerializable uint8_t Read(uint32_t addr, MemoryOperationType type); - void SetSP(uint16_t sp); + void SetSP(uint16_t sp, bool allowEmulationMode = true); + __forceinline void RestrictStackPointerValue(); void SetPS(uint8_t ps); void SetRegister(uint8_t ®, uint8_t value); @@ -100,11 +101,11 @@ class SnesCpu : public ISerializable uint16_t GetWordValue(); - void PushByte(uint8_t value); - uint8_t PopByte(); + void PushByte(uint8_t value, bool allowEmulationMode = true); + uint8_t PopByte(bool allowEmulationMode = true); - void PushWord(uint16_t value); - uint16_t PopWord(); + void PushWord(uint16_t value, bool allowEmulationMode = true); + uint16_t PopWord(bool allowEmulationMode = true); //Add/subtract instructions void Add8(uint8_t value);