From 831758beb80559b75646e19c92719f89c6433c17 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Tue, 5 Aug 2025 22:44:53 +0300 Subject: [PATCH] Memory/CRO: Workaround for Pokemon XY --- include/memory.hpp | 3 ++- src/core/memory.cpp | 7 +++++-- src/core/services/ldr_ro.cpp | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/memory.hpp b/include/memory.hpp index 02ced32c..71637517 100644 --- a/include/memory.hpp +++ b/include/memory.hpp @@ -290,7 +290,8 @@ class Memory { bool allocMemoryLinear(u32& outVaddr, u32 inVaddr, s32 pages, FcramRegion region, bool r, bool w, bool x); bool mapVirtualMemory( u32 dstVaddr, u32 srcVaddr, s32 pages, bool r, bool w, bool x, KernelMemoryTypes::MemoryState oldDstState, - KernelMemoryTypes::MemoryState oldSrcState, KernelMemoryTypes::MemoryState newDstState, KernelMemoryTypes::MemoryState newSrcState + KernelMemoryTypes::MemoryState oldSrcState, KernelMemoryTypes::MemoryState newDstState, KernelMemoryTypes::MemoryState newSrcState, + bool unmapPages = true ); void changePermissions(u32 vaddr, s32 pages, bool r, bool w, bool x); Result::HorizonResult queryMemory(KernelMemoryTypes::MemoryInfo& out, u32 vaddr); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 20042a29..650c8d0e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -463,7 +463,7 @@ bool Memory::allocMemoryLinear(u32& outVaddr, u32 inVaddr, s32 pages, FcramRegio bool Memory::mapVirtualMemory( u32 dstVaddr, u32 srcVaddr, s32 pages, bool r, bool w, bool x, MemoryState oldDstState, MemoryState oldSrcState, MemoryState newDstState, - MemoryState newSrcState + MemoryState newSrcState, bool unmapPages ) { // Check that the regions have the specified state // TODO: check src perms @@ -487,7 +487,10 @@ bool Memory::mapVirtualMemory( // Map or unmap each physical block for (auto& block : physicalList) { if (newDstState == MemoryState::Free) { - unmapPhysicalMemory(dstVaddr, block.paddr, block.pages); + // TODO: Games with CROs will unmap the CRO yet still continue accessing the address it was mapped to? + if (unmapPages) { + unmapPhysicalMemory(dstVaddr, block.paddr, block.pages); + } } else { mapPhysicalMemory(dstVaddr, block.paddr, block.pages, r, w, x); } diff --git a/src/core/services/ldr_ro.cpp b/src/core/services/ldr_ro.cpp index 9d714dc7..561bdf3e 100644 --- a/src/core/services/ldr_ro.cpp +++ b/src/core/services/ldr_ro.cpp @@ -1403,7 +1403,8 @@ void LDRService::unloadCRO(u32 messagePointer) { u32 size = cro.getSize(); bool succeeded = mem.mapVirtualMemory( - mapVaddr, croPointer, size >> 12, false, false, false, MemoryState::Locked, MemoryState::AliasCode, MemoryState::Free, MemoryState::Private + mapVaddr, croPointer, size >> 12, false, false, false, MemoryState::Locked, MemoryState::AliasCode, MemoryState::Free, MemoryState::Private, + false ); if (!succeeded) {