mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-02 01:06:50 +02:00
Improved handling of DSi roms and DSiWare. Fixes some system tools DSi roms being misdetected as DSiWare (related to #23)
This commit is contained in:
@@ -165,9 +165,9 @@ void NdsLoader::Load(BootMode bootMode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isHomebrew = (_romHeader.ntrHeader.makerCode[0] == 0 && _romHeader.ntrHeader.makerCode[1] == 0)
|
bool isHomebrew = (_romHeader.makerCode[0] == 0 && _romHeader.makerCode[1] == 0)
|
||||||
|| _romHeader.ntrHeader.arm9AutoLoadDoneHookAddress == 0
|
|| _romHeader.arm9AutoLoadDoneHookAddress == 0
|
||||||
|| _romHeader.ntrHeader.arm7LoadAddress >= 0x03000000;
|
|| _romHeader.arm7LoadAddress >= 0x03000000;
|
||||||
|
|
||||||
if (isHomebrew)
|
if (isHomebrew)
|
||||||
{
|
{
|
||||||
@@ -186,16 +186,7 @@ void NdsLoader::Load(BootMode bootMode)
|
|||||||
memset(&_dsiwareSaveResult, 0, sizeof(_dsiwareSaveResult));
|
memset(&_dsiwareSaveResult, 0, sizeof(_dsiwareSaveResult));
|
||||||
if (bootMode != BootMode::Multiboot)
|
if (bootMode != BootMode::Multiboot)
|
||||||
{
|
{
|
||||||
if (!_romHeader.IsDsiWare())
|
if (_romHeader.IsDsiWare())
|
||||||
{
|
|
||||||
if (bootMode != BootMode::SdkResetSystem)
|
|
||||||
{
|
|
||||||
HandleCardSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleAntiPiracy();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (bootMode == BootMode::SdkResetSystem)
|
if (bootMode == BootMode::SdkResetSystem)
|
||||||
{
|
{
|
||||||
@@ -210,6 +201,15 @@ void NdsLoader::Load(BootMode bootMode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bootMode != BootMode::SdkResetSystem)
|
||||||
|
{
|
||||||
|
HandleCardSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleAntiPiracy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,14 +224,14 @@ void NdsLoader::Load(BootMode bootMode)
|
|||||||
|
|
||||||
SetupSharedMemory(cardId, agbMem, resetParam, romOffset, bootType);
|
SetupSharedMemory(cardId, agbMem, resetParam, romOffset, bootType);
|
||||||
|
|
||||||
if (Environment::IsDsiMode() && _romHeader.IsTwlRom())
|
|
||||||
{
|
|
||||||
SetupTwlConfig();
|
|
||||||
TwlAes().SetupAes(&_romHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Environment::IsDsiMode())
|
if (Environment::IsDsiMode())
|
||||||
{
|
{
|
||||||
|
if (_romHeader.IsTwlRom())
|
||||||
|
{
|
||||||
|
SetupTwlConfig();
|
||||||
|
TwlAes().SetupAes(&_romHeader);
|
||||||
|
}
|
||||||
|
|
||||||
RemapWram();
|
RemapWram();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,20 +321,20 @@ void NdsLoader::Load(BootMode bootMode)
|
|||||||
|
|
||||||
if (Environment::IsDsiMode())
|
if (Environment::IsDsiMode())
|
||||||
{
|
{
|
||||||
if (!_romHeader.IsTwlRom())
|
if (_romHeader.IsTwlRom())
|
||||||
{
|
|
||||||
DSMode().SwitchToDSMode(_romHeader.ntrHeader.gameCode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (!(_romHeader.twlFlags2 & 1))
|
if (!(_romHeader.twlFlags2 & 1))
|
||||||
{
|
{
|
||||||
DSMode().SwitchToDSTouchAndSoundMode(_romHeader.ntrHeader.gameCode);
|
DSMode().SwitchToDSTouchAndSoundMode(_romHeader.gameCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set back power button handling to irq mode
|
// Set back power button handling to irq mode
|
||||||
mcu_writeReg(MCU_REG_MODE, 1);
|
mcu_writeReg(MCU_REG_MODE, 1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSMode().SwitchToDSMode(_romHeader.gameCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHomebrew)
|
if (isHomebrew)
|
||||||
@@ -349,11 +349,11 @@ void NdsLoader::Load(BootMode bootMode)
|
|||||||
bool NdsLoader::IsCloneBootRom(u32 romOffset)
|
bool NdsLoader::IsCloneBootRom(u32 romOffset)
|
||||||
{
|
{
|
||||||
bool isCloneBootRom = false;
|
bool isCloneBootRom = false;
|
||||||
if (_romHeader.ntrHeader.ntrRomSize != 0)
|
if (_romHeader.ntrRomSize != 0)
|
||||||
{
|
{
|
||||||
UINT bytesRead = 0;
|
UINT bytesRead = 0;
|
||||||
u16 signatureHeader;
|
u16 signatureHeader;
|
||||||
if (f_lseek(&_romFile, romOffset + _romHeader.ntrHeader.ntrRomSize) == FR_OK &&
|
if (f_lseek(&_romFile, romOffset + _romHeader.ntrRomSize) == FR_OK &&
|
||||||
f_read(&_romFile, &signatureHeader, sizeof(signatureHeader), &bytesRead) == FR_OK &&
|
f_read(&_romFile, &signatureHeader, sizeof(signatureHeader), &bytesRead) == FR_OK &&
|
||||||
bytesRead == 2 &&
|
bytesRead == 2 &&
|
||||||
signatureHeader == 0x6361)
|
signatureHeader == 0x6361)
|
||||||
@@ -371,7 +371,7 @@ void NdsLoader::InsertArgv()
|
|||||||
u32 argSize = 0;
|
u32 argSize = 0;
|
||||||
|
|
||||||
// Find the address to write argv
|
// Find the address to write argv
|
||||||
u32 argDst = ((_romHeader.ntrHeader.arm9LoadAddress + _romHeader.ntrHeader.arm9Size + 3) & ~3) + 4;
|
u32 argDst = ((_romHeader.arm9LoadAddress + _romHeader.arm9Size + 3) & ~3) + 4;
|
||||||
if (_romHeader.IsTwlRom())
|
if (_romHeader.IsTwlRom())
|
||||||
{
|
{
|
||||||
u32 argDstTwl = ((_romHeader.arm9iLoadAddress + _romHeader.arm9iSize + 3) & ~3) + 4;
|
u32 argDstTwl = ((_romHeader.arm9iLoadAddress + _romHeader.arm9iSize + 3) & ~3) + 4;
|
||||||
@@ -475,8 +475,8 @@ void NdsLoader::SetupSharedMemory(u32 cardId, u32 agbMem, u32 resetParam, u32 ro
|
|||||||
memcpy(TWL_SHARED_MEMORY->ntrSharedMem.romHeader, &_romHeader, sizeof(nds_header_ntr_t));
|
memcpy(TWL_SHARED_MEMORY->ntrSharedMem.romHeader, &_romHeader, sizeof(nds_header_ntr_t));
|
||||||
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0] = cardId;
|
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0] = cardId;
|
||||||
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[4] = cardId;
|
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[4] = cardId;
|
||||||
*(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[8] = _romHeader.ntrHeader.headerCrc;
|
*(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[8] = _romHeader.headerCrc;
|
||||||
*(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0xA] = _romHeader.ntrHeader.secureAreaCrc;
|
*(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0xA] = _romHeader.secureAreaCrc;
|
||||||
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0x10] = 0x5835; // use correct card id address
|
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0x10] = 0x5835; // use correct card id address
|
||||||
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.isDebuggerData[0x1C] = agbMem;
|
*(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.isDebuggerData[0x1C] = agbMem;
|
||||||
TWL_SHARED_MEMORY->ntrSharedMem.resetParam = resetParam;
|
TWL_SHARED_MEMORY->ntrSharedMem.resetParam = resetParam;
|
||||||
@@ -536,7 +536,7 @@ bool NdsLoader::ShouldAttemptDldiPatch()
|
|||||||
{
|
{
|
||||||
// Some games contain a fake dldi header to trick flashcards
|
// Some games contain a fake dldi header to trick flashcards
|
||||||
// See also: https://shutterbug2000.github.io/very-clever/
|
// See also: https://shutterbug2000.github.io/very-clever/
|
||||||
switch (_romHeader.ntrHeader.gameCode)
|
switch (_romHeader.gameCode)
|
||||||
{
|
{
|
||||||
// Final Fantasy IV
|
// Final Fantasy IV
|
||||||
case GAMECODE("YF4P"):
|
case GAMECODE("YF4P"):
|
||||||
@@ -610,7 +610,7 @@ bool NdsLoader::TryLoadRomHeader(u32 romOffset)
|
|||||||
|
|
||||||
void NdsLoader::HandleCardSave()
|
void NdsLoader::HandleCardSave()
|
||||||
{
|
{
|
||||||
if (!CardSaveArranger().SetupCardSave(_romHeader.ntrHeader.gameCode, _savePath))
|
if (!CardSaveArranger().SetupCardSave(_romHeader.gameCode, _savePath))
|
||||||
{
|
{
|
||||||
ErrorDisplay().PrintError("Failed to setup save file.");
|
ErrorDisplay().PrintError("Failed to setup save file.");
|
||||||
}
|
}
|
||||||
@@ -621,7 +621,7 @@ void NdsLoader::HandleAntiPiracy()
|
|||||||
auto apList = ApListFactory().CreateFromFile(AP_LIST_PATH);
|
auto apList = ApListFactory().CreateFromFile(AP_LIST_PATH);
|
||||||
if (apList)
|
if (apList)
|
||||||
{
|
{
|
||||||
auto entry = apList->FindEntry(_romHeader.ntrHeader.gameCode, _romHeader.ntrHeader.softwareVersion);
|
auto entry = apList->FindEntry(_romHeader.gameCode, _romHeader.softwareVersion);
|
||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
entry->Dump();
|
entry->Dump();
|
||||||
@@ -683,15 +683,15 @@ void NdsLoader::RemapWram()
|
|||||||
|
|
||||||
bool NdsLoader::TryLoadArm9()
|
bool NdsLoader::TryLoadArm9()
|
||||||
{
|
{
|
||||||
if (f_lseek(&_romFile, _romHeader.ntrHeader.arm9RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK)
|
if (f_lseek(&_romFile, _romHeader.arm9RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK)
|
||||||
{
|
{
|
||||||
LOG_FATAL("Failed to seek to arm9\n");
|
LOG_FATAL("Failed to seek to arm9\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT bytesRead = 0;
|
UINT bytesRead = 0;
|
||||||
FRESULT result = f_read(&_romFile, (void*)_romHeader.ntrHeader.arm9LoadAddress, _romHeader.ntrHeader.arm9Size, &bytesRead);
|
FRESULT result = f_read(&_romFile, (void*)_romHeader.arm9LoadAddress, _romHeader.arm9Size, &bytesRead);
|
||||||
if (result != FR_OK || bytesRead != _romHeader.ntrHeader.arm9Size)
|
if (result != FR_OK || bytesRead != _romHeader.arm9Size)
|
||||||
{
|
{
|
||||||
LOG_FATAL("Failed to read arm9. Result: %d, bytesRead: %d\n", result, bytesRead);
|
LOG_FATAL("Failed to read arm9. Result: %d, bytesRead: %d\n", result, bytesRead);
|
||||||
return false;
|
return false;
|
||||||
@@ -736,7 +736,7 @@ bool NdsLoader::TryLoadArm9i()
|
|||||||
|
|
||||||
bool NdsLoader::TryDecryptArm9i()
|
bool NdsLoader::TryDecryptArm9i()
|
||||||
{
|
{
|
||||||
if (!(_romHeader.ntrHeader.twlFlags & (1 << 1)))
|
if (!(_romHeader.twlFlags & (1 << 1)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -756,7 +756,7 @@ bool NdsLoader::TryDecryptArm9i()
|
|||||||
|
|
||||||
bool NdsLoader::TryDecryptArm7i()
|
bool NdsLoader::TryDecryptArm7i()
|
||||||
{
|
{
|
||||||
if (!(_romHeader.ntrHeader.twlFlags & (1 << 1)) || _romHeader.modcryptArea2Size == 0)
|
if (!(_romHeader.twlFlags & (1 << 1)) || _romHeader.modcryptArea2Size == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -776,15 +776,15 @@ bool NdsLoader::TryDecryptArm7i()
|
|||||||
|
|
||||||
bool NdsLoader::TryLoadArm7()
|
bool NdsLoader::TryLoadArm7()
|
||||||
{
|
{
|
||||||
if (f_lseek(&_romFile, _romHeader.ntrHeader.arm7RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK)
|
if (f_lseek(&_romFile, _romHeader.arm7RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK)
|
||||||
{
|
{
|
||||||
LOG_FATAL("Failed to seek to arm7\n");
|
LOG_FATAL("Failed to seek to arm7\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT bytesRead = 0;
|
UINT bytesRead = 0;
|
||||||
FRESULT result = f_read(&_romFile, (void*)_romHeader.ntrHeader.arm7LoadAddress, _romHeader.ntrHeader.arm7Size, &bytesRead);
|
FRESULT result = f_read(&_romFile, (void*)_romHeader.arm7LoadAddress, _romHeader.arm7Size, &bytesRead);
|
||||||
if (result != FR_OK || bytesRead != _romHeader.ntrHeader.arm7Size)
|
if (result != FR_OK || bytesRead != _romHeader.arm7Size)
|
||||||
{
|
{
|
||||||
LOG_FATAL("Failed to read arm7. Result: %d, bytesRead: %d\n", result, bytesRead);
|
LOG_FATAL("Failed to read arm7. Result: %d, bytesRead: %d\n", result, bytesRead);
|
||||||
return false;
|
return false;
|
||||||
@@ -828,19 +828,19 @@ void NdsLoader::HandleDldiPatching()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int arm9DldiAddr = sDldiStubMatcher.FindFirstOccurance(
|
int arm9DldiAddr = sDldiStubMatcher.FindFirstOccurance(
|
||||||
(const u32*)_romHeader.ntrHeader.arm9LoadAddress, _romHeader.ntrHeader.arm9Size >> 2) << 2;
|
(const u32*)_romHeader.arm9LoadAddress, _romHeader.arm9Size >> 2) << 2;
|
||||||
if (arm9DldiAddr >= 0)
|
if (arm9DldiAddr >= 0)
|
||||||
{
|
{
|
||||||
dldi_header_t* arm9Dldi = (dldi_header_t*)(_romHeader.ntrHeader.arm9LoadAddress + arm9DldiAddr);
|
dldi_header_t* arm9Dldi = (dldi_header_t*)(_romHeader.arm9LoadAddress + arm9DldiAddr);
|
||||||
LOG_DEBUG("Dldi found in arm9 at address %p\n", arm9Dldi);
|
LOG_DEBUG("Dldi found in arm9 at address %p\n", arm9Dldi);
|
||||||
dldi_patchTo(arm9Dldi);
|
dldi_patchTo(arm9Dldi);
|
||||||
}
|
}
|
||||||
|
|
||||||
int arm7DldiAddr = sDldiStubMatcher.FindFirstOccurance(
|
int arm7DldiAddr = sDldiStubMatcher.FindFirstOccurance(
|
||||||
(const u32*)_romHeader.ntrHeader.arm7LoadAddress, _romHeader.ntrHeader.arm7Size >> 2) << 2;
|
(const u32*)_romHeader.arm7LoadAddress, _romHeader.arm7Size >> 2) << 2;
|
||||||
if (arm7DldiAddr >= 0)
|
if (arm7DldiAddr >= 0)
|
||||||
{
|
{
|
||||||
dldi_header_t* arm7Dldi = (dldi_header_t*)(_romHeader.ntrHeader.arm7LoadAddress + arm7DldiAddr);
|
dldi_header_t* arm7Dldi = (dldi_header_t*)(_romHeader.arm7LoadAddress + arm7DldiAddr);
|
||||||
LOG_DEBUG("Dldi found in arm7 at address %p\n", arm7Dldi);
|
LOG_DEBUG("Dldi found in arm7 at address %p\n", arm7Dldi);
|
||||||
dldi_patchTo(arm7Dldi);
|
dldi_patchTo(arm7Dldi);
|
||||||
}
|
}
|
||||||
@@ -860,7 +860,7 @@ void NdsLoader::StartRom(BootMode bootMode)
|
|||||||
REG_IF2 = ~0u;
|
REG_IF2 = ~0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
((entrypoint_t)_romHeader.ntrHeader.arm7EntryAddress)();
|
((entrypoint_t)_romHeader.arm7EntryAddress)();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NdsLoader::SetupTwlConfig()
|
void NdsLoader::SetupTwlConfig()
|
||||||
@@ -970,20 +970,20 @@ bool NdsLoader::TrySetupDsiWareSave()
|
|||||||
|
|
||||||
bool NdsLoader::TryDecryptSecureArea()
|
bool NdsLoader::TryDecryptSecureArea()
|
||||||
{
|
{
|
||||||
if (_romHeader.ntrHeader.arm9RomOffset < 0x4000 || _romHeader.ntrHeader.arm9RomOffset >= 0x8000)
|
if (_romHeader.arm9RomOffset < 0x4000 || _romHeader.arm9RomOffset >= 0x8000)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((u32*)_romHeader.ntrHeader.arm9LoadAddress)[0] == 0xE7FFDEFF &&
|
if (((u32*)_romHeader.arm9LoadAddress)[0] == 0xE7FFDEFF &&
|
||||||
((u32*)_romHeader.ntrHeader.arm9LoadAddress)[1] == 0xE7FFDEFF)
|
((u32*)_romHeader.arm9LoadAddress)[1] == 0xE7FFDEFF)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 secureAreaCrc = swi_getCrc16(0xFFFF,
|
u16 secureAreaCrc = swi_getCrc16(0xFFFF,
|
||||||
(const void*)_romHeader.ntrHeader.arm9LoadAddress, 0x8000 - _romHeader.ntrHeader.arm9RomOffset);
|
(const void*)_romHeader.arm9LoadAddress, 0x8000 - _romHeader.arm9RomOffset);
|
||||||
if (secureAreaCrc != _romHeader.ntrHeader.secureAreaCrc)
|
if (secureAreaCrc != _romHeader.secureAreaCrc)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1000,13 +1000,13 @@ bool NdsLoader::TryDecryptSecureArea()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto blowfish = std::make_unique<Blowfish>(keyTable.get());
|
auto blowfish = std::make_unique<Blowfish>(keyTable.get());
|
||||||
blowfish->TransformTable(_romHeader.ntrHeader.gameCode, 3, 8);
|
blowfish->TransformTable(_romHeader.gameCode, 3, 8);
|
||||||
blowfish->Decrypt(
|
blowfish->Decrypt(
|
||||||
(const void*)_romHeader.ntrHeader.arm9LoadAddress,
|
(const void*)_romHeader.arm9LoadAddress,
|
||||||
(void*)_romHeader.ntrHeader.arm9LoadAddress,
|
(void*)_romHeader.arm9LoadAddress,
|
||||||
0x4800 - _romHeader.ntrHeader.arm9RomOffset);
|
0x4800 - _romHeader.arm9RomOffset);
|
||||||
((u32*)_romHeader.ntrHeader.arm9LoadAddress)[0] = 0xE7FFDEFF;
|
((u32*)_romHeader.arm9LoadAddress)[0] = 0xE7FFDEFF;
|
||||||
((u32*)_romHeader.ntrHeader.arm9LoadAddress)[1] = 0xE7FFDEFF;
|
((u32*)_romHeader.arm9LoadAddress)[1] = 0xE7FFDEFF;
|
||||||
|
|
||||||
LOG_DEBUG("Decrypted secure area\n");
|
LOG_DEBUG("Decrypted secure area\n");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ void TwlAes::DecryptModuleAes(void* data, u32 length, const aes_u128_t* iv) cons
|
|||||||
|
|
||||||
void TwlAes::SetupModuleKeyXY(const nds_header_twl_t* romHeader) const
|
void TwlAes::SetupModuleKeyXY(const nds_header_twl_t* romHeader) const
|
||||||
{
|
{
|
||||||
if ((romHeader->ntrHeader.twlFlags & (1 << 2)) || (romHeader->twlFlags2 & (1 << 7)))
|
if ((romHeader->twlFlags & (1 << 2)) || (romHeader->twlFlags2 & (1 << 7)))
|
||||||
{
|
{
|
||||||
// debug
|
// debug
|
||||||
aes_setKey(KEY_SLOT_MODULE, (const aes_u128_t*)romHeader);
|
aes_setKey(KEY_SLOT_MODULE, (const aes_u128_t*)romHeader);
|
||||||
@@ -116,8 +116,8 @@ void TwlAes::SetupModuleKeyXY(const nds_header_twl_t* romHeader) const
|
|||||||
{
|
{
|
||||||
MODULE_KEYX_NINT,
|
MODULE_KEYX_NINT,
|
||||||
MODULE_KEYX_ENDO,
|
MODULE_KEYX_ENDO,
|
||||||
romHeader->ntrHeader.gameCode,
|
romHeader->gameCode,
|
||||||
__builtin_bswap32(romHeader->ntrHeader.gameCode)
|
__builtin_bswap32(romHeader->gameCode)
|
||||||
}};
|
}};
|
||||||
aes_setKeyXY(KEY_SLOT_MODULE, &keyX, (const aes_u128_t*)romHeader->arm9iSha1Hmac);
|
aes_setKeyXY(KEY_SLOT_MODULE, &keyX, (const aes_u128_t*)romHeader->arm9iSha1Hmac);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,15 +49,18 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform) const
|
|||||||
patchCollection.AddPatch(arm7ArenaPatch);
|
patchCollection.AddPatch(arm7ArenaPatch);
|
||||||
|
|
||||||
if (romHeader->unitCode == 0) // seems only present on NITRO, not on HYBRID or LIMITED
|
if (romHeader->unitCode == 0) // seems only present on NITRO, not on HYBRID or LIMITED
|
||||||
|
{
|
||||||
patchCollection.AddPatch(new DisableArm7WramClearPatch());
|
patchCollection.AddPatch(new DisableArm7WramClearPatch());
|
||||||
|
}
|
||||||
|
|
||||||
if (sdkVersion.IsTwlSdk())
|
if (sdkVersion.IsTwlSdk())
|
||||||
{
|
{
|
||||||
if (gIsDsiMode && romHeader->IsTwlRom() && twlRomHeader->IsDsiWare())
|
if (gIsDsiMode && (twlRomHeader->HasNandAccess() || twlRomHeader->HasSdAccess()))
|
||||||
{
|
{
|
||||||
patchCollection.AddPatch(new Sdk5DsiSdCardRedirectPatch());
|
patchCollection.AddPatch(new Sdk5DsiSdCardRedirectPatch());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!twlRomHeader->IsDsiWare())
|
||||||
{
|
{
|
||||||
patchCollection.AddPatch(new CardiDoTaskFromArm9Patch());
|
patchCollection.AddPatch(new CardiDoTaskFromArm9Patch());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,14 +153,13 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SecureSysCallsUnusedSpaceLocator secureSysCallsUnusedSpaceLocator;
|
SecureSysCallsUnusedSpaceLocator().FindUnusedSpace(romHeader, patchContext.GetPatchHeap());
|
||||||
secureSysCallsUnusedSpaceLocator.FindUnusedSpace(romHeader, patchContext.GetPatchHeap());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdkVersion.IsTwlSdk())
|
if (sdkVersion.IsTwlSdk())
|
||||||
{
|
{
|
||||||
if (!(romHeader->IsTwlRom() && twlRomHeader->IsDsiWare()))
|
if (!twlRomHeader->IsDsiWare())
|
||||||
{
|
{
|
||||||
// if ((romHeader->unitCode & 3) != 3)
|
// if ((romHeader->unitCode & 3) != 3)
|
||||||
{
|
{
|
||||||
@@ -168,7 +167,7 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
}
|
}
|
||||||
patchCollection.AddPatch(new CardiReadRomWithCpuPatch());
|
patchCollection.AddPatch(new CardiReadRomWithCpuPatch());
|
||||||
|
|
||||||
if (gIsDsiMode && (romHeader->unitCode & 2))
|
if (gIsDsiMode && romHeader->IsTwlRom())
|
||||||
{
|
{
|
||||||
patchCollection.AddPatch(new CardiReadCardWithHashInternalAsyncPatch());
|
patchCollection.AddPatch(new CardiReadCardWithHashInternalAsyncPatch());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ static u32 correctAddressForArm7iAutoLoad(u32 address)
|
|||||||
{
|
{
|
||||||
auto romHeader = (const nds_header_twl_t*)TWL_SHARED_MEMORY->twlRomHeader;
|
auto romHeader = (const nds_header_twl_t*)TWL_SHARED_MEMORY->twlRomHeader;
|
||||||
auto arm7iModuleParams = (const module_params_twl_t*)(
|
auto arm7iModuleParams = (const module_params_twl_t*)(
|
||||||
romHeader->ntrHeader.arm7LoadAddress + romHeader->arm7iModuleParamsAddress);
|
romHeader->arm7LoadAddress + romHeader->arm7iModuleParamsAddress);
|
||||||
|
|
||||||
auto autoLoadListEntry = (autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListStart;
|
auto autoLoadListEntry = (autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListStart;
|
||||||
u32 currentAddress = arm7iModuleParams->autoloadStart;
|
u32 currentAddress = arm7iModuleParams->autoloadStart;
|
||||||
|
|||||||
@@ -63,9 +63,11 @@ struct nds_header_ntr_t
|
|||||||
|
|
||||||
static_assert(sizeof(nds_header_ntr_t) == 0x170, "Invalid size for nds_header_ntr_t");
|
static_assert(sizeof(nds_header_ntr_t) == 0x170, "Invalid size for nds_header_ntr_t");
|
||||||
|
|
||||||
struct nds_header_twl_t
|
#define NDS_HEADER_TWL_ACCESS_CONTROL_SD_ACCESS (1 << 3)
|
||||||
|
#define NDS_HEADER_TWL_ACCESS_CONTROL_NAND_ACCESS (1 << 4)
|
||||||
|
|
||||||
|
struct nds_header_twl_t : public nds_header_ntr_t
|
||||||
{
|
{
|
||||||
nds_header_ntr_t ntrHeader;
|
|
||||||
u8 gap170[0x10];
|
u8 gap170[0x10];
|
||||||
u32 globalMbkSettings[5]; // slot mapping
|
u32 globalMbkSettings[5]; // slot mapping
|
||||||
u32 arm9MbkSettings[3]; // wram mapping
|
u32 arm9MbkSettings[3]; // wram mapping
|
||||||
@@ -130,14 +132,19 @@ struct nds_header_twl_t
|
|||||||
u8 gapF00[0x80];
|
u8 gapF00[0x80];
|
||||||
u8 headerRsaSha1Signature[0x80];
|
u8 headerRsaSha1Signature[0x80];
|
||||||
|
|
||||||
constexpr bool IsTwlRom() const
|
|
||||||
{
|
|
||||||
return ntrHeader.IsTwlRom();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool IsDsiWare() const
|
constexpr bool IsDsiWare() const
|
||||||
{
|
{
|
||||||
return IsTwlRom() && ((titleId >> 32) & 0xFF) != 0;
|
return IsTwlRom() && ((titleId >> 32) & 4) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool HasSdAccess() const
|
||||||
|
{
|
||||||
|
return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SD_ACCESS) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool HasNandAccess() const
|
||||||
|
{
|
||||||
|
return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_NAND_ACCESS) != 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user