fix Key1 code to source the DS-mode key data from the ARM9i BIOS, so it works even if no DS BIOSes are provided

(had to rework the loading code to make it work -- if carts are passed to the DSi constructor, they get initialized before the DSi stuff is initialized, and can't read the DSi BIOSes)
This commit is contained in:
Arisotura
2024-11-17 19:04:13 +01:00
parent f0a023b572
commit 5e3d2d07c3
3 changed files with 52 additions and 31 deletions

View File

@ -109,36 +109,52 @@ void NDSCartSlot::Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept
}
}
void NDSCartSlot::Key1_LoadKeyBuf(bool dsi, const u8 *bios, u32 biosLength) noexcept
void NDSCartSlot::Key1_LoadKeyBuf(bool dsimode) noexcept
{
if (NDS.IsLoadedARM7BIOSKnownNative())
if (NDS.ConsoleType == 1)
{
u32 expected_bios_length = dsi ? 0x10000 : 0x4000;
if (biosLength != expected_bios_length)
// DSi mode: grab the right key depending on the requested cart mode
auto& dsi = static_cast<DSi&>(NDS);
if (dsimode)
{
Platform::Log(LogLevel::Error, "NDSCart: Expected an ARM7 BIOS of %u bytes, got %u bytes\n", expected_bios_length, biosLength);
}
else if (bios == nullptr)
{
Platform::Log(LogLevel::Error, "NDSCart: Expected an ARM7 BIOS of %u bytes, got nullptr\n", expected_bios_length);
// load from ARM7 BIOS at 0xC6D0
const u8* bios = dsi.ARM7iBIOS.data();
memcpy(Key1_KeyBuf.data(), bios + 0xC6D0, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from ARM7i BIOS\n");
}
else
{
memcpy(Key1_KeyBuf.data(), bios + (dsi ? 0xC6D0 : 0x0030), sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from memory\n");
// load from ARM9 BIOS at 0x99A0
const u8* bios = dsi.ARM9iBIOS.data();
memcpy(Key1_KeyBuf.data(), bios + 0x99A0, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from ARM9i BIOS\n");
}
}
else
{
// well
memset(Key1_KeyBuf.data(), 0, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf to zero\n");
// DS mode: load from ARM7 BIOS at 0x0030
if (NDS.IsLoadedARM7BIOSKnownNative())
{
const u8* bios = NDS.GetARM7BIOS().data();
memcpy(Key1_KeyBuf.data(), bios + 0x0030, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from ARM7 BIOS\n");
}
else
{
// well
memset(Key1_KeyBuf.data(), 0, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf to zero\n");
}
}
}
void NDSCartSlot::Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod, const u8 *bios, u32 biosLength) noexcept
void NDSCartSlot::Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod) noexcept
{
Key1_LoadKeyBuf(dsi, bios, biosLength);
Key1_LoadKeyBuf(dsi);
u32 keycode[3] = {idcode, idcode>>1, idcode<<1};
if (level >= 1) Key1_ApplyKeycode(keycode, mod);
@ -262,16 +278,15 @@ int CartCommon::ROMCommandStart(NDS& nds, NDSCartSlot& cartslot, const u8* cmd,
case 0x3C:
CmdEncMode = 1;
cartslot.Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2, nds.GetARM7BIOS().data(), ARM7BIOSSize);
cartslot.Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2);
DSiMode = false;
return 0;
case 0x3D:
if (IsDSi)
{
auto& dsi = static_cast<DSi&>(nds);
CmdEncMode = 1;
cartslot.Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2, &dsi.ARM7iBIOS[0], sizeof(DSi::ARM7iBIOS));
cartslot.Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2);
DSiMode = true;
}
return 0;
@ -1552,10 +1567,10 @@ void NDSCartSlot::DecryptSecureArea(u8* out) noexcept
memcpy(out, &cartrom[arm9base], 0x800);
Key1_InitKeycode(false, gamecode, 2, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
Key1_InitKeycode(false, gamecode, 2, 2);
Key1_Decrypt((u32*)&out[0]);
Key1_InitKeycode(false, gamecode, 3, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
Key1_InitKeycode(false, gamecode, 3, 2);
for (u32 i = 0; i < 0x800; i += 8)
Key1_Decrypt((u32*)&out[i]);
@ -1714,11 +1729,11 @@ void NDSCartSlot::SetCart(std::unique_ptr<CartCommon>&& cart) noexcept
strncpy((char*)&cartrom[header.ARM9ROMOffset], "encryObj", 8);
Key1_InitKeycode(false, romparams.GameCode, 3, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
Key1_InitKeycode(false, romparams.GameCode, 3, 2);
for (u32 i = 0; i < 0x800; i += 8)
Key1_Encrypt((u32*)&cartrom[header.ARM9ROMOffset + i]);
Key1_InitKeycode(false, romparams.GameCode, 2, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
Key1_InitKeycode(false, romparams.GameCode, 2, 2);
Key1_Encrypt((u32*)&cartrom[header.ARM9ROMOffset]);
Log(LogLevel::Debug, "Re-encrypted cart secure area\n");