mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 14:45:41 +12:00
Add old LoadCRO
Silly Pokémon X needs this.
This commit is contained in:
parent
d452caa976
commit
4cd9c6c77e
2 changed files with 24 additions and 13 deletions
|
@ -17,8 +17,8 @@ class LDRService {
|
|||
|
||||
// Service commands
|
||||
void initialize(u32 messagePointer);
|
||||
void loadCRO(u32 messagePointer, bool isNew);
|
||||
void loadCRR(u32 messagePointer);
|
||||
void loadCRONew(u32 messagePointer);
|
||||
void unloadCRO(u32 messagePointer);
|
||||
|
||||
public:
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace LDRCommands {
|
|||
enum : u32 {
|
||||
Initialize = 0x000100C2,
|
||||
LoadCRR = 0x00020082,
|
||||
LoadCRO = 0x000402C2,
|
||||
UnloadCRO = 0x000500C2,
|
||||
LoadCRONew = 0x000902C2,
|
||||
};
|
||||
|
@ -577,7 +578,7 @@ public:
|
|||
}
|
||||
|
||||
// Links CROs. Heavily based on Citra's CRO linker
|
||||
bool link(u32 loadedCRS) {
|
||||
bool link(u32 loadedCRS, bool isNew) {
|
||||
if (loadedCRS == 0) {
|
||||
Helpers::panic("CRS not loaded");
|
||||
}
|
||||
|
@ -587,11 +588,13 @@ public:
|
|||
// Fix data segment offset (LoadCRO_New)
|
||||
// Note: the old LoadCRO does *not* fix .data
|
||||
u32 dataVaddr;
|
||||
if (segmentTable.size > 1) {
|
||||
// Note: ldr:ro assumes that segment index 2 is .data
|
||||
dataVaddr = mem.read32(segmentTable.offset + 24 + SegmentTable::Offset);
|
||||
if (isNew) {
|
||||
if (segmentTable.size > 1) {
|
||||
// Note: ldr:ro assumes that segment index 2 is .data
|
||||
dataVaddr = mem.read32(segmentTable.offset + 24 + SegmentTable::Offset);
|
||||
|
||||
mem.write32(segmentTable.offset + 24 + SegmentTable::Offset, mem.read32(croPointer + CROHeader::DataOffset));
|
||||
mem.write32(segmentTable.offset + 24 + SegmentTable::Offset, mem.read32(croPointer + CROHeader::DataOffset));
|
||||
}
|
||||
}
|
||||
|
||||
importNamedSymbols(loadedCRS);
|
||||
|
@ -600,8 +603,10 @@ public:
|
|||
// TODO: export symbols to other CROs
|
||||
|
||||
// Restore .data segment offset (LoadCRO_New)
|
||||
if (segmentTable.size > 1) {
|
||||
mem.write32(segmentTable.offset + 24 + SegmentTable::Offset, dataVaddr);
|
||||
if (isNew) {
|
||||
if (segmentTable.size > 1) {
|
||||
mem.write32(segmentTable.offset + 24 + SegmentTable::Offset, dataVaddr);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -656,8 +661,9 @@ void LDRService::handleSyncRequest(u32 messagePointer) {
|
|||
switch (command) {
|
||||
case LDRCommands::Initialize: initialize(messagePointer); break;
|
||||
case LDRCommands::LoadCRR: loadCRR(messagePointer); break;
|
||||
case LDRCommands::LoadCRO: loadCRO(messagePointer, false); break;
|
||||
case LDRCommands::UnloadCRO: unloadCRO(messagePointer); break;
|
||||
case LDRCommands::LoadCRONew: loadCRONew(messagePointer); break;
|
||||
case LDRCommands::LoadCRONew: loadCRO(messagePointer, true); break;
|
||||
default: Helpers::panic("LDR::RO service requested. Command: %08X\n", command);
|
||||
}
|
||||
}
|
||||
|
@ -722,7 +728,7 @@ void LDRService::loadCRR(u32 messagePointer) {
|
|||
mem.write32(messagePointer + 4, Result::Success);
|
||||
}
|
||||
|
||||
void LDRService::loadCRONew(u32 messagePointer) {
|
||||
void LDRService::loadCRO(u32 messagePointer, bool isNew) {
|
||||
const u32 croPointer = mem.read32(messagePointer + 4);
|
||||
const u32 mapVaddr = mem.read32(messagePointer + 8);
|
||||
const u32 size = mem.read32(messagePointer + 12);
|
||||
|
@ -734,7 +740,7 @@ void LDRService::loadCRONew(u32 messagePointer) {
|
|||
const u32 fixLevel = mem.read32(messagePointer + 40);
|
||||
const Handle process = mem.read32(messagePointer + 52);
|
||||
|
||||
log("LDR_RO::LoadCRONew (buffer = %08X, vaddr = %08X, size = %08X, .data vaddr = %08X, .data size = %08X, .bss vaddr = %08X, .bss size = %08X, auto link = %d, fix level = %X, process = %X)\n", croPointer, mapVaddr, size, dataVaddr, dataSize, bssVaddr, bssSize, autoLink, fixLevel, process);
|
||||
log("LDR_RO::LoadCRO (isNew = %d, buffer = %08X, vaddr = %08X, size = %08X, .data vaddr = %08X, .data size = %08X, .bss vaddr = %08X, .bss size = %08X, auto link = %d, fix level = %X, process = %X)\n", isNew, croPointer, mapVaddr, size, dataVaddr, dataSize, bssVaddr, bssSize, autoLink, fixLevel, process);
|
||||
|
||||
// Sanity checks
|
||||
if (size < CRO_HEADER_SIZE) {
|
||||
|
@ -766,7 +772,7 @@ void LDRService::loadCRONew(u32 messagePointer) {
|
|||
Helpers::panic("Failed to rebase CRO");
|
||||
}
|
||||
|
||||
if (!cro.link(loadedCRS)) {
|
||||
if (!cro.link(loadedCRS, isNew)) {
|
||||
Helpers::panic("Failed to link CRO");
|
||||
}
|
||||
|
||||
|
@ -776,7 +782,12 @@ void LDRService::loadCRONew(u32 messagePointer) {
|
|||
|
||||
//kernel.clearInstructionCache();
|
||||
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
|
||||
if (isNew) {
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x9, 2, 0));
|
||||
} else {
|
||||
mem.write32(messagePointer, IPC::responseHeader(0x4, 2, 0));
|
||||
}
|
||||
|
||||
mem.write32(messagePointer + 4, Result::Success);
|
||||
mem.write32(messagePointer + 8, size);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue