diff options
author | Jesse Talavera <jesse@jesse.tg> | 2023-12-15 08:54:41 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-15 14:54:41 +0100 |
commit | 24c402af51fe9c0537582173fc48d1ad3daff459 (patch) | |
tree | 854213830c1565e0fd40571c80294741822a2d21 | |
parent | c867a7f1c09b3c5f07e0772fcddabce07bcd7fe7 (diff) |
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
-rw-r--r-- | src/ARMJIT.cpp | 4 | ||||
-rw-r--r-- | src/MemConstants.h | 2 | ||||
-rw-r--r-- | src/NDS.cpp | 18 | ||||
-rw-r--r-- | src/NDS.h | 24 | ||||
-rw-r--r-- | src/NDSCart.cpp | 12 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 4 |
6 files changed, 49 insertions, 15 deletions
diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 5e0e207..c3fcba2 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -63,12 +63,12 @@ const u32 CodeRegionSizes[ARMJIT_Memory::memregions_Count] = 0, ITCMPhysicalSize, 0, - sizeof(NDS::ARM9BIOS), + ARM9BIOSSize, MainRAMMaxSize, SharedWRAMSize, 0, 0x100000, - sizeof(NDS::ARM7BIOS), + ARM7BIOSSize, ARM7WRAMSize, 0, 0, diff --git a/src/MemConstants.h b/src/MemConstants.h index 4cf2d36..e9aa6b2 100644 --- a/src/MemConstants.h +++ b/src/MemConstants.h @@ -32,6 +32,8 @@ constexpr u32 ARM7BIOSSize = 0x4000; constexpr u32 DSiBIOSSize = 0x10000; constexpr u32 ITCMPhysicalSize = 0x8000; constexpr u32 DTCMPhysicalSize = 0x4000; +constexpr u32 ARM7BIOSCRC32 = 0x1280f0d5; +constexpr u32 ARM9BIOSCRC32 = 0x2ab23573; } #endif // MELONDS_MEMCONSTANTS_H
\ No newline at end of file diff --git a/src/NDS.cpp b/src/NDS.cpp index 4fa5eef..ed68b68 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -92,6 +92,8 @@ NDS::NDS(NDSArgs&& args, int type) noexcept : ConsoleType(type), ARM7BIOS(args.ARM7BIOS), ARM9BIOS(args.ARM9BIOS), + ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32), + ARM9BIOSNative(CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32), JIT(*this, args.JIT), SPU(*this, args.BitDepth, args.Interpolation), GPU(*this, std::move(args.Renderer3D)), @@ -270,7 +272,7 @@ bool NDS::NeedsDirectBoot() const return true; // FreeBIOS requires direct boot (it can't boot firmware) - if (IsLoadedARM7BIOSBuiltIn() || IsLoadedARM9BIOSBuiltIn()) + if (!IsLoadedARM9BIOSKnownNative() || !IsLoadedARM7BIOSKnownNative()) return true; 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 // Games need this for DS<->GBA comm to work - if (IsLoadedARM9BIOSBuiltIn()) + if (!IsLoadedARM9BIOSKnownNative()) { memcpy(ARM9BIOS.data() + 0x20, header.NintendoLogo, 0x9C); } @@ -756,6 +758,18 @@ void NDS::LoadBIOS() 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 minEvent = UINT64_MAX; @@ -39,6 +39,7 @@ #include "MemRegion.h" #include "ARMJIT_Memory.h" #include "ARM.h" +#include "CRC32.h" #include "DMA.h" #include "FreeBIOS.h" @@ -227,7 +228,7 @@ private: bool EnableJIT; #endif -public: +public: // TODO: Encapsulate the rest of these members int ConsoleType; int CurCPU; @@ -261,8 +262,14 @@ public: u8 ROMSeed0[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, ARM7BIOSSize> ARM7BIOS; + bool ARM9BIOSNative; + bool ARM7BIOSNative; +public: // TODO: Encapsulate the rest of these members u16 ARM7BIOSProt; u8* MainRAM; @@ -310,8 +317,19 @@ public: void SetARM7RegionTimings(u32 addrstart, u32 addrend, u32 region, int buswidth, int nonseq, int seq); 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]] const NDSCart::CartCommon* GetNDSCart() const { return NDSCartSlot.GetCart(); } diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 4474f97..1f2fe69 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -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 { - if (!NDS.IsLoadedARM7BIOSBuiltIn()) + if (NDS.IsLoadedARM7BIOSKnownNative()) { u32 expected_bios_length = dsi ? 0x10000 : 0x4000; if (biosLength != expected_bios_length) @@ -261,7 +261,7 @@ int CartCommon::ROMCommandStart(NDS& nds, NDSCartSlot& cartslot, const u8* cmd, case 0x3C: 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; return 0; @@ -1540,10 +1540,10 @@ void NDSCartSlot::DecryptSecureArea(u8* out) noexcept 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_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) 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); - 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) 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]); Log(LogLevel::Debug, "Re-encrypted cart secure area\n"); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 3eb5db0..ba5fecb 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -395,8 +395,8 @@ bool EmuThread::UpdateConsole(UpdateConsoleNDSArgs&& ndsargs, UpdateConsoleGBAAr }; NDS->SetJITArgs(Config::JIT_Enable ? std::make_optional(jitargs) : std::nullopt); #endif - NDS->ARM7BIOS = *arm7bios; - NDS->ARM9BIOS = *arm9bios; + NDS->SetARM7BIOS(*arm7bios); + NDS->SetARM9BIOS(*arm9bios); NDS->SetFirmware(std::move(*firmware)); NDS->SetNDSCart(std::move(nextndscart)); NDS->SPU.SetInterpolation(static_cast<AudioInterpolation>(Config::AudioInterp)); |