From 8a97ce9124c94f868b078d67208f81795f259323 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Tue, 27 May 2025 23:05:47 +0200 Subject: [PATCH 1/3] MMU: Use templates for Read/Write functions --- Source/Core/Common/TypeUtils.h | 11 + Source/Core/Core/AchievementManager.cpp | 4 +- Source/Core/Core/ActionReplay.cpp | 36 +- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 43 +-- Source/Core/Core/CheatSearch.cpp | 94 +---- .../Core/Core/Debugger/Debugger_SymbolMap.cpp | 6 +- Source/Core/Core/Debugger/OSThread.cpp | 82 ++--- .../Core/Core/Debugger/PPCDebugInterface.cpp | 10 +- Source/Core/Core/Debugger/RSO.cpp | 81 ++--- Source/Core/Core/FifoPlayer/FifoPlayer.cpp | 8 +- Source/Core/Core/GeckoCode.cpp | 40 +-- Source/Core/Core/HLE/HLE_Misc.cpp | 17 +- Source/Core/Core/HLE/HLE_OS.cpp | 11 +- Source/Core/Core/HLE/HLE_VarArgs.cpp | 12 +- Source/Core/Core/HLE/HLE_VarArgs.h | 8 +- Source/Core/Core/HW/AddressSpace.cpp | 18 +- Source/Core/Core/MemoryWatcher.cpp | 2 +- Source/Core/Core/PatchEngine.cpp | 10 +- Source/Core/Core/PowerPC/Expression.cpp | 54 +-- .../Core/PowerPC/Interpreter/Interpreter.cpp | 2 +- .../Interpreter/Interpreter_LoadStore.cpp | 120 +++---- .../Interpreter_LoadStorePaired.cpp | 50 +-- .../Core/PowerPC/Jit64Common/EmuCodeBlock.cpp | 32 +- .../PowerPC/JitArm64/JitArm64_BackPatch.cpp | 16 +- Source/Core/Core/PowerPC/JitInterface.cpp | 3 +- Source/Core/Core/PowerPC/MMU.cpp | 335 ++++++------------ Source/Core/Core/PowerPC/MMU.h | 129 +++---- .../PowerPC/SignatureDB/MEGASignatureDB.cpp | 2 +- Source/Core/DiscIO/RiivolutionPatcher.cpp | 8 +- .../Core/DolphinQt/Debugger/ThreadWidget.cpp | 6 +- .../Core/DolphinQt/Debugger/WatchWidget.cpp | 8 +- Source/Core/DolphinQt/MenuBar.cpp | 4 +- 32 files changed, 487 insertions(+), 775 deletions(-) diff --git a/Source/Core/Common/TypeUtils.h b/Source/Core/Common/TypeUtils.h index 59a6393444..2e18a411ed 100644 --- a/Source/Core/Common/TypeUtils.h +++ b/Source/Core/Common/TypeUtils.h @@ -5,6 +5,8 @@ #include #include #include +#include "Common/CommonTypes.h" +#include "Common/MathUtil.h" namespace Common { @@ -141,4 +143,13 @@ concept TypedEnum = std::is_same_v, Underlying>; template concept BooleanEnum = TypedEnum; + +template +requires(sizeof(T) <= sizeof(u64) && std::has_single_bit(sizeof(T))) +using MakeUnsignedSameSize = + std::tuple_element_t>; + +template +using MakeAtLeastU32 = std::conditional_t, u64, u32>; + } // namespace Common diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 789c9ffb12..7717180c1f 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -1370,8 +1370,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(thread_guard, address + num_read, + PowerPC::RequestedAddressSpace::Physical); if (!value.has_value()) return num_read; buffer[num_read] = value.value().value; diff --git a/Source/Core/Core/ActionReplay.cpp b/Source/Core/Core/ActionReplay.cpp index b41ea48943..c61da10bee 100644 --- a/Source/Core/Core/ActionReplay.cpp +++ b/Source/Core/Core/ActionReplay.cpp @@ -434,7 +434,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(guard, new_addr); LogInfo("Hardware Address: {:08x}", new_addr); LogInfo("Size: {:08x}", addr.size); @@ -503,16 +503,17 @@ static bool Subtype_AddCode(const Core::CPUThreadGuard& guard, const ARAddr& add case DATATYPE_8BIT: LogInfo("8-bit Add"); LogInfo("--------"); - ApplyMemoryPatch(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); + ApplyMemoryPatch(guard, PowerPC::MMU::HostRead(guard, new_addr) + data, new_addr); + LogInfo("Wrote {:02x} to address {:08x}", PowerPC::MMU::HostRead(guard, new_addr), + new_addr); LogInfo("--------"); break; case DATATYPE_16BIT: LogInfo("16-bit Add"); LogInfo("--------"); - ApplyMemoryPatch(guard, PowerPC::MMU::HostRead_U16(guard, new_addr) + data, new_addr); - LogInfo("Wrote {:04x} to address {:08x}", PowerPC::MMU::HostRead_U16(guard, new_addr), + ApplyMemoryPatch(guard, PowerPC::MMU::HostRead(guard, new_addr) + data, new_addr); + LogInfo("Wrote {:04x} to address {:08x}", PowerPC::MMU::HostRead(guard, new_addr), new_addr); LogInfo("--------"); break; @@ -520,8 +521,8 @@ static bool Subtype_AddCode(const Core::CPUThreadGuard& guard, const ARAddr& add case DATATYPE_32BIT: LogInfo("32-bit Add"); LogInfo("--------"); - ApplyMemoryPatch(guard, PowerPC::MMU::HostRead_U32(guard, new_addr) + data, new_addr); - LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead_U32(guard, new_addr), + ApplyMemoryPatch(guard, PowerPC::MMU::HostRead(guard, new_addr) + data, new_addr); + LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead(guard, new_addr), new_addr); LogInfo("--------"); break; @@ -531,7 +532,7 @@ 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(guard, new_addr); const float read_float = std::bit_cast(read); // data contains an (unsigned?) integer value const float fread = read_float + static_cast(data); @@ -666,14 +667,14 @@ 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(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(guard, addr_src); LogInfo("Resolved Src Address to: {:08x}", ptr_src); for (int i = 0; i < num_bytes; ++i) { - ApplyMemoryPatch(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), + ApplyMemoryPatch(guard, PowerPC::MMU::HostRead(guard, ptr_src + i), ptr_dest + i); + LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead(guard, ptr_src + i), ptr_dest + i); } LogInfo("--------"); @@ -684,8 +685,8 @@ static bool ZeroCode_MemoryCopy(const Core::CPUThreadGuard& guard, const u32 val LogInfo("--------"); for (int i = 0; i < num_bytes; ++i) { - ApplyMemoryPatch(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), + ApplyMemoryPatch(guard, PowerPC::MMU::HostRead(guard, addr_src + i), addr_dest + i); + LogInfo("Wrote {:08x} to address {:08x}", PowerPC::MMU::HostRead(guard, addr_src + i), addr_dest + i); } LogInfo("--------"); @@ -793,16 +794,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(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(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(guard, new_addr), data, addr.type); break; default: diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 884a11bd87..149f92f7c1 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -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(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(iAppLoaderFuncAddr + 0); + const u32 iAppLoaderMain = mmu.Read(iAppLoaderFuncAddr + 4); + const u32 iAppLoaderClose = mmu.Read(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(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(0x81300004); + const u32 length = mmu.Read(0x81300008); + const u32 dvd_offset = mmu.Read(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(guard, 0x0D15EA5E, 0x80000020); // Physical Memory Size (24MB on retail) - PowerPC::MMU::HostWrite_U32(guard, memory.GetRamSizeReal(), 0x80000028); + PowerPC::MMU::HostWrite(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(Core::ConsoleType::LatestDevkit); - PowerPC::MMU::HostWrite_U32(guard, console_type, 0x8000002C); + PowerPC::MMU::HostWrite(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(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(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(guard, 0x09a7ec80, 0x800000F8); // Bus Clock Speed + PowerPC::MMU::HostWrite(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(guard, 0x4c000064, 0x80000300); // Write default DSI Handler: rfi + PowerPC::MMU::HostWrite(guard, 0x4c000064, 0x80000800); // Write default FPU Handler: rfi + PowerPC::MMU::HostWrite(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(guard, 0x8200, 0x000030e6); // Console type } // __________________________________________________________________________________________________ diff --git a/Source/Core/Core/CheatSearch.cpp b/Source/Core/Core/CheatSearch.cpp index a3bd123e0c..f2fdd5a058 100644 --- a/Source/Core/Core/CheatSearch.cpp +++ b/Source/Core/Core/CheatSearch.cpp @@ -100,106 +100,14 @@ std::vector Cheats::GetValueAsByteVector(const Cheats::SearchValue& value) } } -namespace -{ template static std::optional> -TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, - PowerPC::RequestedAddressSpace space); - -template <> -std::optional> TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, PowerPC::RequestedAddressSpace space) { - return PowerPC::MMU::HostTryReadU8(guard, addr, space); + return PowerPC::MMU::HostTryRead(guard, addr, space); } -template <> -std::optional> -TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, - PowerPC::RequestedAddressSpace space) -{ - return PowerPC::MMU::HostTryReadU16(guard, addr, space); -} - -template <> -std::optional> -TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, - PowerPC::RequestedAddressSpace space) -{ - return PowerPC::MMU::HostTryReadU32(guard, addr, space); -} - -template <> -std::optional> -TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, - PowerPC::RequestedAddressSpace space) -{ - return PowerPC::MMU::HostTryReadU64(guard, addr, space); -} - -template <> -std::optional> -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(tmp->translated, std::bit_cast(tmp->value)); -} - -template <> -std::optional> -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(tmp->translated, std::bit_cast(tmp->value)); -} - -template <> -std::optional> -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(tmp->translated, std::bit_cast(tmp->value)); -} - -template <> -std::optional> -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(tmp->translated, std::bit_cast(tmp->value)); -} - -template <> -std::optional> -TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, - PowerPC::RequestedAddressSpace space) -{ - return PowerPC::MMU::HostTryReadF32(guard, addr, space); -} - -template <> -std::optional> -TryReadValueFromEmulatedMemory(const Core::CPUThreadGuard& guard, u32 addr, - PowerPC::RequestedAddressSpace space) -{ - return PowerPC::MMU::HostTryReadF64(guard, addr, space); -} -} // namespace - template Common::Result>> Cheats::NewSearch(const Core::CPUThreadGuard& guard, diff --git a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp index 7ee5868fce..76bfd0c780 100644 --- a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp +++ b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp @@ -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(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(guard, addr + 4); stack_step(func_addr); if (IsStackBottom(guard, addr)) break; - addr = PowerPC::MMU::HostRead_U32(guard, addr); + addr = PowerPC::MMU::HostRead(guard, addr); } } } diff --git a/Source/Core/Core/Debugger/OSThread.cpp b/Source/Core/Core/Debugger/OSThread.cpp index d4cee37d26..b5fd60e3a1 100644 --- a/Source/Core/Core/Debugger/OSThread.cpp +++ b/Source/Core/Core/Debugger/OSThread.cpp @@ -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(guard, addr + u32(i * sizeof(int))); + cr = PowerPC::MMU::HostRead(guard, addr + 0x80); + lr = PowerPC::MMU::HostRead(guard, addr + 0x84); + ctr = PowerPC::MMU::HostRead(guard, addr + 0x88); + xer = PowerPC::MMU::HostRead(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(PowerPC::MMU::HostRead_U16(guard, addr + 0x1a2)); + fpr[i] = PowerPC::MMU::HostRead(guard, addr + 0x90 + u32(i * sizeof(double))); + fpscr = PowerPC::MMU::HostRead(guard, addr + 0x190); + srr0 = PowerPC::MMU::HostRead(guard, addr + 0x198); + srr1 = PowerPC::MMU::HostRead(guard, addr + 0x19c); + dummy = PowerPC::MMU::HostRead(guard, addr + 0x1a0); + state = static_cast(PowerPC::MMU::HostRead(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(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(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(guard, addr); + thread_queue.tail = PowerPC::MMU::HostRead(guard, addr + 0x4); + owner_addr = PowerPC::MMU::HostRead(guard, addr + 0x8); + lock_count = PowerPC::MMU::HostRead(guard, addr + 0xc); + link.next = PowerPC::MMU::HostRead(guard, addr + 0x10); + link.prev = PowerPC::MMU::HostRead(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(guard, addr + 0x2c8); + is_detached = PowerPC::MMU::HostRead(guard, addr + 0x2ca); + suspend = PowerPC::MMU::HostRead(guard, addr + 0x2cc); + effective_priority = PowerPC::MMU::HostRead(guard, addr + 0x2d0); + base_priority = PowerPC::MMU::HostRead(guard, addr + 0x2d4); + exit_code_addr = PowerPC::MMU::HostRead(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(guard, addr + 0x2dc); + queue_link.next = PowerPC::MMU::HostRead(guard, addr + 0x2e0); + queue_link.prev = PowerPC::MMU::HostRead(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(guard, addr + 0x2e8); + join_queue.tail = PowerPC::MMU::HostRead(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(guard, addr + 0x2f0); + mutex_queue.head = PowerPC::MMU::HostRead(guard, addr + 0x2f4); + mutex_queue.tail = PowerPC::MMU::HostRead(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(guard, addr + 0x2fc); + thread_link.prev = PowerPC::MMU::HostRead(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(guard, addr + 0x304); + stack_end = PowerPC::MMU::HostRead(guard, addr + 0x308); + error = PowerPC::MMU::HostRead(guard, addr + 0x30c); + specific[0] = PowerPC::MMU::HostRead(guard, addr + 0x310); + specific[1] = PowerPC::MMU::HostRead(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(guard, stack_end) == STACK_MAGIC; } OSThreadView::OSThreadView(const Core::CPUThreadGuard& guard, u32 addr) diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Debugger/PPCDebugInterface.cpp index bf4225ba66..f38d1c8346 100644 --- a/Source/Core/Core/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Debugger/PPCDebugInterface.cpp @@ -47,10 +47,10 @@ void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, std::span value, co bool should_invalidate_cache = false; for (u32 offset = 0; offset < size; ++offset) { - u8 old_value = PowerPC::MMU::HostRead_U8(guard, address + offset); + u8 old_value = PowerPC::MMU::HostRead(guard, address + offset); if (old_value != value[offset]) { - PowerPC::MMU::HostWrite_U8(guard, value[offset], address + offset); + PowerPC::MMU::HostWrite(guard, value[offset], address + offset); should_invalidate_cache = true; if (store_existing_value) value[offset] = old_value; @@ -245,7 +245,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(guard, ACTIVE_QUEUE_HEAD_ADDR); if (!PowerPC::MMU::HostIsRAMAddress(guard, active_queue_head)) return threads; @@ -326,7 +326,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(guard, address); } u32 PPCDebugInterface::ReadExtraMemory(const Core::CPUThreadGuard& guard, int memory, @@ -335,7 +335,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(guard, address); case 1: { const auto& dsp = guard.GetSystem().GetDSP(); diff --git a/Source/Core/Core/Debugger/RSO.cpp b/Source/Core/Core/Debugger/RSO.cpp index 7ee9481df3..81183344d4 100644 --- a/Source/Core/Core/Debugger/RSO.cpp +++ b/Source/Core/Core/Debugger/RSO.cpp @@ -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(guard, address); + m_header.entry.prev_entry = PowerPC::MMU::HostRead(guard, address + 0x04); + m_header.entry.section_count = PowerPC::MMU::HostRead(guard, address + 0x08); + m_header.entry.section_table_offset = PowerPC::MMU::HostRead(guard, address + 0xC); + m_header.entry.name_offset = PowerPC::MMU::HostRead(guard, address + 0x10); + m_header.entry.name_size = PowerPC::MMU::HostRead(guard, address + 0x14); + m_header.entry.version = PowerPC::MMU::HostRead(guard, address + 0x18); + m_header.entry.bss_size = PowerPC::MMU::HostRead(guard, address + 0x1C); + m_header.section_info.prolog_section_index = PowerPC::MMU::HostRead(guard, address + 0x20); + m_header.section_info.epilog_section_index = PowerPC::MMU::HostRead(guard, address + 0x21); + m_header.section_info.unresolved_section_index = + PowerPC::MMU::HostRead(guard, address + 0x22); + m_header.section_info.bss_section_index = PowerPC::MMU::HostRead(guard, address + 0x23); + m_header.section_info.prolog_offset = PowerPC::MMU::HostRead(guard, address + 0x24); + m_header.section_info.epilog_offset = PowerPC::MMU::HostRead(guard, address + 0x28); + m_header.section_info.unresolved_offset = PowerPC::MMU::HostRead(guard, address + 0x2C); + m_header.relocation_tables.internals_offset = PowerPC::MMU::HostRead(guard, address + 0x30); + m_header.relocation_tables.internals_size = PowerPC::MMU::HostRead(guard, address + 0x34); + m_header.relocation_tables.externals_offset = PowerPC::MMU::HostRead(guard, address + 0x38); + m_header.relocation_tables.externals_size = PowerPC::MMU::HostRead(guard, address + 0x3C); + m_header.symbol_tables.exports_offset = PowerPC::MMU::HostRead(guard, address + 0x40); + m_header.symbol_tables.exports_size = PowerPC::MMU::HostRead(guard, address + 0x44); + m_header.symbol_tables.exports_name_table = PowerPC::MMU::HostRead(guard, address + 0x48); + m_header.symbol_tables.imports_offset = PowerPC::MMU::HostRead(guard, address + 0x4C); + m_header.symbol_tables.imports_size = PowerPC::MMU::HostRead(guard, address + 0x50); + m_header.symbol_tables.imports_name_table = PowerPC::MMU::HostRead(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(guard, address); + section.size = PowerPC::MMU::HostRead(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(guard, address); + rso_import.code_offset = PowerPC::MMU::HostRead(guard, address + 4); + rso_import.entry_offset = PowerPC::MMU::HostRead(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(guard, address); + rso_export.code_offset = PowerPC::MMU::HostRead(guard, address + 4); + rso_export.section_index = PowerPC::MMU::HostRead(guard, address + 8); + rso_export.hash = PowerPC::MMU::HostRead(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(guard, address); + entry.r_info = PowerPC::MMU::HostRead(guard, address + 4); + entry.r_addend = PowerPC::MMU::HostRead(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(guard, address); + entry.r_info = PowerPC::MMU::HostRead(guard, address + 4); + entry.r_addend = PowerPC::MMU::HostRead(guard, address + 8); m_entries.emplace_back(std::move(entry)); address += sizeof(RSOExternalsEntry); } diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index 7529d406b4..a4b08dc0d2 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -706,12 +706,12 @@ void FifoPlayer::LoadTextureMemory() void FifoPlayer::WriteCP(u32 address, u16 value) { - m_system.GetMMU().Write_U16(value, 0xCC000000 | address); + m_system.GetMMU().Write(value, 0xCC000000 | address); } void FifoPlayer::WritePI(u32 address, u32 value) { - m_system.GetMMU().Write_U32(value, 0xCC003000 | address); + m_system.GetMMU().Write(value, 0xCC003000 | address); } void FifoPlayer::FlushWGP() @@ -810,13 +810,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(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(0xCC000000 | CommandProcessor::STATUS_REGISTER); return status.OverflowHiWatermark; } diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index 5f4e8b9cb8..45b8db279a 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -139,17 +139,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(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(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(guard, 0x3f000000u | mmio_addr << 8, INSTALLER_BASE_ADDRESS + h); } } @@ -159,11 +159,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(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(guard, 0x00d0c0de, codelist_base_address); + PowerPC::MMU::HostWrite(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; @@ -186,8 +186,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(guard, code.address, next_address); + PowerPC::MMU::HostWrite(guard, code.data, next_address + 4); next_address += CODE_SIZE; } } @@ -196,12 +196,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(guard, 0xF0000000, next_address); + PowerPC::MMU::HostWrite(guard, 0x00000000, next_address + 4); + PowerPC::MMU::HostWrite(guard, 0, HLE_TRAMPOLINE_ADDRESS); // Turn on codes - PowerPC::MMU::HostWrite_U8(guard, 1, INSTALLER_BASE_ADDRESS + 7); + PowerPC::MMU::HostWrite(guard, 1, INSTALLER_BASE_ADDRESS + 7); // Invalidate the icache and any asm codes auto& ppc_state = guard.GetSystem().GetPPCState(); @@ -271,18 +271,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(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(guard, SFP, SP + 8); // Real stack frame + PowerPC::MMU::HostWrite(guard, ppc_state.pc, SP + 12); + PowerPC::MMU::HostWrite(guard, LR(ppc_state), SP + 16); + PowerPC::MMU::HostWrite(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(guard, ppc_state.ps[i].PS0AsU64(), SP + 24 + 2 * i * sizeof(u64)); + PowerPC::MMU::HostWrite(guard, ppc_state.ps[i].PS1AsU64(), + SP + 24 + (2 * i + 1) * sizeof(u64)); } DEBUG_LOG_FMT(ACTIONREPLAY, "GeckoCodes: Initiating phantom branch-and-link. " diff --git a/Source/Core/Core/HLE/HLE_Misc.cpp b/Source/Core/Core/HLE/HLE_Misc.cpp index 423ba465dd..6f2a2fc389 100644 --- a/Source/Core/Core/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/HLE/HLE_Misc.cpp @@ -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(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(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(guard, SP + 8); + ppc_state.npc = PowerPC::MMU::HostRead(guard, SP + 12); + LR(ppc_state) = PowerPC::MMU::HostRead(guard, SP + 16); + ppc_state.cr.Set(PowerPC::MMU::HostRead(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(guard, SP + 24 + 2 * i * sizeof(u64)), + PowerPC::MMU::HostRead(guard, SP + 24 + (2 * i + 1) * sizeof(u64))); } } } // namespace HLE_Misc diff --git a/Source/Core/Core/HLE/HLE_OS.cpp b/Source/Core/Core/HLE/HLE_OS.cpp index a81f294107..43f5796bb4 100644 --- a/Source/Core/Core/HLE/HLE_OS.cpp +++ b/Source/Core/Core/HLE/HLE_OS.cpp @@ -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(guard, ppc_state.gpr[3])) || + PowerPC::MMU::HostRead(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(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(PowerPC::MMU::HostRead_U16(guard, ppc_state.gpr[3] + 0xE)); + fd = static_cast(PowerPC::MMU::HostRead(guard, ppc_state.gpr[3] + 0xE)); } if (fd != 1 && fd != 2) { // On RVL SDK it seems stored at FILE+0x2. - fd = static_cast(PowerPC::MMU::HostRead_U16(guard, ppc_state.gpr[3] + 0x2)); + fd = static_cast(PowerPC::MMU::HostRead(guard, ppc_state.gpr[3] + 0x2)); } if (fd != 1 && fd != 2) return; diff --git a/Source/Core/Core/HLE/HLE_VarArgs.cpp b/Source/Core/Core/HLE/HLE_VarArgs.cpp index 453940f2c2..b16d1dfd32 100644 --- a/Source/Core/Core/HLE/HLE_VarArgs.cpp +++ b/Source/Core/Core/HLE/HLE_VarArgs.cpp @@ -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(guard, address), + PowerPC::MMU::HostRead(guard, address + 1), + PowerPC::MMU::HostRead(guard, address + 4), + PowerPC::MMU::HostRead(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(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(m_guard, fpr_address); } diff --git a/Source/Core/Core/HLE/HLE_VarArgs.h b/Source/Core/Core/HLE/HLE_VarArgs.h index a1c3eee7e9..c1a9f0a770 100644 --- a/Source/Core/Core/HLE/HLE_VarArgs.h +++ b/Source/Core/Core/HLE/HLE_VarArgs.h @@ -55,7 +55,7 @@ public: for (size_t i = 0; i < sizeof(T); i += 1, addr += 1) { - reinterpret_cast(&obj)[i] = PowerPC::MMU::HostRead_U8(m_guard, addr); + reinterpret_cast(&obj)[i] = PowerPC::MMU::HostRead(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(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(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(m_guard, m_stack); m_stack += 8; } diff --git a/Source/Core/Core/HW/AddressSpace.cpp b/Source/Core/Core/HW/AddressSpace.cpp index adee6ba97c..099b89b4f3 100644 --- a/Source/Core/Core/HW/AddressSpace.cpp +++ b/Source/Core/Core/HW/AddressSpace.cpp @@ -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(guard, address); } void WriteU8(const Core::CPUThreadGuard& guard, u32 address, u8 value) override { - PowerPC::MMU::HostWrite_U8(guard, value, address); + PowerPC::MMU::HostWrite(guard, value, address); } u16 ReadU16(const Core::CPUThreadGuard& guard, u32 address) const override { - return PowerPC::MMU::HostRead_U16(guard, address); + return PowerPC::MMU::HostRead(guard, address); } void WriteU16(const Core::CPUThreadGuard& guard, u32 address, u16 value) override { - PowerPC::MMU::HostWrite_U16(guard, value, address); + PowerPC::MMU::HostWrite(guard, value, address); } u32 ReadU32(const Core::CPUThreadGuard& guard, u32 address) const override { - return PowerPC::MMU::HostRead_U32(guard, address); + return PowerPC::MMU::HostRead(guard, address); } void WriteU32(const Core::CPUThreadGuard& guard, u32 address, u32 value) override { - PowerPC::MMU::HostWrite_U32(guard, value, address); + PowerPC::MMU::HostWrite(guard, value, address); } u64 ReadU64(const Core::CPUThreadGuard& guard, u32 address) const override { - return PowerPC::MMU::HostRead_U64(guard, address); + return PowerPC::MMU::HostRead(guard, address); } void WriteU64(const Core::CPUThreadGuard& guard, u32 address, u64 value) override { - PowerPC::MMU::HostWrite_U64(guard, value, address); + PowerPC::MMU::HostWrite(guard, value, address); } float ReadF32(const Core::CPUThreadGuard& guard, u32 address) const override { - return PowerPC::MMU::HostRead_F32(guard, address); + return PowerPC::MMU::HostRead(guard, address); } bool Matches(const Core::CPUThreadGuard& guard, u32 haystack_start, const u8* needle_start, diff --git a/Source/Core/Core/MemoryWatcher.cpp b/Source/Core/Core/MemoryWatcher.cpp index 38cdebe1b4..770906b7e1 100644 --- a/Source/Core/Core/MemoryWatcher.cpp +++ b/Source/Core/Core/MemoryWatcher.cpp @@ -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(guard, value + offset); if (!PowerPC::MMU::HostIsRAMAddress(guard, value)) break; } diff --git a/Source/Core/Core/PatchEngine.cpp b/Source/Core/Core/PatchEngine.cpp index b7dc594858..8ac96bb3f9 100644 --- a/Source/Core/Core/PatchEngine.cpp +++ b/Source/Core/Core/PatchEngine.cpp @@ -230,20 +230,20 @@ static void ApplyPatches(const Core::CPUThreadGuard& guard, const std::vector(comparand)) + PowerPC::MMU::HostRead(guard, addr) == static_cast(comparand)) { ApplyMemoryPatch(guard, static_cast(value), addr); } break; case PatchType::Patch16Bit: if (!entry.conditional || - PowerPC::MMU::HostRead_U16(guard, addr) == static_cast(comparand)) + PowerPC::MMU::HostRead(guard, addr) == static_cast(comparand)) { ApplyMemoryPatch(guard, static_cast(value), addr); } break; case PatchType::Patch32Bit: - if (!entry.conditional || PowerPC::MMU::HostRead_U32(guard, addr) == comparand) + if (!entry.conditional || PowerPC::MMU::HostRead(guard, addr) == comparand) ApplyMemoryPatch(guard, value, addr); break; default: @@ -280,7 +280,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(guard, SP); if (next_SP <= SP || !PowerPC::MMU::HostIsRAMAddress(guard, next_SP) || !PowerPC::MMU::HostIsRAMAddress(guard, next_SP + 4)) { @@ -288,7 +288,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(guard, next_SP + 4); return PowerPC::MMU::HostIsInstructionRAMAddress(guard, address) && 0 != PowerPC::MMU::HostRead_Instruction(guard, address); } diff --git a/Source/Core/Core/PowerPC/Expression.cpp b/Source/Core/Core/PowerPC/Expression.cpp index 6dda61040a..4fd946c393 100644 --- a/Source/Core/Core/PowerPC/Expression.cpp +++ b/Source/Core/Core/PowerPC/Expression.cpp @@ -35,57 +35,15 @@ using std::isnan; #include "Core/System.h" template -static T HostRead(const Core::CPUThreadGuard& guard, u32 address); +static T HostRead(const Core::CPUThreadGuard& guard, u32 address) +{ + return PowerPC::MMU::HostRead(guard, address); +} template -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(guard, var, address); } template diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index b9d0333249..d38ba08809 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -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(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, diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index db342600a0..035904930d 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(current_value >> misalignment_bits), - current_address); + interpreter.m_mmu.Write(static_cast(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(current_address) << (n * 8)) & 0xFFFF'FFFF; if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) return; - interpreter.m_mmu.Write_U32(static_cast(current_value >> (n * 8)), current_address); + interpreter.m_mmu.Write(static_cast(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(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(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(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(ppc_state.gpr[inst.RS], address); } void Interpreter::sync(Interpreter& interpreter, UGeckoInstruction inst) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index 55babb6d22..990656f5d9 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -69,24 +69,9 @@ SType ScaleAndClamp(double ps, u32 st_scale) } template -static T ReadUnpaired(PowerPC::MMU& mmu, u32 addr); - -template <> -u8 ReadUnpaired(PowerPC::MMU& mmu, u32 addr) +static T ReadUnpaired(PowerPC::MMU& mmu, u32 addr) { - return mmu.Read_U8(addr); -} - -template <> -u16 ReadUnpaired(PowerPC::MMU& mmu, u32 addr) -{ - return mmu.Read_U16(addr); -} - -template <> -u32 ReadUnpaired(PowerPC::MMU& mmu, u32 addr) -{ - return mmu.Read_U32(addr); + return mmu.Read(addr); } template @@ -95,43 +80,28 @@ static std::pair ReadPair(PowerPC::MMU& mmu, u32 addr); template <> std::pair ReadPair(PowerPC::MMU& mmu, u32 addr) { - const u16 val = mmu.Read_U16(addr); + const u16 val = mmu.Read(addr); return {u8(val >> 8), u8(val)}; } template <> std::pair ReadPair(PowerPC::MMU& mmu, u32 addr) { - const u32 val = mmu.Read_U32(addr); + const u32 val = mmu.Read(addr); return {u16(val >> 16), u16(val)}; } template <> std::pair ReadPair(PowerPC::MMU& mmu, u32 addr) { - const u64 val = mmu.Read_U64(addr); + const u64 val = mmu.Read(addr); return {u32(val >> 32), u32(val)}; } template -static void WriteUnpaired(PowerPC::MMU& mmu, T val, u32 addr); - -template <> -void WriteUnpaired(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(PowerPC::MMU& mmu, u16 val, u32 addr) -{ - mmu.Write_U16(val, addr); -} - -template <> -void WriteUnpaired(PowerPC::MMU& mmu, u32 val, u32 addr) -{ - mmu.Write_U32(val, addr); + mmu.Write(val, addr); } template @@ -140,19 +110,19 @@ static void WritePair(PowerPC::MMU& mmu, T val1, T val2, u32 addr); template <> void WritePair(PowerPC::MMU& mmu, u8 val1, u8 val2, u32 addr) { - mmu.Write_U16((u16{val1} << 8) | u16{val2}, addr); + mmu.Write((u16{val1} << 8) | u16{val2}, addr); } template <> void WritePair(PowerPC::MMU& mmu, u16 val1, u16 val2, u32 addr) { - mmu.Write_U32((u32{val1} << 16) | u32{val2}, addr); + mmu.Write((u32{val1} << 16) | u32{val2}, addr); } template <> void WritePair(PowerPC::MMU& mmu, u32 val1, u32 val2, u32 addr) { - mmu.Write_U64((u64{val1} << 32) | u64{val2}, addr); + mmu.Write((u64{val1} << 32) | u64{val2}, addr); } template diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp index b7f90db5e9..58b34698ad 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp @@ -405,16 +405,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, &m_jit.m_mmu, reg_addr); break; case 32: - ABI_CallFunctionPR(PowerPC::ReadU32FromJit, &m_jit.m_mmu, reg_addr); + ABI_CallFunctionPR(PowerPC::ReadFromJit, &m_jit.m_mmu, reg_addr); break; case 16: - ABI_CallFunctionPR(PowerPC::ReadU16FromJit, &m_jit.m_mmu, reg_addr); + ABI_CallFunctionPR(PowerPC::ReadFromJit, &m_jit.m_mmu, reg_addr); break; case 8: - ABI_CallFunctionPR(PowerPC::ReadU8FromJit, &m_jit.m_mmu, reg_addr); + ABI_CallFunctionPR(PowerPC::ReadFromJit, &m_jit.m_mmu, reg_addr); break; } ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment); @@ -468,16 +468,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, &m_jit.m_mmu, address); break; case 32: - ABI_CallFunctionPC(PowerPC::ReadU32FromJit, &m_jit.m_mmu, address); + ABI_CallFunctionPC(PowerPC::ReadFromJit, &m_jit.m_mmu, address); break; case 16: - ABI_CallFunctionPC(PowerPC::ReadU16FromJit, &m_jit.m_mmu, address); + ABI_CallFunctionPC(PowerPC::ReadFromJit, &m_jit.m_mmu, address); break; case 8: - ABI_CallFunctionPC(PowerPC::ReadU8FromJit, &m_jit.m_mmu, address); + ABI_CallFunctionPC(PowerPC::ReadFromJit, &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 : PowerPC::WriteU64SwapFromJit, &m_jit.m_mmu, reg, reg_addr); break; case 32: - ABI_CallFunctionPRR(swap ? PowerPC::WriteU32FromJit : PowerPC::WriteU32SwapFromJit, + ABI_CallFunctionPRR(swap ? PowerPC::WriteFromJit : PowerPC::WriteU32SwapFromJit, &m_jit.m_mmu, reg, reg_addr); break; case 16: - ABI_CallFunctionPRR(swap ? PowerPC::WriteU16FromJit : PowerPC::WriteU16SwapFromJit, + ABI_CallFunctionPRR(swap ? PowerPC::WriteFromJit : 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, &m_jit.m_mmu, reg, reg_addr); break; } ABI_PopRegistersAndAdjustStack(registersInUse, rsp_alignment); @@ -669,16 +669,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, &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, &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, &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, &m_jit.m_mmu, arg, address); break; } ABI_PopRegistersAndAdjustStack(registersInUse, 0); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index 654d6bed6f..0c11dcbc3a 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -222,22 +222,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, &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, &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, &m_mmu, src_reg, ARM64Reg::W2); } else { - ABI_CallFunction(&PowerPC::WriteU8FromJit, &m_mmu, src_reg, ARM64Reg::W2); + ABI_CallFunction(&PowerPC::WriteFromJit, &m_mmu, src_reg, ARM64Reg::W2); } } else if (flags & BackPatchInfo::FLAG_ZERO_256) @@ -247,13 +247,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, &m_mmu, ARM64Reg::W1); else if (access_size == 32) - ABI_CallFunction(&PowerPC::ReadU32FromJit, &m_mmu, ARM64Reg::W1); + ABI_CallFunction(&PowerPC::ReadFromJit, &m_mmu, ARM64Reg::W1); else if (access_size == 16) - ABI_CallFunction(&PowerPC::ReadU16FromJit, &m_mmu, ARM64Reg::W1); + ABI_CallFunction(&PowerPC::ReadFromJit, &m_mmu, ARM64Reg::W1); else - ABI_CallFunction(&PowerPC::ReadU8FromJit, &m_mmu, ARM64Reg::W1); + ABI_CallFunction(&PowerPC::ReadFromJit, &m_mmu, ARM64Reg::W1); } m_float_emit.ABI_PopRegisters(fprs_to_push, ARM64Reg::X30); diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp index be0f21f2e9..52e62cf1fc 100644 --- a/Source/Core/Core/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/PowerPC/JitInterface.cpp @@ -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(guard, ppc_state.pc), ppc_state.pc) + ->type; if (optype != OpType::Store && optype != OpType::StoreFP && optype != OpType::StorePS) return; } diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 17f42e9d90..ad14ebbc2c 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -144,7 +144,7 @@ static void EFB_Write(u32 data, u32 addr) } } -template +template T MMU::ReadFromHardware(u32 em_address) { // ReadFromHardware is currently used with XCheckTLBFlag::OpcodeNoException by host instruction @@ -161,12 +161,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(em_address + i); } - return static_cast(var); + return var; } bool wi = false; @@ -577,37 +577,21 @@ 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) +template +T MMU::Read(const u32 address) { - u8 var = ReadFromHardware(address); - Memcheck(address, var, false, 1); + T var = ReadFromHardware(address); + Memcheck(address, var, false, sizeof(T)); return var; } +template u8 MMU::Read(const u32 address); +template u16 MMU::Read(const u32 address); +template u32 MMU::Read(const u32 address); +template u64 MMU::Read(const u32 address); -u16 MMU::Read_U16(const u32 address) -{ - u16 var = ReadFromHardware(address); - Memcheck(address, var, false, 2); - return var; -} - -u32 MMU::Read_U32(const u32 address) -{ - u32 var = ReadFromHardware(address); - Memcheck(address, var, false, 4); - return var; -} - -u64 MMU::Read_U64(const u32 address) -{ - u64 var = ReadFromHardware(address); - Memcheck(address, var, false, 8); - return var; -} - -template -std::optional> MMU::HostTryReadUX(const Core::CPUThreadGuard& guard, - const u32 address, RequestedAddressSpace space) +template +std::optional> MMU::HostTryRead(const Core::CPUThreadGuard& guard, const u32 address, + RequestedAddressSpace space) { if (!HostIsRAMAddress(guard, address, space)) return std::nullopt; @@ -637,167 +621,88 @@ std::optional> MMU::HostTryReadUX(const Core::CPUThreadGuard& guar ASSERT(false); return std::nullopt; } +template std::optional> MMU::HostTryRead(const Core::CPUThreadGuard& guard, + const u32 address, + RequestedAddressSpace space); +template std::optional> MMU::HostTryRead(const Core::CPUThreadGuard& guard, + const u32 address, + RequestedAddressSpace space); +template std::optional> MMU::HostTryRead(const Core::CPUThreadGuard& guard, + const u32 address, + RequestedAddressSpace space); +template std::optional> MMU::HostTryRead(const Core::CPUThreadGuard& guard, + const u32 address, + RequestedAddressSpace space); -std::optional> MMU::HostTryReadU8(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space) +template +void MMU::Write(const Common::MakeAtLeastU32 var, const u32 address) { - return HostTryReadUX(guard, address, space); + Memcheck(address, var, true, sizeof(T)); + WriteToHardware(address, var, sizeof(T)); } - -std::optional> MMU::HostTryReadU16(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space) -{ - return HostTryReadUX(guard, address, space); -} - -std::optional> MMU::HostTryReadU32(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space) -{ - return HostTryReadUX(guard, address, space); -} - -std::optional> MMU::HostTryReadU64(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space) -{ - return HostTryReadUX(guard, address, space); -} - -std::optional> MMU::HostTryReadF32(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space) -{ - const auto result = HostTryReadUX(guard, address, space); - if (!result) - return std::nullopt; - return ReadResult(result->translated, std::bit_cast(result->value)); -} - -std::optional> MMU::HostTryReadF64(const Core::CPUThreadGuard& guard, - u32 address, RequestedAddressSpace space) -{ - const auto result = HostTryReadUX(guard, address, space); - if (!result) - return std::nullopt; - return ReadResult(result->translated, std::bit_cast(result->value)); -} - -void MMU::Write_U8(const u32 var, const u32 address) -{ - Memcheck(address, var, true, 1); - WriteToHardware(address, var, 1); -} - -void MMU::Write_U16(const u32 var, const u32 address) -{ - Memcheck(address, var, true, 2); - WriteToHardware(address, var, 2); -} -void MMU::Write_U16_Swap(const u32 var, const u32 address) -{ - Write_U16((var & 0xFFFF0000) | Common::swap16(static_cast(var)), address); -} - -void MMU::Write_U32(const u32 var, const u32 address) -{ - Memcheck(address, var, true, 4); - WriteToHardware(address, var, 4); -} -void MMU::Write_U32_Swap(const u32 var, const u32 address) -{ - Write_U32(Common::swap32(var), address); -} - -void MMU::Write_U64(const u64 var, const u32 address) +template void MMU::Write(const u32 var, const u32 address); +template void MMU::Write(const u32 var, const u32 address); +template void MMU::Write(const u32 var, const u32 address); +template <> +void MMU::Write(const u64 var, const u32 address) { Memcheck(address, var, true, 8); WriteToHardware(address, static_cast(var >> 32), 4); WriteToHardware(address + sizeof(u32), static_cast(var), 4); } + +void MMU::Write_U16_Swap(const u32 var, const u32 address) +{ + Write((var & 0xFFFF0000) | Common::swap16(static_cast(var)), address); +} +void MMU::Write_U32_Swap(const u32 var, const u32 address) +{ + Write(Common::swap32(var), address); +} void MMU::Write_U64_Swap(const u64 var, const u32 address) { - Write_U64(Common::swap64(var), address); + Write(Common::swap64(var), address); } -u8 MMU::HostRead_U8(const Core::CPUThreadGuard& guard, const u32 address) +template +T MMU::HostRead(const Core::CPUThreadGuard& guard, const u32 address) { auto& mmu = guard.GetSystem().GetMMU(); - return mmu.ReadFromHardware(address); + return mmu.ReadFromHardware(address); } +template u8 MMU::HostRead(const Core::CPUThreadGuard& guard, const u32 address); +template u16 MMU::HostRead(const Core::CPUThreadGuard& guard, const u32 address); +template u32 MMU::HostRead(const Core::CPUThreadGuard& guard, const u32 address); +template u64 MMU::HostRead(const Core::CPUThreadGuard& guard, const u32 address); -u16 MMU::HostRead_U16(const Core::CPUThreadGuard& guard, const u32 address) +template +void MMU::HostWrite(const Core::CPUThreadGuard& guard, const Common::MakeAtLeastU32 var, + const u32 address) { auto& mmu = guard.GetSystem().GetMMU(); - return mmu.ReadFromHardware(address); + mmu.WriteToHardware(address, var, sizeof(T)); } - -u32 MMU::HostRead_U32(const Core::CPUThreadGuard& guard, const u32 address) -{ - auto& mmu = guard.GetSystem().GetMMU(); - return mmu.ReadFromHardware(address); -} - -u64 MMU::HostRead_U64(const Core::CPUThreadGuard& guard, const u32 address) -{ - auto& mmu = guard.GetSystem().GetMMU(); - return mmu.ReadFromHardware(address); -} - -float MMU::HostRead_F32(const Core::CPUThreadGuard& guard, const u32 address) -{ - const u32 integral = HostRead_U32(guard, address); - - return std::bit_cast(integral); -} - -double MMU::HostRead_F64(const Core::CPUThreadGuard& guard, const u32 address) -{ - const u64 integral = HostRead_U64(guard, address); - - return std::bit_cast(integral); -} - -void MMU::HostWrite_U8(const Core::CPUThreadGuard& guard, const u32 var, const u32 address) -{ - auto& mmu = guard.GetSystem().GetMMU(); - mmu.WriteToHardware(address, var, 1); -} - -void MMU::HostWrite_U16(const Core::CPUThreadGuard& guard, const u32 var, const u32 address) -{ - auto& mmu = guard.GetSystem().GetMMU(); - mmu.WriteToHardware(address, var, 2); -} - -void MMU::HostWrite_U32(const Core::CPUThreadGuard& guard, const u32 var, const u32 address) -{ - auto& mmu = guard.GetSystem().GetMMU(); - mmu.WriteToHardware(address, var, 4); -} - -void MMU::HostWrite_U64(const Core::CPUThreadGuard& guard, const u64 var, const u32 address) +template void MMU::HostWrite(const Core::CPUThreadGuard& guard, const u32 var, + const u32 address); +template void MMU::HostWrite(const Core::CPUThreadGuard& guard, const u32 var, + const u32 address); +template void MMU::HostWrite(const Core::CPUThreadGuard& guard, const u32 var, + const u32 address); +template <> +void MMU::HostWrite(const Core::CPUThreadGuard& guard, const u64 var, const u32 address) { auto& mmu = guard.GetSystem().GetMMU(); mmu.WriteToHardware(address, static_cast(var >> 32), 4); mmu.WriteToHardware(address + sizeof(u32), static_cast(var), 4); } -void MMU::HostWrite_F32(const Core::CPUThreadGuard& guard, const float var, const u32 address) +template +std::optional MMU::HostTryWrite(const Core::CPUThreadGuard& guard, + const Common::MakeAtLeastU32 var, const u32 address, + RequestedAddressSpace space) { - const u32 integral = std::bit_cast(var); + constexpr auto size = sizeof(T); - 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(var); - - HostWrite_U64(guard, integral, address); -} - -std::optional 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; @@ -820,47 +725,24 @@ std::optional MMU::HostTryWriteUX(const Core::CPUThreadGuard& guard ASSERT(false); return std::nullopt; } - -std::optional MMU::HostTryWriteU8(const Core::CPUThreadGuard& guard, const u32 var, - const u32 address, RequestedAddressSpace space) +template std::optional MMU::HostTryWrite(const Core::CPUThreadGuard& guard, + const u32 var, const u32 address, + RequestedAddressSpace space); +template std::optional MMU::HostTryWrite(const Core::CPUThreadGuard& guard, + const u32 var, const u32 address, + RequestedAddressSpace space); +template std::optional MMU::HostTryWrite(const Core::CPUThreadGuard& guard, + const u32 var, const u32 address, + RequestedAddressSpace space); +template <> +std::optional MMU::HostTryWrite(const Core::CPUThreadGuard& guard, const u64 var, + const u32 address, RequestedAddressSpace space) { - return HostTryWriteUX(guard, var, address, 1, space); -} - -std::optional MMU::HostTryWriteU16(const Core::CPUThreadGuard& guard, const u32 var, - const u32 address, RequestedAddressSpace space) -{ - return HostTryWriteUX(guard, var, address, 2, space); -} - -std::optional MMU::HostTryWriteU32(const Core::CPUThreadGuard& guard, const u32 var, - const u32 address, RequestedAddressSpace space) -{ - return HostTryWriteUX(guard, var, address, 4, space); -} - -std::optional MMU::HostTryWriteU64(const Core::CPUThreadGuard& guard, const u64 var, - const u32 address, RequestedAddressSpace space) -{ - const auto result = HostTryWriteUX(guard, static_cast(var >> 32), address, 4, space); + const auto result = HostTryWrite(guard, static_cast(var >> 32), address, space); if (!result) return result; - return HostTryWriteUX(guard, static_cast(var), address + 4, 4, space); -} - -std::optional MMU::HostTryWriteF32(const Core::CPUThreadGuard& guard, const float var, - const u32 address, RequestedAddressSpace space) -{ - const u32 integral = std::bit_cast(var); - return HostTryWriteU32(guard, integral, address, space); -} - -std::optional MMU::HostTryWriteF64(const Core::CPUThreadGuard& guard, const double var, - const u32 address, RequestedAddressSpace space) -{ - const u64 integral = std::bit_cast(var); - return HostTryWriteU64(guard, integral, address, space); + return HostTryWrite(guard, static_cast(var), address + 4, space); } std::string MMU::HostGetString(const Core::CPUThreadGuard& guard, u32 address, size_t size) @@ -870,7 +752,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(guard, address); if (!res) break; s += static_cast(res); @@ -886,7 +768,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(guard, address); if (!res) break; s += static_cast(res); @@ -899,7 +781,7 @@ std::optional> MMU::HostTryReadString(const Core::CPUThr u32 address, size_t size, RequestedAddressSpace space) { - auto c = HostTryReadU8(guard, address, space); + auto c = HostTryRead(guard, address, space); if (!c) return std::nullopt; if (c->value == 0) @@ -910,7 +792,7 @@ std::optional> MMU::HostTryReadString(const Core::CPUThr while (size == 0 || s.length() < size) { ++address; - const auto res = HostTryReadU8(guard, address, space); + const auto res = HostTryRead(guard, address, space); if (!res || res->value == 0) break; s += static_cast(res->value); @@ -1703,38 +1585,25 @@ void ClearDCacheLineFromJit(MMU& mmu, u32 address) { mmu.ClearDCacheLine(address); } -u32 ReadU8FromJit(MMU& mmu, u32 address) +template +Common::MakeAtLeastU32 ReadFromJit(MMU& mmu, u32 address) { - return mmu.Read_U8(address); + return mmu.Read(address); } -u32 ReadU16FromJit(MMU& mmu, u32 address) +template u32 ReadFromJit(MMU& mmu, u32 address); +template u32 ReadFromJit(MMU& mmu, u32 address); +template u32 ReadFromJit(MMU& mmu, u32 address); +template u64 ReadFromJit(MMU& mmu, u32 address); + +template +void WriteFromJit(MMU& mmu, Common::MakeAtLeastU32 var, 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); + mmu.Write(var, address); } +template void WriteFromJit(MMU& mmu, u32 var, u32 address); +template void WriteFromJit(MMU& mmu, u32 var, u32 address); +template void WriteFromJit(MMU& mmu, u32 var, u32 address); +template void WriteFromJit(MMU& mmu, u64 var, u32 address); void WriteU16SwapFromJit(MMU& mmu, u32 var, u32 address) { mmu.Write_U16_Swap(var, address); diff --git a/Source/Core/Core/PowerPC/MMU.h b/Source/Core/Core/PowerPC/MMU.h index cee7d3213b..018657cd5f 100644 --- a/Source/Core/Core/PowerPC/MMU.h +++ b/Source/Core/Core/PowerPC/MMU.h @@ -10,6 +10,7 @@ #include "Common/BitField.h" #include "Common/CommonTypes.h" +#include "Common/TypeUtils.h" namespace Core { @@ -124,12 +125,17 @@ 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 + static T HostRead(const Core::CPUThreadGuard& guard, const u32 address); + template + requires(!std::unsigned_integral) + static T HostRead(const Core::CPUThreadGuard& guard, const u32 address) + { + using U = Common::MakeUnsignedSameSize; + U result = HostRead(guard, address); + return std::bit_cast(result); + } + 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 +145,20 @@ 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> - HostTryReadU8(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional> - HostTryReadU16(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional> - HostTryReadU32(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional> - HostTryReadU64(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional> - HostTryReadF32(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional> - HostTryReadF64(const Core::CPUThreadGuard& guard, u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); + template + static std::optional> + HostTryRead(const Core::CPUThreadGuard& guard, u32 address, + RequestedAddressSpace space = RequestedAddressSpace::Effective); + template + static std::optional> + HostTryRead(const Core::CPUThreadGuard& guard, u32 address, + RequestedAddressSpace space = RequestedAddressSpace::Effective) + requires(!std::unsigned_integral) + { + using U = Common::MakeUnsignedSameSize; + std::optional> result = HostTryRead(guard, address); + return std::bit_cast>>(result); + } static std::optional> HostTryReadInstruction(const Core::CPUThreadGuard& guard, u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective); @@ -167,35 +169,36 @@ 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 + static void HostWrite(const Core::CPUThreadGuard& guard, Common::MakeAtLeastU32 var, + u32 address); + template + static void HostWrite(const Core::CPUThreadGuard& guard, T var, u32 address) + requires(!std::unsigned_integral) + { + using U = Common::MakeUnsignedSameSize; + U cast_var = std::bit_cast(var); + return HostWrite(guard, cast_var, address); + } // 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 static std::optional - HostTryWriteU8(const Core::CPUThreadGuard& guard, u32 var, const u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); + HostTryWrite(const Core::CPUThreadGuard& guard, const Common::MakeAtLeastU32 var, + const u32 address, RequestedAddressSpace space = RequestedAddressSpace::Effective); + template static std::optional - HostTryWriteU16(const Core::CPUThreadGuard& guard, u32 var, const u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional - HostTryWriteU32(const Core::CPUThreadGuard& guard, u32 var, const u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional - HostTryWriteU64(const Core::CPUThreadGuard& guard, u64 var, const u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional - HostTryWriteF32(const Core::CPUThreadGuard& guard, float var, const u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); - static std::optional - HostTryWriteF64(const Core::CPUThreadGuard& guard, double var, const u32 address, - RequestedAddressSpace space = RequestedAddressSpace::Effective); + HostTryWrite(const Core::CPUThreadGuard& guard, const T var, const u32 address, + RequestedAddressSpace space = RequestedAddressSpace::Effective) + requires(!std::unsigned_integral) + { + using U = Common::MakeUnsignedSameSize; + U cast_var = std::bit_cast(var); + return HostTryWrite(guard, cast_var, address, space); + } // Returns whether a read or write to the given address will resolve to a RAM access in the given // address space. @@ -213,15 +216,11 @@ 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 + T Read(const u32 address); - 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 + void Write(const Common::MakeAtLeastU32 var, const u32 address); void Write_U16_Swap(u32 var, u32 address); void Write_U32_Swap(u32 var, u32 address); @@ -305,7 +304,7 @@ private: void UpdateBATs(BatTable& bat_table, u32 base_spr); void UpdateFakeMMUBat(BatTable& bat_table, u32 start_addr); - template + template T ReadFromHardware(u32 em_address); template void WriteToHardware(u32 em_address, const u32 data, const u32 size); @@ -313,13 +312,6 @@ private: bool IsEffectiveRAMAddress(u32 address); bool IsPhysicalRAMAddress(u32 address) const; - template - static std::optional> HostTryReadUX(const Core::CPUThreadGuard& guard, - const u32 address, RequestedAddressSpace space); - static std::optional 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; @@ -330,14 +322,11 @@ 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 +// Returns zero-extended value +Common::MakeAtLeastU32 ReadFromJit(MMU& mmu, u32 address); +template +void WriteFromJit(MMU& mmu, Common::MakeAtLeastU32 var, u32 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); diff --git a/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp index 6b0f573b27..64fbebc227 100644 --- a/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp +++ b/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp @@ -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( guard, static_cast(address + i * sizeof(u32))) != sig.code[i]) { return false; diff --git a/Source/Core/DiscIO/RiivolutionPatcher.cpp b/Source/Core/DiscIO/RiivolutionPatcher.cpp index c7bf51f3d0..04d07b2c95 100644 --- a/Source/Core/DiscIO/RiivolutionPatcher.cpp +++ b/Source/Core/DiscIO/RiivolutionPatcher.cpp @@ -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(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(value.size()); for (u32 i = 0; i < size; ++i) - PowerPC::MMU::HostTryWriteU8(guard, value[i], offset + i); + PowerPC::MMU::HostTryWrite(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(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(guard, jmp, blr_address); const u32 overlapping_hook_count = HLE::UnpatchRange(system, blr_address, blr_address + 4); if (overlapping_hook_count != 0) diff --git a/Source/Core/DolphinQt/Debugger/ThreadWidget.cpp b/Source/Core/DolphinQt/Debugger/ThreadWidget.cpp index 3b71ebb98e..1ecb64cb04 100644 --- a/Source/Core/DolphinQt/Debugger/ThreadWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/ThreadWidget.cpp @@ -277,7 +277,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(guard, addr) : 0; return format_hex(addr); }; const auto get_state = [](u16 thread_state) { @@ -463,7 +463,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(guard, sp + 4); m_callstack_table->setItem(i, 2, new QTableWidgetItem(format_hex(lr_save))); m_callstack_table->setItem( i, 3, @@ -474,7 +474,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(guard, sp); m_callstack_table->setItem(i, 1, new QTableWidgetItem(format_hex(sp))); } } diff --git a/Source/Core/DolphinQt/Debugger/WatchWidget.cpp b/Source/Core/DolphinQt/Debugger/WatchWidget.cpp index 7cc61d1334..06fe4aa48b 100644 --- a/Source/Core/DolphinQt/Debugger/WatchWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/WatchWidget.cpp @@ -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(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(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(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(guard, value, debug_interface.GetWatch(row).address); } } else diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 35223131b2..39ea3efabe 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -1644,7 +1644,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(guard, *found_addr - (len + 1)); if (!std::isprint(res)) { break; @@ -1988,7 +1988,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(guard, addr), addr)) { NOTICE_LOG_FMT(POWERPC, "Found {} at {:08x}", op_std, addr); found = true; From c0028610411bab6d2a03f1786c598f1ba5fb065c Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Sun, 25 May 2025 19:11:36 +0200 Subject: [PATCH 2/3] CheatSearchWidget: "Add to watch" to all selected items Instead of just the right-clicked item. --- Source/Core/DolphinQt/CheatSearchWidget.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/DolphinQt/CheatSearchWidget.cpp b/Source/Core/DolphinQt/CheatSearchWidget.cpp index 304e682674..f0f0346db8 100644 --- a/Source/Core/DolphinQt/CheatSearchWidget.cpp +++ b/Source/Core/DolphinQt/CheatSearchWidget.cpp @@ -498,9 +498,13 @@ void CheatSearchWidget::OnAddressTableContextMenu() 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("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); From f8d30e796cbb9391eec16403380f7ba5578d3e51 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Mon, 26 May 2025 15:10:40 +0200 Subject: [PATCH 3/3] CheatSearchWidget: New feature, writing a value to all selected addresses --- Source/Core/Core/CheatSearch.cpp | 17 +++++++++ Source/Core/Core/CheatSearch.h | 5 +++ Source/Core/DolphinQt/CheatSearchWidget.cpp | 39 ++++++++++++++++++--- Source/Core/DolphinQt/CheatSearchWidget.h | 1 + 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/CheatSearch.cpp b/Source/Core/Core/CheatSearch.cpp index f2fdd5a058..40868e5efc 100644 --- a/Source/Core/Core/CheatSearch.cpp +++ b/Source/Core/Core/CheatSearch.cpp @@ -505,6 +505,23 @@ bool Cheats::CheatSearchSession::WasFirstSearchDone() const return m_first_search_done; } +template +bool Cheats::CheatSearchSession::WriteValue(const Core::CPUThreadGuard& guard, + std::span addresses) const +{ + if (!m_value) + return false; + + T value = m_value.value(); + bool result = true; + for (auto address : addresses) + { + if (!PowerPC::MMU::HostTryWrite(guard, value, address, m_address_space).has_value()) + result = false; + } + return result; +} + template std::unique_ptr Cheats::CheatSearchSession::Clone() const { diff --git a/Source/Core/Core/CheatSearch.h b/Source/Core/Core/CheatSearch.h index bd3c6f3598..6c6d509047 100644 --- a/Source/Core/Core/CheatSearch.h +++ b/Source/Core/Core/CheatSearch.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -165,6 +166,8 @@ public: virtual SearchResultValueState GetResultValueState(size_t index) const = 0; virtual bool WasFirstSearchDone() const = 0; + virtual bool WriteValue(const Core::CPUThreadGuard& guard, std::span addresses) const = 0; + // Create a complete copy of this search session. virtual std::unique_ptr Clone() const = 0; @@ -212,6 +215,8 @@ public: SearchResultValueState GetResultValueState(size_t index) const override; bool WasFirstSearchDone() const override; + bool WriteValue(const Core::CPUThreadGuard& guard, std::span addresses) const override; + std::unique_ptr Clone() const override; std::unique_ptr ClonePartial(size_t begin_index, size_t end_index) const override; diff --git a/Source/Core/DolphinQt/CheatSearchWidget.cpp b/Source/Core/DolphinQt/CheatSearchWidget.cpp index f0f0346db8..7d8146ba9b 100644 --- a/Source/Core/DolphinQt/CheatSearchWidget.cpp +++ b/Source/Core/DolphinQt/CheatSearchWidget.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -491,13 +492,14 @@ 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("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()) { @@ -507,6 +509,7 @@ void CheatSearchWidget::OnAddressTableContextMenu() } }); menu->addAction(tr("Generate Action Replay Code(s)"), this, &CheatSearchWidget::GenerateARCodes); + menu->addAction(tr("Write value"), this, &CheatSearchWidget::WriteValue); menu->exec(QCursor::pos()); } @@ -590,6 +593,34 @@ 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_last_value_session->SetValueFromString(text.toStdString(), + m_parse_values_as_hex_checkbox->isChecked())) + { + m_info_label_1->setText(tr("Invalid value.")); + return; + } + + auto items = m_address_table->selectedItems(); + std::vector 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_last_value_session->WriteValue(guard, std::span(addresses))) + { + m_info_label_1->setText(tr("There was an error writing (some) values.")); + } +} + size_t CheatSearchWidget::GetTableRowCount() const { return std::min(TABLE_MAX_ROWS, m_last_value_session->GetResultCount()); diff --git a/Source/Core/DolphinQt/CheatSearchWidget.h b/Source/Core/DolphinQt/CheatSearchWidget.h index 96448c281c..18aa5a14b0 100644 --- a/Source/Core/DolphinQt/CheatSearchWidget.h +++ b/Source/Core/DolphinQt/CheatSearchWidget.h @@ -71,6 +71,7 @@ private: UpdateSource source); void RecreateGUITable(); void GenerateARCodes(); + void WriteValue(); int GetVisibleRowsBeginIndex() const; int GetVisibleRowsEndIndex() const; size_t GetTableRowCount() const;