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; // DSi mode: grab the right key depending on the requested cart mode
if (biosLength != expected_bios_length)
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); // load from ARM7 BIOS at 0xC6D0
}
else if (bios == nullptr) const u8* bios = dsi.ARM7iBIOS.data();
{ memcpy(Key1_KeyBuf.data(), bios + 0xC6D0, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Error, "NDSCart: Expected an ARM7 BIOS of %u bytes, got nullptr\n", expected_bios_length); Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from ARM7i BIOS\n");
} }
else else
{ {
memcpy(Key1_KeyBuf.data(), bios + (dsi ? 0xC6D0 : 0x0030), sizeof(Key1_KeyBuf)); // load from ARM9 BIOS at 0x99A0
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from memory\n");
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 else
{ {
// well // DS mode: load from ARM7 BIOS at 0x0030
memset(Key1_KeyBuf.data(), 0, sizeof(Key1_KeyBuf));
Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf to zero\n"); 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}; u32 keycode[3] = {idcode, idcode>>1, idcode<<1};
if (level >= 1) Key1_ApplyKeycode(keycode, mod); if (level >= 1) Key1_ApplyKeycode(keycode, mod);
@ -262,16 +278,15 @@ int CartCommon::ROMCommandStart(NDS& nds, NDSCartSlot& cartslot, const u8* cmd,
case 0x3C: case 0x3C:
CmdEncMode = 1; 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; DSiMode = false;
return 0; return 0;
case 0x3D: case 0x3D:
if (IsDSi) if (IsDSi)
{ {
auto& dsi = static_cast<DSi&>(nds);
CmdEncMode = 1; 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; DSiMode = true;
} }
return 0; return 0;
@ -1552,10 +1567,10 @@ void NDSCartSlot::DecryptSecureArea(u8* out) noexcept
memcpy(out, &cartrom[arm9base], 0x800); 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_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) for (u32 i = 0; i < 0x800; i += 8)
Key1_Decrypt((u32*)&out[i]); 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); 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) for (u32 i = 0; i < 0x800; i += 8)
Key1_Encrypt((u32*)&cartrom[header.ARM9ROMOffset + i]); 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]); Key1_Encrypt((u32*)&cartrom[header.ARM9ROMOffset]);
Log(LogLevel::Debug, "Re-encrypted cart secure area\n"); Log(LogLevel::Debug, "Re-encrypted cart secure area\n");

View File

@ -445,8 +445,8 @@ private:
void Key1_Encrypt(u32* data) const noexcept; void Key1_Encrypt(u32* data) const noexcept;
void Key1_Decrypt(u32* data) const noexcept; void Key1_Decrypt(u32* data) const noexcept;
void Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept; void Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept;
void Key1_LoadKeyBuf(bool dsi, const u8 *bios, u32 biosLength) noexcept; void Key1_LoadKeyBuf(bool dsi) noexcept;
void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod, const u8 *bios, u32 biosLength) noexcept; void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod) noexcept;
void Key2_Encrypt(const u8* data, u32 len) noexcept; void Key2_Encrypt(const u8* data, u32 len) noexcept;
void ROMEndTransfer(u32 param) noexcept; void ROMEndTransfer(u32 param) noexcept;
void ROMPrepareData(u32 param) noexcept; void ROMPrepareData(u32 param) noexcept;

View File

@ -1296,8 +1296,10 @@ bool EmuInstance::updateConsole() noexcept
#endif #endif
NDSArgs ndsargs { NDSArgs ndsargs {
std::move(nextndscart), //std::move(nextndscart),
std::move(nextgbacart), //std::move(nextgbacart),
nullptr,
nullptr,
std::move(arm9bios), std::move(arm9bios),
std::move(arm7bios), std::move(arm7bios),
std::move(*firmware), std::move(*firmware),
@ -1365,8 +1367,6 @@ bool EmuInstance::updateConsole() noexcept
nds->SetARM7BIOS(*args->ARM7BIOS); nds->SetARM7BIOS(*args->ARM7BIOS);
nds->SetARM9BIOS(*args->ARM9BIOS); nds->SetARM9BIOS(*args->ARM9BIOS);
nds->SetFirmware(std::move(args->Firmware)); nds->SetFirmware(std::move(args->Firmware));
nds->SetNDSCart(std::move(args->NDSROM));
nds->SetGBACart(std::move(args->GBAROM));
nds->SetJITArgs(args->JIT); nds->SetJITArgs(args->JIT);
// TODO GDB stub shit // TODO GDB stub shit
nds->SPU.SetInterpolation(args->Interpolation); nds->SPU.SetInterpolation(args->Interpolation);
@ -1384,10 +1384,16 @@ bool EmuInstance::updateConsole() noexcept
dsi->SetSDCard(std::move(_dsiargs.DSiSDCard)); dsi->SetSDCard(std::move(_dsiargs.DSiSDCard));
// We're moving the optional, not the card // We're moving the optional, not the card
// (inserting std::nullopt here is okay, it means no card) // (inserting std::nullopt here is okay, it means no card)
dsi->EjectGBACart();
} }
} }
// loads the carts later -- to be sure that everything else is initialized
nds->SetNDSCart(std::move(nextndscart));
if (consoleType == 1)
nds->EjectGBACart();
else
nds->SetGBACart(std::move(nextgbacart));
renderLock.unlock(); renderLock.unlock();
loadCheats(); loadCheats();