Memory/CRO: Workaround for Pokemon XY

This commit is contained in:
wheremyfoodat 2025-08-05 22:44:53 +03:00
commit 831758beb8
3 changed files with 9 additions and 4 deletions

View file

@ -290,7 +290,8 @@ class Memory {
bool allocMemoryLinear(u32& outVaddr, u32 inVaddr, s32 pages, FcramRegion region, bool r, bool w, bool x); bool allocMemoryLinear(u32& outVaddr, u32 inVaddr, s32 pages, FcramRegion region, bool r, bool w, bool x);
bool mapVirtualMemory( bool mapVirtualMemory(
u32 dstVaddr, u32 srcVaddr, s32 pages, bool r, bool w, bool x, KernelMemoryTypes::MemoryState oldDstState, 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); void changePermissions(u32 vaddr, s32 pages, bool r, bool w, bool x);
Result::HorizonResult queryMemory(KernelMemoryTypes::MemoryInfo& out, u32 vaddr); Result::HorizonResult queryMemory(KernelMemoryTypes::MemoryInfo& out, u32 vaddr);

View file

@ -463,7 +463,7 @@ bool Memory::allocMemoryLinear(u32& outVaddr, u32 inVaddr, s32 pages, FcramRegio
bool Memory::mapVirtualMemory( bool Memory::mapVirtualMemory(
u32 dstVaddr, u32 srcVaddr, s32 pages, bool r, bool w, bool x, MemoryState oldDstState, MemoryState oldSrcState, MemoryState newDstState, 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 // Check that the regions have the specified state
// TODO: check src perms // TODO: check src perms
@ -487,7 +487,10 @@ bool Memory::mapVirtualMemory(
// Map or unmap each physical block // Map or unmap each physical block
for (auto& block : physicalList) { for (auto& block : physicalList) {
if (newDstState == MemoryState::Free) { 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 { } else {
mapPhysicalMemory(dstVaddr, block.paddr, block.pages, r, w, x); mapPhysicalMemory(dstVaddr, block.paddr, block.pages, r, w, x);
} }

View file

@ -1403,7 +1403,8 @@ void LDRService::unloadCRO(u32 messagePointer) {
u32 size = cro.getSize(); u32 size = cro.getSize();
bool succeeded = mem.mapVirtualMemory( 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) { if (!succeeded) {