Added detection of DS mode DSiWare. Fixes #95.

This commit is contained in:
Gericom
2026-01-11 13:20:01 +01:00
parent c62945af58
commit 24346eaf30
6 changed files with 50 additions and 43 deletions

View File

@@ -24,7 +24,7 @@ bool CardSaveArranger::SetupCardSave(const nds_header_ntr_t* header, const TCHAR
if (header->nandBackupRegionStart != 0) if (header->nandBackupRegionStart != 0)
{ {
saveType = CardSaveType::Nand; saveType = CardSaveType::Nand;
u32 blockSize = header->IsTwlRom() ? TWL_NAND_BLOCK_SIZE : NTR_NAND_BLOCK_SIZE; u32 blockSize = header->SupportsDsiMode() ? TWL_NAND_BLOCK_SIZE : NTR_NAND_BLOCK_SIZE;
u32 nandBackupRegionStart = header->nandBackupRegionStart * blockSize; u32 nandBackupRegionStart = header->nandBackupRegionStart * blockSize;
saveSize = NAND_RW_REGION_END - nandBackupRegionStart; saveSize = NAND_RW_REGION_END - nandBackupRegionStart;
LOG_DEBUG("NAND save. Size: 0x%X.", saveSize); LOG_DEBUG("NAND save. Size: 0x%X.", saveSize);

View File

@@ -188,17 +188,21 @@ void NdsLoader::Load(BootMode bootMode)
{ {
if (_romHeader.IsDsiWare()) if (_romHeader.IsDsiWare())
{ {
if (bootMode == BootMode::SdkResetSystem) // There exist DS mode DSiWare applications, which don't have a save file.
if (_romHeader.SupportsDsiMode())
{ {
// todo: for DSiWare we should store the rom path if (bootMode == BootMode::SdkResetSystem)
LOG_FATAL("Soft reset from DSiWare not yet supported\n"); {
return; // todo: for DSiWare we should store the rom path
} LOG_FATAL("Soft reset from DSiWare not yet supported\n");
return;
}
if (!TrySetupDsiWareSave()) if (!TrySetupDsiWareSave())
{ {
ErrorDisplay().PrintError("Failed to setup DSiWare save."); ErrorDisplay().PrintError("Failed to setup DSiWare save.");
return; return;
}
} }
} }
else else
@@ -231,7 +235,7 @@ void NdsLoader::Load(BootMode bootMode)
if (Environment::IsDsiMode()) if (Environment::IsDsiMode())
{ {
if (_romHeader.IsTwlRom()) if (_romHeader.SupportsDsiMode())
{ {
SetupTwlConfig(); SetupTwlConfig();
TwlAes().SetupAes(&_romHeader); TwlAes().SetupAes(&_romHeader);
@@ -248,7 +252,7 @@ void NdsLoader::Load(BootMode bootMode)
return; return;
} }
if (Environment::IsDsiMode() && _romHeader.IsTwlRom()) if (Environment::IsDsiMode() && _romHeader.SupportsDsiMode())
{ {
if (!TryLoadArm9i()) if (!TryLoadArm9i())
{ {
@@ -271,7 +275,7 @@ void NdsLoader::Load(BootMode bootMode)
return; return;
} }
if (Environment::IsDsiMode() && _romHeader.IsTwlRom()) if (Environment::IsDsiMode() && _romHeader.SupportsDsiMode())
{ {
if (!TryLoadArm7i()) if (!TryLoadArm7i())
{ {
@@ -293,7 +297,7 @@ void NdsLoader::Load(BootMode bootMode)
LOG_DEBUG("Arm7 patches done\n"); LOG_DEBUG("Arm7 patches done\n");
} }
if (Environment::IsDsiMode() && _romHeader.IsTwlRom()) if (Environment::IsDsiMode() && _romHeader.SupportsDsiMode())
{ {
SetupDsiDeviceList(); SetupDsiDeviceList();
@@ -329,7 +333,7 @@ void NdsLoader::Load(BootMode bootMode)
if (Environment::IsDsiMode()) if (Environment::IsDsiMode())
{ {
if (_romHeader.IsTwlRom()) if (_romHeader.SupportsDsiMode())
{ {
if (!(_romHeader.twlFlags2 & 1)) if (!(_romHeader.twlFlags2 & 1))
{ {
@@ -380,7 +384,7 @@ void NdsLoader::InsertArgv()
// Find the address to write argv // Find the address to write argv
u32 argDst = ((_romHeader.arm9LoadAddress + _romHeader.arm9Size + 3) & ~3) + 4; u32 argDst = ((_romHeader.arm9LoadAddress + _romHeader.arm9Size + 3) & ~3) + 4;
if (_romHeader.IsTwlRom()) if (_romHeader.SupportsDsiMode())
{ {
u32 argDstTwl = ((_romHeader.arm9iLoadAddress + _romHeader.arm9iSize + 3) & ~3) + 4; u32 argDstTwl = ((_romHeader.arm9iLoadAddress + _romHeader.arm9iSize + 3) & ~3) + 4;
if (argDstTwl > argDst) if (argDstTwl > argDst)
@@ -442,7 +446,7 @@ void NdsLoader::ApplyArm7Patches()
u32 mbk6 = 0; u32 mbk6 = 0;
u32 mbk7 = 0; u32 mbk7 = 0;
u32 mbk8 = 0; u32 mbk8 = 0;
if (Environment::IsDsiMode() && _romHeader.IsTwlRom()) if (Environment::IsDsiMode() && _romHeader.SupportsDsiMode())
{ {
mbk6 = REG_MBK6; mbk6 = REG_MBK6;
mbk7 = REG_MBK7; mbk7 = REG_MBK7;
@@ -466,7 +470,7 @@ void NdsLoader::ApplyArm7Patches()
memcpy(patchCode.get(), srcAddress, patchSpaceSize); memcpy(patchCode.get(), srcAddress, patchSpaceSize);
} }
if (Environment::IsDsiMode() && _romHeader.IsTwlRom()) if (Environment::IsDsiMode() && _romHeader.SupportsDsiMode())
{ {
REG_MBK6 = mbk6; REG_MBK6 = mbk6;
REG_MBK7 = mbk7; REG_MBK7 = mbk7;
@@ -493,7 +497,7 @@ void NdsLoader::SetupSharedMemory(u32 cardId, u32 agbMem, u32 resetParam, u32 ro
LoadFirmwareUserSettings(); LoadFirmwareUserSettings();
if (!_romHeader.IsTwlRom()) if (!_romHeader.SupportsDsiMode())
{ {
memcpy((void*)0x027FF800, (void*)0x02FFF800, sizeof(shared_memory_ntr_t)); memcpy((void*)0x027FF800, (void*)0x02FFF800, sizeof(shared_memory_ntr_t));
memcpy((void*)0x023FF800, (void*)0x02FFF800, sizeof(shared_memory_ntr_t)); memcpy((void*)0x023FF800, (void*)0x02FFF800, sizeof(shared_memory_ntr_t));
@@ -505,10 +509,10 @@ void NdsLoader::SetupSharedMemory(u32 cardId, u32 agbMem, u32 resetParam, u32 ro
{ {
strcpy(TWL_SHARED_MEMORY->sysMenuVersionInfoContentId, "00000009"); strcpy(TWL_SHARED_MEMORY->sysMenuVersionInfoContentId, "00000009");
TWL_SHARED_MEMORY->sysMenuVersionInfoContentLastInitialCode = 'P'; // europe TWL_SHARED_MEMORY->sysMenuVersionInfoContentLastInitialCode = 'P'; // europe
memcpy(TWL_SHARED_MEMORY->twlCardRomHeader, &_romHeader, sizeof(nds_header_twl_t));
memcpy(TWL_SHARED_MEMORY->twlRomHeader, &_romHeader, sizeof(nds_header_twl_t));
} }
memcpy(TWL_SHARED_MEMORY->twlCardRomHeader, &_romHeader, sizeof(nds_header_twl_t));
memcpy(TWL_SHARED_MEMORY->twlRomHeader, &_romHeader, sizeof(nds_header_twl_t));
} }
void NdsLoader::LoadFirmwareUserSettings() void NdsLoader::LoadFirmwareUserSettings()
@@ -643,7 +647,7 @@ void NdsLoader::HandleAntiPiracy()
void NdsLoader::RemapWram() void NdsLoader::RemapWram()
{ {
mem_unlockAllTwlWram(); mem_unlockAllTwlWram();
if (_romHeader.IsTwlRom()) if (_romHeader.SupportsDsiMode())
{ {
REG_MBK6 = _romHeader.arm7MbkSettings[0]; REG_MBK6 = _romHeader.arm7MbkSettings[0];
REG_MBK7 = _romHeader.arm7MbkSettings[1]; REG_MBK7 = _romHeader.arm7MbkSettings[1];

View File

@@ -35,8 +35,8 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform) const
{ {
(void*)romHeader->arm7LoadAddress, (void*)romHeader->arm7LoadAddress,
romHeader->arm7Size, romHeader->arm7Size,
(romHeader->IsTwlRom()) ? (void*)twlRomHeader->arm7iLoadAddress : nullptr, (romHeader->SupportsDsiMode()) ? (void*)twlRomHeader->arm7iLoadAddress : nullptr,
(romHeader->IsTwlRom()) ? twlRomHeader->arm7iSize : 0, (romHeader->SupportsDsiMode()) ? twlRomHeader->arm7iSize : 0,
sdkVersion, sdkVersion,
romHeader->gameCode, romHeader->gameCode,
romHeader->softwareVersion, romHeader->softwareVersion,
@@ -114,7 +114,7 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform) const
u32 mbk6 = 0; u32 mbk6 = 0;
u32 mbk7 = 0; u32 mbk7 = 0;
u32 mbk8 = 0; u32 mbk8 = 0;
if (gIsDsiMode && romHeader->IsTwlRom()) if (gIsDsiMode && romHeader->SupportsDsiMode())
{ {
mbk6 = REG_MBK6; mbk6 = REG_MBK6;
mbk7 = REG_MBK7; mbk7 = REG_MBK7;
@@ -133,7 +133,7 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform) const
ic_invalidateAll(); ic_invalidateAll();
// If in DSi mode and the rom is a DSi rom, restore twl wram. // If in DSi mode and the rom is a DSi rom, restore twl wram.
if (gIsDsiMode && romHeader->IsTwlRom()) if (gIsDsiMode && romHeader->SupportsDsiMode())
{ {
REG_MBK6 = mbk6; REG_MBK6 = mbk6;
REG_MBK7 = mbk7; REG_MBK7 = mbk7;

View File

@@ -51,7 +51,7 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
auto romHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader; auto romHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader;
auto twlRomHeader = (const nds_header_twl_t*)TWL_SHARED_MEMORY->twlRomHeader; auto twlRomHeader = (const nds_header_twl_t*)TWL_SHARED_MEMORY->twlRomHeader;
u32 arm9Size = romHeader->arm9Size; u32 arm9Size = romHeader->arm9Size;
u32 arm9iSize = romHeader->IsTwlRom() ? twlRomHeader->arm9iSize : 0; u32 arm9iSize = romHeader->SupportsDsiMode() ? twlRomHeader->arm9iSize : 0;
u32 compressedEnd = 0; u32 compressedEnd = 0;
auto moduleParams = ModuleParamsLocator().FindModuleParams(romHeader); auto moduleParams = ModuleParamsLocator().FindModuleParams(romHeader);
SdkVersion sdkVersion = moduleParams ? moduleParams->sdkVersion : 0u; SdkVersion sdkVersion = moduleParams ? moduleParams->sdkVersion : 0u;
@@ -76,7 +76,7 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
} }
} }
if (gIsDsiMode && romHeader->IsTwlRom()) if (gIsDsiMode && romHeader->SupportsDsiMode())
{ {
auto arm9iModuleParams = (module_params_twl_t*)(romHeader->arm9LoadAddress + twlRomHeader->arm9iModuleParamsAddress); auto arm9iModuleParams = (module_params_twl_t*)(romHeader->arm9LoadAddress + twlRomHeader->arm9iModuleParamsAddress);
if (arm9iModuleParams->magicBigEndian == MODULE_PARAMS_TWL_MAGIC_BE && if (arm9iModuleParams->magicBigEndian == MODULE_PARAMS_TWL_MAGIC_BE &&
@@ -112,7 +112,7 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
{ {
(void*)romHeader->arm9LoadAddress, (void*)romHeader->arm9LoadAddress,
arm9Size, arm9Size,
romHeader->IsTwlRom() ? (void*)twlRomHeader->arm9iLoadAddress : nullptr, romHeader->SupportsDsiMode() ? (void*)twlRomHeader->arm9iLoadAddress : nullptr,
arm9iSize, arm9iSize,
sdkVersion, sdkVersion,
romHeader->gameCode, romHeader->gameCode,
@@ -156,13 +156,10 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
{ {
if (!twlRomHeader->IsDsiWare()) if (!twlRomHeader->IsDsiWare())
{ {
// if ((romHeader->unitCode & 3) != 3) patchCollection.AddPatch(new CardiIsRomDmaAvailablePatch());
{
patchCollection.AddPatch(new CardiIsRomDmaAvailablePatch());
}
patchCollection.AddPatch(new CardiReadRomWithCpuPatch()); patchCollection.AddPatch(new CardiReadRomWithCpuPatch());
if (gIsDsiMode && romHeader->IsTwlRom()) if (gIsDsiMode && romHeader->SupportsDsiMode())
{ {
patchCollection.AddPatch(new CardiReadCardWithHashInternalAsyncPatch()); patchCollection.AddPatch(new CardiReadCardWithHashInternalAsyncPatch());
} }

View File

@@ -220,7 +220,7 @@ static void handleBootCommand()
Arm9IoRegisterClearer().ClearNtrIoRegisters(isSdkResetSystem); Arm9IoRegisterClearer().ClearNtrIoRegisters(isSdkResetSystem);
REG_EXMEMCNT |= 0x0880; // map ds and gba slot to arm7 REG_EXMEMCNT |= 0x0880; // map ds and gba slot to arm7
auto ntrRomHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader; auto ntrRomHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader;
if (gIsDsiMode && ntrRomHeader->IsTwlRom()) if (gIsDsiMode && ntrRomHeader->SupportsDsiMode())
{ {
Arm9IoRegisterClearer().ClearTwlIoRegisters(); Arm9IoRegisterClearer().ClearTwlIoRegisters();
REG_SCFG_EXT = 0x8307F100; REG_SCFG_EXT = 0x8307F100;

View File

@@ -1,6 +1,9 @@
#pragma once #pragma once
#include <nds/ndstypes.h> #include <nds/ndstypes.h>
#define NDS_HEADER_UNIT_CODE_NOT_SUPPORTS_DS_MODE (1 << 0)
#define NDS_HEADER_UNIT_CODE_SUPPORTS_DSI_MODE (1 << 1)
struct nds_header_ntr_t struct nds_header_ntr_t
{ {
u8 gameTitle[12]; u8 gameTitle[12];
@@ -55,9 +58,9 @@ struct nds_header_ntr_t
u32 debugRomLoadAddress; // and arm9 entry u32 debugRomLoadAddress; // and arm9 entry
u32 debugRomArm7EntryAddress; u32 debugRomArm7EntryAddress;
constexpr bool IsTwlRom() const constexpr bool SupportsDsiMode() const
{ {
return unitCode & 2; return unitCode & NDS_HEADER_UNIT_CODE_SUPPORTS_DSI_MODE;
} }
}; };
@@ -134,29 +137,32 @@ struct nds_header_twl_t : public nds_header_ntr_t
u8 gapF00[0x80]; u8 gapF00[0x80];
u8 headerRsaSha1Signature[0x80]; u8 headerRsaSha1Signature[0x80];
/// @brief Returns if this is a DSiWare application. Note that this does not imply that the app runs in DSi mode.
/// @return \c true when this is a DSiWare application, or \c false otherwise.
constexpr bool IsDsiWare() const constexpr bool IsDsiWare() const
{ {
return IsTwlRom() && ((titleId >> 32) & 4) != 0; // Do not use SupportsDsiMode() here, because there exist DS mode DSiWare applications.
return (twlFlags & 1) != 0 && ((titleId >> 32) & 4) != 0;
} }
constexpr bool HasSdAccess() const constexpr bool HasSdAccess() const
{ {
return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SD_ACCESS) != 0; return SupportsDsiMode() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SD_ACCESS) != 0;
} }
constexpr bool HasNandAccess() const constexpr bool HasNandAccess() const
{ {
return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_NAND_ACCESS) != 0; return SupportsDsiMode() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_NAND_ACCESS) != 0;
} }
constexpr bool HasShared2Access() const constexpr bool HasShared2Access() const
{ {
return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SHARED2_ACCESS) != 0; return SupportsDsiMode() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SHARED2_ACCESS) != 0;
} }
constexpr bool HasSslCertAccess() const constexpr bool HasSslCertAccess() const
{ {
return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SSLCERT_ACCESS) != 0; return SupportsDsiMode() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SSLCERT_ACCESS) != 0;
} }
}; };