Skip to content

Commit

Permalink
SNES: Fixed CPU 6502 emulation mode edge case regarding wrapping beha…
Browse files Browse the repository at this point in the history
…vior for (direct, x) addressing mode
  • Loading branch information
SourMesen committed Oct 29, 2023
1 parent 020b29f commit c0ea124
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 1 deletion.
1 change: 1 addition & 0 deletions Core/SNES/Coprocessors/SA1/Sa1Cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Sa1Cpu : public ISerializable
uint16_t GetDirectAddress(uint16_t offset, bool allowEmulationMode = true);

uint16_t GetDirectAddressIndirectWord(uint16_t offset);
uint16_t GetDirectAddressIndirectWordWithPageWrap(uint16_t offset);
uint32_t GetDirectAddressIndirectLong(uint16_t offset);

uint8_t GetOpCode();
Expand Down
2 changes: 1 addition & 1 deletion Core/SNES/SnesCpu.Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ void SnesCpu::AddrMode_DirIdxIndX()
{
uint8_t operandByte = ReadDirectOperandByte();
Idle();
_operand = GetDataAddress(GetDirectAddressIndirectWord(operandByte + _state.X));
_operand = GetDataAddress(GetDirectAddressIndirectWordWithPageWrap(operandByte + _state.X));
}

void SnesCpu::AddrMode_DirIndIdxY(bool isWrite)
Expand Down
18 changes: 18 additions & 0 deletions Core/SNES/SnesCpu.Shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,24 @@ uint16_t SnesCpu::GetDirectAddress(uint16_t offset, bool allowEmulationMode)
}
}

uint16_t SnesCpu::GetDirectAddressIndirectWordWithPageWrap(uint16_t offset)
{
uint8_t lsb = ReadData(GetDirectAddress(offset + 0));
if(!_state.EmulationMode || (_state.D & 0xFF) == 0) {
return (ReadData(GetDirectAddress(offset + 1)) << 8) | lsb;
} else {
uint16_t addr = GetDirectAddress(offset + 1);
uint8_t msb;
if((addr & 0xFF) == 0) {
//Crossed to next page, wrap around to start of previous page instead (cpu bug?)
msb = ReadData((uint16_t)(addr - 0x100));
} else {
msb = ReadData(addr);
}
return (msb << 8) | lsb;
}
}

uint16_t SnesCpu::GetDirectAddressIndirectWord(uint16_t offset)
{
uint8_t lsb = ReadData(GetDirectAddress(offset + 0));
Expand Down
1 change: 1 addition & 0 deletions Core/SNES/SnesCpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class SnesCpu : public ISerializable
uint16_t GetDirectAddress(uint16_t offset, bool allowEmulationMode = true);

uint16_t GetDirectAddressIndirectWord(uint16_t offset);
uint16_t GetDirectAddressIndirectWordWithPageWrap(uint16_t offset);
uint32_t GetDirectAddressIndirectLong(uint16_t offset);

uint8_t GetOpCode();
Expand Down

0 comments on commit c0ea124

Please sign in to comment.