Merge 20f1bbf7c6
into 53b54406bd
This commit is contained in:
commit
342ddf0a64
|
@ -1354,8 +1354,8 @@ u32 AchievementManager::MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_
|
|||
address += (MEM2_START - MEM1_SIZE);
|
||||
for (u32 num_read = 0; num_read < num_bytes; num_read++)
|
||||
{
|
||||
auto value = system.GetMMU().HostTryReadU8(thread_guard, address + num_read,
|
||||
PowerPC::RequestedAddressSpace::Physical);
|
||||
auto value = system.GetMMU().HostTryRead<u8>(thread_guard, address + num_read,
|
||||
PowerPC::RequestedAddressSpace::Physical);
|
||||
if (!value.has_value())
|
||||
return num_read;
|
||||
buffer[num_read] = value.value().value;
|
||||
|
|
|
@ -379,7 +379,7 @@ static bool Subtype_RamWriteAndFill(const Core::CPUThreadGuard& guard, const ARA
|
|||
const u32 repeat = data >> 8;
|
||||
for (u32 i = 0; i <= repeat; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, data & 0xFF, new_addr + i);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, data & 0xFF, new_addr + i);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", data & 0xFF, new_addr + i);
|
||||
}
|
||||
LogInfo("--------");
|
||||
|
@ -393,7 +393,7 @@ static bool Subtype_RamWriteAndFill(const Core::CPUThreadGuard& guard, const ARA
|
|||
const u32 repeat = data >> 16;
|
||||
for (u32 i = 0; i <= repeat; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U16(guard, data & 0xFFFF, new_addr + i * 2);
|
||||
PowerPC::MMU::HostWrite<u16>(guard, data & 0xFFFF, new_addr + i * 2);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", data & 0xFFFF, new_addr + i * 2);
|
||||
}
|
||||
LogInfo("--------");
|
||||
|
@ -404,7 +404,7 @@ static bool Subtype_RamWriteAndFill(const Core::CPUThreadGuard& guard, const ARA
|
|||
case DATATYPE_32BIT: // Dword write
|
||||
LogInfo("32-bit Write");
|
||||
LogInfo("--------");
|
||||
PowerPC::MMU::HostWrite_U32(guard, data, new_addr);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, data, new_addr);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", data, new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
@ -424,7 +424,7 @@ static bool Subtype_WriteToPointer(const Core::CPUThreadGuard& guard, const ARAd
|
|||
const u32 data)
|
||||
{
|
||||
const u32 new_addr = addr.GCAddress();
|
||||
const u32 ptr = PowerPC::MMU::HostRead_U32(guard, new_addr);
|
||||
const u32 ptr = PowerPC::MMU::HostRead<u32>(guard, new_addr);
|
||||
|
||||
LogInfo("Hardware Address: {:08x}", new_addr);
|
||||
LogInfo("Size: {:08x}", addr.size);
|
||||
|
@ -440,7 +440,7 @@ static bool Subtype_WriteToPointer(const Core::CPUThreadGuard& guard, const ARAd
|
|||
LogInfo("Pointer: {:08x}", ptr);
|
||||
LogInfo("Byte: {:08x}", thebyte);
|
||||
LogInfo("Offset: {:08x}", offset);
|
||||
PowerPC::MMU::HostWrite_U8(guard, thebyte, ptr + offset);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, thebyte, ptr + offset);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", thebyte, ptr + offset);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
@ -455,7 +455,7 @@ static bool Subtype_WriteToPointer(const Core::CPUThreadGuard& guard, const ARAd
|
|||
LogInfo("Pointer: {:08x}", ptr);
|
||||
LogInfo("Byte: {:08x}", theshort);
|
||||
LogInfo("Offset: {:08x}", offset);
|
||||
PowerPC::MMU::HostWrite_U16(guard, theshort, ptr + offset);
|
||||
PowerPC::MMU::HostWrite<u16>(guard, theshort, ptr + offset);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", theshort, ptr + offset);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
@ -465,7 +465,7 @@ static bool Subtype_WriteToPointer(const Core::CPUThreadGuard& guard, const ARAd
|
|||
case DATATYPE_32BIT:
|
||||
LogInfo("Write 32-bit to pointer");
|
||||
LogInfo("--------");
|
||||
PowerPC::MMU::HostWrite_U32(guard, data, ptr);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, data, ptr);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", data, ptr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
@ -493,17 +493,19 @@ static bool Subtype_AddCode(const Core::CPUThreadGuard& guard, const ARAddr& add
|
|||
case DATATYPE_8BIT:
|
||||
LogInfo("8-bit Add");
|
||||
LogInfo("--------");
|
||||
PowerPC::MMU::HostWrite_U8(guard, PowerPC::MMU::HostRead_U8(guard, new_addr) + data, new_addr);
|
||||
LogInfo("Wrote {:02x} to address {:08x}", PowerPC::MMU::HostRead_U8(guard, new_addr), new_addr);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, PowerPC::MMU::HostRead<u8>(guard, new_addr) + data,
|
||||
new_addr);
|
||||
LogInfo("Wrote {:02x} to address {:08x}", PowerPC::MMU::HostRead<u8>(guard, new_addr),
|
||||
new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
||||
case DATATYPE_16BIT:
|
||||
LogInfo("16-bit Add");
|
||||
LogInfo("--------");
|
||||
PowerPC::MMU::HostWrite_U16(guard, PowerPC::MMU::HostRead_U16(guard, new_addr) + data,
|
||||
new_addr);
|
||||
LogInfo("Wrote {:04x} to address {:08x}", PowerPC::MMU::HostRead_U16(guard, new_addr),
|
||||
PowerPC::MMU::HostWrite<u16>(guard, PowerPC::MMU::HostRead<u16>(guard, new_addr) + data,
|
||||
new_addr);
|
||||
LogInfo("Wrote {:04x} to address {:08x}", PowerPC::MMU::HostRead<u16>(guard, new_addr),
|
||||
new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
@ -511,9 +513,9 @@ static bool Subtype_AddCode(const Core::CPUThreadGuard& guard, const ARAddr& add
|
|||
case DATATYPE_32BIT:
|
||||
LogInfo("32-bit Add");
|
||||
LogInfo("--------");
|
||||
PowerPC::MMU::HostWrite_U32(guard, PowerPC::MMU::HostRead_U32(guard, new_addr) + data,
|
||||
new_addr);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead_U32(guard, new_addr),
|
||||
PowerPC::MMU::HostWrite<u32>(guard, PowerPC::MMU::HostRead<u32>(guard, new_addr) + data,
|
||||
new_addr);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead<u32>(guard, new_addr),
|
||||
new_addr);
|
||||
LogInfo("--------");
|
||||
break;
|
||||
|
@ -523,12 +525,12 @@ static bool Subtype_AddCode(const Core::CPUThreadGuard& guard, const ARAddr& add
|
|||
LogInfo("32-bit floating Add");
|
||||
LogInfo("--------");
|
||||
|
||||
const u32 read = PowerPC::MMU::HostRead_U32(guard, new_addr);
|
||||
const u32 read = PowerPC::MMU::HostRead<u32>(guard, new_addr);
|
||||
const float read_float = std::bit_cast<float>(read);
|
||||
// data contains an (unsigned?) integer value
|
||||
const float fread = read_float + static_cast<float>(data);
|
||||
const u32 newval = std::bit_cast<u32>(fread);
|
||||
PowerPC::MMU::HostWrite_U32(guard, newval, new_addr);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, newval, new_addr);
|
||||
LogInfo("Old Value {:08x}", read);
|
||||
LogInfo("Increment {:08x}", data);
|
||||
LogInfo("New value {:08x}", newval);
|
||||
|
@ -586,7 +588,7 @@ static bool ZeroCode_FillAndSlide(const Core::CPUThreadGuard& guard, const u32 v
|
|||
LogInfo("--------");
|
||||
for (int i = 0; i < write_num; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, val & 0xFF, curr_addr);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, val & 0xFF, curr_addr);
|
||||
curr_addr += addr_incr;
|
||||
val += val_incr;
|
||||
LogInfo("Write {:08x} to address {:08x}", val & 0xFF, curr_addr);
|
||||
|
@ -602,7 +604,7 @@ static bool ZeroCode_FillAndSlide(const Core::CPUThreadGuard& guard, const u32 v
|
|||
LogInfo("--------");
|
||||
for (int i = 0; i < write_num; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U16(guard, val & 0xFFFF, curr_addr);
|
||||
PowerPC::MMU::HostWrite<u16>(guard, val & 0xFFFF, curr_addr);
|
||||
LogInfo("Write {:08x} to address {:08x}", val & 0xFFFF, curr_addr);
|
||||
curr_addr += addr_incr * 2;
|
||||
val += val_incr;
|
||||
|
@ -617,7 +619,7 @@ static bool ZeroCode_FillAndSlide(const Core::CPUThreadGuard& guard, const u32 v
|
|||
LogInfo("--------");
|
||||
for (int i = 0; i < write_num; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U32(guard, val, curr_addr);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, val, curr_addr);
|
||||
LogInfo("Write {:08x} to address {:08x}", val, curr_addr);
|
||||
curr_addr += addr_incr * 4;
|
||||
val += val_incr;
|
||||
|
@ -658,15 +660,15 @@ static bool ZeroCode_MemoryCopy(const Core::CPUThreadGuard& guard, const u32 val
|
|||
{ // Memory Copy With Pointers Support
|
||||
LogInfo("Memory Copy With Pointers Support");
|
||||
LogInfo("--------");
|
||||
const u32 ptr_dest = PowerPC::MMU::HostRead_U32(guard, addr_dest);
|
||||
const u32 ptr_dest = PowerPC::MMU::HostRead<u32>(guard, addr_dest);
|
||||
LogInfo("Resolved Dest Address to: {:08x}", ptr_dest);
|
||||
const u32 ptr_src = PowerPC::MMU::HostRead_U32(guard, addr_src);
|
||||
const u32 ptr_src = PowerPC::MMU::HostRead<u32>(guard, addr_src);
|
||||
LogInfo("Resolved Src Address to: {:08x}", ptr_src);
|
||||
for (int i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, PowerPC::MMU::HostRead_U8(guard, ptr_src + i),
|
||||
ptr_dest + i);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead_U8(guard, ptr_src + i),
|
||||
PowerPC::MMU::HostWrite<u8>(guard, PowerPC::MMU::HostRead<u8>(guard, ptr_src + i),
|
||||
ptr_dest + i);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead<u8>(guard, ptr_src + i),
|
||||
ptr_dest + i);
|
||||
}
|
||||
LogInfo("--------");
|
||||
|
@ -677,9 +679,9 @@ static bool ZeroCode_MemoryCopy(const Core::CPUThreadGuard& guard, const u32 val
|
|||
LogInfo("--------");
|
||||
for (int i = 0; i < num_bytes; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, PowerPC::MMU::HostRead_U8(guard, addr_src + i),
|
||||
addr_dest + i);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead_U8(guard, addr_src + i),
|
||||
PowerPC::MMU::HostWrite<u8>(guard, PowerPC::MMU::HostRead<u8>(guard, addr_src + i),
|
||||
addr_dest + i);
|
||||
LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead<u8>(guard, addr_src + i),
|
||||
addr_dest + i);
|
||||
}
|
||||
LogInfo("--------");
|
||||
|
@ -787,16 +789,17 @@ static bool ConditionalCode(const Core::CPUThreadGuard& guard, const ARAddr& add
|
|||
switch (addr.size)
|
||||
{
|
||||
case DATATYPE_8BIT:
|
||||
result = CompareValues(PowerPC::MMU::HostRead_U8(guard, new_addr), (data & 0xFF), addr.type);
|
||||
result = CompareValues(PowerPC::MMU::HostRead<u8>(guard, new_addr), (data & 0xFF), addr.type);
|
||||
break;
|
||||
|
||||
case DATATYPE_16BIT:
|
||||
result = CompareValues(PowerPC::MMU::HostRead_U16(guard, new_addr), (data & 0xFFFF), addr.type);
|
||||
result =
|
||||
CompareValues(PowerPC::MMU::HostRead<u16>(guard, new_addr), (data & 0xFFFF), addr.type);
|
||||
break;
|
||||
|
||||
case DATATYPE_32BIT_FLOAT:
|
||||
case DATATYPE_32BIT:
|
||||
result = CompareValues(PowerPC::MMU::HostRead_U32(guard, new_addr), data, addr.type);
|
||||
result = CompareValues(PowerPC::MMU::HostRead<u32>(guard, new_addr), data, addr.type);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -52,7 +52,7 @@ void PresetTimeBaseTicks(Core::System& system, const Core::CPUThreadGuard& guard
|
|||
|
||||
const u64 time_base_ticks = emulated_time * 40500000ULL;
|
||||
|
||||
PowerPC::MMU::HostWrite_U64(guard, time_base_ticks, 0x800030D8);
|
||||
PowerPC::MMU::HostWrite<u64>(guard, time_base_ticks, 0x800030D8);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
|
@ -172,14 +172,14 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard
|
|||
ppc_state.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
ppc_state.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(system, *entry);
|
||||
const u32 iAppLoaderInit = mmu.Read_U32(iAppLoaderFuncAddr + 0);
|
||||
const u32 iAppLoaderMain = mmu.Read_U32(iAppLoaderFuncAddr + 4);
|
||||
const u32 iAppLoaderClose = mmu.Read_U32(iAppLoaderFuncAddr + 8);
|
||||
const u32 iAppLoaderInit = mmu.Read<u32>(iAppLoaderFuncAddr + 0);
|
||||
const u32 iAppLoaderMain = mmu.Read<u32>(iAppLoaderFuncAddr + 4);
|
||||
const u32 iAppLoaderClose = mmu.Read<u32>(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG_FMT(BOOT, "Call iAppLoaderInit");
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x4E800020, 0x81300000); // Write BLR
|
||||
HLE::Patch(system, 0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x4E800020, 0x81300000); // Write BLR
|
||||
HLE::Patch(system, 0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader
|
||||
ppc_state.gpr[3] = 0x81300000;
|
||||
RunFunction(system, iAppLoaderInit);
|
||||
|
||||
|
@ -200,9 +200,9 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard
|
|||
// iAppLoaderMain returns 0 when there are no more sections to copy.
|
||||
while (ppc_state.gpr[3] != 0x00)
|
||||
{
|
||||
const u32 ram_address = mmu.Read_U32(0x81300004);
|
||||
const u32 length = mmu.Read_U32(0x81300008);
|
||||
const u32 dvd_offset = mmu.Read_U32(0x8130000c) << (is_wii ? 2 : 0);
|
||||
const u32 ram_address = mmu.Read<u32>(0x81300004);
|
||||
const u32 length = mmu.Read<u32>(0x81300008);
|
||||
const u32 dvd_offset = mmu.Read<u32>(0x8130000c) << (is_wii ? 2 : 0);
|
||||
|
||||
INFO_LOG_FMT(BOOT, "DVDRead: offset: {:08x} memOffset: {:08x} length: {}", dvd_offset,
|
||||
ram_address, length);
|
||||
|
@ -243,35 +243,36 @@ void CBoot::SetupGCMemory(Core::System& system, const Core::CPUThreadGuard& guar
|
|||
auto& memory = system.GetMemory();
|
||||
|
||||
// Booted from bootrom. 0xE5207C22 = booted from jtag
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x0D15EA5E, 0x80000020);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x0D15EA5E, 0x80000020);
|
||||
|
||||
// Physical Memory Size (24MB on retail)
|
||||
PowerPC::MMU::HostWrite_U32(guard, memory.GetRamSizeReal(), 0x80000028);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, memory.GetRamSizeReal(), 0x80000028);
|
||||
|
||||
// Console type - DevKit (retail ID == 0x00000003) see YAGCD 4.2.1.1.2
|
||||
// TODO: determine why some games fail when using a retail ID.
|
||||
// (Seem to take different EXI paths, see Ikaruga for example)
|
||||
const u32 console_type = static_cast<u32>(Core::ConsoleType::LatestDevkit);
|
||||
PowerPC::MMU::HostWrite_U32(guard, console_type, 0x8000002C);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, console_type, 0x8000002C);
|
||||
|
||||
// Fake the VI Init of the IPL (YAGCD 4.2.1.4)
|
||||
PowerPC::MMU::HostWrite_U32(guard, DiscIO::IsNTSC(SConfig::GetInstance().m_region) ? 0 : 1,
|
||||
0x800000CC);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, DiscIO::IsNTSC(SConfig::GetInstance().m_region) ? 0 : 1,
|
||||
0x800000CC);
|
||||
|
||||
// ARAM Size. 16MB main + 4/16/32MB external. (retail consoles have no external ARAM)
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x01000000, 0x800000d0);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x01000000, 0x800000d0);
|
||||
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x09a7ec80, 0x800000F8); // Bus Clock Speed
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x1cf7c580, 0x800000FC); // CPU Clock Speed
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x09a7ec80, 0x800000F8); // Bus Clock Speed
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x1cf7c580, 0x800000FC); // CPU Clock Speed
|
||||
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x4c000064, 0x80000300); // Write default DSI Handler: rfi
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x4c000064, 0x80000C00); // Write default Syscall Handler: rfi
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x4c000064, 0x80000300); // Write default DSI Handler: rfi
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x4c000064, 0x80000800); // Write default FPU Handler: rfi
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x4c000064,
|
||||
0x80000C00); // Write default Syscall Handler: rfi
|
||||
|
||||
PresetTimeBaseTicks(system, guard);
|
||||
|
||||
// HIO checks this
|
||||
// PowerPC::MMU::HostWrite_U16(0x8200, 0x000030e6); // Console type
|
||||
// PowerPC::MMU::HostWrite_UX<u16>(0x8200, 0x000030e6); // Console type
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
|
|
|
@ -100,106 +100,14 @@ std::vector<u8> Cheats::GetValueAsByteVector(const Cheats::SearchValue& value)
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
static std::optional<PowerPC::ReadResult<T>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space);
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<u8>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
return PowerPC::MMU::HostTryReadU8(guard, addr, space);
|
||||
return PowerPC::MMU::HostTryRead<T>(guard, addr, space);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<u16>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
return PowerPC::MMU::HostTryReadU16(guard, addr, space);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<u32>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
return PowerPC::MMU::HostTryReadU32(guard, addr, space);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<u64>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
return PowerPC::MMU::HostTryReadU64(guard, addr, space);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<s8>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
auto tmp = PowerPC::MMU::HostTryReadU8(guard, addr, space);
|
||||
if (!tmp)
|
||||
return std::nullopt;
|
||||
return PowerPC::ReadResult<s8>(tmp->translated, std::bit_cast<s8>(tmp->value));
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<s16>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
auto tmp = PowerPC::MMU::HostTryReadU16(guard, addr, space);
|
||||
if (!tmp)
|
||||
return std::nullopt;
|
||||
return PowerPC::ReadResult<s16>(tmp->translated, std::bit_cast<s16>(tmp->value));
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<s32>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
auto tmp = PowerPC::MMU::HostTryReadU32(guard, addr, space);
|
||||
if (!tmp)
|
||||
return std::nullopt;
|
||||
return PowerPC::ReadResult<s32>(tmp->translated, std::bit_cast<s32>(tmp->value));
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<s64>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
auto tmp = PowerPC::MMU::HostTryReadU64(guard, addr, space);
|
||||
if (!tmp)
|
||||
return std::nullopt;
|
||||
return PowerPC::ReadResult<s64>(tmp->translated, std::bit_cast<s64>(tmp->value));
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<float>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
return PowerPC::MMU::HostTryReadF32(guard, addr, space);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<PowerPC::ReadResult<double>>
|
||||
TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr,
|
||||
PowerPC::RequestedAddressSpace space)
|
||||
{
|
||||
return PowerPC::MMU::HostTryReadF64(guard, addr, space);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename T>
|
||||
Common::Result<Cheats::SearchErrorCode, std::vector<Cheats::SearchResult<T>>>
|
||||
Cheats::NewSearch(const Core::CPUThreadGuard& guard,
|
||||
|
@ -597,6 +505,23 @@ bool Cheats::CheatSearchSession<T>::WasFirstSearchDone() const
|
|||
return m_first_search_done;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Cheats::CheatSearchSession<T>::WriteValue(const Core::CPUThreadGuard& guard,
|
||||
std::span<u32> addresses) const
|
||||
{
|
||||
if (!m_value)
|
||||
return false;
|
||||
|
||||
T value = m_value.value();
|
||||
bool result = true;
|
||||
for (auto address : addresses)
|
||||
{
|
||||
if (!PowerPC::MMU::HostTryWrite<T>(guard, value, address, m_address_space).has_value())
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<Cheats::CheatSearchSessionBase> Cheats::CheatSearchSession<T>::Clone() const
|
||||
{
|
||||
|
|
|
@ -165,6 +165,8 @@ public:
|
|||
virtual SearchResultValueState GetResultValueState(size_t index) const = 0;
|
||||
virtual bool WasFirstSearchDone() const = 0;
|
||||
|
||||
virtual bool WriteValue(const Core::CPUThreadGuard&, std::span<u32>) const = 0;
|
||||
|
||||
// Create a complete copy of this search session.
|
||||
virtual std::unique_ptr<CheatSearchSessionBase> Clone() const = 0;
|
||||
|
||||
|
@ -212,6 +214,8 @@ public:
|
|||
SearchResultValueState GetResultValueState(size_t index) const override;
|
||||
bool WasFirstSearchDone() const override;
|
||||
|
||||
bool WriteValue(const Core::CPUThreadGuard&, std::span<u32>) const override;
|
||||
|
||||
std::unique_ptr<CheatSearchSessionBase> Clone() const override;
|
||||
std::unique_ptr<CheatSearchSessionBase> ClonePartial(size_t begin_index,
|
||||
size_t end_index) const override;
|
||||
|
|
|
@ -34,18 +34,18 @@ static void WalkTheStack(const Core::CPUThreadGuard& guard,
|
|||
|
||||
if (!IsStackBottom(guard, ppc_state.gpr[1]))
|
||||
{
|
||||
u32 addr = PowerPC::MMU::HostRead_U32(guard, ppc_state.gpr[1]); // SP
|
||||
u32 addr = PowerPC::MMU::HostRead<u32>(guard, ppc_state.gpr[1]); // SP
|
||||
|
||||
// Walk the stack chain
|
||||
for (int count = 0; !IsStackBottom(guard, addr + 4) && (count < 20); ++count)
|
||||
{
|
||||
u32 func_addr = PowerPC::MMU::HostRead_U32(guard, addr + 4);
|
||||
u32 func_addr = PowerPC::MMU::HostRead<u32>(guard, addr + 4);
|
||||
stack_step(func_addr);
|
||||
|
||||
if (IsStackBottom(guard, addr))
|
||||
break;
|
||||
|
||||
addr = PowerPC::MMU::HostRead_U32(guard, addr);
|
||||
addr = PowerPC::MMU::HostRead<u32>(guard, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,23 +19,23 @@ namespace Core::Debug
|
|||
void OSContext::Read(const Core::CPUThreadGuard& guard, u32 addr)
|
||||
{
|
||||
for (std::size_t i = 0; i < gpr.size(); i++)
|
||||
gpr[i] = PowerPC::MMU::HostRead_U32(guard, addr + u32(i * sizeof(int)));
|
||||
cr = PowerPC::MMU::HostRead_U32(guard, addr + 0x80);
|
||||
lr = PowerPC::MMU::HostRead_U32(guard, addr + 0x84);
|
||||
ctr = PowerPC::MMU::HostRead_U32(guard, addr + 0x88);
|
||||
xer = PowerPC::MMU::HostRead_U32(guard, addr + 0x8C);
|
||||
gpr[i] = PowerPC::MMU::HostRead<u32>(guard, addr + u32(i * sizeof(int)));
|
||||
cr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x80);
|
||||
lr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x84);
|
||||
ctr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x88);
|
||||
xer = PowerPC::MMU::HostRead<u32>(guard, addr + 0x8C);
|
||||
for (std::size_t i = 0; i < fpr.size(); i++)
|
||||
fpr[i] = PowerPC::MMU::HostRead_F64(guard, addr + 0x90 + u32(i * sizeof(double)));
|
||||
fpscr = PowerPC::MMU::HostRead_U64(guard, addr + 0x190);
|
||||
srr0 = PowerPC::MMU::HostRead_U32(guard, addr + 0x198);
|
||||
srr1 = PowerPC::MMU::HostRead_U32(guard, addr + 0x19c);
|
||||
dummy = PowerPC::MMU::HostRead_U16(guard, addr + 0x1a0);
|
||||
state = static_cast<OSContext::State>(PowerPC::MMU::HostRead_U16(guard, addr + 0x1a2));
|
||||
fpr[i] = PowerPC::MMU::HostRead<double>(guard, addr + 0x90 + u32(i * sizeof(double)));
|
||||
fpscr = PowerPC::MMU::HostRead<u64>(guard, addr + 0x190);
|
||||
srr0 = PowerPC::MMU::HostRead<u32>(guard, addr + 0x198);
|
||||
srr1 = PowerPC::MMU::HostRead<u32>(guard, addr + 0x19c);
|
||||
dummy = PowerPC::MMU::HostRead<u16>(guard, addr + 0x1a0);
|
||||
state = static_cast<OSContext::State>(PowerPC::MMU::HostRead<u16>(guard, addr + 0x1a2));
|
||||
for (std::size_t i = 0; i < gqr.size(); i++)
|
||||
gqr[i] = PowerPC::MMU::HostRead_U32(guard, addr + 0x1a4 + u32(i * sizeof(int)));
|
||||
gqr[i] = PowerPC::MMU::HostRead<u32>(guard, addr + 0x1a4 + u32(i * sizeof(int)));
|
||||
psf_padding = 0;
|
||||
for (std::size_t i = 0; i < psf.size(); i++)
|
||||
psf[i] = PowerPC::MMU::HostRead_F64(guard, addr + 0x1c8 + u32(i * sizeof(double)));
|
||||
psf[i] = PowerPC::MMU::HostRead<double>(guard, addr + 0x1c8 + u32(i * sizeof(double)));
|
||||
}
|
||||
|
||||
// Mutex offsets based on the following functions:
|
||||
|
@ -44,12 +44,12 @@ void OSContext::Read(const Core::CPUThreadGuard& guard, u32 addr)
|
|||
// - __OSUnlockAllMutex
|
||||
void OSMutex::Read(const Core::CPUThreadGuard& guard, u32 addr)
|
||||
{
|
||||
thread_queue.head = PowerPC::MMU::HostRead_U32(guard, addr);
|
||||
thread_queue.tail = PowerPC::MMU::HostRead_U32(guard, addr + 0x4);
|
||||
owner_addr = PowerPC::MMU::HostRead_U32(guard, addr + 0x8);
|
||||
lock_count = PowerPC::MMU::HostRead_U32(guard, addr + 0xc);
|
||||
link.next = PowerPC::MMU::HostRead_U32(guard, addr + 0x10);
|
||||
link.prev = PowerPC::MMU::HostRead_U32(guard, addr + 0x14);
|
||||
thread_queue.head = PowerPC::MMU::HostRead<u32>(guard, addr);
|
||||
thread_queue.tail = PowerPC::MMU::HostRead<u32>(guard, addr + 0x4);
|
||||
owner_addr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x8);
|
||||
lock_count = PowerPC::MMU::HostRead<u32>(guard, addr + 0xc);
|
||||
link.next = PowerPC::MMU::HostRead<u32>(guard, addr + 0x10);
|
||||
link.prev = PowerPC::MMU::HostRead<u32>(guard, addr + 0x14);
|
||||
}
|
||||
|
||||
// Thread offsets based on the following functions:
|
||||
|
@ -67,38 +67,38 @@ void OSMutex::Read(const Core::CPUThreadGuard& guard, u32 addr)
|
|||
void OSThread::Read(const Core::CPUThreadGuard& guard, u32 addr)
|
||||
{
|
||||
context.Read(guard, addr);
|
||||
state = PowerPC::MMU::HostRead_U16(guard, addr + 0x2c8);
|
||||
is_detached = PowerPC::MMU::HostRead_U16(guard, addr + 0x2ca);
|
||||
suspend = PowerPC::MMU::HostRead_U32(guard, addr + 0x2cc);
|
||||
effective_priority = PowerPC::MMU::HostRead_U32(guard, addr + 0x2d0);
|
||||
base_priority = PowerPC::MMU::HostRead_U32(guard, addr + 0x2d4);
|
||||
exit_code_addr = PowerPC::MMU::HostRead_U32(guard, addr + 0x2d8);
|
||||
state = PowerPC::MMU::HostRead<u16>(guard, addr + 0x2c8);
|
||||
is_detached = PowerPC::MMU::HostRead<u16>(guard, addr + 0x2ca);
|
||||
suspend = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2cc);
|
||||
effective_priority = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2d0);
|
||||
base_priority = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2d4);
|
||||
exit_code_addr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2d8);
|
||||
|
||||
queue_addr = PowerPC::MMU::HostRead_U32(guard, addr + 0x2dc);
|
||||
queue_link.next = PowerPC::MMU::HostRead_U32(guard, addr + 0x2e0);
|
||||
queue_link.prev = PowerPC::MMU::HostRead_U32(guard, addr + 0x2e4);
|
||||
queue_addr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2dc);
|
||||
queue_link.next = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2e0);
|
||||
queue_link.prev = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2e4);
|
||||
|
||||
join_queue.head = PowerPC::MMU::HostRead_U32(guard, addr + 0x2e8);
|
||||
join_queue.tail = PowerPC::MMU::HostRead_U32(guard, addr + 0x2ec);
|
||||
join_queue.head = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2e8);
|
||||
join_queue.tail = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2ec);
|
||||
|
||||
mutex_addr = PowerPC::MMU::HostRead_U32(guard, addr + 0x2f0);
|
||||
mutex_queue.head = PowerPC::MMU::HostRead_U32(guard, addr + 0x2f4);
|
||||
mutex_queue.tail = PowerPC::MMU::HostRead_U32(guard, addr + 0x2f8);
|
||||
mutex_addr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2f0);
|
||||
mutex_queue.head = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2f4);
|
||||
mutex_queue.tail = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2f8);
|
||||
|
||||
thread_link.next = PowerPC::MMU::HostRead_U32(guard, addr + 0x2fc);
|
||||
thread_link.prev = PowerPC::MMU::HostRead_U32(guard, addr + 0x300);
|
||||
thread_link.next = PowerPC::MMU::HostRead<u32>(guard, addr + 0x2fc);
|
||||
thread_link.prev = PowerPC::MMU::HostRead<u32>(guard, addr + 0x300);
|
||||
|
||||
stack_addr = PowerPC::MMU::HostRead_U32(guard, addr + 0x304);
|
||||
stack_end = PowerPC::MMU::HostRead_U32(guard, addr + 0x308);
|
||||
error = PowerPC::MMU::HostRead_U32(guard, addr + 0x30c);
|
||||
specific[0] = PowerPC::MMU::HostRead_U32(guard, addr + 0x310);
|
||||
specific[1] = PowerPC::MMU::HostRead_U32(guard, addr + 0x314);
|
||||
stack_addr = PowerPC::MMU::HostRead<u32>(guard, addr + 0x304);
|
||||
stack_end = PowerPC::MMU::HostRead<u32>(guard, addr + 0x308);
|
||||
error = PowerPC::MMU::HostRead<u32>(guard, addr + 0x30c);
|
||||
specific[0] = PowerPC::MMU::HostRead<u32>(guard, addr + 0x310);
|
||||
specific[1] = PowerPC::MMU::HostRead<u32>(guard, addr + 0x314);
|
||||
}
|
||||
|
||||
bool OSThread::IsValid(const Core::CPUThreadGuard& guard) const
|
||||
{
|
||||
return PowerPC::MMU::HostIsRAMAddress(guard, stack_end) &&
|
||||
PowerPC::MMU::HostRead_U32(guard, stack_end) == STACK_MAGIC;
|
||||
PowerPC::MMU::HostRead<u32>(guard, stack_end) == STACK_MAGIC;
|
||||
}
|
||||
|
||||
OSThreadView::OSThreadView(const Core::CPUThreadGuard& guard, u32 addr)
|
||||
|
|
|
@ -48,13 +48,13 @@ void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, Common::Debug::MemoryPa
|
|||
{
|
||||
if (store_existing_value)
|
||||
{
|
||||
const u8 value = PowerPC::MMU::HostRead_U8(guard, address + offset);
|
||||
PowerPC::MMU::HostWrite_U8(guard, patch.value[offset], address + offset);
|
||||
const u8 value = PowerPC::MMU::HostRead<u8>(guard, address + offset);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, patch.value[offset], address + offset);
|
||||
patch.value[offset] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, patch.value[offset], address + offset);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, patch.value[offset], address + offset);
|
||||
}
|
||||
|
||||
if (((address + offset) % 4) == 3)
|
||||
|
@ -242,7 +242,7 @@ Common::Debug::Threads PPCDebugInterface::GetThreads(const Core::CPUThreadGuard&
|
|||
constexpr u32 ACTIVE_QUEUE_HEAD_ADDR = 0x800000dc;
|
||||
if (!PowerPC::MMU::HostIsRAMAddress(guard, ACTIVE_QUEUE_HEAD_ADDR))
|
||||
return threads;
|
||||
const u32 active_queue_head = PowerPC::MMU::HostRead_U32(guard, ACTIVE_QUEUE_HEAD_ADDR);
|
||||
const u32 active_queue_head = PowerPC::MMU::HostRead<u32>(guard, ACTIVE_QUEUE_HEAD_ADDR);
|
||||
if (!PowerPC::MMU::HostIsRAMAddress(guard, active_queue_head))
|
||||
return threads;
|
||||
|
||||
|
@ -323,7 +323,7 @@ std::string PPCDebugInterface::GetRawMemoryString(const Core::CPUThreadGuard& gu
|
|||
|
||||
u32 PPCDebugInterface::ReadMemory(const Core::CPUThreadGuard& guard, u32 address) const
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U32(guard, address);
|
||||
return PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
}
|
||||
|
||||
u32 PPCDebugInterface::ReadExtraMemory(const Core::CPUThreadGuard& guard, int memory,
|
||||
|
@ -332,7 +332,7 @@ u32 PPCDebugInterface::ReadExtraMemory(const Core::CPUThreadGuard& guard, int me
|
|||
switch (memory)
|
||||
{
|
||||
case 0:
|
||||
return PowerPC::MMU::HostRead_U32(guard, address);
|
||||
return PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
case 1:
|
||||
{
|
||||
const auto& dsp = guard.GetSystem().GetDSP();
|
||||
|
|
|
@ -17,31 +17,32 @@
|
|||
void RSOHeaderView::Load(const Core::CPUThreadGuard& guard, u32 address)
|
||||
{
|
||||
m_address = address;
|
||||
m_header.entry.next_entry = PowerPC::MMU::HostRead_U32(guard, address);
|
||||
m_header.entry.prev_entry = PowerPC::MMU::HostRead_U32(guard, address + 0x04);
|
||||
m_header.entry.section_count = PowerPC::MMU::HostRead_U32(guard, address + 0x08);
|
||||
m_header.entry.section_table_offset = PowerPC::MMU::HostRead_U32(guard, address + 0xC);
|
||||
m_header.entry.name_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x10);
|
||||
m_header.entry.name_size = PowerPC::MMU::HostRead_U32(guard, address + 0x14);
|
||||
m_header.entry.version = PowerPC::MMU::HostRead_U32(guard, address + 0x18);
|
||||
m_header.entry.bss_size = PowerPC::MMU::HostRead_U32(guard, address + 0x1C);
|
||||
m_header.section_info.prolog_section_index = PowerPC::MMU::HostRead_U8(guard, address + 0x20);
|
||||
m_header.section_info.epilog_section_index = PowerPC::MMU::HostRead_U8(guard, address + 0x21);
|
||||
m_header.section_info.unresolved_section_index = PowerPC::MMU::HostRead_U8(guard, address + 0x22);
|
||||
m_header.section_info.bss_section_index = PowerPC::MMU::HostRead_U8(guard, address + 0x23);
|
||||
m_header.section_info.prolog_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x24);
|
||||
m_header.section_info.epilog_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x28);
|
||||
m_header.section_info.unresolved_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x2C);
|
||||
m_header.relocation_tables.internals_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x30);
|
||||
m_header.relocation_tables.internals_size = PowerPC::MMU::HostRead_U32(guard, address + 0x34);
|
||||
m_header.relocation_tables.externals_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x38);
|
||||
m_header.relocation_tables.externals_size = PowerPC::MMU::HostRead_U32(guard, address + 0x3C);
|
||||
m_header.symbol_tables.exports_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x40);
|
||||
m_header.symbol_tables.exports_size = PowerPC::MMU::HostRead_U32(guard, address + 0x44);
|
||||
m_header.symbol_tables.exports_name_table = PowerPC::MMU::HostRead_U32(guard, address + 0x48);
|
||||
m_header.symbol_tables.imports_offset = PowerPC::MMU::HostRead_U32(guard, address + 0x4C);
|
||||
m_header.symbol_tables.imports_size = PowerPC::MMU::HostRead_U32(guard, address + 0x50);
|
||||
m_header.symbol_tables.imports_name_table = PowerPC::MMU::HostRead_U32(guard, address + 0x54);
|
||||
m_header.entry.next_entry = PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
m_header.entry.prev_entry = PowerPC::MMU::HostRead<u32>(guard, address + 0x04);
|
||||
m_header.entry.section_count = PowerPC::MMU::HostRead<u32>(guard, address + 0x08);
|
||||
m_header.entry.section_table_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0xC);
|
||||
m_header.entry.name_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x10);
|
||||
m_header.entry.name_size = PowerPC::MMU::HostRead<u32>(guard, address + 0x14);
|
||||
m_header.entry.version = PowerPC::MMU::HostRead<u32>(guard, address + 0x18);
|
||||
m_header.entry.bss_size = PowerPC::MMU::HostRead<u32>(guard, address + 0x1C);
|
||||
m_header.section_info.prolog_section_index = PowerPC::MMU::HostRead<u8>(guard, address + 0x20);
|
||||
m_header.section_info.epilog_section_index = PowerPC::MMU::HostRead<u8>(guard, address + 0x21);
|
||||
m_header.section_info.unresolved_section_index =
|
||||
PowerPC::MMU::HostRead<u8>(guard, address + 0x22);
|
||||
m_header.section_info.bss_section_index = PowerPC::MMU::HostRead<u8>(guard, address + 0x23);
|
||||
m_header.section_info.prolog_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x24);
|
||||
m_header.section_info.epilog_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x28);
|
||||
m_header.section_info.unresolved_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x2C);
|
||||
m_header.relocation_tables.internals_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x30);
|
||||
m_header.relocation_tables.internals_size = PowerPC::MMU::HostRead<u32>(guard, address + 0x34);
|
||||
m_header.relocation_tables.externals_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x38);
|
||||
m_header.relocation_tables.externals_size = PowerPC::MMU::HostRead<u32>(guard, address + 0x3C);
|
||||
m_header.symbol_tables.exports_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x40);
|
||||
m_header.symbol_tables.exports_size = PowerPC::MMU::HostRead<u32>(guard, address + 0x44);
|
||||
m_header.symbol_tables.exports_name_table = PowerPC::MMU::HostRead<u32>(guard, address + 0x48);
|
||||
m_header.symbol_tables.imports_offset = PowerPC::MMU::HostRead<u32>(guard, address + 0x4C);
|
||||
m_header.symbol_tables.imports_size = PowerPC::MMU::HostRead<u32>(guard, address + 0x50);
|
||||
m_header.symbol_tables.imports_name_table = PowerPC::MMU::HostRead<u32>(guard, address + 0x54);
|
||||
|
||||
// Prevent an invalid name going wild
|
||||
if (m_header.entry.name_size < 0x100)
|
||||
|
@ -181,8 +182,8 @@ void RSOSectionsView::Load(const Core::CPUThreadGuard& guard, u32 address, std::
|
|||
for (std::size_t i = 0; i < count; ++i)
|
||||
{
|
||||
RSOSection section;
|
||||
section.offset = PowerPC::MMU::HostRead_U32(guard, address);
|
||||
section.size = PowerPC::MMU::HostRead_U32(guard, address + 4);
|
||||
section.offset = PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
section.size = PowerPC::MMU::HostRead<u32>(guard, address + 4);
|
||||
m_sections.emplace_back(std::move(section));
|
||||
address += sizeof(RSOSection);
|
||||
}
|
||||
|
@ -209,9 +210,9 @@ void RSOImportsView::Load(const Core::CPUThreadGuard& guard, u32 address, std::s
|
|||
for (std::size_t i = 0; i < count; ++i)
|
||||
{
|
||||
RSOImport rso_import;
|
||||
rso_import.name_offset = PowerPC::MMU::HostRead_U32(guard, address);
|
||||
rso_import.code_offset = PowerPC::MMU::HostRead_U32(guard, address + 4);
|
||||
rso_import.entry_offset = PowerPC::MMU::HostRead_U32(guard, address + 8);
|
||||
rso_import.name_offset = PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
rso_import.code_offset = PowerPC::MMU::HostRead<u32>(guard, address + 4);
|
||||
rso_import.entry_offset = PowerPC::MMU::HostRead<u32>(guard, address + 8);
|
||||
m_imports.emplace_back(std::move(rso_import));
|
||||
address += sizeof(RSOImport);
|
||||
}
|
||||
|
@ -238,10 +239,10 @@ void RSOExportsView::Load(const Core::CPUThreadGuard& guard, u32 address, std::s
|
|||
for (std::size_t i = 0; i < count; ++i)
|
||||
{
|
||||
RSOExport rso_export;
|
||||
rso_export.name_offset = PowerPC::MMU::HostRead_U32(guard, address);
|
||||
rso_export.code_offset = PowerPC::MMU::HostRead_U32(guard, address + 4);
|
||||
rso_export.section_index = PowerPC::MMU::HostRead_U32(guard, address + 8);
|
||||
rso_export.hash = PowerPC::MMU::HostRead_U32(guard, address + 12);
|
||||
rso_export.name_offset = PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
rso_export.code_offset = PowerPC::MMU::HostRead<u32>(guard, address + 4);
|
||||
rso_export.section_index = PowerPC::MMU::HostRead<u32>(guard, address + 8);
|
||||
rso_export.hash = PowerPC::MMU::HostRead<u32>(guard, address + 12);
|
||||
m_exports.emplace_back(std::move(rso_export));
|
||||
address += sizeof(RSOExport);
|
||||
}
|
||||
|
@ -268,9 +269,9 @@ void RSOInternalsView::Load(const Core::CPUThreadGuard& guard, u32 address, std:
|
|||
for (std::size_t i = 0; i < count; ++i)
|
||||
{
|
||||
RSOInternalsEntry entry;
|
||||
entry.r_offset = PowerPC::MMU::HostRead_U32(guard, address);
|
||||
entry.r_info = PowerPC::MMU::HostRead_U32(guard, address + 4);
|
||||
entry.r_addend = PowerPC::MMU::HostRead_U32(guard, address + 8);
|
||||
entry.r_offset = PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
entry.r_info = PowerPC::MMU::HostRead<u32>(guard, address + 4);
|
||||
entry.r_addend = PowerPC::MMU::HostRead<u32>(guard, address + 8);
|
||||
m_entries.emplace_back(std::move(entry));
|
||||
address += sizeof(RSOInternalsEntry);
|
||||
}
|
||||
|
@ -297,9 +298,9 @@ void RSOExternalsView::Load(const Core::CPUThreadGuard& guard, u32 address, std:
|
|||
for (std::size_t i = 0; i < count; ++i)
|
||||
{
|
||||
RSOExternalsEntry entry;
|
||||
entry.r_offset = PowerPC::MMU::HostRead_U32(guard, address);
|
||||
entry.r_info = PowerPC::MMU::HostRead_U32(guard, address + 4);
|
||||
entry.r_addend = PowerPC::MMU::HostRead_U32(guard, address + 8);
|
||||
entry.r_offset = PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
entry.r_info = PowerPC::MMU::HostRead<u32>(guard, address + 4);
|
||||
entry.r_addend = PowerPC::MMU::HostRead<u32>(guard, address + 8);
|
||||
m_entries.emplace_back(std::move(entry));
|
||||
address += sizeof(RSOExternalsEntry);
|
||||
}
|
||||
|
|
|
@ -712,12 +712,12 @@ void FifoPlayer::LoadTextureMemory()
|
|||
|
||||
void FifoPlayer::WriteCP(u32 address, u16 value)
|
||||
{
|
||||
m_system.GetMMU().Write_U16(value, 0xCC000000 | address);
|
||||
m_system.GetMMU().Write<u16>(value, 0xCC000000 | address);
|
||||
}
|
||||
|
||||
void FifoPlayer::WritePI(u32 address, u32 value)
|
||||
{
|
||||
m_system.GetMMU().Write_U32(value, 0xCC003000 | address);
|
||||
m_system.GetMMU().Write<u32>(value, 0xCC003000 | address);
|
||||
}
|
||||
|
||||
void FifoPlayer::FlushWGP()
|
||||
|
@ -816,13 +816,13 @@ bool FifoPlayer::ShouldLoadXF(u8 reg)
|
|||
bool FifoPlayer::IsIdleSet() const
|
||||
{
|
||||
CommandProcessor::UCPStatusReg status =
|
||||
m_system.GetMMU().Read_U16(0xCC000000 | CommandProcessor::STATUS_REGISTER);
|
||||
m_system.GetMMU().Read<u16>(0xCC000000 | CommandProcessor::STATUS_REGISTER);
|
||||
return status.CommandIdle;
|
||||
}
|
||||
|
||||
bool FifoPlayer::IsHighWatermarkSet() const
|
||||
{
|
||||
CommandProcessor::UCPStatusReg status =
|
||||
m_system.GetMMU().Read_U16(0xCC000000 | CommandProcessor::STATUS_REGISTER);
|
||||
m_system.GetMMU().Read<u16>(0xCC000000 | CommandProcessor::STATUS_REGISTER);
|
||||
return status.OverflowHiWatermark;
|
||||
}
|
||||
|
|
|
@ -130,17 +130,17 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
|
|||
|
||||
// Install code handler
|
||||
for (u32 i = 0; i < data.size(); ++i)
|
||||
PowerPC::MMU::HostWrite_U8(guard, data[i], INSTALLER_BASE_ADDRESS + i);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, data[i], INSTALLER_BASE_ADDRESS + i);
|
||||
|
||||
// Patch the code handler to the current system type (Gamecube/Wii)
|
||||
for (u32 h = 0; h < data.length(); h += 4)
|
||||
{
|
||||
// Patch MMIO address
|
||||
if (PowerPC::MMU::HostRead_U32(guard, INSTALLER_BASE_ADDRESS + h) ==
|
||||
if (PowerPC::MMU::HostRead<u32>(guard, INSTALLER_BASE_ADDRESS + h) ==
|
||||
(0x3f000000u | ((mmio_addr ^ 1) << 8)))
|
||||
{
|
||||
NOTICE_LOG_FMT(ACTIONREPLAY, "Patching MMIO access at {:08x}", INSTALLER_BASE_ADDRESS + h);
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x3f000000u | mmio_addr << 8, INSTALLER_BASE_ADDRESS + h);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x3f000000u | mmio_addr << 8, INSTALLER_BASE_ADDRESS + h);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,11 +150,11 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
|
|||
|
||||
// Write a magic value to 'gameid' (codehandleronly does not actually read this).
|
||||
// This value will be read back and modified over time by HLE_Misc::GeckoCodeHandlerICacheFlush.
|
||||
PowerPC::MMU::HostWrite_U32(guard, MAGIC_GAMEID, INSTALLER_BASE_ADDRESS);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, MAGIC_GAMEID, INSTALLER_BASE_ADDRESS);
|
||||
|
||||
// Create GCT in memory
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x00d0c0de, codelist_base_address);
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x00d0c0de, codelist_base_address + 4);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x00d0c0de, codelist_base_address);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x00d0c0de, codelist_base_address + 4);
|
||||
|
||||
// Each code is 8 bytes (2 words) wide. There is a starter code and an end code.
|
||||
const u32 start_address = codelist_base_address + CODE_SIZE;
|
||||
|
@ -177,8 +177,8 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
|
|||
|
||||
for (const GeckoCode::Code& code : active_code.codes)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U32(guard, code.address, next_address);
|
||||
PowerPC::MMU::HostWrite_U32(guard, code.data, next_address + 4);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, code.address, next_address);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, code.data, next_address + 4);
|
||||
next_address += CODE_SIZE;
|
||||
}
|
||||
}
|
||||
|
@ -187,12 +187,12 @@ static Installation InstallCodeHandlerLocked(const Core::CPUThreadGuard& guard)
|
|||
end_address - start_address);
|
||||
|
||||
// Stop code. Tells the handler that this is the end of the list.
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0xF0000000, next_address);
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0x00000000, next_address + 4);
|
||||
PowerPC::MMU::HostWrite_U32(guard, 0, HLE_TRAMPOLINE_ADDRESS);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0xF0000000, next_address);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0x00000000, next_address + 4);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, 0, HLE_TRAMPOLINE_ADDRESS);
|
||||
|
||||
// Turn on codes
|
||||
PowerPC::MMU::HostWrite_U8(guard, 1, INSTALLER_BASE_ADDRESS + 7);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, 1, INSTALLER_BASE_ADDRESS + 7);
|
||||
|
||||
// Invalidate the icache and any asm codes
|
||||
auto& ppc_state = guard.GetSystem().GetPPCState();
|
||||
|
@ -262,18 +262,18 @@ void RunCodeHandler(const Core::CPUThreadGuard& guard)
|
|||
ppc_state.gpr[1] -= 8; // Fake stack frame for codehandler
|
||||
ppc_state.gpr[1] &= 0xFFFFFFF0; // Align stack to 16bytes
|
||||
u32 SP = ppc_state.gpr[1]; // Stack Pointer
|
||||
PowerPC::MMU::HostWrite_U32(guard, SP + 8, SP);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, SP + 8, SP);
|
||||
// SP + 4 is reserved for the codehandler to save LR to the stack.
|
||||
PowerPC::MMU::HostWrite_U32(guard, SFP, SP + 8); // Real stack frame
|
||||
PowerPC::MMU::HostWrite_U32(guard, ppc_state.pc, SP + 12);
|
||||
PowerPC::MMU::HostWrite_U32(guard, LR(ppc_state), SP + 16);
|
||||
PowerPC::MMU::HostWrite_U32(guard, ppc_state.cr.Get(), SP + 20);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, SFP, SP + 8); // Real stack frame
|
||||
PowerPC::MMU::HostWrite<u32>(guard, ppc_state.pc, SP + 12);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, LR(ppc_state), SP + 16);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, ppc_state.cr.Get(), SP + 20);
|
||||
// Registers FPR0->13 are volatile
|
||||
for (u32 i = 0; i < 14; ++i)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U64(guard, ppc_state.ps[i].PS0AsU64(), SP + 24 + 2 * i * sizeof(u64));
|
||||
PowerPC::MMU::HostWrite_U64(guard, ppc_state.ps[i].PS1AsU64(),
|
||||
SP + 24 + (2 * i + 1) * sizeof(u64));
|
||||
PowerPC::MMU::HostWrite<u64>(guard, ppc_state.ps[i].PS0AsU64(), SP + 24 + 2 * i * sizeof(u64));
|
||||
PowerPC::MMU::HostWrite<u64>(guard, ppc_state.ps[i].PS1AsU64(),
|
||||
SP + 24 + (2 * i + 1) * sizeof(u64));
|
||||
}
|
||||
DEBUG_LOG_FMT(ACTIONREPLAY,
|
||||
"GeckoCodes: Initiating phantom branch-and-link. "
|
||||
|
|
|
@ -44,7 +44,7 @@ void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard)
|
|||
// been read into memory, or such, so we do the first 5 frames. More
|
||||
// robust alternative would be to actually detect memory writes, but that
|
||||
// would be even uglier.)
|
||||
u32 gch_gameid = PowerPC::MMU::HostRead_U32(guard, Gecko::INSTALLER_BASE_ADDRESS);
|
||||
u32 gch_gameid = PowerPC::MMU::HostRead<u32>(guard, Gecko::INSTALLER_BASE_ADDRESS);
|
||||
if (gch_gameid - Gecko::MAGIC_GAMEID == 5)
|
||||
{
|
||||
return;
|
||||
|
@ -53,7 +53,7 @@ void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard)
|
|||
{
|
||||
gch_gameid = Gecko::MAGIC_GAMEID;
|
||||
}
|
||||
PowerPC::MMU::HostWrite_U32(guard, gch_gameid + 1, Gecko::INSTALLER_BASE_ADDRESS);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, gch_gameid + 1, Gecko::INSTALLER_BASE_ADDRESS);
|
||||
|
||||
ppc_state.iCache.Reset(jit_interface);
|
||||
}
|
||||
|
@ -69,14 +69,15 @@ void GeckoReturnTrampoline(const Core::CPUThreadGuard& guard)
|
|||
|
||||
// Stack frame is built in GeckoCode.cpp, Gecko::RunCodeHandler.
|
||||
const u32 SP = ppc_state.gpr[1];
|
||||
ppc_state.gpr[1] = PowerPC::MMU::HostRead_U32(guard, SP + 8);
|
||||
ppc_state.npc = PowerPC::MMU::HostRead_U32(guard, SP + 12);
|
||||
LR(ppc_state) = PowerPC::MMU::HostRead_U32(guard, SP + 16);
|
||||
ppc_state.cr.Set(PowerPC::MMU::HostRead_U32(guard, SP + 20));
|
||||
ppc_state.gpr[1] = PowerPC::MMU::HostRead<u32>(guard, SP + 8);
|
||||
ppc_state.npc = PowerPC::MMU::HostRead<u32>(guard, SP + 12);
|
||||
LR(ppc_state) = PowerPC::MMU::HostRead<u32>(guard, SP + 16);
|
||||
ppc_state.cr.Set(PowerPC::MMU::HostRead<u32>(guard, SP + 20));
|
||||
for (int i = 0; i < 14; ++i)
|
||||
{
|
||||
ppc_state.ps[i].SetBoth(PowerPC::MMU::HostRead_U64(guard, SP + 24 + 2 * i * sizeof(u64)),
|
||||
PowerPC::MMU::HostRead_U64(guard, SP + 24 + (2 * i + 1) * sizeof(u64)));
|
||||
ppc_state.ps[i].SetBoth(
|
||||
PowerPC::MMU::HostRead<u64>(guard, SP + 24 + 2 * i * sizeof(u64)),
|
||||
PowerPC::MMU::HostRead<u64>(guard, SP + 24 + (2 * i + 1) * sizeof(u64)));
|
||||
}
|
||||
}
|
||||
} // namespace HLE_Misc
|
||||
|
|
|
@ -62,8 +62,9 @@ static void HLE_GeneralDebugPrint(const Core::CPUThreadGuard& guard, ParameterTy
|
|||
|
||||
// Is gpr3 pointing to a pointer (including nullptr) rather than an ASCII string
|
||||
if (PowerPC::MMU::HostIsRAMAddress(guard, ppc_state.gpr[3]) &&
|
||||
(PowerPC::MMU::HostIsRAMAddress(guard, PowerPC::MMU::HostRead_U32(guard, ppc_state.gpr[3])) ||
|
||||
PowerPC::MMU::HostRead_U32(guard, ppc_state.gpr[3]) == 0))
|
||||
(PowerPC::MMU::HostIsRAMAddress(guard,
|
||||
PowerPC::MMU::HostRead<u32>(guard, ppc_state.gpr[3])) ||
|
||||
PowerPC::MMU::HostRead<u32>(guard, ppc_state.gpr[3]) == 0))
|
||||
{
|
||||
if (PowerPC::MMU::HostIsRAMAddress(guard, ppc_state.gpr[4]))
|
||||
{
|
||||
|
@ -117,7 +118,7 @@ void HLE_write_console(const Core::CPUThreadGuard& guard)
|
|||
std::string report_message = GetStringVA(system, guard, 4);
|
||||
if (PowerPC::MMU::HostIsRAMAddress(guard, ppc_state.gpr[5]))
|
||||
{
|
||||
const u32 size = system.GetMMU().Read_U32(ppc_state.gpr[5]);
|
||||
const u32 size = system.GetMMU().Read<u32>(ppc_state.gpr[5]);
|
||||
if (size > report_message.size())
|
||||
WARN_LOG_FMT(OSREPORT_HLE, "__write_console uses an invalid size of {:#010x}", size);
|
||||
else if (size == 0)
|
||||
|
@ -178,12 +179,12 @@ static void HLE_LogFPrint(const Core::CPUThreadGuard& guard, ParameterType param
|
|||
PowerPC::MMU::HostIsRAMAddress(guard, ppc_state.gpr[3] + 0xF))
|
||||
{
|
||||
// The fd is stored as a short at FILE+0xE.
|
||||
fd = static_cast<short>(PowerPC::MMU::HostRead_U16(guard, ppc_state.gpr[3] + 0xE));
|
||||
fd = static_cast<short>(PowerPC::MMU::HostRead<u16>(guard, ppc_state.gpr[3] + 0xE));
|
||||
}
|
||||
if (fd != 1 && fd != 2)
|
||||
{
|
||||
// On RVL SDK it seems stored at FILE+0x2.
|
||||
fd = static_cast<short>(PowerPC::MMU::HostRead_U16(guard, ppc_state.gpr[3] + 0x2));
|
||||
fd = static_cast<short>(PowerPC::MMU::HostRead<u16>(guard, ppc_state.gpr[3] + 0x2));
|
||||
}
|
||||
if (fd != 1 && fd != 2)
|
||||
return;
|
||||
|
|
|
@ -21,10 +21,10 @@ double HLE::SystemVABI::VAList::GetFPR(u32 fpr) const
|
|||
}
|
||||
|
||||
HLE::SystemVABI::VAListStruct::VAListStruct(const Core::CPUThreadGuard& guard, u32 address)
|
||||
: VAList(guard, 0), m_va_list{PowerPC::MMU::HostRead_U8(guard, address),
|
||||
PowerPC::MMU::HostRead_U8(guard, address + 1),
|
||||
PowerPC::MMU::HostRead_U32(guard, address + 4),
|
||||
PowerPC::MMU::HostRead_U32(guard, address + 8)},
|
||||
: VAList(guard, 0), m_va_list{PowerPC::MMU::HostRead<u8>(guard, address),
|
||||
PowerPC::MMU::HostRead<u8>(guard, address + 1),
|
||||
PowerPC::MMU::HostRead<u32>(guard, address + 4),
|
||||
PowerPC::MMU::HostRead<u32>(guard, address + 8)},
|
||||
m_address(address), m_has_fpr_area(guard.GetSystem().GetPPCState().cr.GetBit(6) == 1)
|
||||
{
|
||||
m_stack = m_va_list.overflow_arg_area;
|
||||
|
@ -50,7 +50,7 @@ u32 HLE::SystemVABI::VAListStruct::GetGPR(u32 gpr) const
|
|||
return 0;
|
||||
}
|
||||
const u32 gpr_address = Common::AlignUp(GetGPRArea() + 4 * (gpr - 3), 4);
|
||||
return PowerPC::MMU::HostRead_U32(m_guard, gpr_address);
|
||||
return PowerPC::MMU::HostRead<u32>(m_guard, gpr_address);
|
||||
}
|
||||
|
||||
double HLE::SystemVABI::VAListStruct::GetFPR(u32 fpr) const
|
||||
|
@ -61,5 +61,5 @@ double HLE::SystemVABI::VAListStruct::GetFPR(u32 fpr) const
|
|||
return 0.0;
|
||||
}
|
||||
const u32 fpr_address = Common::AlignUp(GetFPRArea() + 8 * (fpr - 1), 8);
|
||||
return PowerPC::MMU::HostRead_F64(m_guard, fpr_address);
|
||||
return PowerPC::MMU::HostRead<double>(m_guard, fpr_address);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
for (size_t i = 0; i < sizeof(T); i += 1, addr += 1)
|
||||
{
|
||||
reinterpret_cast<u8*>(&obj)[i] = PowerPC::MMU::HostRead_U8(m_guard, addr);
|
||||
reinterpret_cast<u8*>(&obj)[i] = PowerPC::MMU::HostRead<u8>(m_guard, addr);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -76,7 +76,7 @@ public:
|
|||
else
|
||||
{
|
||||
m_stack = Common::AlignUp(m_stack, 4);
|
||||
value = PowerPC::MMU::HostRead_U32(m_guard, m_stack);
|
||||
value = PowerPC::MMU::HostRead<u32>(m_guard, m_stack);
|
||||
m_stack += 4;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ public:
|
|||
else
|
||||
{
|
||||
m_stack = Common::AlignUp(m_stack, 8);
|
||||
value = PowerPC::MMU::HostRead_U64(m_guard, m_stack);
|
||||
value = PowerPC::MMU::HostRead<u64>(m_guard, m_stack);
|
||||
m_stack += 8;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
else
|
||||
{
|
||||
m_stack = Common::AlignUp(m_stack, 8);
|
||||
value = PowerPC::MMU::HostRead_F64(m_guard, m_stack);
|
||||
value = PowerPC::MMU::HostRead<double>(m_guard, m_stack);
|
||||
m_stack += 8;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,39 +87,39 @@ struct EffectiveAddressSpaceAccessors : Accessors
|
|||
}
|
||||
u8 ReadU8(const Core::CPUThreadGuard& guard, u32 address) const override
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U8(guard, address);
|
||||
return PowerPC::MMU::HostRead<u8>(guard, address);
|
||||
}
|
||||
void WriteU8(const Core::CPUThreadGuard& guard, u32 address, u8 value) override
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, value, address);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, value, address);
|
||||
}
|
||||
u16 ReadU16(const Core::CPUThreadGuard& guard, u32 address) const override
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U16(guard, address);
|
||||
return PowerPC::MMU::HostRead<u16>(guard, address);
|
||||
}
|
||||
void WriteU16(const Core::CPUThreadGuard& guard, u32 address, u16 value) override
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U16(guard, value, address);
|
||||
PowerPC::MMU::HostWrite<u16>(guard, value, address);
|
||||
}
|
||||
u32 ReadU32(const Core::CPUThreadGuard& guard, u32 address) const override
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U32(guard, address);
|
||||
return PowerPC::MMU::HostRead<u32>(guard, address);
|
||||
}
|
||||
void WriteU32(const Core::CPUThreadGuard& guard, u32 address, u32 value) override
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U32(guard, value, address);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, value, address);
|
||||
}
|
||||
u64 ReadU64(const Core::CPUThreadGuard& guard, u32 address) const override
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U64(guard, address);
|
||||
return PowerPC::MMU::HostRead<u64>(guard, address);
|
||||
}
|
||||
void WriteU64(const Core::CPUThreadGuard& guard, u32 address, u64 value) override
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U64(guard, value, address);
|
||||
PowerPC::MMU::HostWrite<u64>(guard, value, address);
|
||||
}
|
||||
float ReadF32(const Core::CPUThreadGuard& guard, u32 address) const override
|
||||
{
|
||||
return PowerPC::MMU::HostRead_F32(guard, address);
|
||||
return PowerPC::MMU::HostRead<float>(guard, address);
|
||||
}
|
||||
|
||||
bool Matches(const Core::CPUThreadGuard& guard, u32 haystack_start, const u8* needle_start,
|
||||
|
|
|
@ -72,7 +72,7 @@ u32 MemoryWatcher::ChasePointer(const Core::CPUThreadGuard& guard, const std::st
|
|||
u32 value = 0;
|
||||
for (u32 offset : m_addresses[line])
|
||||
{
|
||||
value = PowerPC::MMU::HostRead_U32(guard, value + offset);
|
||||
value = PowerPC::MMU::HostRead<u32>(guard, value + offset);
|
||||
if (!PowerPC::MMU::HostIsRAMAddress(guard, value))
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -217,21 +217,21 @@ static void ApplyPatches(const Core::CPUThreadGuard& guard, const std::vector<Pa
|
|||
{
|
||||
case PatchType::Patch8Bit:
|
||||
if (!entry.conditional ||
|
||||
PowerPC::MMU::HostRead_U8(guard, addr) == static_cast<u8>(comparand))
|
||||
PowerPC::MMU::HostRead<u8>(guard, addr) == static_cast<u8>(comparand))
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, static_cast<u8>(value), addr);
|
||||
PowerPC::MMU::HostWrite<u8>(guard, static_cast<u8>(value), addr);
|
||||
}
|
||||
break;
|
||||
case PatchType::Patch16Bit:
|
||||
if (!entry.conditional ||
|
||||
PowerPC::MMU::HostRead_U16(guard, addr) == static_cast<u16>(comparand))
|
||||
PowerPC::MMU::HostRead<u16>(guard, addr) == static_cast<u16>(comparand))
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U16(guard, static_cast<u16>(value), addr);
|
||||
PowerPC::MMU::HostWrite<u16>(guard, static_cast<u16>(value), addr);
|
||||
}
|
||||
break;
|
||||
case PatchType::Patch32Bit:
|
||||
if (!entry.conditional || PowerPC::MMU::HostRead_U32(guard, addr) == comparand)
|
||||
PowerPC::MMU::HostWrite_U32(guard, value, addr);
|
||||
if (!entry.conditional || PowerPC::MMU::HostRead<u32>(guard, addr) == comparand)
|
||||
PowerPC::MMU::HostWrite<u32>(guard, value, addr);
|
||||
break;
|
||||
default:
|
||||
// unknown patchtype
|
||||
|
@ -267,7 +267,7 @@ static bool IsStackValid(const Core::CPUThreadGuard& guard)
|
|||
return false;
|
||||
|
||||
// Read the frame pointer from the stack (find 2nd frame from top), assert that it makes sense
|
||||
const u32 next_SP = PowerPC::MMU::HostRead_U32(guard, SP);
|
||||
const u32 next_SP = PowerPC::MMU::HostRead<u32>(guard, SP);
|
||||
if (next_SP <= SP || !PowerPC::MMU::HostIsRAMAddress(guard, next_SP) ||
|
||||
!PowerPC::MMU::HostIsRAMAddress(guard, next_SP + 4))
|
||||
{
|
||||
|
@ -275,7 +275,7 @@ static bool IsStackValid(const Core::CPUThreadGuard& guard)
|
|||
}
|
||||
|
||||
// Check the link register makes sense (that it points to a valid IBAT address)
|
||||
const u32 address = PowerPC::MMU::HostRead_U32(guard, next_SP + 4);
|
||||
const u32 address = PowerPC::MMU::HostRead<u32>(guard, next_SP + 4);
|
||||
return PowerPC::MMU::HostIsInstructionRAMAddress(guard, address) &&
|
||||
0 != PowerPC::MMU::HostRead_Instruction(guard, address);
|
||||
}
|
||||
|
|
|
@ -34,57 +34,15 @@ using std::isnan;
|
|||
#include "Core/System.h"
|
||||
|
||||
template <typename T>
|
||||
static T HostRead(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static T HostRead(const Core::CPUThreadGuard& guard, u32 address)
|
||||
{
|
||||
return PowerPC::MMU::HostRead<T>(guard, address);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void HostWrite(const Core::CPUThreadGuard& guard, T var, u32 address);
|
||||
|
||||
template <>
|
||||
u8 HostRead(const Core::CPUThreadGuard& guard, u32 address)
|
||||
static void HostWrite(const Core::CPUThreadGuard& guard, T var, u32 address)
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U8(guard, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
u16 HostRead(const Core::CPUThreadGuard& guard, u32 address)
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U16(guard, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
u32 HostRead(const Core::CPUThreadGuard& guard, u32 address)
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U32(guard, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
u64 HostRead(const Core::CPUThreadGuard& guard, u32 address)
|
||||
{
|
||||
return PowerPC::MMU::HostRead_U64(guard, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
void HostWrite(const Core::CPUThreadGuard& guard, u8 var, u32 address)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U8(guard, var, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
void HostWrite(const Core::CPUThreadGuard& guard, u16 var, u32 address)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U16(guard, var, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
void HostWrite(const Core::CPUThreadGuard& guard, u32 var, u32 address)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U32(guard, var, address);
|
||||
}
|
||||
|
||||
template <>
|
||||
void HostWrite(const Core::CPUThreadGuard& guard, u64 var, u32 address)
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U64(guard, var, address);
|
||||
PowerPC::MMU::HostWrite<T>(guard, var, address);
|
||||
}
|
||||
|
||||
template <typename T, typename U = T>
|
||||
|
|
|
@ -293,7 +293,7 @@ void Interpreter::unknown_instruction(Interpreter& interpreter, UGeckoInstructio
|
|||
Core::CPUThreadGuard guard(system);
|
||||
|
||||
const u32 last_pc = interpreter.m_last_pc;
|
||||
const u32 opcode = PowerPC::MMU::HostRead_U32(guard, last_pc);
|
||||
const u32 opcode = PowerPC::MMU::HostRead<u32>(guard, last_pc);
|
||||
const std::string disasm = Common::GekkoDisassembler::Disassemble(opcode, last_pc);
|
||||
NOTICE_LOG_FMT(POWERPC, "Last PC = {:08x} : {}", last_pc, disasm);
|
||||
Dolphin_Debugger::PrintCallstack(guard, Common::Log::LogType::POWERPC,
|
||||
|
|
|
@ -41,7 +41,7 @@ static u32 Helper_Get_EA_UX(const PowerPC::PowerPCState& ppcs, const UGeckoInstr
|
|||
void Interpreter::lbz(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = interpreter.m_mmu.Read_U8(Helper_Get_EA(ppc_state, inst));
|
||||
const u32 temp = interpreter.m_mmu.Read<u8>(Helper_Get_EA(ppc_state, inst));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
ppc_state.gpr[inst.RD] = temp;
|
||||
|
@ -51,7 +51,7 @@ void Interpreter::lbzu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U8(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u8>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ void Interpreter::lfd(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u64 temp = interpreter.m_mmu.Read_U64(address);
|
||||
const u64 temp = interpreter.m_mmu.Read<u64>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
ppc_state.ps[inst.FD].SetPS0(temp);
|
||||
|
@ -88,7 +88,7 @@ void Interpreter::lfdu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u64 temp = interpreter.m_mmu.Read_U64(address);
|
||||
const u64 temp = interpreter.m_mmu.Read<u64>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ void Interpreter::lfdux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u64 temp = interpreter.m_mmu.Read_U64(address);
|
||||
const u64 temp = interpreter.m_mmu.Read<u64>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -128,7 +128,7 @@ void Interpreter::lfdx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u64 temp = interpreter.m_mmu.Read_U64(address);
|
||||
const u64 temp = interpreter.m_mmu.Read<u64>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
ppc_state.ps[inst.FD].SetPS0(temp);
|
||||
|
@ -145,7 +145,7 @@ void Interpreter::lfs(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ void Interpreter::lfsu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ void Interpreter::lfsux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -207,7 +207,7 @@ void Interpreter::lfsx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -219,7 +219,7 @@ void Interpreter::lfsx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lha(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = u32(s32(s16(interpreter.m_mmu.Read_U16(Helper_Get_EA(ppc_state, inst)))));
|
||||
const u32 temp = u32(s32(s16(interpreter.m_mmu.Read<u16>(Helper_Get_EA(ppc_state, inst)))));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -231,7 +231,7 @@ void Interpreter::lhau(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
const u32 temp = u32(s32(s16(interpreter.m_mmu.Read_U16(address))));
|
||||
const u32 temp = u32(s32(s16(interpreter.m_mmu.Read<u16>(address))));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -243,7 +243,7 @@ void Interpreter::lhau(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lhz(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = interpreter.m_mmu.Read_U16(Helper_Get_EA(ppc_state, inst));
|
||||
const u32 temp = interpreter.m_mmu.Read<u16>(Helper_Get_EA(ppc_state, inst));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -255,7 +255,7 @@ void Interpreter::lhzu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U16(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u16>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
|
||||
for (u32 i = inst.RD; i <= 31; i++, address += 4)
|
||||
{
|
||||
const u32 temp_reg = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp_reg = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
|
@ -307,7 +307,7 @@ void Interpreter::stmw(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
|
||||
for (u32 i = inst.RS; i <= 31; i++, address += 4)
|
||||
{
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[i], address);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[i], address);
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
PanicAlertFmt("DSI exception in stmw");
|
||||
|
@ -321,7 +321,7 @@ void Interpreter::lwz(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -333,7 +333,7 @@ void Interpreter::lwzu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -345,7 +345,7 @@ void Interpreter::lwzu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::stb(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
interpreter.m_mmu.Write_U8(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst));
|
||||
interpreter.m_mmu.Write<u8>(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst));
|
||||
}
|
||||
|
||||
void Interpreter::stbu(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -353,7 +353,7 @@ void Interpreter::stbu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U8(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u8>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -371,7 +371,7 @@ void Interpreter::stfd(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
interpreter.m_mmu.Write<u64>(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
}
|
||||
|
||||
void Interpreter::stfdu(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -385,7 +385,7 @@ void Interpreter::stfdu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
interpreter.m_mmu.Write<u64>(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -403,7 +403,7 @@ void Interpreter::stfs(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
interpreter.m_mmu.Write<u32>(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
}
|
||||
|
||||
void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -417,7 +417,7 @@ void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
interpreter.m_mmu.Write<u32>(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -427,7 +427,7 @@ void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::sth(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
interpreter.m_mmu.Write_U16(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst));
|
||||
interpreter.m_mmu.Write<u16>(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst));
|
||||
}
|
||||
|
||||
void Interpreter::sthu(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -435,7 +435,7 @@ void Interpreter::sthu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U16(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u16>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -445,7 +445,7 @@ void Interpreter::sthu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::stw(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst));
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst));
|
||||
}
|
||||
|
||||
void Interpreter::stwu(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -453,7 +453,7 @@ void Interpreter::stwu(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_U(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -595,7 +595,7 @@ void Interpreter::eciwx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
ppc_state.gpr[inst.RD] = interpreter.m_mmu.Read_U32(EA);
|
||||
ppc_state.gpr[inst.RD] = interpreter.m_mmu.Read<u32>(EA);
|
||||
}
|
||||
|
||||
void Interpreter::ecowx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -615,7 +615,7 @@ void Interpreter::ecowx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[inst.RS], EA);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[inst.RS], EA);
|
||||
}
|
||||
|
||||
void Interpreter::eieio(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -640,7 +640,7 @@ void Interpreter::lbzux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U8(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u8>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -652,7 +652,7 @@ void Interpreter::lbzux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lbzx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = interpreter.m_mmu.Read_U8(Helper_Get_EA_X(ppc_state, inst));
|
||||
const u32 temp = interpreter.m_mmu.Read<u8>(Helper_Get_EA_X(ppc_state, inst));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -664,7 +664,7 @@ void Interpreter::lhaux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
const s32 temp = s32{s16(interpreter.m_mmu.Read_U16(address))};
|
||||
const s32 temp = s32{s16(interpreter.m_mmu.Read<u16>(address))};
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -676,7 +676,7 @@ void Interpreter::lhaux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lhax(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const s32 temp = s32{s16(interpreter.m_mmu.Read_U16(Helper_Get_EA_X(ppc_state, inst)))};
|
||||
const s32 temp = s32{s16(interpreter.m_mmu.Read<u16>(Helper_Get_EA_X(ppc_state, inst)))};
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -687,7 +687,7 @@ void Interpreter::lhax(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lhbrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = Common::swap16(interpreter.m_mmu.Read_U16(Helper_Get_EA_X(ppc_state, inst)));
|
||||
const u32 temp = Common::swap16(interpreter.m_mmu.Read<u16>(Helper_Get_EA_X(ppc_state, inst)));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -699,7 +699,7 @@ void Interpreter::lhzux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U16(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u16>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -711,7 +711,7 @@ void Interpreter::lhzux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lhzx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = interpreter.m_mmu.Read_U16(Helper_Get_EA_X(ppc_state, inst));
|
||||
const u32 temp = interpreter.m_mmu.Read<u16>(Helper_Get_EA_X(ppc_state, inst));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -740,7 +740,7 @@ void Interpreter::lswx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
if ((n & 0b11) == 0)
|
||||
ppc_state.gpr[reg] = 0;
|
||||
|
||||
const u32 temp_value = interpreter.m_mmu.Read_U8(EA) << (24 - offset);
|
||||
const u32 temp_value = interpreter.m_mmu.Read<u8>(EA) << (24 - offset);
|
||||
// Not64 (Homebrew N64 Emulator for Wii) triggers the following case.
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
|
@ -756,7 +756,7 @@ void Interpreter::lswx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::lwbrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 temp = Common::swap32(interpreter.m_mmu.Read_U32(Helper_Get_EA_X(ppc_state, inst)));
|
||||
const u32 temp = Common::swap32(interpreter.m_mmu.Read<u32>(Helper_Get_EA_X(ppc_state, inst)));
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -768,7 +768,7 @@ void Interpreter::lwzux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -781,7 +781,7 @@ void Interpreter::lwzx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_X(ppc_state, inst);
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -794,7 +794,7 @@ void Interpreter::stbux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U8(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u8>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -804,7 +804,7 @@ void Interpreter::stbux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::stbx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
interpreter.m_mmu.Write_U8(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst));
|
||||
interpreter.m_mmu.Write<u8>(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst));
|
||||
}
|
||||
|
||||
void Interpreter::stfdux(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -818,7 +818,7 @@ void Interpreter::stfdux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
interpreter.m_mmu.Write<u64>(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -836,7 +836,7 @@ void Interpreter::stfdx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
interpreter.m_mmu.Write<u64>(ppc_state.ps[inst.FS].PS0AsU64(), address);
|
||||
}
|
||||
|
||||
// Stores Floating points into Integers indeXed
|
||||
|
@ -851,7 +851,7 @@ void Interpreter::stfiwx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U32(ppc_state.ps[inst.FS].PS0AsU32(), address);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.ps[inst.FS].PS0AsU32(), address);
|
||||
}
|
||||
|
||||
void Interpreter::stfsux(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -865,7 +865,7 @@ void Interpreter::stfsux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
interpreter.m_mmu.Write<u32>(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -883,7 +883,7 @@ void Interpreter::stfsx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
interpreter.m_mmu.Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
interpreter.m_mmu.Write<u32>(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address);
|
||||
}
|
||||
|
||||
void Interpreter::sthbrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -897,7 +897,7 @@ void Interpreter::sthux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U16(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u16>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -907,7 +907,7 @@ void Interpreter::sthux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
void Interpreter::sthx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
interpreter.m_mmu.Write_U16(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst));
|
||||
interpreter.m_mmu.Write<u16>(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst));
|
||||
}
|
||||
|
||||
// lswi - bizarro string instruction
|
||||
|
@ -940,7 +940,7 @@ void Interpreter::lswi(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
ppc_state.gpr[r] = 0;
|
||||
}
|
||||
|
||||
const u32 temp_value = interpreter.m_mmu.Read_U8(EA) << (24 - i);
|
||||
const u32 temp_value = interpreter.m_mmu.Read<u8>(EA) << (24 - i);
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
PanicAlertFmt("DSI exception in lsw.");
|
||||
|
@ -1007,7 +1007,7 @@ void Interpreter::Helper_StoreString(Interpreter& interpreter, const u32 EA, u32
|
|||
if (misalignment_bytes != 0)
|
||||
{
|
||||
// Handle misalignment at start
|
||||
current_value = interpreter.m_mmu.Read_U32(current_address);
|
||||
current_value = interpreter.m_mmu.Read<u32>(current_address);
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
return;
|
||||
current_value <<= misalignment_bits;
|
||||
|
@ -1018,8 +1018,8 @@ void Interpreter::Helper_StoreString(Interpreter& interpreter, const u32 EA, u32
|
|||
while (n >= 4)
|
||||
{
|
||||
current_value |= ppc_state.gpr[r];
|
||||
interpreter.m_mmu.Write_U32(static_cast<u32>(current_value >> misalignment_bits),
|
||||
current_address);
|
||||
interpreter.m_mmu.Write<u32>(static_cast<u32>(current_value >> misalignment_bits),
|
||||
current_address);
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
return;
|
||||
|
||||
|
@ -1042,10 +1042,10 @@ void Interpreter::Helper_StoreString(Interpreter& interpreter, const u32 EA, u32
|
|||
current_value >>= (misalignment_bytes - n) * 8;
|
||||
}
|
||||
current_value &= 0xFFFF'FFFF'0000'0000;
|
||||
current_value |= (interpreter.m_mmu.Read_U32(current_address) << (n * 8)) & 0xFFFF'FFFF;
|
||||
current_value |= (interpreter.m_mmu.Read<u32>(current_address) << (n * 8)) & 0xFFFF'FFFF;
|
||||
if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0)
|
||||
return;
|
||||
interpreter.m_mmu.Write_U32(static_cast<u32>(current_value >> (n * 8)), current_address);
|
||||
interpreter.m_mmu.Write<u32>(static_cast<u32>(current_value >> (n * 8)), current_address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1071,7 +1071,7 @@ void Interpreter::lwarx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
return;
|
||||
}
|
||||
|
||||
const u32 temp = interpreter.m_mmu.Read_U32(address);
|
||||
const u32 temp = interpreter.m_mmu.Read<u32>(address);
|
||||
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
|
@ -1097,7 +1097,7 @@ void Interpreter::stwcxd(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
if (address == ppc_state.reserve_address)
|
||||
{
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.reserve = false;
|
||||
|
@ -1115,7 +1115,7 @@ void Interpreter::stwux(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_UX(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[inst.RS], address);
|
||||
if (!(ppc_state.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
ppc_state.gpr[inst.RA] = address;
|
||||
|
@ -1127,7 +1127,7 @@ void Interpreter::stwx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
auto& ppc_state = interpreter.m_ppc_state;
|
||||
const u32 address = Helper_Get_EA_X(ppc_state, inst);
|
||||
|
||||
interpreter.m_mmu.Write_U32(ppc_state.gpr[inst.RS], address);
|
||||
interpreter.m_mmu.Write<u32>(ppc_state.gpr[inst.RS], address);
|
||||
}
|
||||
|
||||
void Interpreter::sync(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
|
|
@ -69,24 +69,9 @@ SType ScaleAndClamp(double ps, u32 st_scale)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
static T ReadUnpaired(PowerPC::MMU& mmu, u32 addr);
|
||||
|
||||
template <>
|
||||
u8 ReadUnpaired<u8>(PowerPC::MMU& mmu, u32 addr)
|
||||
static T ReadUnpaired(PowerPC::MMU& mmu, u32 addr)
|
||||
{
|
||||
return mmu.Read_U8(addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
u16 ReadUnpaired<u16>(PowerPC::MMU& mmu, u32 addr)
|
||||
{
|
||||
return mmu.Read_U16(addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
u32 ReadUnpaired<u32>(PowerPC::MMU& mmu, u32 addr)
|
||||
{
|
||||
return mmu.Read_U32(addr);
|
||||
return mmu.Read<T>(addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -95,43 +80,28 @@ static std::pair<T, T> ReadPair(PowerPC::MMU& mmu, u32 addr);
|
|||
template <>
|
||||
std::pair<u8, u8> ReadPair<u8>(PowerPC::MMU& mmu, u32 addr)
|
||||
{
|
||||
const u16 val = mmu.Read_U16(addr);
|
||||
const u16 val = mmu.Read<u16>(addr);
|
||||
return {u8(val >> 8), u8(val)};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<u16, u16> ReadPair<u16>(PowerPC::MMU& mmu, u32 addr)
|
||||
{
|
||||
const u32 val = mmu.Read_U32(addr);
|
||||
const u32 val = mmu.Read<u32>(addr);
|
||||
return {u16(val >> 16), u16(val)};
|
||||
}
|
||||
|
||||
template <>
|
||||
std::pair<u32, u32> ReadPair<u32>(PowerPC::MMU& mmu, u32 addr)
|
||||
{
|
||||
const u64 val = mmu.Read_U64(addr);
|
||||
const u64 val = mmu.Read<u64>(addr);
|
||||
return {u32(val >> 32), u32(val)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void WriteUnpaired(PowerPC::MMU& mmu, T val, u32 addr);
|
||||
|
||||
template <>
|
||||
void WriteUnpaired<u8>(PowerPC::MMU& mmu, u8 val, u32 addr)
|
||||
static void WriteUnpaired(PowerPC::MMU& mmu, T val, u32 addr)
|
||||
{
|
||||
mmu.Write_U8(val, addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
void WriteUnpaired<u16>(PowerPC::MMU& mmu, u16 val, u32 addr)
|
||||
{
|
||||
mmu.Write_U16(val, addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
void WriteUnpaired<u32>(PowerPC::MMU& mmu, u32 val, u32 addr)
|
||||
{
|
||||
mmu.Write_U32(val, addr);
|
||||
mmu.Write<T>(val, addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -140,19 +110,19 @@ static void WritePair(PowerPC::MMU& mmu, T val1, T val2, u32 addr);
|
|||
template <>
|
||||
void WritePair<u8>(PowerPC::MMU& mmu, u8 val1, u8 val2, u32 addr)
|
||||
{
|
||||
mmu.Write_U16((u16{val1} << 8) | u16{val2}, addr);
|
||||
mmu.Write<u16>((u16{val1} << 8) | u16{val2}, addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
void WritePair<u16>(PowerPC::MMU& mmu, u16 val1, u16 val2, u32 addr)
|
||||
{
|
||||
mmu.Write_U32((u32{val1} << 16) | u32{val2}, addr);
|
||||
mmu.Write<u32>((u32{val1} << 16) | u32{val2}, addr);
|
||||
}
|
||||
|
||||
template <>
|
||||
void WritePair<u32>(PowerPC::MMU& mmu, u32 val1, u32 val2, u32 addr)
|
||||
{
|
||||
mmu.Write_U64((u64{val1} << 32) | u64{val2}, addr);
|
||||
mmu.Write<u64>((u64{val1} << 32) | u64{val2}, addr);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -401,16 +401,16 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
|
|||
switch (accessSize)
|
||||
{
|
||||
case 64:
|
||||
ABI_CallFunctionPR(PowerPC::ReadU64FromJit, &m_jit.m_mmu, reg_addr);
|
||||
ABI_CallFunctionPR(PowerPC::ReadFromJit<u64>, &m_jit.m_mmu, reg_addr);
|
||||
break;
|
||||
case 32:
|
||||
ABI_CallFunctionPR(PowerPC::ReadU32FromJit, &m_jit.m_mmu, reg_addr);
|
||||
ABI_CallFunctionPR(PowerPC::ReadFromJit<u32>, &m_jit.m_mmu, reg_addr);
|
||||
break;
|
||||
case 16:
|
||||
ABI_CallFunctionPR(PowerPC::ReadU16FromJit, &m_jit.m_mmu, reg_addr);
|
||||
ABI_CallFunctionPR(PowerPC::ReadFromJit<u16>, &m_jit.m_mmu, reg_addr);
|
||||
break;
|
||||
case 8:
|
||||
ABI_CallFunctionPR(PowerPC::ReadU8FromJit, &m_jit.m_mmu, reg_addr);
|
||||
ABI_CallFunctionPR(PowerPC::ReadFromJit<u8>, &m_jit.m_mmu, reg_addr);
|
||||
break;
|
||||
}
|
||||
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
|
||||
|
@ -465,16 +465,16 @@ void EmuCodeBlock::SafeLoadToRegImmediate(X64Reg reg_value, u32 address, int acc
|
|||
switch (accessSize)
|
||||
{
|
||||
case 64:
|
||||
ABI_CallFunctionPC(PowerPC::ReadU64FromJit, &m_jit.m_mmu, address);
|
||||
ABI_CallFunctionPC(PowerPC::ReadFromJit<u64>, &m_jit.m_mmu, address);
|
||||
break;
|
||||
case 32:
|
||||
ABI_CallFunctionPC(PowerPC::ReadU32FromJit, &m_jit.m_mmu, address);
|
||||
ABI_CallFunctionPC(PowerPC::ReadFromJit<u32>, &m_jit.m_mmu, address);
|
||||
break;
|
||||
case 16:
|
||||
ABI_CallFunctionPC(PowerPC::ReadU16FromJit, &m_jit.m_mmu, address);
|
||||
ABI_CallFunctionPC(PowerPC::ReadFromJit<u16>, &m_jit.m_mmu, address);
|
||||
break;
|
||||
case 8:
|
||||
ABI_CallFunctionPC(PowerPC::ReadU8FromJit, &m_jit.m_mmu, address);
|
||||
ABI_CallFunctionPC(PowerPC::ReadFromJit<u8>, &m_jit.m_mmu, address);
|
||||
break;
|
||||
}
|
||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||
|
@ -588,19 +588,19 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
|||
switch (accessSize)
|
||||
{
|
||||
case 64:
|
||||
ABI_CallFunctionPRR(swap ? PowerPC::WriteU64FromJit : PowerPC::WriteU64SwapFromJit,
|
||||
ABI_CallFunctionPRR(swap ? PowerPC::WriteFromJit<u64> : PowerPC::WriteU64SwapFromJit,
|
||||
&m_jit.m_mmu, reg, reg_addr);
|
||||
break;
|
||||
case 32:
|
||||
ABI_CallFunctionPRR(swap ? PowerPC::WriteU32FromJit : PowerPC::WriteU32SwapFromJit,
|
||||
ABI_CallFunctionPRR(swap ? PowerPC::WriteFromJit<u32> : PowerPC::WriteU32SwapFromJit,
|
||||
&m_jit.m_mmu, reg, reg_addr);
|
||||
break;
|
||||
case 16:
|
||||
ABI_CallFunctionPRR(swap ? PowerPC::WriteU16FromJit : PowerPC::WriteU16SwapFromJit,
|
||||
ABI_CallFunctionPRR(swap ? PowerPC::WriteFromJit<u16> : PowerPC::WriteU16SwapFromJit,
|
||||
&m_jit.m_mmu, reg, reg_addr);
|
||||
break;
|
||||
case 8:
|
||||
ABI_CallFunctionPRR(PowerPC::WriteU8FromJit, &m_jit.m_mmu, reg, reg_addr);
|
||||
ABI_CallFunctionPRR(PowerPC::WriteFromJit<u8>, &m_jit.m_mmu, reg, reg_addr);
|
||||
break;
|
||||
}
|
||||
ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment);
|
||||
|
@ -670,16 +670,16 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address,
|
|||
switch (accessSize)
|
||||
{
|
||||
case 64:
|
||||
ABI_CallFunctionPAC(64, PowerPC::WriteU64FromJit, &m_jit.m_mmu, arg, address);
|
||||
ABI_CallFunctionPAC(64, PowerPC::WriteFromJit<u64>, &m_jit.m_mmu, arg, address);
|
||||
break;
|
||||
case 32:
|
||||
ABI_CallFunctionPAC(32, PowerPC::WriteU32FromJit, &m_jit.m_mmu, arg, address);
|
||||
ABI_CallFunctionPAC(32, PowerPC::WriteFromJit<u32>, &m_jit.m_mmu, arg, address);
|
||||
break;
|
||||
case 16:
|
||||
ABI_CallFunctionPAC(16, PowerPC::WriteU16FromJit, &m_jit.m_mmu, arg, address);
|
||||
ABI_CallFunctionPAC(16, PowerPC::WriteFromJit<u16>, &m_jit.m_mmu, arg, address);
|
||||
break;
|
||||
case 8:
|
||||
ABI_CallFunctionPAC(8, PowerPC::WriteU8FromJit, &m_jit.m_mmu, arg, address);
|
||||
ABI_CallFunctionPAC(8, PowerPC::WriteFromJit<u8>, &m_jit.m_mmu, arg, address);
|
||||
break;
|
||||
}
|
||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||
|
|
|
@ -226,22 +226,22 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, MemAccessMode mode, ARM64Reg RS,
|
|||
|
||||
if (access_size == 64)
|
||||
{
|
||||
ABI_CallFunction(reverse ? &PowerPC::WriteU64SwapFromJit : &PowerPC::WriteU64FromJit,
|
||||
ABI_CallFunction(reverse ? &PowerPC::WriteU64SwapFromJit : &PowerPC::WriteFromJit<u64>,
|
||||
&m_mmu, src_reg, ARM64Reg::W2);
|
||||
}
|
||||
else if (access_size == 32)
|
||||
{
|
||||
ABI_CallFunction(reverse ? &PowerPC::WriteU32SwapFromJit : &PowerPC::WriteU32FromJit,
|
||||
ABI_CallFunction(reverse ? &PowerPC::WriteU32SwapFromJit : &PowerPC::WriteFromJit<u32>,
|
||||
&m_mmu, src_reg, ARM64Reg::W2);
|
||||
}
|
||||
else if (access_size == 16)
|
||||
{
|
||||
ABI_CallFunction(reverse ? &PowerPC::WriteU16SwapFromJit : &PowerPC::WriteU16FromJit,
|
||||
ABI_CallFunction(reverse ? &PowerPC::WriteU16SwapFromJit : &PowerPC::WriteFromJit<u16>,
|
||||
&m_mmu, src_reg, ARM64Reg::W2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ABI_CallFunction(&PowerPC::WriteU8FromJit, &m_mmu, src_reg, ARM64Reg::W2);
|
||||
ABI_CallFunction(&PowerPC::WriteFromJit<u8>, &m_mmu, src_reg, ARM64Reg::W2);
|
||||
}
|
||||
}
|
||||
else if (flags & BackPatchInfo::FLAG_ZERO_256)
|
||||
|
@ -251,13 +251,13 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, MemAccessMode mode, ARM64Reg RS,
|
|||
else
|
||||
{
|
||||
if (access_size == 64)
|
||||
ABI_CallFunction(&PowerPC::ReadU64FromJit, &m_mmu, ARM64Reg::W1);
|
||||
ABI_CallFunction(&PowerPC::ReadFromJit<u64>, &m_mmu, ARM64Reg::W1);
|
||||
else if (access_size == 32)
|
||||
ABI_CallFunction(&PowerPC::ReadU32FromJit, &m_mmu, ARM64Reg::W1);
|
||||
ABI_CallFunction(&PowerPC::ReadFromJit<u32>, &m_mmu, ARM64Reg::W1);
|
||||
else if (access_size == 16)
|
||||
ABI_CallFunction(&PowerPC::ReadU16FromJit, &m_mmu, ARM64Reg::W1);
|
||||
ABI_CallFunction(&PowerPC::ReadFromJit<u16>, &m_mmu, ARM64Reg::W1);
|
||||
else
|
||||
ABI_CallFunction(&PowerPC::ReadU8FromJit, &m_mmu, ARM64Reg::W1);
|
||||
ABI_CallFunction(&PowerPC::ReadFromJit<u8>, &m_mmu, ARM64Reg::W1);
|
||||
}
|
||||
|
||||
m_float_emit.ABI_PopRegisters(fprs_to_push, ARM64Reg::X30);
|
||||
|
|
|
@ -330,7 +330,8 @@ void JitInterface::CompileExceptionCheck(ExceptionType type)
|
|||
|
||||
// Check in case the code has been replaced since: do we need to do this?
|
||||
const OpType optype =
|
||||
PPCTables::GetOpInfo(PowerPC::MMU::HostRead_U32(guard, ppc_state.pc), ppc_state.pc)->type;
|
||||
PPCTables::GetOpInfo(PowerPC::MMU::HostRead<u32>(guard, ppc_state.pc), ppc_state.pc)
|
||||
->type;
|
||||
if (optype != OpType::Store && optype != OpType::StoreFP && optype != OpType::StorePS)
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -26,17 +26,16 @@
|
|||
#include "Core/PowerPC/MMU.h"
|
||||
|
||||
#include <bit>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "Common/Align.h"
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/BitUtils.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/CPU.h"
|
||||
#include "Core/HW/GPFifo.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
|
@ -44,8 +43,6 @@
|
|||
#include "Core/HW/ProcessorInterface.h"
|
||||
#include "Core/PowerPC/GDBStub.h"
|
||||
#include "Core/PowerPC/JitInterface.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "VideoCommon/EFBInterface.h"
|
||||
|
||||
|
@ -144,7 +141,7 @@ static void EFB_Write(u32 data, u32 addr)
|
|||
}
|
||||
}
|
||||
|
||||
template <XCheckTLBFlag flag, typename T, bool never_translate>
|
||||
template <XCheckTLBFlag flag, std::unsigned_integral T, bool never_translate>
|
||||
T MMU::ReadFromHardware(u32 em_address)
|
||||
{
|
||||
// ReadFromHardware is currently used with XCheckTLBFlag::OpcodeNoException by host instruction
|
||||
|
@ -161,12 +158,12 @@ T MMU::ReadFromHardware(u32 em_address)
|
|||
// way isn't too terrible.
|
||||
// TODO: floats on non-word-aligned boundaries should technically cause alignment exceptions.
|
||||
// Note that "word" means 32-bit, so paired singles or doubles might still be 32-bit aligned!
|
||||
u64 var = 0;
|
||||
T var = 0;
|
||||
for (u32 i = 0; i < sizeof(T); ++i)
|
||||
{
|
||||
var = (var << 8) | ReadFromHardware<flag, u8, never_translate>(em_address + i);
|
||||
}
|
||||
return static_cast<T>(var);
|
||||
return var;
|
||||
}
|
||||
|
||||
bool wi = false;
|
||||
|
@ -193,8 +190,7 @@ T MMU::ReadFromHardware(u32 em_address)
|
|||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>(
|
||||
m_memory.GetMMIOMapping()->Read<std::make_unsigned_t<T>>(m_system, em_address));
|
||||
return static_cast<T>(m_memory.GetMMIOMapping()->Read<T>(m_system, em_address));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,6 +262,17 @@ T MMU::ReadFromHardware(u32 em_address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Instantiation of the ReadFromHardware calls used by MMU.h
|
||||
#define InstantiateRFH(T) \
|
||||
template T MMU::ReadFromHardware<XCheckTLBFlag::NoException, T>(u32); \
|
||||
template T MMU::ReadFromHardware<XCheckTLBFlag::NoException, T, true>(u32); \
|
||||
template T MMU::ReadFromHardware<XCheckTLBFlag::Read, T>(u32);
|
||||
|
||||
InstantiateRFH(u8);
|
||||
InstantiateRFH(u16);
|
||||
InstantiateRFH(u32);
|
||||
InstantiateRFH(u64);
|
||||
|
||||
template <XCheckTLBFlag flag, bool never_translate>
|
||||
void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
|
||||
{
|
||||
|
@ -454,6 +461,12 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
|
|||
m_ppc_state.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
|
||||
}
|
||||
}
|
||||
// Instantiation of the WriteToHardware calls
|
||||
template void MMU::WriteToHardware<XCheckTLBFlag::NoException>(u32, const u32, const u32);
|
||||
template void MMU::WriteToHardware<XCheckTLBFlag::NoException, true>(u32, const u32, const u32);
|
||||
template void MMU::WriteToHardware<XCheckTLBFlag::Write>(u32, const u32, const u32);
|
||||
template void MMU::WriteToHardware<XCheckTLBFlag::Write, true>(u32, const u32, const u32);
|
||||
|
||||
// =====================
|
||||
|
||||
// =================================
|
||||
|
@ -577,290 +590,19 @@ void MMU::Memcheck(u32 address, u64 var, bool write, size_t size)
|
|||
m_ppc_state.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
|
||||
}
|
||||
|
||||
u8 MMU::Read_U8(const u32 address)
|
||||
{
|
||||
u8 var = ReadFromHardware<XCheckTLBFlag::Read, u8>(address);
|
||||
Memcheck(address, var, false, 1);
|
||||
return var;
|
||||
}
|
||||
|
||||
u16 MMU::Read_U16(const u32 address)
|
||||
{
|
||||
u16 var = ReadFromHardware<XCheckTLBFlag::Read, u16>(address);
|
||||
Memcheck(address, var, false, 2);
|
||||
return var;
|
||||
}
|
||||
|
||||
u32 MMU::Read_U32(const u32 address)
|
||||
{
|
||||
u32 var = ReadFromHardware<XCheckTLBFlag::Read, u32>(address);
|
||||
Memcheck(address, var, false, 4);
|
||||
return var;
|
||||
}
|
||||
|
||||
u64 MMU::Read_U64(const u32 address)
|
||||
{
|
||||
u64 var = ReadFromHardware<XCheckTLBFlag::Read, u64>(address);
|
||||
Memcheck(address, var, false, 8);
|
||||
return var;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<ReadResult<T>> MMU::HostTryReadUX(const Core::CPUThreadGuard& guard,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
if (!HostIsRAMAddress(guard, address, space))
|
||||
return std::nullopt;
|
||||
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
switch (space)
|
||||
{
|
||||
case RequestedAddressSpace::Effective:
|
||||
{
|
||||
T value = mmu.ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
|
||||
return ReadResult<T>(!!mmu.m_ppc_state.msr.DR, std::move(value));
|
||||
}
|
||||
case RequestedAddressSpace::Physical:
|
||||
{
|
||||
T value = mmu.ReadFromHardware<XCheckTLBFlag::NoException, T, true>(address);
|
||||
return ReadResult<T>(false, std::move(value));
|
||||
}
|
||||
case RequestedAddressSpace::Virtual:
|
||||
{
|
||||
if (!mmu.m_ppc_state.msr.DR)
|
||||
return std::nullopt;
|
||||
T value = mmu.ReadFromHardware<XCheckTLBFlag::NoException, T>(address);
|
||||
return ReadResult<T>(true, std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(false);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<ReadResult<u8>> MMU::HostTryReadU8(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryReadUX<u8>(guard, address, space);
|
||||
}
|
||||
|
||||
std::optional<ReadResult<u16>> MMU::HostTryReadU16(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryReadUX<u16>(guard, address, space);
|
||||
}
|
||||
|
||||
std::optional<ReadResult<u32>> MMU::HostTryReadU32(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryReadUX<u32>(guard, address, space);
|
||||
}
|
||||
|
||||
std::optional<ReadResult<u64>> MMU::HostTryReadU64(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryReadUX<u64>(guard, address, space);
|
||||
}
|
||||
|
||||
std::optional<ReadResult<float>> MMU::HostTryReadF32(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
const auto result = HostTryReadUX<u32>(guard, address, space);
|
||||
if (!result)
|
||||
return std::nullopt;
|
||||
return ReadResult<float>(result->translated, std::bit_cast<float>(result->value));
|
||||
}
|
||||
|
||||
std::optional<ReadResult<double>> MMU::HostTryReadF64(const Core::CPUThreadGuard& guard,
|
||||
u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
const auto result = HostTryReadUX<u64>(guard, address, space);
|
||||
if (!result)
|
||||
return std::nullopt;
|
||||
return ReadResult<double>(result->translated, std::bit_cast<double>(result->value));
|
||||
}
|
||||
|
||||
void MMU::Write_U8(const u32 var, const u32 address)
|
||||
{
|
||||
Memcheck(address, var, true, 1);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address, var, 1);
|
||||
}
|
||||
|
||||
void MMU::Write_U16(const u32 var, const u32 address)
|
||||
{
|
||||
Memcheck(address, var, true, 2);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address, var, 2);
|
||||
}
|
||||
void MMU::Write_U16_Swap(const u32 var, const u32 address)
|
||||
{
|
||||
Write_U16((var & 0xFFFF0000) | Common::swap16(static_cast<u16>(var)), address);
|
||||
Write<u16>((var & 0xFFFF0000) | Common::swap16(static_cast<u16>(var)), address);
|
||||
}
|
||||
|
||||
void MMU::Write_U32(const u32 var, const u32 address)
|
||||
{
|
||||
Memcheck(address, var, true, 4);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address, var, 4);
|
||||
}
|
||||
void MMU::Write_U32_Swap(const u32 var, const u32 address)
|
||||
{
|
||||
Write_U32(Common::swap32(var), address);
|
||||
Write<u32>(Common::swap32(var), address);
|
||||
}
|
||||
|
||||
void MMU::Write_U64(const u64 var, const u32 address)
|
||||
{
|
||||
Memcheck(address, var, true, 8);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address, static_cast<u32>(var >> 32), 4);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address + sizeof(u32), static_cast<u32>(var), 4);
|
||||
}
|
||||
void MMU::Write_U64_Swap(const u64 var, const u32 address)
|
||||
{
|
||||
Write_U64(Common::swap64(var), address);
|
||||
}
|
||||
|
||||
u8 MMU::HostRead_U8(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
return mmu.ReadFromHardware<XCheckTLBFlag::NoException, u8>(address);
|
||||
}
|
||||
|
||||
u16 MMU::HostRead_U16(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
return mmu.ReadFromHardware<XCheckTLBFlag::NoException, u16>(address);
|
||||
}
|
||||
|
||||
u32 MMU::HostRead_U32(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
return mmu.ReadFromHardware<XCheckTLBFlag::NoException, u32>(address);
|
||||
}
|
||||
|
||||
u64 MMU::HostRead_U64(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
return mmu.ReadFromHardware<XCheckTLBFlag::NoException, u64>(address);
|
||||
}
|
||||
|
||||
float MMU::HostRead_F32(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
const u32 integral = HostRead_U32(guard, address);
|
||||
|
||||
return std::bit_cast<float>(integral);
|
||||
}
|
||||
|
||||
double MMU::HostRead_F64(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
const u64 integral = HostRead_U64(guard, address);
|
||||
|
||||
return std::bit_cast<double>(integral);
|
||||
}
|
||||
|
||||
void MMU::HostWrite_U8(const Core::CPUThreadGuard& guard, const u32 var, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, var, 1);
|
||||
}
|
||||
|
||||
void MMU::HostWrite_U16(const Core::CPUThreadGuard& guard, const u32 var, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, var, 2);
|
||||
}
|
||||
|
||||
void MMU::HostWrite_U32(const Core::CPUThreadGuard& guard, const u32 var, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, var, 4);
|
||||
}
|
||||
|
||||
void MMU::HostWrite_U64(const Core::CPUThreadGuard& guard, const u64 var, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, static_cast<u32>(var >> 32), 4);
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address + sizeof(u32), static_cast<u32>(var), 4);
|
||||
}
|
||||
|
||||
void MMU::HostWrite_F32(const Core::CPUThreadGuard& guard, const float var, const u32 address)
|
||||
{
|
||||
const u32 integral = std::bit_cast<u32>(var);
|
||||
|
||||
HostWrite_U32(guard, integral, address);
|
||||
}
|
||||
|
||||
void MMU::HostWrite_F64(const Core::CPUThreadGuard& guard, const double var, const u32 address)
|
||||
{
|
||||
const u64 integral = std::bit_cast<u64>(var);
|
||||
|
||||
HostWrite_U64(guard, integral, address);
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteUX(const Core::CPUThreadGuard& guard, const u32 var,
|
||||
const u32 address, const u32 size,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
if (!HostIsRAMAddress(guard, address, space))
|
||||
return std::nullopt;
|
||||
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
switch (space)
|
||||
{
|
||||
case RequestedAddressSpace::Effective:
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
|
||||
return WriteResult(!!mmu.m_ppc_state.msr.DR);
|
||||
case RequestedAddressSpace::Physical:
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException, true>(address, var, size);
|
||||
return WriteResult(false);
|
||||
case RequestedAddressSpace::Virtual:
|
||||
if (!mmu.m_ppc_state.msr.DR)
|
||||
return std::nullopt;
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, var, size);
|
||||
return WriteResult(true);
|
||||
}
|
||||
|
||||
ASSERT(false);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteU8(const Core::CPUThreadGuard& guard, const u32 var,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryWriteUX(guard, var, address, 1, space);
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteU16(const Core::CPUThreadGuard& guard, const u32 var,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryWriteUX(guard, var, address, 2, space);
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteU32(const Core::CPUThreadGuard& guard, const u32 var,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
return HostTryWriteUX(guard, var, address, 4, space);
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteU64(const Core::CPUThreadGuard& guard, const u64 var,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
const auto result = HostTryWriteUX(guard, static_cast<u32>(var >> 32), address, 4, space);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
return HostTryWriteUX(guard, static_cast<u32>(var), address + 4, 4, space);
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteF32(const Core::CPUThreadGuard& guard, const float var,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
const u32 integral = std::bit_cast<u32>(var);
|
||||
return HostTryWriteU32(guard, integral, address, space);
|
||||
}
|
||||
|
||||
std::optional<WriteResult> MMU::HostTryWriteF64(const Core::CPUThreadGuard& guard, const double var,
|
||||
const u32 address, RequestedAddressSpace space)
|
||||
{
|
||||
const u64 integral = std::bit_cast<u64>(var);
|
||||
return HostTryWriteU64(guard, integral, address, space);
|
||||
Write<u64>(Common::swap64(var), address);
|
||||
}
|
||||
|
||||
std::string MMU::HostGetString(const Core::CPUThreadGuard& guard, u32 address, size_t size)
|
||||
|
@ -870,7 +612,7 @@ std::string MMU::HostGetString(const Core::CPUThreadGuard& guard, u32 address, s
|
|||
{
|
||||
if (!HostIsRAMAddress(guard, address))
|
||||
break;
|
||||
u8 res = HostRead_U8(guard, address);
|
||||
u8 res = HostRead<u8>(guard, address);
|
||||
if (!res)
|
||||
break;
|
||||
s += static_cast<char>(res);
|
||||
|
@ -886,7 +628,7 @@ std::u16string MMU::HostGetU16String(const Core::CPUThreadGuard& guard, u32 addr
|
|||
{
|
||||
if (!HostIsRAMAddress(guard, address) || !HostIsRAMAddress(guard, address + 1))
|
||||
break;
|
||||
const u16 res = HostRead_U16(guard, address);
|
||||
const u16 res = HostRead<u16>(guard, address);
|
||||
if (!res)
|
||||
break;
|
||||
s += static_cast<char16_t>(res);
|
||||
|
@ -899,7 +641,7 @@ std::optional<ReadResult<std::string>> MMU::HostTryReadString(const Core::CPUThr
|
|||
u32 address, size_t size,
|
||||
RequestedAddressSpace space)
|
||||
{
|
||||
auto c = HostTryReadU8(guard, address, space);
|
||||
auto c = HostTryRead<u8>(guard, address, space);
|
||||
if (!c)
|
||||
return std::nullopt;
|
||||
if (c->value == 0)
|
||||
|
@ -910,7 +652,7 @@ std::optional<ReadResult<std::string>> MMU::HostTryReadString(const Core::CPUThr
|
|||
while (size == 0 || s.length() < size)
|
||||
{
|
||||
++address;
|
||||
const auto res = HostTryReadU8(guard, address, space);
|
||||
const auto res = HostTryRead<u8>(guard, address, space);
|
||||
if (!res || res->value == 0)
|
||||
break;
|
||||
s += static_cast<char>(res->value);
|
||||
|
@ -1692,38 +1434,7 @@ void ClearDCacheLineFromJit(MMU& mmu, u32 address)
|
|||
{
|
||||
mmu.ClearDCacheLine(address);
|
||||
}
|
||||
u32 ReadU8FromJit(MMU& mmu, u32 address)
|
||||
{
|
||||
return mmu.Read_U8(address);
|
||||
}
|
||||
u32 ReadU16FromJit(MMU& mmu, u32 address)
|
||||
{
|
||||
return mmu.Read_U16(address);
|
||||
}
|
||||
u32 ReadU32FromJit(MMU& mmu, u32 address)
|
||||
{
|
||||
return mmu.Read_U32(address);
|
||||
}
|
||||
u64 ReadU64FromJit(MMU& mmu, u32 address)
|
||||
{
|
||||
return mmu.Read_U64(address);
|
||||
}
|
||||
void WriteU8FromJit(MMU& mmu, u32 var, u32 address)
|
||||
{
|
||||
mmu.Write_U8(var, address);
|
||||
}
|
||||
void WriteU16FromJit(MMU& mmu, u32 var, u32 address)
|
||||
{
|
||||
mmu.Write_U16(var, address);
|
||||
}
|
||||
void WriteU32FromJit(MMU& mmu, u32 var, u32 address)
|
||||
{
|
||||
mmu.Write_U32(var, address);
|
||||
}
|
||||
void WriteU64FromJit(MMU& mmu, u64 var, u32 address)
|
||||
{
|
||||
mmu.Write_U64(var, address);
|
||||
}
|
||||
|
||||
void WriteU16SwapFromJit(MMU& mmu, u32 var, u32 address)
|
||||
{
|
||||
mmu.Write_U16_Swap(var, address);
|
||||
|
|
|
@ -4,12 +4,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/BitField.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
|
@ -106,6 +112,20 @@ enum class XCheckTLBFlag
|
|||
OpcodeNoException
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using make_unsigned_same_size = typename std::enable_if_t<
|
||||
sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8,
|
||||
std::conditional_t<
|
||||
sizeof(T) == 1, u8,
|
||||
std::conditional_t<sizeof(T) == 2, u16, std::conditional_t<sizeof(T) == 4, u32, u64>>>>;
|
||||
|
||||
template <typename T>
|
||||
using make_atleast_u32 =
|
||||
std::enable_if_t<std::is_unsigned_v<T>, std::conditional_t<std::is_same_v<T, u64>, u64, u32>>;
|
||||
|
||||
template <typename T>
|
||||
concept Size64 = (sizeof(T) == 8);
|
||||
|
||||
class MMU
|
||||
{
|
||||
public:
|
||||
|
@ -124,12 +144,14 @@ public:
|
|||
// If the read fails (eg. address does not correspond to a mapped address in the current address
|
||||
// space), a PanicAlert will be shown to the user and zero (or an empty string for the string
|
||||
// case) will be returned.
|
||||
static u8 HostRead_U8(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static u16 HostRead_U16(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static u32 HostRead_U32(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static u64 HostRead_U64(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static float HostRead_F32(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static double HostRead_F64(const Core::CPUThreadGuard& guard, u32 address);
|
||||
template <typename T>
|
||||
static T HostRead(const Core::CPUThreadGuard& guard, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
return std::bit_cast<T>(
|
||||
mmu.ReadFromHardware<XCheckTLBFlag::NoException, make_unsigned_same_size<T>>(address));
|
||||
}
|
||||
|
||||
static u32 HostRead_Instruction(const Core::CPUThreadGuard& guard, u32 address);
|
||||
static std::string HostGetString(const Core::CPUThreadGuard& guard, u32 address, size_t size = 0);
|
||||
static std::u16string HostGetU16String(const Core::CPUThreadGuard& guard, u32 address,
|
||||
|
@ -139,24 +161,41 @@ public:
|
|||
// If the read succeeds, the returned value will be present and the ReadResult contains the read
|
||||
// value and information on whether the given address had to be translated or not. Unlike the
|
||||
// HostRead functions, this does not raise a user-visible alert on failure.
|
||||
static std::optional<ReadResult<u8>>
|
||||
HostTryReadU8(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<ReadResult<u16>>
|
||||
HostTryReadU16(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<ReadResult<u32>>
|
||||
HostTryReadU32(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<ReadResult<u64>>
|
||||
HostTryReadU64(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<ReadResult<float>>
|
||||
HostTryReadF32(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<ReadResult<double>>
|
||||
HostTryReadF64(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
template <typename T>
|
||||
static std::optional<ReadResult<T>>
|
||||
HostTryRead(const Core::CPUThreadGuard& guard, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective)
|
||||
{
|
||||
if (!HostIsRAMAddress(guard, address, space))
|
||||
return std::nullopt;
|
||||
|
||||
using U = make_unsigned_same_size<T>;
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
switch (space)
|
||||
{
|
||||
case RequestedAddressSpace::Effective:
|
||||
{
|
||||
U value = mmu.ReadFromHardware<XCheckTLBFlag::NoException, U>(address);
|
||||
return ReadResult<T>(!!mmu.m_ppc_state.msr.DR, std::bit_cast<T>(std::move(value)));
|
||||
}
|
||||
case RequestedAddressSpace::Physical:
|
||||
{
|
||||
U value = mmu.ReadFromHardware<XCheckTLBFlag::NoException, U, true>(address);
|
||||
return ReadResult<T>(false, std::bit_cast<T>(std::move(value)));
|
||||
}
|
||||
case RequestedAddressSpace::Virtual:
|
||||
{
|
||||
if (!mmu.m_ppc_state.msr.DR)
|
||||
return std::nullopt;
|
||||
U value = mmu.ReadFromHardware<XCheckTLBFlag::NoException, U>(address);
|
||||
return ReadResult<T>(true, std::bit_cast<T>(std::move(value)));
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(false);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static std::optional<ReadResult<u32>>
|
||||
HostTryReadInstruction(const Core::CPUThreadGuard& guard, u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
|
@ -167,35 +206,74 @@ public:
|
|||
// Writes a value to emulated memory using the currently active MMU settings.
|
||||
// If the write fails (eg. address does not correspond to a mapped address in the current address
|
||||
// space), a PanicAlert will be shown to the user.
|
||||
static void HostWrite_U8(const Core::CPUThreadGuard& guard, u32 var, u32 address);
|
||||
static void HostWrite_U16(const Core::CPUThreadGuard& guard, u32 var, u32 address);
|
||||
static void HostWrite_U32(const Core::CPUThreadGuard& guard, u32 var, u32 address);
|
||||
static void HostWrite_U64(const Core::CPUThreadGuard& guard, u64 var, u32 address);
|
||||
static void HostWrite_F32(const Core::CPUThreadGuard& guard, float var, u32 address);
|
||||
static void HostWrite_F64(const Core::CPUThreadGuard& guard, double var, u32 address);
|
||||
template <typename T>
|
||||
requires(!Size64<T>)
|
||||
static void HostWrite(const Core::CPUThreadGuard& guard, const auto var, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
const auto v = std::bit_cast<make_unsigned_same_size<decltype(var)>>(var);
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, static_cast<u32>(v), sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires Size64<T>
|
||||
static void HostWrite(const Core::CPUThreadGuard& guard, const auto var, const u32 address)
|
||||
{
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
const auto v = std::bit_cast<make_unsigned_same_size<decltype(var)>>(var);
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, static_cast<u32>(v >> 32), 4);
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address + sizeof(u32), static_cast<u32>(v), 4);
|
||||
}
|
||||
|
||||
// Try to a write a value to memory at the given address in the given memory space.
|
||||
// If the write succeeds, the returned TryWriteResult contains information on whether the given
|
||||
// address had to be translated or not. Unlike the HostWrite functions, this does not raise a
|
||||
// user-visible alert on failure.
|
||||
template <typename T>
|
||||
requires(!Size64<T>)
|
||||
static std::optional<WriteResult>
|
||||
HostTryWriteU8(const Core::CPUThreadGuard& guard, u32 var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
HostTryWrite(const Core::CPUThreadGuard& guard, const auto var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective)
|
||||
{
|
||||
constexpr auto size = sizeof(T);
|
||||
const auto v = std::bit_cast<make_unsigned_same_size<decltype(var)>>(var);
|
||||
|
||||
if (!HostIsRAMAddress(guard, address, space))
|
||||
return std::nullopt;
|
||||
|
||||
auto& mmu = guard.GetSystem().GetMMU();
|
||||
switch (space)
|
||||
{
|
||||
case RequestedAddressSpace::Effective:
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, static_cast<u32>(v), size);
|
||||
return WriteResult(!!mmu.m_ppc_state.msr.DR);
|
||||
case RequestedAddressSpace::Physical:
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException, true>(address, static_cast<u32>(v), size);
|
||||
return WriteResult(false);
|
||||
case RequestedAddressSpace::Virtual:
|
||||
if (!mmu.m_ppc_state.msr.DR)
|
||||
return std::nullopt;
|
||||
mmu.WriteToHardware<XCheckTLBFlag::NoException>(address, static_cast<u32>(v), size);
|
||||
return WriteResult(true);
|
||||
}
|
||||
|
||||
ASSERT(false);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires Size64<T>
|
||||
static std::optional<WriteResult>
|
||||
HostTryWriteU16(const Core::CPUThreadGuard& guard, u32 var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<WriteResult>
|
||||
HostTryWriteU32(const Core::CPUThreadGuard& guard, u32 var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<WriteResult>
|
||||
HostTryWriteU64(const Core::CPUThreadGuard& guard, u64 var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<WriteResult>
|
||||
HostTryWriteF32(const Core::CPUThreadGuard& guard, float var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
static std::optional<WriteResult>
|
||||
HostTryWriteF64(const Core::CPUThreadGuard& guard, double var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective);
|
||||
HostTryWrite(const Core::CPUThreadGuard& guard, const auto var, const u32 address,
|
||||
RequestedAddressSpace space = RequestedAddressSpace::Effective)
|
||||
{
|
||||
const auto v = std::bit_cast<make_unsigned_same_size<decltype(var)>>(var);
|
||||
const auto result = HostTryWrite<u32>(guard, static_cast<u32>(v >> 32), address, space);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
return HostTryWrite<u32>(guard, static_cast<u32>(v), address + 4, space);
|
||||
}
|
||||
|
||||
// Returns whether a read or write to the given address will resolve to a RAM access in the given
|
||||
// address space.
|
||||
|
@ -213,15 +291,34 @@ public:
|
|||
u32 Read_Opcode(u32 address);
|
||||
TryReadInstResult TryReadInstruction(u32 address);
|
||||
|
||||
u8 Read_U8(u32 address);
|
||||
u16 Read_U16(u32 address);
|
||||
u32 Read_U32(u32 address);
|
||||
u64 Read_U64(u32 address);
|
||||
template <typename T>
|
||||
T Read(const u32 address)
|
||||
{
|
||||
using U = make_unsigned_same_size<T>;
|
||||
U var = ReadFromHardware<XCheckTLBFlag::Read, U>(address);
|
||||
Memcheck(address, var, false, sizeof(T));
|
||||
return std::bit_cast<T>(var);
|
||||
}
|
||||
|
||||
void Write_U8(u32 var, u32 address);
|
||||
void Write_U16(u32 var, u32 address);
|
||||
void Write_U32(u32 var, u32 address);
|
||||
void Write_U64(u64 var, u32 address);
|
||||
template <typename T>
|
||||
requires(!Size64<T>)
|
||||
void Write(const auto var, const u32 address)
|
||||
{
|
||||
constexpr auto size = sizeof(T);
|
||||
const auto v = std::bit_cast<make_unsigned_same_size<decltype(var)>>(var);
|
||||
Memcheck(address, v, true, size);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address, static_cast<u32>(v), size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires Size64<T>
|
||||
void Write(const auto var, const u32 address)
|
||||
{
|
||||
const auto v = std::bit_cast<make_unsigned_same_size<decltype(var)>>(var);
|
||||
Memcheck(address, v, true, 8);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address, static_cast<u32>(v >> 32), 4);
|
||||
WriteToHardware<XCheckTLBFlag::Write>(address + sizeof(u32), static_cast<u32>(v), 4);
|
||||
}
|
||||
|
||||
void Write_U16_Swap(u32 var, u32 address);
|
||||
void Write_U32_Swap(u32 var, u32 address);
|
||||
|
@ -305,20 +402,13 @@ private:
|
|||
void UpdateBATs(BatTable& bat_table, u32 base_spr);
|
||||
void UpdateFakeMMUBat(BatTable& bat_table, u32 start_addr);
|
||||
|
||||
template <XCheckTLBFlag flag, typename T, bool never_translate = false>
|
||||
template <XCheckTLBFlag flag, std::unsigned_integral T, bool never_translate = false>
|
||||
T ReadFromHardware(u32 em_address);
|
||||
template <XCheckTLBFlag flag, bool never_translate = false>
|
||||
void WriteToHardware(u32 em_address, const u32 data, const u32 size);
|
||||
template <XCheckTLBFlag flag>
|
||||
bool IsRAMAddress(u32 address, bool translate);
|
||||
|
||||
template <typename T>
|
||||
static std::optional<ReadResult<T>> HostTryReadUX(const Core::CPUThreadGuard& guard,
|
||||
const u32 address, RequestedAddressSpace space);
|
||||
static std::optional<WriteResult> HostTryWriteUX(const Core::CPUThreadGuard& guard, const u32 var,
|
||||
const u32 address, const u32 size,
|
||||
RequestedAddressSpace space);
|
||||
|
||||
Core::System& m_system;
|
||||
Memory::MemoryManager& m_memory;
|
||||
PowerPC::PowerPCManager& m_power_pc;
|
||||
|
@ -329,14 +419,18 @@ private:
|
|||
};
|
||||
|
||||
void ClearDCacheLineFromJit(MMU& mmu, u32 address);
|
||||
u32 ReadU8FromJit(MMU& mmu, u32 address); // Returns zero-extended 32bit value
|
||||
u32 ReadU16FromJit(MMU& mmu, u32 address); // Returns zero-extended 32bit value
|
||||
u32 ReadU32FromJit(MMU& mmu, u32 address);
|
||||
u64 ReadU64FromJit(MMU& mmu, u32 address);
|
||||
void WriteU8FromJit(MMU& mmu, u32 var, u32 address);
|
||||
void WriteU16FromJit(MMU& mmu, u32 var, u32 address);
|
||||
void WriteU32FromJit(MMU& mmu, u32 var, u32 address);
|
||||
void WriteU64FromJit(MMU& mmu, u64 var, u32 address);
|
||||
template <typename T>
|
||||
// Returns zero-extended value
|
||||
make_atleast_u32<T> ReadFromJit(MMU& mmu, u32 address)
|
||||
{
|
||||
return mmu.Read<T>(address);
|
||||
}
|
||||
template <typename T>
|
||||
// Can't use auto for var, as it'd prevent making a function pointer
|
||||
void WriteFromJit(MMU& mmu, make_atleast_u32<T> var, u32 address)
|
||||
{
|
||||
mmu.Write<T>(var, address);
|
||||
}
|
||||
void WriteU16SwapFromJit(MMU& mmu, u32 var, u32 address);
|
||||
void WriteU32SwapFromJit(MMU& mmu, u32 var, u32 address);
|
||||
void WriteU64SwapFromJit(MMU& mmu, u64 var, u32 address);
|
||||
|
|
|
@ -108,7 +108,7 @@ bool Compare(const Core::CPUThreadGuard& guard, u32 address, u32 size, const MEG
|
|||
|
||||
for (size_t i = 0; i < sig.code.size(); ++i)
|
||||
{
|
||||
if (sig.code[i] != 0 && PowerPC::MMU::HostRead_U32(
|
||||
if (sig.code[i] != 0 && PowerPC::MMU::HostRead<u32>(
|
||||
guard, static_cast<u32>(address + i * sizeof(u32))) != sig.code[i])
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -510,7 +510,7 @@ static bool MemoryMatchesAt(const Core::CPUThreadGuard& guard, u32 offset,
|
|||
{
|
||||
for (u32 i = 0; i < value.size(); ++i)
|
||||
{
|
||||
auto result = PowerPC::MMU::HostTryReadU8(guard, offset + i);
|
||||
auto result = PowerPC::MMU::HostTryRead<u8>(guard, offset + i);
|
||||
if (!result || result->value != value[i])
|
||||
return false;
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ static void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, u32 offset,
|
|||
auto& system = guard.GetSystem();
|
||||
const u32 size = static_cast<u32>(value.size());
|
||||
for (u32 i = 0; i < size; ++i)
|
||||
PowerPC::MMU::HostTryWriteU8(guard, value[i], offset + i);
|
||||
PowerPC::MMU::HostTryWrite<u8>(guard, value[i], offset + i);
|
||||
const u32 overlapping_hook_count = HLE::UnpatchRange(system, offset, offset + size);
|
||||
if (overlapping_hook_count != 0)
|
||||
{
|
||||
|
@ -596,13 +596,13 @@ static void ApplyOcarinaMemoryPatch(const Core::CPUThreadGuard& guard, const Pat
|
|||
{
|
||||
// from the pattern find the next blr instruction
|
||||
const u32 blr_address = ram_start + i;
|
||||
auto blr = PowerPC::MMU::HostTryReadU32(guard, blr_address);
|
||||
auto blr = PowerPC::MMU::HostTryRead<u32>(guard, blr_address);
|
||||
if (blr && blr->value == 0x4e800020)
|
||||
{
|
||||
// and replace it with a jump to the given offset
|
||||
const u32 target = memory_patch.m_offset | 0x80000000;
|
||||
const u32 jmp = ((target - blr_address) & 0x03fffffc) | 0x48000000;
|
||||
PowerPC::MMU::HostTryWriteU32(guard, jmp, blr_address);
|
||||
PowerPC::MMU::HostTryWrite<u32>(guard, jmp, blr_address);
|
||||
const u32 overlapping_hook_count =
|
||||
HLE::UnpatchRange(system, blr_address, blr_address + 4);
|
||||
if (overlapping_hook_count != 0)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <QComboBox>
|
||||
#include <QCursor>
|
||||
#include <QHBoxLayout>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
|
@ -493,18 +494,24 @@ void CheatSearchWidget::OnAddressTableContextMenu()
|
|||
if (m_address_table->selectedItems().isEmpty())
|
||||
return;
|
||||
|
||||
auto* item = m_address_table->selectedItems()[0];
|
||||
const u32 address = item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
|
||||
|
||||
QMenu* menu = new QMenu(this);
|
||||
menu->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
menu->addAction(tr("Show in memory"), [this, address] { emit ShowMemory(address); });
|
||||
menu->addAction(tr("Add to watch"), this, [this, address] {
|
||||
const QString name = QStringLiteral("mem_%1").arg(address, 8, 16, QLatin1Char('0'));
|
||||
emit RequestWatch(name, address);
|
||||
menu->addAction(tr("Show in memory"), this, [this] {
|
||||
auto* item = m_address_table->selectedItems()[0];
|
||||
const u32 address = item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
|
||||
emit ShowMemory(address);
|
||||
});
|
||||
menu->addAction(tr("Add to watch"), this, [this] {
|
||||
for (auto* const item : m_address_table->selectedItems())
|
||||
{
|
||||
const u32 address = item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
|
||||
const QString name = QStringLiteral("mem_%1").arg(address, 8, 16, QLatin1Char('0'));
|
||||
emit RequestWatch(name, address);
|
||||
}
|
||||
});
|
||||
menu->addAction(tr("Generate Action Replay Code(s)"), this, &CheatSearchWidget::GenerateARCodes);
|
||||
menu->addAction(tr("Write value"), this, &CheatSearchWidget::WriteValue);
|
||||
|
||||
menu->exec(QCursor::pos());
|
||||
}
|
||||
|
@ -590,10 +597,40 @@ void CheatSearchWidget::GenerateARCodes()
|
|||
}
|
||||
}
|
||||
|
||||
void CheatSearchWidget::WriteValue()
|
||||
{
|
||||
if (m_address_table->selectedItems().isEmpty())
|
||||
return;
|
||||
|
||||
bool ok{};
|
||||
QString text = QInputDialog::getText(this, tr("Write value"), tr("Value:"), QLineEdit::Normal,
|
||||
QString{}, &ok);
|
||||
|
||||
if (ok && m_session->SetValueFromString(text.toStdString(),
|
||||
m_parse_values_as_hex_checkbox->isChecked()))
|
||||
{
|
||||
auto items = m_address_table->selectedItems();
|
||||
std::vector<u32> addresses(items.size());
|
||||
std::transform(items.begin(), items.end(), addresses.begin(), [](QTableWidgetItem* item) {
|
||||
return item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
|
||||
});
|
||||
|
||||
Core::CPUThreadGuard guard{m_system};
|
||||
if (!m_session->WriteValue(guard, std::span<u32>(addresses)))
|
||||
{
|
||||
m_info_label_1->setText(tr("There was an error writing (some) values."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info_label_1->setText(tr("Invalid value."));
|
||||
}
|
||||
}
|
||||
|
||||
void CheatSearchWidget::RefreshCurrentValueTableItem(
|
||||
QTableWidgetItem* const current_value_table_item)
|
||||
{
|
||||
const auto address = current_value_table_item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
|
||||
const u32 address = current_value_table_item->data(ADDRESS_TABLE_ADDRESS_ROLE).toUInt();
|
||||
const auto curr_val_iter = m_address_table_current_values.find(address);
|
||||
if (curr_val_iter != m_address_table_current_values.end())
|
||||
current_value_table_item->setText(QString::fromStdString(curr_val_iter->second));
|
||||
|
|
|
@ -77,6 +77,7 @@ private:
|
|||
UpdateSource source);
|
||||
void RecreateGUITable();
|
||||
void GenerateARCodes();
|
||||
void WriteValue();
|
||||
int GetVisibleRowsBeginIndex() const;
|
||||
int GetVisibleRowsEndIndex() const;
|
||||
|
||||
|
|
|
@ -274,7 +274,7 @@ void ThreadWidget::Update()
|
|||
};
|
||||
const auto format_hex_from = [&format_hex](const Core::CPUThreadGuard& guard, u32 addr) {
|
||||
addr =
|
||||
PowerPC::MMU::HostIsRAMAddress(guard, addr) ? PowerPC::MMU::HostRead_U32(guard, addr) : 0;
|
||||
PowerPC::MMU::HostIsRAMAddress(guard, addr) ? PowerPC::MMU::HostRead<u32>(guard, addr) : 0;
|
||||
return format_hex(addr);
|
||||
};
|
||||
const auto get_state = [](u16 thread_state) {
|
||||
|
@ -460,7 +460,7 @@ void ThreadWidget::UpdateThreadCallstack(const Core::CPUThreadGuard& guard,
|
|||
m_callstack_table->setItem(i, 0, new QTableWidgetItem(format_hex(sp)));
|
||||
if (PowerPC::MMU::HostIsRAMAddress(guard, sp + 4))
|
||||
{
|
||||
const u32 lr_save = PowerPC::MMU::HostRead_U32(guard, sp + 4);
|
||||
const u32 lr_save = PowerPC::MMU::HostRead<u32>(guard, sp + 4);
|
||||
m_callstack_table->setItem(i, 2, new QTableWidgetItem(format_hex(lr_save)));
|
||||
m_callstack_table->setItem(
|
||||
i, 3,
|
||||
|
@ -471,7 +471,7 @@ void ThreadWidget::UpdateThreadCallstack(const Core::CPUThreadGuard& guard,
|
|||
{
|
||||
m_callstack_table->setItem(i, 2, new QTableWidgetItem(QStringLiteral("--------")));
|
||||
}
|
||||
sp = PowerPC::MMU::HostRead_U32(guard, sp);
|
||||
sp = PowerPC::MMU::HostRead<u32>(guard, sp);
|
||||
m_callstack_table->setItem(i, 1, new QTableWidgetItem(format_hex(sp)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,12 +203,12 @@ void WatchWidget::Update()
|
|||
{
|
||||
if (PowerPC::MMU::HostIsRAMAddress(guard, entry.address))
|
||||
{
|
||||
hex->setText(QStringLiteral("%1").arg(PowerPC::MMU::HostRead_U32(guard, entry.address), 8,
|
||||
hex->setText(QStringLiteral("%1").arg(PowerPC::MMU::HostRead<u32>(guard, entry.address), 8,
|
||||
16, QLatin1Char('0')));
|
||||
decimal->setText(QString::number(PowerPC::MMU::HostRead_U32(guard, entry.address)));
|
||||
decimal->setText(QString::number(PowerPC::MMU::HostRead<u32>(guard, entry.address)));
|
||||
string->setText(
|
||||
QString::fromStdString(PowerPC::MMU::HostGetString(guard, entry.address, 32)));
|
||||
floatValue->setText(QString::number(PowerPC::MMU::HostRead_F32(guard, entry.address)));
|
||||
floatValue->setText(QString::number(PowerPC::MMU::HostRead<float>(guard, entry.address)));
|
||||
lockValue->setCheckState(entry.locked ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
|||
}
|
||||
else
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U32(guard, value, debug_interface.GetWatch(row).address);
|
||||
PowerPC::MMU::HostWrite<u32>(guard, value, debug_interface.GetWatch(row).address);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1645,7 +1645,7 @@ RSOVector MenuBar::DetectRSOModules(ParallelProgressDialog& progress)
|
|||
|
||||
for (; len < MODULE_NAME_MAX_LENGTH; ++len)
|
||||
{
|
||||
const auto res = PowerPC::MMU::HostRead_U8(guard, *found_addr - (len + 1));
|
||||
const auto res = PowerPC::MMU::HostRead<u8>(guard, *found_addr - (len + 1));
|
||||
if (!std::isprint(res))
|
||||
{
|
||||
break;
|
||||
|
@ -1989,7 +1989,7 @@ void MenuBar::SearchInstruction()
|
|||
for (u32 addr = Memory::MEM1_BASE_ADDR; addr < Memory::MEM1_BASE_ADDR + memory.GetRamSizeReal();
|
||||
addr += 4)
|
||||
{
|
||||
if (op_std == PPCTables::GetInstructionName(PowerPC::MMU::HostRead_U32(guard, addr), addr))
|
||||
if (op_std == PPCTables::GetInstructionName(PowerPC::MMU::HostRead<u32>(guard, addr), addr))
|
||||
{
|
||||
NOTICE_LOG_FMT(POWERPC, "Found {} at {:08x}", op_std, addr);
|
||||
found = true;
|
||||
|
|
Loading…
Reference in New Issue