Fix detection of native NDS ARM BIOS images (#1910)
* Fix detection of native NDS ARM BIOS images - Instead of checking for built-in BIOS images, now the altered methods check for native ones - The CRC32 must match exactly; patched BIOS images will result in `false` * Encapsulate `NDS::ARM9BIOS` and `ARM7BIOS` - Also compute the checksum only when setting the BIOS
This commit is contained in:
parent
c867a7f1c0
commit
24c402af51
|
@ -63,12 +63,12 @@ const u32 CodeRegionSizes[ARMJIT_Memory::memregions_Count] =
|
||||||
0,
|
0,
|
||||||
ITCMPhysicalSize,
|
ITCMPhysicalSize,
|
||||||
0,
|
0,
|
||||||
sizeof(NDS::ARM9BIOS),
|
ARM9BIOSSize,
|
||||||
MainRAMMaxSize,
|
MainRAMMaxSize,
|
||||||
SharedWRAMSize,
|
SharedWRAMSize,
|
||||||
0,
|
0,
|
||||||
0x100000,
|
0x100000,
|
||||||
sizeof(NDS::ARM7BIOS),
|
ARM7BIOSSize,
|
||||||
ARM7WRAMSize,
|
ARM7WRAMSize,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -32,6 +32,8 @@ constexpr u32 ARM7BIOSSize = 0x4000;
|
||||||
constexpr u32 DSiBIOSSize = 0x10000;
|
constexpr u32 DSiBIOSSize = 0x10000;
|
||||||
constexpr u32 ITCMPhysicalSize = 0x8000;
|
constexpr u32 ITCMPhysicalSize = 0x8000;
|
||||||
constexpr u32 DTCMPhysicalSize = 0x4000;
|
constexpr u32 DTCMPhysicalSize = 0x4000;
|
||||||
|
constexpr u32 ARM7BIOSCRC32 = 0x1280f0d5;
|
||||||
|
constexpr u32 ARM9BIOSCRC32 = 0x2ab23573;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MELONDS_MEMCONSTANTS_H
|
#endif // MELONDS_MEMCONSTANTS_H
|
18
src/NDS.cpp
18
src/NDS.cpp
|
@ -92,6 +92,8 @@ NDS::NDS(NDSArgs&& args, int type) noexcept :
|
||||||
ConsoleType(type),
|
ConsoleType(type),
|
||||||
ARM7BIOS(args.ARM7BIOS),
|
ARM7BIOS(args.ARM7BIOS),
|
||||||
ARM9BIOS(args.ARM9BIOS),
|
ARM9BIOS(args.ARM9BIOS),
|
||||||
|
ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32),
|
||||||
|
ARM9BIOSNative(CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32),
|
||||||
JIT(*this, args.JIT),
|
JIT(*this, args.JIT),
|
||||||
SPU(*this, args.BitDepth, args.Interpolation),
|
SPU(*this, args.BitDepth, args.Interpolation),
|
||||||
GPU(*this, std::move(args.Renderer3D)),
|
GPU(*this, std::move(args.Renderer3D)),
|
||||||
|
@ -270,7 +272,7 @@ bool NDS::NeedsDirectBoot() const
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// FreeBIOS requires direct boot (it can't boot firmware)
|
// FreeBIOS requires direct boot (it can't boot firmware)
|
||||||
if (IsLoadedARM7BIOSBuiltIn() || IsLoadedARM9BIOSBuiltIn())
|
if (!IsLoadedARM9BIOSKnownNative() || !IsLoadedARM7BIOSKnownNative())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -286,7 +288,7 @@ void NDS::SetupDirectBoot()
|
||||||
|
|
||||||
// Copy the Nintendo logo from the NDS ROM header to the ARM9 BIOS if using FreeBIOS
|
// Copy the Nintendo logo from the NDS ROM header to the ARM9 BIOS if using FreeBIOS
|
||||||
// Games need this for DS<->GBA comm to work
|
// Games need this for DS<->GBA comm to work
|
||||||
if (IsLoadedARM9BIOSBuiltIn())
|
if (!IsLoadedARM9BIOSKnownNative())
|
||||||
{
|
{
|
||||||
memcpy(ARM9BIOS.data() + 0x20, header.NintendoLogo, 0x9C);
|
memcpy(ARM9BIOS.data() + 0x20, header.NintendoLogo, 0x9C);
|
||||||
}
|
}
|
||||||
|
@ -756,6 +758,18 @@ void NDS::LoadBIOS()
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NDS::SetARM7BIOS(const std::array<u8, ARM7BIOSSize>& bios) noexcept
|
||||||
|
{
|
||||||
|
ARM7BIOS = bios;
|
||||||
|
ARM7BIOSNative = CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NDS::SetARM9BIOS(const std::array<u8, ARM9BIOSSize>& bios) noexcept
|
||||||
|
{
|
||||||
|
ARM9BIOS = bios;
|
||||||
|
ARM9BIOSNative = CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32;
|
||||||
|
}
|
||||||
|
|
||||||
u64 NDS::NextTarget()
|
u64 NDS::NextTarget()
|
||||||
{
|
{
|
||||||
u64 minEvent = UINT64_MAX;
|
u64 minEvent = UINT64_MAX;
|
||||||
|
|
24
src/NDS.h
24
src/NDS.h
|
@ -39,6 +39,7 @@
|
||||||
#include "MemRegion.h"
|
#include "MemRegion.h"
|
||||||
#include "ARMJIT_Memory.h"
|
#include "ARMJIT_Memory.h"
|
||||||
#include "ARM.h"
|
#include "ARM.h"
|
||||||
|
#include "CRC32.h"
|
||||||
#include "DMA.h"
|
#include "DMA.h"
|
||||||
#include "FreeBIOS.h"
|
#include "FreeBIOS.h"
|
||||||
|
|
||||||
|
@ -227,7 +228,7 @@ private:
|
||||||
bool EnableJIT;
|
bool EnableJIT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public: // TODO: Encapsulate the rest of these members
|
||||||
int ConsoleType;
|
int ConsoleType;
|
||||||
int CurCPU;
|
int CurCPU;
|
||||||
|
|
||||||
|
@ -261,8 +262,14 @@ public:
|
||||||
u8 ROMSeed0[2*8];
|
u8 ROMSeed0[2*8];
|
||||||
u8 ROMSeed1[2*8];
|
u8 ROMSeed1[2*8];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// These BIOS arrays should be declared *before* the component objects (JIT, SPI, etc.)
|
||||||
|
// so that they're initialized before the component objects' constructors run.
|
||||||
std::array<u8, ARM9BIOSSize> ARM9BIOS;
|
std::array<u8, ARM9BIOSSize> ARM9BIOS;
|
||||||
std::array<u8, ARM7BIOSSize> ARM7BIOS;
|
std::array<u8, ARM7BIOSSize> ARM7BIOS;
|
||||||
|
bool ARM9BIOSNative;
|
||||||
|
bool ARM7BIOSNative;
|
||||||
|
public: // TODO: Encapsulate the rest of these members
|
||||||
u16 ARM7BIOSProt;
|
u16 ARM7BIOSProt;
|
||||||
|
|
||||||
u8* MainRAM;
|
u8* MainRAM;
|
||||||
|
@ -310,8 +317,19 @@ public:
|
||||||
void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq);
|
void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq);
|
||||||
|
|
||||||
void LoadBIOS();
|
void LoadBIOS();
|
||||||
[[nodiscard]] bool IsLoadedARM9BIOSBuiltIn() const noexcept { return ARM9BIOS == bios_arm9_bin; }
|
|
||||||
[[nodiscard]] bool IsLoadedARM7BIOSBuiltIn() const noexcept { return ARM7BIOS == bios_arm7_bin; }
|
/// @return \c true if the loaded ARM9 BIOS image is a known dump
|
||||||
|
/// of a native DS-compatible ARM9 BIOS.
|
||||||
|
[[nodiscard]] bool IsLoadedARM9BIOSKnownNative() const noexcept { return ARM9BIOSNative; }
|
||||||
|
[[nodiscard]] const std::array<u8, ARM9BIOSSize>& GetARM9BIOS() const noexcept { return ARM9BIOS; }
|
||||||
|
void SetARM9BIOS(const std::array<u8, ARM9BIOSSize>& bios) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] const std::array<u8, ARM7BIOSSize>& GetARM7BIOS() const noexcept { return ARM7BIOS; }
|
||||||
|
void SetARM7BIOS(const std::array<u8, ARM7BIOSSize>& bios) noexcept;
|
||||||
|
|
||||||
|
/// @return \c true if the loaded ARM7 BIOS image is a known dump
|
||||||
|
/// of a native DS-compatible ARM9 BIOS.
|
||||||
|
[[nodiscard]] bool IsLoadedARM7BIOSKnownNative() const noexcept { return ARM7BIOSNative; }
|
||||||
|
|
||||||
[[nodiscard]] NDSCart::CartCommon* GetNDSCart() { return NDSCartSlot.GetCart(); }
|
[[nodiscard]] NDSCart::CartCommon* GetNDSCart() { return NDSCartSlot.GetCart(); }
|
||||||
[[nodiscard]] const NDSCart::CartCommon* GetNDSCart() const { return NDSCartSlot.GetCart(); }
|
[[nodiscard]] const NDSCart::CartCommon* GetNDSCart() const { return NDSCartSlot.GetCart(); }
|
||||||
|
|
|
@ -111,7 +111,7 @@ 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 dsi, const u8 *bios, u32 biosLength) noexcept
|
||||||
{
|
{
|
||||||
if (!NDS.IsLoadedARM7BIOSBuiltIn())
|
if (NDS.IsLoadedARM7BIOSKnownNative())
|
||||||
{
|
{
|
||||||
u32 expected_bios_length = dsi ? 0x10000 : 0x4000;
|
u32 expected_bios_length = dsi ? 0x10000 : 0x4000;
|
||||||
if (biosLength != expected_bios_length)
|
if (biosLength != expected_bios_length)
|
||||||
|
@ -261,7 +261,7 @@ 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.ARM7BIOS[0], sizeof(NDS::ARM7BIOS));
|
cartslot.Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2, nds.GetARM7BIOS().data(), ARM7BIOSSize);
|
||||||
DSiMode = false;
|
DSiMode = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1540,10 +1540,10 @@ void NDSCartSlot::DecryptSecureArea(u8* out) noexcept
|
||||||
|
|
||||||
memcpy(out, &cartrom[arm9base], 0x800);
|
memcpy(out, &cartrom[arm9base], 0x800);
|
||||||
|
|
||||||
Key1_InitKeycode(false, gamecode, 2, 2, &NDS.ARM7BIOS[0], sizeof(NDS::ARM7BIOS));
|
Key1_InitKeycode(false, gamecode, 2, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
|
||||||
Key1_Decrypt((u32*)&out[0]);
|
Key1_Decrypt((u32*)&out[0]);
|
||||||
|
|
||||||
Key1_InitKeycode(false, gamecode, 3, 2, &NDS.ARM7BIOS[0], sizeof(NDS::ARM7BIOS));
|
Key1_InitKeycode(false, gamecode, 3, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
|
||||||
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]);
|
||||||
|
|
||||||
|
@ -1695,11 +1695,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.ARM7BIOS[0], sizeof(NDS::ARM7BIOS));
|
Key1_InitKeycode(false, romparams.GameCode, 3, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
|
||||||
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.ARM7BIOS[0], sizeof(NDS::ARM7BIOS));
|
Key1_InitKeycode(false, romparams.GameCode, 2, 2, NDS.GetARM7BIOS().data(), ARM7BIOSSize);
|
||||||
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");
|
||||||
|
|
|
@ -395,8 +395,8 @@ bool EmuThread::UpdateConsole(UpdateConsoleNDSArgs&& ndsargs, UpdateConsoleGBAAr
|
||||||
};
|
};
|
||||||
NDS->SetJITArgs(Config::JIT_Enable ? std::make_optional(jitargs) : std::nullopt);
|
NDS->SetJITArgs(Config::JIT_Enable ? std::make_optional(jitargs) : std::nullopt);
|
||||||
#endif
|
#endif
|
||||||
NDS->ARM7BIOS = *arm7bios;
|
NDS->SetARM7BIOS(*arm7bios);
|
||||||
NDS->ARM9BIOS = *arm9bios;
|
NDS->SetARM9BIOS(*arm9bios);
|
||||||
NDS->SetFirmware(std::move(*firmware));
|
NDS->SetFirmware(std::move(*firmware));
|
||||||
NDS->SetNDSCart(std::move(nextndscart));
|
NDS->SetNDSCart(std::move(nextndscart));
|
||||||
NDS->SPU.SetInterpolation(static_cast<AudioInterpolation>(Config::AudioInterp));
|
NDS->SPU.SetInterpolation(static_cast<AudioInterpolation>(Config::AudioInterp));
|
||||||
|
|
Loading…
Reference in New Issue