Bus: Handle unaligned accesses in safe memory routines

This commit is contained in:
Connor McLaughlin 2021-09-15 12:23:05 +10:00
parent 14865d0007
commit f7f121f036

View file

@ -1960,6 +1960,8 @@ bool SafeReadMemoryByte(VirtualMemoryAddress addr, u8* value)
} }
bool SafeReadMemoryHalfWord(VirtualMemoryAddress addr, u16* value) bool SafeReadMemoryHalfWord(VirtualMemoryAddress addr, u16* value)
{
if ((addr & 1) == 0)
{ {
u32 temp = 0; u32 temp = 0;
if (!DoSafeMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::HalfWord>(addr, temp)) if (!DoSafeMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::HalfWord>(addr, temp))
@ -1969,9 +1971,25 @@ bool SafeReadMemoryHalfWord(VirtualMemoryAddress addr, u16* value)
return true; return true;
} }
u8 low, high;
if (!SafeReadMemoryByte(addr, &low) || !SafeReadMemoryByte(addr + 1, &high))
return false;
*value = (ZeroExtend16(high) << 8) | ZeroExtend16(low);
return true;
}
bool SafeReadMemoryWord(VirtualMemoryAddress addr, u32* value) bool SafeReadMemoryWord(VirtualMemoryAddress addr, u32* value)
{ {
if ((addr & 3) == 0)
return DoSafeMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::Word>(addr, *value); return DoSafeMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::Word>(addr, *value);
u16 low, high;
if (!SafeReadMemoryHalfWord(addr, &low) || !SafeReadMemoryHalfWord(addr + 2, &high))
return false;
*value = (ZeroExtend32(high) << 16) | ZeroExtend32(low);
return true;
} }
bool SafeWriteMemoryByte(VirtualMemoryAddress addr, u8 value) bool SafeWriteMemoryByte(VirtualMemoryAddress addr, u8 value)
@ -1981,14 +1999,23 @@ bool SafeWriteMemoryByte(VirtualMemoryAddress addr, u8 value)
} }
bool SafeWriteMemoryHalfWord(VirtualMemoryAddress addr, u16 value) bool SafeWriteMemoryHalfWord(VirtualMemoryAddress addr, u16 value)
{
if ((addr & 1) == 0)
{ {
u32 temp = ZeroExtend32(value); u32 temp = ZeroExtend32(value);
return DoSafeMemoryAccess<MemoryAccessType::Write, MemoryAccessSize::HalfWord>(addr, temp); return DoSafeMemoryAccess<MemoryAccessType::Write, MemoryAccessSize::HalfWord>(addr, temp);
} }
return SafeWriteMemoryByte(addr, Truncate8(value)) && SafeWriteMemoryByte(addr + 1, Truncate8(value >> 8));
}
bool SafeWriteMemoryWord(VirtualMemoryAddress addr, u32 value) bool SafeWriteMemoryWord(VirtualMemoryAddress addr, u32 value)
{ {
if ((addr & 3) == 0)
return DoSafeMemoryAccess<MemoryAccessType::Write, MemoryAccessSize::Word>(addr, value); return DoSafeMemoryAccess<MemoryAccessType::Write, MemoryAccessSize::Word>(addr, value);
return SafeWriteMemoryHalfWord(addr, Truncate16(value >> 16)) &&
SafeWriteMemoryHalfWord(addr + 2, Truncate16(value >> 16));
} }
void* GetDirectReadMemoryPointer(VirtualMemoryAddress address, MemoryAccessSize size, TickCount* read_ticks) void* GetDirectReadMemoryPointer(VirtualMemoryAddress address, MemoryAccessSize size, TickCount* read_ticks)