From 88072a02c523e26390af6bd726608b3e567f996f Mon Sep 17 00:00:00 2001 From: Jesse Talavera-Greenberg Date: Thu, 9 Nov 2023 12:57:16 -0500 Subject: [PATCH] Move NDSCart-related global state into objects (#1871) * Move NDSCart-related global state into objects - RAII will now do the heavy lifting - Mark some methods as const or noexcept * Move GBACart-related global state into objects (#1870) - RAII will now do the heavy lifting - Mark some methods as const or noexcept - Once the `NDS` object is finalized, most of these `assert`s can go away * Make AREngine::RunCheat public (#1872) - I use it directly in melonDS DS to apply single cheats without using ARCodeFile - Before the AREngine refactor I could just redeclare the function in my code - Now I can't --- src/ARMJIT_Memory.cpp | 7 +- src/DSi.cpp | 16 +- src/NDS.cpp | 288 +++++++++++++------------- src/NDS.h | 2 + src/NDSCart.cpp | 151 +++++--------- src/NDSCart.h | 178 +++++++++------- src/frontend/qt_sdl/ROMInfoDialog.cpp | 4 +- 7 files changed, 324 insertions(+), 322 deletions(-) diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index b1673abc..095fb301 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -1248,6 +1248,11 @@ T VRAMRead(u32 addr) } } +u32 NDSCartSlot_ReadROMData() +{ // TODO: Add a NDS* parameter, when NDS* is eventually implemented + return NDS::NDSCartSlot->ReadROMData(); +} + void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) { if (cpu->Num == 0) @@ -1256,7 +1261,7 @@ void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) { case 0x04000000: if (!store && size == 32 && addr == 0x04100010 && NDS::ExMemCnt[0] & (1<<11)) - return (void*)NDSCart::ReadROMData; + return (void*)NDSCartSlot_ReadROMData; /* unfortunately we can't map GPU2D this way diff --git a/src/DSi.cpp b/src/DSi.cpp index 8ea26c5f..bf7748e2 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -193,7 +193,7 @@ void Reset() SCFG_Clock7 = 0x0187; SCFG_EXT[0] = 0x8307F100; SCFG_EXT[1] = 0x93FFFB06; - SCFG_MC = 0x0010 | (~((u32)(NDSCart::Cart != nullptr))&1);//0x0011; + SCFG_MC = 0x0010 | (~((u32)(NDS::NDSCartSlot->GetCart() != nullptr))&1);//0x0011; SCFG_RST = 0; DSP->SetRstLine(false); @@ -310,13 +310,13 @@ void DecryptModcryptArea(u32 offset, u32 size, u8* iv) if ((offset == 0) || (size == 0)) return; - const NDSHeader& header = NDSCart::Cart->GetHeader(); + const NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader(); if ((header.DSiCryptoFlags & (1<<4)) || (header.AppFlags & (1<<7))) { // dev key - const u8* cartrom = NDSCart::Cart->GetROM(); + const u8* cartrom = NDS::NDSCartSlot->GetCart()->GetROM(); memcpy(key, &cartrom[0], 16); } else @@ -403,9 +403,9 @@ void DecryptModcryptArea(u32 offset, u32 size, u8* iv) void SetupDirectBoot() { bool dsmode = false; - NDSHeader& header = NDSCart::Cart->GetHeader(); - const u8* cartrom = NDSCart::Cart->GetROM(); - u32 cartid = NDSCart::Cart->ID(); + NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader(); + const u8* cartrom = NDS::NDSCartSlot->GetCart()->GetROM(); + u32 cartid = NDS::NDSCartSlot->GetCart()->ID(); DSi_TSC* tsc = (DSi_TSC*)NDS::SPI->GetTSC(); // TODO: add controls for forcing DS or DSi mode? @@ -594,7 +594,7 @@ void SetupDirectBoot() if (header.ARM9ROMOffset >= 0x4000 && header.ARM9ROMOffset < 0x8000) { u8 securearea[0x800]; - NDSCart::DecryptSecureArea(securearea); + NDS::NDSCartSlot->DecryptSecureArea(securearea); for (u32 i = 0; i < 0x800; i+=4) { @@ -1289,7 +1289,7 @@ void Set_SCFG_MC(u32 val) if ((oldslotstatus == 0x0) && ((SCFG_MC & 0xC) == 0x4)) { - NDSCart::ResetCart(); + NDS::NDSCartSlot->ResetCart(); } } diff --git a/src/NDS.cpp b/src/NDS.cpp index 8eca7154..79359290 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -183,6 +183,7 @@ class SPU* SPU; class SPIHost* SPI; class RTC* RTC; class Wifi* Wifi; +std::unique_ptr NDSCartSlot; std::unique_ptr GBACartSlot; class AREngine* AREngine; @@ -227,9 +228,8 @@ bool Init() SPI = new class SPIHost(); RTC = new class RTC(); Wifi = new class Wifi(); + NDSCartSlot = std::make_unique(); GBACartSlot = std::make_unique(); - - if (!NDSCart::Init()) return false; if (!GPU::Init()) return false; if (!DSi::Init()) return false; @@ -259,7 +259,7 @@ void DeInit() delete RTC; RTC = nullptr; delete Wifi; Wifi = nullptr; - NDSCart::DeInit(); + NDSCartSlot = nullptr; GBACartSlot = nullptr; GPU::DeInit(); @@ -405,7 +405,7 @@ bool NeedsDirectBoot() void SetupDirectBoot(const std::string& romname) { - const NDSHeader& header = NDSCart::Cart->GetHeader(); + const NDSHeader& header = NDSCartSlot->GetCart()->GetHeader(); if (ConsoleType == 1) { @@ -413,8 +413,8 @@ void SetupDirectBoot(const std::string& romname) } else { - u32 cartid = NDSCart::Cart->ID(); - const u8* cartrom = NDSCart::Cart->GetROM(); + u32 cartid = NDSCartSlot->GetCart()->ID(); + const u8* cartrom = NDSCartSlot->GetCart()->GetROM(); MapSharedWRAM(3); // setup main RAM data @@ -447,7 +447,7 @@ void SetupDirectBoot(const std::string& romname) if (header.ARM9ROMOffset >= 0x4000 && header.ARM9ROMOffset < 0x8000) { u8 securearea[0x800]; - NDSCart::DecryptSecureArea(securearea); + NDSCartSlot->DecryptSecureArea(securearea); for (u32 i = 0; i < 0x800; i+=4) { @@ -500,7 +500,7 @@ void SetupDirectBoot(const std::string& romname) ARM9->CP15Write(0x911, 0x00000020); } - NDSCart::SetupDirectBoot(romname); + NDSCartSlot->SetupDirectBoot(romname); ARM9->R[12] = header.ARM9EntryAddress; ARM9->R[13] = 0x03002F7C; @@ -526,7 +526,7 @@ void SetupDirectBoot(const std::string& romname) // checkme RCnt = 0x8000; - NDSCart::SPICnt = 0x8000; + NDSCartSlot->SetSPICnt(0x8000); SPU->SetBias(0x200); @@ -644,7 +644,7 @@ void Reset() KeyCnt[1] = 0; RCnt = 0; - NDSCart::Reset(); + NDSCartSlot->Reset(); GBACartSlot->Reset(); GPU::Reset(); SPU->Reset(); @@ -845,7 +845,7 @@ bool DoSavestate(Savestate* file) ARM9->DoSavestate(file); ARM7->DoSavestate(file); - NDSCart::DoSavestate(file); + NDSCartSlot->DoSavestate(file); if (ConsoleType == 0) GBACartSlot->DoSavestate(file); GPU::DoSavestate(file); @@ -885,11 +885,11 @@ void SetConsoleType(int type) bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) { - if (!NDSCart::LoadROM(romdata, romlen)) + if (!NDSCartSlot->LoadROM(romdata, romlen)) return false; if (savedata && savelen) - NDSCart::LoadSave(savedata, savelen); + NDSCartSlot->LoadSave(savedata, savelen); return true; } @@ -897,17 +897,17 @@ bool LoadCart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) void LoadSave(const u8* savedata, u32 savelen) { if (savedata && savelen) - NDSCart::LoadSave(savedata, savelen); + NDSCartSlot->LoadSave(savedata, savelen); } void EjectCart() { - NDSCart::EjectCart(); + NDSCartSlot->EjectCart(); } bool CartInserted() { - return NDSCart::Cart != nullptr; + return NDSCartSlot->GetCart() != nullptr; } bool LoadGBACart(const u8* romdata, u32 romlen, const u8* savedata, u32 savelen) @@ -1741,9 +1741,9 @@ void MonitorARM9Jump(u32 addr) // checkme: can the entrypoint addr be THUMB? // also TODO: make it work in DSi mode - if ((!RunningGame) && NDSCart::Cart) + if ((!RunningGame) && NDSCartSlot->GetCart()) { - const NDSHeader& header = NDSCart::Cart->GetHeader(); + const NDSHeader& header = NDSCartSlot->GetCart()->GetHeader(); if (addr == header.ARM9EntryAddress) { Log(LogLevel::Info, "Game is now booting\n"); @@ -3035,40 +3035,40 @@ u8 ARM9IORead8(u32 addr) case 0x040001A2: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ReadSPIData(); + return NDSCartSlot->ReadSPIData(); return 0; case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[0]; + return NDSCartSlot->GetROMCommand(0); return 0; case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[1]; + return NDSCartSlot->GetROMCommand(1); return 0; case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[2]; + return NDSCartSlot->GetROMCommand(2); return 0; case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[3]; + return NDSCartSlot->GetROMCommand(3); return 0; case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[4]; + return NDSCartSlot->GetROMCommand(4); return 0; case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[5]; + return NDSCartSlot->GetROMCommand(5); return 0; case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[6]; + return NDSCartSlot->GetROMCommand(6); return 0; case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[7]; + return NDSCartSlot->GetROMCommand(7); return 0; case 0x04000208: return IME[0]; @@ -3182,32 +3182,32 @@ u16 ARM9IORead16(u32 addr) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::SPICnt; + return NDSCartSlot->GetSPICnt(); return 0; case 0x040001A2: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ReadSPIData(); + return NDSCartSlot->ReadSPIData(); return 0; case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[0] | - (NDSCart::ROMCommand[1] << 8); + return NDSCartSlot->GetROMCommand(0) | + (NDSCartSlot->GetROMCommand(1) << 8); return 0; case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[2] | - (NDSCart::ROMCommand[3] << 8); + return NDSCartSlot->GetROMCommand(2) | + (NDSCartSlot->GetROMCommand(3) << 8); return 0; case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[4] | - (NDSCart::ROMCommand[5] << 8); + return NDSCartSlot->GetROMCommand(4) | + (NDSCartSlot->GetROMCommand(5) << 8); return 0; case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[6] | - (NDSCart::ROMCommand[7] << 8); + return NDSCartSlot->GetROMCommand(6) | + (NDSCartSlot->GetROMCommand(7) << 8); return 0; case 0x04000204: return ExMemCnt[0]; @@ -3316,26 +3316,26 @@ u32 ARM9IORead32(u32 addr) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); + return NDSCartSlot->GetSPICnt() | (NDSCartSlot->ReadSPIData() << 16); return 0; case 0x040001A4: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCnt; + return NDSCartSlot->GetROMCnt(); return 0; case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[0] | - (NDSCart::ROMCommand[1] << 8) | - (NDSCart::ROMCommand[2] << 16) | - (NDSCart::ROMCommand[3] << 24); + return NDSCartSlot->GetROMCommand(0) | + (NDSCartSlot->GetROMCommand(1) << 8) | + (NDSCartSlot->GetROMCommand(2) << 16) | + (NDSCartSlot->GetROMCommand(3) << 24); return 0; case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) - return NDSCart::ROMCommand[4] | - (NDSCart::ROMCommand[5] << 8) | - (NDSCart::ROMCommand[6] << 16) | - (NDSCart::ROMCommand[7] << 24); + return NDSCartSlot->GetROMCommand(4) | + (NDSCartSlot->GetROMCommand(5) << 8) | + (NDSCartSlot->GetROMCommand(6) << 16) | + (NDSCartSlot->GetROMCommand(7) << 24); return 0; case 0x04000208: return IME[0]; @@ -3386,7 +3386,7 @@ u32 ARM9IORead32(u32 addr) return IPCFIFO7.Peek(); case 0x04100010: - if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData(); + if (!(ExMemCnt[0] & (1<<11))) return NDSCartSlot->ReadROMData(); return 0; case 0x04004000: @@ -3441,25 +3441,25 @@ void ARM9IOWrite8(u32 addr, u8 val) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) - NDSCart::WriteSPICnt((NDSCart::SPICnt & 0xFF00) | val); + NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0xFF00) | val); return; case 0x040001A1: if (!(ExMemCnt[0] & (1<<11))) - NDSCart::WriteSPICnt((NDSCart::SPICnt & 0x00FF) | (val << 8)); + NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0x00FF) | (val << 8)); return; case 0x040001A2: if (!(ExMemCnt[0] & (1<<11))) - NDSCart::WriteSPIData(val); + NDSCartSlot->WriteSPIData(val); return; - case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[0] = val; return; - case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[1] = val; return; - case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[2] = val; return; - case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[3] = val; return; - case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[4] = val; return; - case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[5] = val; return; - case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[6] = val; return; - case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) NDSCart::ROMCommand[7] = val; return; + case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(0, val); return; + case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(1, val); return; + case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(2, val); return; + case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(3, val); return; + case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(4, val); return; + case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(5, val); return; + case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(6, val); return; + case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->SetROMCommand(7, val); return; case 0x04000208: IME[0] = val & 0x1; UpdateIRQ(0); return; @@ -3574,39 +3574,39 @@ void ARM9IOWrite16(u32 addr, u16 val) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) - NDSCart::WriteSPICnt(val); + NDSCartSlot->WriteSPICnt(val); return; case 0x040001A2: if (!(ExMemCnt[0] & (1<<11))) - NDSCart::WriteSPIData(val & 0xFF); + NDSCartSlot->WriteSPIData(val & 0xFF); return; case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::ROMCommand[0] = val & 0xFF; - NDSCart::ROMCommand[1] = val >> 8; + NDSCartSlot->SetROMCommand(0, val & 0xFF); + NDSCartSlot->SetROMCommand(1, val >> 8); } return; case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::ROMCommand[2] = val & 0xFF; - NDSCart::ROMCommand[3] = val >> 8; + NDSCartSlot->SetROMCommand(2, val & 0xFF); + NDSCartSlot->SetROMCommand(3, val >> 8); } return; case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::ROMCommand[4] = val & 0xFF; - NDSCart::ROMCommand[5] = val >> 8; + NDSCartSlot->SetROMCommand(4, val & 0xFF); + NDSCartSlot->SetROMCommand(5, val >> 8); } return; case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::ROMCommand[6] = val & 0xFF; - NDSCart::ROMCommand[7] = val >> 8; + NDSCartSlot->SetROMCommand(6, val & 0xFF); + NDSCartSlot->SetROMCommand(7, val >> 8); } return; @@ -3760,31 +3760,31 @@ void ARM9IOWrite32(u32 addr, u32 val) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::WriteSPICnt(val & 0xFFFF); - NDSCart::WriteSPIData((val >> 16) & 0xFF); + NDSCartSlot->WriteSPICnt(val & 0xFFFF); + NDSCartSlot->WriteSPIData((val >> 16) & 0xFF); } return; case 0x040001A4: if (!(ExMemCnt[0] & (1<<11))) - NDSCart::WriteROMCnt(val); + NDSCartSlot->WriteROMCnt(val); return; case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::ROMCommand[0] = val & 0xFF; - NDSCart::ROMCommand[1] = (val >> 8) & 0xFF; - NDSCart::ROMCommand[2] = (val >> 16) & 0xFF; - NDSCart::ROMCommand[3] = val >> 24; + NDSCartSlot->SetROMCommand(0, val & 0xFF); + NDSCartSlot->SetROMCommand(1, (val >> 8) & 0xFF); + NDSCartSlot->SetROMCommand(2, (val >> 16) & 0xFF); + NDSCartSlot->SetROMCommand(3, val >> 24); } return; case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::ROMCommand[4] = val & 0xFF; - NDSCart::ROMCommand[5] = (val >> 8) & 0xFF; - NDSCart::ROMCommand[6] = (val >> 16) & 0xFF; - NDSCart::ROMCommand[7] = val >> 24; + NDSCartSlot->SetROMCommand(4, val & 0xFF); + NDSCartSlot->SetROMCommand(5, (val >> 8) & 0xFF); + NDSCartSlot->SetROMCommand(6, (val >> 16) & 0xFF); + NDSCartSlot->SetROMCommand(7, val >> 24); } return; @@ -3830,7 +3830,7 @@ void ARM9IOWrite32(u32 addr, u32 val) return; case 0x04100010: - if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteROMData(val); + if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot->WriteROMData(val); return; // NO$GBA debug register "String Out (raw)" @@ -3899,40 +3899,40 @@ u8 ARM7IORead8(u32 addr) case 0x040001A2: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ReadSPIData(); + return NDSCartSlot->ReadSPIData(); return 0; case 0x040001A8: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[0]; + return NDSCartSlot->GetROMCommand(0); return 0; case 0x040001A9: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[1]; + return NDSCartSlot->GetROMCommand(1); return 0; case 0x040001AA: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[2]; + return NDSCartSlot->GetROMCommand(2); return 0; case 0x040001AB: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[3]; + return NDSCartSlot->GetROMCommand(3); return 0; case 0x040001AC: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[4]; + return NDSCartSlot->GetROMCommand(4); return 0; case 0x040001AD: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[5]; + return NDSCartSlot->GetROMCommand(5); return 0; case 0x040001AE: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[6]; + return NDSCartSlot->GetROMCommand(6); return 0; case 0x040001AF: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[7]; + return NDSCartSlot->GetROMCommand(7); return 0; case 0x040001C2: return SPI->ReadData(); @@ -3999,28 +3999,28 @@ u16 ARM7IORead16(u32 addr) return val; } - case 0x040001A0: if (ExMemCnt[0] & (1<<11)) return NDSCart::SPICnt; return 0; - case 0x040001A2: if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadSPIData(); return 0; + case 0x040001A0: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot->GetSPICnt(); return 0; + case 0x040001A2: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot->ReadSPIData(); return 0; case 0x040001A8: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[0] | - (NDSCart::ROMCommand[1] << 8); + return NDSCartSlot->GetROMCommand(0) | + (NDSCartSlot->GetROMCommand(1) << 8); return 0; case 0x040001AA: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[2] | - (NDSCart::ROMCommand[3] << 8); + return NDSCartSlot->GetROMCommand(2) | + (NDSCartSlot->GetROMCommand(3) << 8); return 0; case 0x040001AC: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[4] | - (NDSCart::ROMCommand[5] << 8); + return NDSCartSlot->GetROMCommand(4) | + (NDSCartSlot->GetROMCommand(5) << 8); return 0; case 0x040001AE: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[6] | - (NDSCart::ROMCommand[7] << 8); + return NDSCartSlot->GetROMCommand(6) | + (NDSCartSlot->GetROMCommand(7) << 8); return 0; case 0x040001C0: return SPI->ReadCnt(); @@ -4083,26 +4083,26 @@ u32 ARM7IORead32(u32 addr) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) - return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); + return NDSCartSlot->GetSPICnt() | (NDSCartSlot->ReadSPIData() << 16); return 0; case 0x040001A4: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCnt; + return NDSCartSlot->GetROMCnt(); return 0; case 0x040001A8: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[0] | - (NDSCart::ROMCommand[1] << 8) | - (NDSCart::ROMCommand[2] << 16) | - (NDSCart::ROMCommand[3] << 24); + return NDSCartSlot->GetROMCommand(0) | + (NDSCartSlot->GetROMCommand(1) << 8) | + (NDSCartSlot->GetROMCommand(2) << 16) | + (NDSCartSlot->GetROMCommand(3) << 24); return 0; case 0x040001AC: if (ExMemCnt[0] & (1<<11)) - return NDSCart::ROMCommand[4] | - (NDSCart::ROMCommand[5] << 8) | - (NDSCart::ROMCommand[6] << 16) | - (NDSCart::ROMCommand[7] << 24); + return NDSCartSlot->GetROMCommand(4) | + (NDSCartSlot->GetROMCommand(5) << 8) | + (NDSCartSlot->GetROMCommand(6) << 16) | + (NDSCartSlot->GetROMCommand(7) << 24); return 0; case 0x040001C0: @@ -4137,7 +4137,7 @@ u32 ARM7IORead32(u32 addr) return IPCFIFO9.Peek(); case 0x04100010: - if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData(); + if (ExMemCnt[0] & (1<<11)) return NDSCartSlot->ReadROMData(); return 0; } @@ -4177,26 +4177,26 @@ void ARM7IOWrite8(u32 addr, u8 val) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) { - NDSCart::WriteSPICnt((NDSCart::SPICnt & 0xFF00) | val); + NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0xFF00) | val); } return; case 0x040001A1: if (ExMemCnt[0] & (1<<11)) - NDSCart::WriteSPICnt((NDSCart::SPICnt & 0x00FF) | (val << 8)); + NDSCartSlot->WriteSPICnt((NDSCartSlot->GetSPICnt() & 0x00FF) | (val << 8)); return; case 0x040001A2: if (ExMemCnt[0] & (1<<11)) - NDSCart::WriteSPIData(val); + NDSCartSlot->WriteSPIData(val); return; - case 0x040001A8: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[0] = val; return; - case 0x040001A9: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[1] = val; return; - case 0x040001AA: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[2] = val; return; - case 0x040001AB: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[3] = val; return; - case 0x040001AC: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[4] = val; return; - case 0x040001AD: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[5] = val; return; - case 0x040001AE: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[6] = val; return; - case 0x040001AF: if (ExMemCnt[0] & (1<<11)) NDSCart::ROMCommand[7] = val; return; + case 0x040001A8: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(0, val); return; + case 0x040001A9: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(1, val); return; + case 0x040001AA: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(2, val); return; + case 0x040001AB: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(3, val); return; + case 0x040001AC: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(4, val); return; + case 0x040001AD: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(5, val); return; + case 0x040001AE: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(6, val); return; + case 0x040001AF: if (ExMemCnt[0] & (1<<11)) NDSCartSlot->SetROMCommand(7, val); return; case 0x040001C2: SPI->WriteData(val); @@ -4287,39 +4287,39 @@ void ARM7IOWrite16(u32 addr, u16 val) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) - NDSCart::WriteSPICnt(val); + NDSCartSlot->WriteSPICnt(val); return; case 0x040001A2: if (ExMemCnt[0] & (1<<11)) - NDSCart::WriteSPIData(val & 0xFF); + NDSCartSlot->WriteSPIData(val & 0xFF); return; case 0x040001A8: if (ExMemCnt[0] & (1<<11)) { - NDSCart::ROMCommand[0] = val & 0xFF; - NDSCart::ROMCommand[1] = val >> 8; + NDSCartSlot->SetROMCommand(0, val & 0xFF); + NDSCartSlot->SetROMCommand(1, val >> 8); } return; case 0x040001AA: if (ExMemCnt[0] & (1<<11)) { - NDSCart::ROMCommand[2] = val & 0xFF; - NDSCart::ROMCommand[3] = val >> 8; + NDSCartSlot->SetROMCommand(2, val & 0xFF); + NDSCartSlot->SetROMCommand(3, val >> 8); } return; case 0x040001AC: if (ExMemCnt[0] & (1<<11)) { - NDSCart::ROMCommand[4] = val & 0xFF; - NDSCart::ROMCommand[5] = val >> 8; + NDSCartSlot->SetROMCommand(4, val & 0xFF); + NDSCartSlot->SetROMCommand(5, val >> 8); } return; case 0x040001AE: if (ExMemCnt[0] & (1<<11)) { - NDSCart::ROMCommand[6] = val & 0xFF; - NDSCart::ROMCommand[7] = val >> 8; + NDSCartSlot->SetROMCommand(6, val & 0xFF); + NDSCartSlot->SetROMCommand(7, val >> 8); } return; @@ -4448,31 +4448,31 @@ void ARM7IOWrite32(u32 addr, u32 val) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) { - NDSCart::WriteSPICnt(val & 0xFFFF); - NDSCart::WriteSPIData((val >> 16) & 0xFF); + NDSCartSlot->WriteSPICnt(val & 0xFFFF); + NDSCartSlot->WriteSPIData((val >> 16) & 0xFF); } return; case 0x040001A4: if (ExMemCnt[0] & (1<<11)) - NDSCart::WriteROMCnt(val); + NDSCartSlot->WriteROMCnt(val); return; case 0x040001A8: if (ExMemCnt[0] & (1<<11)) { - NDSCart::ROMCommand[0] = val & 0xFF; - NDSCart::ROMCommand[1] = (val >> 8) & 0xFF; - NDSCart::ROMCommand[2] = (val >> 16) & 0xFF; - NDSCart::ROMCommand[3] = val >> 24; + NDSCartSlot->SetROMCommand(0, val & 0xFF); + NDSCartSlot->SetROMCommand(1, (val >> 8) & 0xFF); + NDSCartSlot->SetROMCommand(2, (val >> 16) & 0xFF); + NDSCartSlot->SetROMCommand(3, val >> 24); } return; case 0x040001AC: if (ExMemCnt[0] & (1<<11)) { - NDSCart::ROMCommand[4] = val & 0xFF; - NDSCart::ROMCommand[5] = (val >> 8) & 0xFF; - NDSCart::ROMCommand[6] = (val >> 16) & 0xFF; - NDSCart::ROMCommand[7] = val >> 24; + NDSCartSlot->SetROMCommand(4, val & 0xFF); + NDSCartSlot->SetROMCommand(5, (val >> 8) & 0xFF); + NDSCartSlot->SetROMCommand(6, (val >> 16) & 0xFF); + NDSCartSlot->SetROMCommand(7, val >> 24); } return; @@ -4504,7 +4504,7 @@ void ARM7IOWrite32(u32 addr, u32 val) return; case 0x04100010: - if (ExMemCnt[0] & (1<<11)) NDSCart::WriteROMData(val); + if (ExMemCnt[0] & (1<<11)) NDSCartSlot->WriteROMData(val); return; } diff --git a/src/NDS.h b/src/NDS.h index 18054370..127510dd 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -26,6 +26,7 @@ #include "Platform.h" #include "Savestate.h" #include "types.h" +#include "NDSCart.h" #include "GBACart.h" // when touching the main loop/timing code, pls test a lot of shit @@ -259,6 +260,7 @@ extern class SPU* SPU; extern class SPIHost* SPI; extern class RTC* RTC; extern class Wifi* Wifi; +extern std::unique_ptr NDSCartSlot; extern std::unique_ptr GBACartSlot; extern class AREngine* AREngine; diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 4c6efddf..bf2b7913 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -41,36 +41,12 @@ enum // SRAM TODO: emulate write delays??? -u16 SPICnt; -u32 ROMCnt; - -u8 SPIData; -u32 SPIDataPos; -bool SPIHold; - -u8 ROMCommand[8]; -u32 ROMData; - -u8 TransferData[0x4000]; -u32 TransferPos; -u32 TransferLen; -u32 TransferDir; -u8 TransferCmd[8]; - -std::unique_ptr Cart; - -u32 Key1_KeyBuf[0x412]; - -u64 Key2_X; -u64 Key2_Y; - - u32 ByteSwap(u32 val) { return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24); } -void Key1_Encrypt(u32* data) +void NDSCartSlot::Key1_Encrypt(u32* data) noexcept { u32 y = data[0]; u32 x = data[1]; @@ -91,7 +67,7 @@ void Key1_Encrypt(u32* data) data[1] = y ^ Key1_KeyBuf[0x11]; } -void Key1_Decrypt(u32* data) +void NDSCartSlot::Key1_Decrypt(u32* data) noexcept { u32 y = data[0]; u32 x = data[1]; @@ -112,7 +88,7 @@ void Key1_Decrypt(u32* data) data[1] = y ^ Key1_KeyBuf[0x0]; } -void Key1_ApplyKeycode(u32* keycode, u32 mod) +void NDSCartSlot::Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept { Key1_Encrypt(&keycode[1]); Key1_Encrypt(&keycode[0]); @@ -131,7 +107,7 @@ void Key1_ApplyKeycode(u32* keycode, u32 mod) } } -void Key1_LoadKeyBuf(bool dsi, bool externalBios, u8 *bios, u32 biosLength) +void NDSCartSlot::Key1_LoadKeyBuf(bool dsi, bool externalBios, u8 *bios, u32 biosLength) noexcept { if (externalBios) { @@ -146,19 +122,19 @@ void Key1_LoadKeyBuf(bool dsi, bool externalBios, u8 *bios, u32 biosLength) } else { - memcpy(Key1_KeyBuf, bios + (dsi ? 0xC6D0 : 0x0030), 0x1048); + memcpy(Key1_KeyBuf.data(), bios + (dsi ? 0xC6D0 : 0x0030), sizeof(Key1_KeyBuf)); Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf from memory\n"); } } else { // well - memset(Key1_KeyBuf, 0, 0x1048); + memset(Key1_KeyBuf.data(), 0, sizeof(Key1_KeyBuf)); Platform::Log(LogLevel::Debug, "NDSCart: Initialized Key1_KeyBuf to zero\n"); } } -void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod, u8 *bios, u32 biosLength) +void NDSCartSlot::Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod, u8 *bios, u32 biosLength) noexcept { Key1_LoadKeyBuf(dsi, Platform::GetConfigBool(Platform::ExternalBIOSEnable), bios, biosLength); @@ -174,7 +150,7 @@ void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod, u8 *bios, u32 bi } -void Key2_Encrypt(u8* data, u32 len) +void NDSCartSlot::Key2_Encrypt(u8* data, u32 len) noexcept { for (u32 i = 0; i < len; i++) { @@ -260,7 +236,7 @@ void CartCommon::LoadSave(const u8* savedata, u32 savelen) { } -int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len) +int CartCommon::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) { if (CmdEncMode == 0) { @@ -289,7 +265,7 @@ int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len) case 0x3C: CmdEncMode = 1; - Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); + cartslot.Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2, NDS::ARM7BIOS, sizeof(NDS::ARM7BIOS)); DSiMode = false; return 0; @@ -297,7 +273,7 @@ int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len) if (IsDSi) { CmdEncMode = 1; - Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2, DSi::ARM7iBIOS, sizeof(DSi::ARM7iBIOS)); + cartslot.Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2, DSi::ARM7iBIOS, sizeof(DSi::ARM7iBIOS)); DSiMode = true; } return 0; @@ -314,7 +290,7 @@ int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len) u8 cmddec[8]; *(u32*)&cmddec[0] = ByteSwap(*(u32*)&cmd[4]); *(u32*)&cmddec[4] = ByteSwap(*(u32*)&cmd[0]); - Key1_Decrypt((u32*)cmddec); + cartslot.Key1_Decrypt((u32*)cmddec); u32 tmp = ByteSwap(*(u32*)&cmddec[4]); *(u32*)&cmddec[4] = ByteSwap(*(u32*)&cmddec[0]); *(u32*)&cmddec[0] = tmp; @@ -518,9 +494,9 @@ void CartRetail::LoadSave(const u8* savedata, u32 savelen) Platform::WriteNDSSave(savedata, len, 0, len); } -int CartRetail::ROMCommandStart(u8* cmd, u8* data, u32 len) +int CartRetail::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) { - if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cmd, data, len); + if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cartslot, cmd, data, len); switch (cmd[0]) { @@ -541,7 +517,7 @@ int CartRetail::ROMCommandStart(u8* cmd, u8* data, u32 len) return 0; default: - return CartCommon::ROMCommandStart(cmd, data, len); + return CartCommon::ROMCommandStart(cartslot, cmd, data, len); } } @@ -922,9 +898,9 @@ void CartRetailNAND::LoadSave(const u8* savedata, u32 savelen) BuildSRAMID(); } -int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) +int CartRetailNAND::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) { - if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cmd, data, len); + if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cartslot, cmd, data, len); switch (cmd[0]) { @@ -1054,7 +1030,7 @@ int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) return 0; default: - return CartRetail::ROMCommandStart(cmd, data, len); + return CartRetail::ROMCommandStart(cartslot, cmd, data, len); } } @@ -1272,9 +1248,9 @@ void CartHomebrew::DoSavestate(Savestate* file) CartCommon::DoSavestate(file); } -int CartHomebrew::ROMCommandStart(u8* cmd, u8* data, u32 len) +int CartHomebrew::ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) { - if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cmd, data, len); + if (CmdEncMode != 2) return CartCommon::ROMCommandStart(cartslot, cmd, data, len); switch (cmd[0]) { @@ -1305,7 +1281,7 @@ int CartHomebrew::ROMCommandStart(u8* cmd, u8* data, u32 len) return 1; default: - return CartCommon::ROMCommandStart(cmd, data, len); + return CartCommon::ROMCommandStart(cartslot, cmd, data, len); } } @@ -1471,32 +1447,29 @@ void CartHomebrew::ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset) -bool Init() +NDSCartSlot::NDSCartSlot() noexcept { - NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData, ROMPrepareData); - NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End, ROMEndTransfer); - NDS::RegisterEventFunc(NDS::Event_ROMSPITransfer, 0, SPITransferDone); - - Cart = nullptr; - - return true; + NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData, MemberEventFunc(NDSCartSlot, ROMPrepareData)); + NDS::RegisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End, MemberEventFunc(NDSCartSlot, ROMEndTransfer)); + NDS::RegisterEventFunc(NDS::Event_ROMSPITransfer, 0, MemberEventFunc(NDSCartSlot, SPITransferDone)); + // All fields are default-constructed because they're listed as such in the class declaration } -void DeInit() +NDSCartSlot::~NDSCartSlot() noexcept { - Cart = nullptr; - NDS::UnregisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_PrepareData); NDS::UnregisterEventFunc(NDS::Event_ROMTransfer, ROMTransfer_End); NDS::UnregisterEventFunc(NDS::Event_ROMSPITransfer, 0); + + // Cart is cleaned up automatically because it's a unique_ptr } -void Reset() +void NDSCartSlot::Reset() noexcept { ResetCart(); } -void DoSavestate(Savestate* file) +void NDSCartSlot::DoSavestate(Savestate* file) noexcept { file->Section("NDSC"); @@ -1507,14 +1480,14 @@ void DoSavestate(Savestate* file) file->Var32(&SPIDataPos); file->Bool32(&SPIHold); - file->VarArray(ROMCommand, 8); + file->VarArray(ROMCommand.data(), sizeof(ROMCommand)); file->Var32(&ROMData); - file->VarArray(TransferData, 0x4000); + file->VarArray(TransferData.data(), sizeof(TransferData)); file->Var32(&TransferPos); file->Var32(&TransferLen); file->Var32(&TransferDir); - file->VarArray(TransferCmd, 8); + file->VarArray(TransferCmd.data(), sizeof(TransferCmd)); // cart inserted/len/ROM/etc should be already populated // savestate should be loaded after the right game is loaded @@ -1589,7 +1562,7 @@ bool ReadROMParams(u32 gamecode, ROMListEntry* params) } -void DecryptSecureArea(u8* out) +void NDSCartSlot::DecryptSecureArea(u8* out) noexcept { const NDSHeader& header = Cart->GetHeader(); const u8* cartrom = Cart->GetROM(); @@ -1741,7 +1714,7 @@ std::unique_ptr ParseROM(const u8* romdata, u32 romlen) return cart; } -bool InsertROM(std::unique_ptr&& cart) +bool NDSCartSlot::InsertROM(std::unique_ptr&& cart) noexcept { if (!cart) { Log(LogLevel::Error, "Failed to insert invalid cart; existing cart (if any) was not ejected.\n"); @@ -1793,36 +1766,26 @@ bool InsertROM(std::unique_ptr&& cart) return true; } -bool LoadROM(const u8* romdata, u32 romlen) +bool NDSCartSlot::LoadROM(const u8* romdata, u32 romlen) noexcept { std::unique_ptr cart = ParseROM(romdata, romlen); return InsertROM(std::move(cart)); } -void LoadSave(const u8* savedata, u32 savelen) +void NDSCartSlot::LoadSave(const u8* savedata, u32 savelen) noexcept { if (Cart) Cart->LoadSave(savedata, savelen); } -void SetupDirectBoot(const std::string& romname) +void NDSCartSlot::SetupDirectBoot(const std::string& romname) noexcept { if (Cart) Cart->SetupDirectBoot(romname); } -u8* GetSaveMemory() -{ - return Cart ? Cart->GetSaveMemory() : nullptr; -} - -u32 GetSaveMemoryLength() -{ - return Cart ? Cart->GetSaveMemoryLength() : 0; -} - -void EjectCart() +void NDSCartSlot::EjectCart() noexcept { if (!Cart) return; @@ -1837,7 +1800,7 @@ void EjectCart() // CHECKME: does an eject imply anything for the ROM/SPI transfer registers? } -void ResetCart() +void NDSCartSlot::ResetCart() noexcept { // CHECKME: what if there is a transfer in progress? @@ -1848,24 +1811,24 @@ void ResetCart() SPIDataPos = 0; SPIHold = false; - memset(ROMCommand, 0, 8); + memset(ROMCommand.data(), 0, sizeof(ROMCommand)); ROMData = 0; Key2_X = 0; Key2_Y = 0; - memset(TransferData, 0, 0x4000); + memset(TransferData.data(), 0, sizeof(TransferData)); TransferPos = 0; TransferLen = 0; TransferDir = 0; - memset(TransferCmd, 0, 8); + memset(TransferCmd.data(), 0, sizeof(TransferCmd)); TransferCmd[0] = 0xFF; if (Cart) Cart->Reset(); } -void ROMEndTransfer(u32 param) +void NDSCartSlot::ROMEndTransfer(u32 param) noexcept { ROMCnt &= ~(1<<31); @@ -1873,10 +1836,10 @@ void ROMEndTransfer(u32 param) NDS::SetIRQ((NDS::ExMemCnt[0]>>11)&0x1, NDS::IRQ_CartXferDone); if (Cart) - Cart->ROMCommandFinish(TransferCmd, TransferData, TransferLen); + Cart->ROMCommandFinish(TransferCmd.data(), TransferData.data(), TransferLen); } -void ROMPrepareData(u32 param) +void NDSCartSlot::ROMPrepareData(u32 param) noexcept { if (TransferDir == 0) { @@ -1896,7 +1859,7 @@ void ROMPrepareData(u32 param) NDS::CheckDMAs(0, 0x05); } -void WriteROMCnt(u32 val) +void NDSCartSlot::WriteROMCnt(u32 val) noexcept { u32 xferstart = (val & ~ROMCnt) & (1<<31); ROMCnt = (val & 0xFF7F7FFF) | (ROMCnt & 0x20800000); @@ -1941,7 +1904,7 @@ void WriteROMCnt(u32 val) *(u32*)&TransferCmd[0] = *(u32*)&ROMCommand[0]; *(u32*)&TransferCmd[4] = *(u32*)&ROMCommand[4]; - memset(TransferData, 0xFF, TransferLen); + memset(TransferData.data(), 0xFF, TransferLen); /*printf("ROM COMMAND %04X %08X %02X%02X%02X%02X%02X%02X%02X%02X SIZE %04X\n", SPICnt, ROMCnt, @@ -1954,7 +1917,7 @@ void WriteROMCnt(u32 val) TransferDir = 0; if (Cart) - TransferDir = Cart->ROMCommandStart(TransferCmd, TransferData, TransferLen); + TransferDir = Cart->ROMCommandStart(*this, TransferCmd.data(), TransferData.data(), TransferLen); if ((datasize > 0) && (((ROMCnt >> 30) & 0x1) != TransferDir)) Log(LogLevel::Debug, "NDSCART: !! BAD TRANSFER DIRECTION FOR CMD %02X, DIR=%d, ROMCNT=%08X\n", ROMCommand[0], TransferDir, ROMCnt); @@ -1985,7 +1948,7 @@ void WriteROMCnt(u32 val) NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*(cmddelay+4), ROMTransfer_PrepareData, 0); } -void AdvanceROMTransfer() +void NDSCartSlot::AdvanceROMTransfer() noexcept { ROMCnt &= ~(1<<23); @@ -2005,7 +1968,7 @@ void AdvanceROMTransfer() ROMEndTransfer(0); } -u32 ReadROMData() +u32 NDSCartSlot::ReadROMData() noexcept { if (ROMCnt & (1<<30)) return 0; @@ -2017,7 +1980,7 @@ u32 ReadROMData() return ROMData; } -void WriteROMData(u32 val) +void NDSCartSlot::WriteROMData(u32 val) noexcept { if (!(ROMCnt & (1<<30))) return; @@ -2038,7 +2001,7 @@ void WriteROMData(u32 val) } -void WriteSPICnt(u16 val) +void NDSCartSlot::WriteSPICnt(u16 val) noexcept { if ((SPICnt & 0x2040) == 0x2040 && (val & 0x2000) == 0x0000) { @@ -2055,12 +2018,12 @@ void WriteSPICnt(u16 val) Log(LogLevel::Debug, "!! CHANGING AUXSPICNT DURING TRANSFER: %04X\n", val); } -void SPITransferDone(u32 param) +void NDSCartSlot::SPITransferDone(u32 param) noexcept { SPICnt &= ~(1<<7); } -u8 ReadSPIData() +u8 NDSCartSlot::ReadSPIData() const noexcept { if (!(SPICnt & (1<<15))) return 0; if (!(SPICnt & (1<<13))) return 0; @@ -2069,7 +2032,7 @@ u8 ReadSPIData() return SPIData; } -void WriteSPIData(u8 val) +void NDSCartSlot::WriteSPIData(u8 val) noexcept { if (!(SPICnt & (1<<15))) return; if (!(SPICnt & (1<<13))) return; diff --git a/src/NDSCart.h b/src/NDSCart.h index 059fd242..1b172518 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -41,6 +41,8 @@ enum CartType Homebrew = 0x201, }; +class NDSCartSlot; + // CartCommon -- base code shared by all cart types class CartCommon { @@ -59,7 +61,7 @@ public: virtual void SetupSave(u32 type); virtual void LoadSave(const u8* savedata, u32 savelen); - virtual int ROMCommandStart(u8* cmd, u8* data, u32 len); + virtual int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len); virtual void ROMCommandFinish(u8* cmd, u8* data, u32 len); virtual u8 SPIWrite(u8 val, u32 pos, bool last); @@ -112,7 +114,7 @@ public: virtual void SetupSave(u32 type) override; virtual void LoadSave(const u8* savedata, u32 savelen) override; - virtual int ROMCommandStart(u8* cmd, u8* data, u32 len) override; + virtual int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override; virtual u8 SPIWrite(u8 val, u32 pos, bool last) override; @@ -151,7 +153,7 @@ public: void LoadSave(const u8* savedata, u32 savelen) override; - int ROMCommandStart(u8* cmd, u8* data, u32 len) override; + int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override; void ROMCommandFinish(u8* cmd, u8* data, u32 len) override; u8 SPIWrite(u8 val, u32 pos, bool last) override; @@ -216,7 +218,7 @@ public: void DoSavestate(Savestate* file) override; - int ROMCommandStart(u8* cmd, u8* data, u32 len) override; + int ROMCommandStart(NDSCart::NDSCartSlot& cartslot, u8* cmd, u8* data, u32 len) override; void ROMCommandFinish(u8* cmd, u8* data, u32 len) override; private: @@ -228,21 +230,110 @@ private: bool ReadOnly; }; -extern u16 SPICnt; -extern u32 ROMCnt; +class NDSCartSlot +{ +public: + NDSCartSlot() noexcept; + ~NDSCartSlot() noexcept; + void Reset() noexcept; + void ResetCart() noexcept; + void DoSavestate(Savestate* file) noexcept; + void DecryptSecureArea(u8* out) noexcept; -extern u8 ROMCommand[8]; + /// Loads a Nintendo DS cart object into the cart slot. + /// The cart slot takes ownership of the cart object and its underlying resources + /// and re-encrypts the ROM's secure area if necessary. + /// If a cartridge is already inserted, it is first ejected + /// and its state is discarded. + /// If the provided cart is not valid, + /// then the currently-loaded ROM will not be ejected. + /// + /// @param cart Movable reference to the cart. + /// @returns \c true if the cart was successfully loaded, + /// \c false otherwise. + /// @post If the cart was successfully loaded, + /// then \c cart will be \c nullptr + /// and \c Cart will contain the object that \c cart previously pointed to. + /// Otherwise, \c cart and \c Cart will be both be unchanged. + bool InsertROM(std::unique_ptr&& cart) noexcept; -/// The currently loaded NDS cart. -extern std::unique_ptr Cart; + /// Parses a ROM image and loads it into the emulator. + /// This function is equivalent to calling ::ParseROM() and ::InsertROM() in sequence. + /// @param romdata Pointer to the ROM image. + /// The cart emulator maintains its own copy of this data, + /// so the caller is free to discard this data after calling this function. + /// @param romlen The length of the ROM image, in bytes. + /// @returns \c true if the ROM image was successfully loaded, + /// \c false if not. + bool LoadROM(const u8* romdata, u32 romlen) noexcept; + void LoadSave(const u8* savedata, u32 savelen) noexcept; + void SetupDirectBoot(const std::string& romname) noexcept; -bool Init(); -void DeInit(); -void Reset(); + /// This function is intended to allow frontends to save and load SRAM + /// without using melonDS APIs. + /// Modifying the emulated SRAM for any other reason is strongly discouraged. + /// The returned pointer may be invalidated if the emulator is reset, + /// or when a new game is loaded. + /// Consequently, don't store the returned pointer for any longer than necessary. + /// @returns Pointer to this cart's SRAM if a cart is loaded and supports SRAM, otherwise \c nullptr. + [[nodiscard]] const u8* GetSaveMemory() const noexcept { return Cart ? Cart->GetSaveMemory() : nullptr; } + [[nodiscard]] u8* GetSaveMemory() noexcept { return Cart ? Cart->GetSaveMemory() : nullptr; } -void DoSavestate(Savestate* file); + /// @returns The length of the buffer returned by ::GetSaveMemory() + /// if a cart is loaded and supports SRAM, otherwise zero. + [[nodiscard]] u32 GetSaveMemoryLength() const noexcept { return Cart ? Cart->GetSaveMemoryLength() : 0; } + void EjectCart() noexcept; + u32 ReadROMData() noexcept; + void WriteROMData(u32 val) noexcept; + void WriteSPICnt(u16 val) noexcept; + void WriteROMCnt(u32 val) noexcept; + [[nodiscard]] u8 ReadSPIData() const noexcept; + void WriteSPIData(u8 val) noexcept; -void DecryptSecureArea(u8* out); + [[nodiscard]] CartCommon* GetCart() noexcept { return Cart.get(); } + [[nodiscard]] const CartCommon* GetCart() const noexcept { return Cart.get(); } + + [[nodiscard]] u8 GetROMCommand(u8 index) const noexcept { return ROMCommand[index]; } + void SetROMCommand(u8 index, u8 val) noexcept { ROMCommand[index] = val; } + + [[nodiscard]] u32 GetROMCnt() const noexcept { return ROMCnt; } + [[nodiscard]] u16 GetSPICnt() const noexcept { return SPICnt; } + void SetSPICnt(u16 val) noexcept { SPICnt = val; } +private: + friend class CartCommon; + u16 SPICnt {}; + u32 ROMCnt {}; + std::array ROMCommand {}; + u8 SPIData; + u32 SPIDataPos; + bool SPIHold; + + u32 ROMData; + + std::array TransferData; + u32 TransferPos; + u32 TransferLen; + u32 TransferDir; + std::array TransferCmd; + + std::unique_ptr Cart; + + std::array Key1_KeyBuf; + + u64 Key2_X; + u64 Key2_Y; + + void Key1_Encrypt(u32* data) noexcept; + void Key1_Decrypt(u32* data) noexcept; + void Key1_ApplyKeycode(u32* keycode, u32 mod) noexcept; + void Key1_LoadKeyBuf(bool dsi, bool externalBios, u8 *bios, u32 biosLength) noexcept; + void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod, u8 *bios, u32 biosLength) noexcept; + void Key2_Encrypt(u8* data, u32 len) noexcept; + void ROMEndTransfer(u32 param) noexcept; + void ROMPrepareData(u32 param) noexcept; + void AdvanceROMTransfer() noexcept; + void SPITransferDone(u32 param) noexcept; +}; /// Parses the given ROM data and constructs a \c NDSCart::CartCommon subclass /// that can be inserted into the emulator or used to extract information about the cart beforehand. @@ -253,65 +344,6 @@ void DecryptSecureArea(u8* out); /// @returns A \c NDSCart::CartCommon object representing the parsed ROM, /// or \c nullptr if the ROM data couldn't be parsed. std::unique_ptr ParseROM(const u8* romdata, u32 romlen); - -/// Loads a Nintendo DS cart object into the emulator. -/// The emulator takes ownership of the cart object and its underlying resources -/// and re-encrypts the ROM's secure area if necessary. -/// If a cartridge is already inserted, it is first ejected -/// and its state is discarded. -/// If the provided cart is not valid, -/// then the currently-loaded ROM will not be ejected. -/// -/// @param cart Movable reference to the cart. -/// @returns \c true if the cart was successfully loaded, -/// \c false otherwise. -/// @post If the cart was successfully loaded, -/// then \c cart will be \c nullptr -/// and \c Cart will contain the object that \c cart previously pointed to. -/// Otherwise, \c cart and \c Cart will be both be unchanged. -bool InsertROM(std::unique_ptr&& cart); - -/// Parses a ROM image and loads it into the emulator. -/// This function is equivalent to calling ::ParseROM() and ::InsertROM() in sequence. -/// @param romdata Pointer to the ROM image. -/// The cart emulator maintains its own copy of this data, -/// so the caller is free to discard this data after calling this function. -/// @param romlen The length of the ROM image, in bytes. -/// @returns \c true if the ROM image was successfully loaded, -/// \c false if not. -bool LoadROM(const u8* romdata, u32 romlen); -void LoadSave(const u8* savedata, u32 savelen); -void SetupDirectBoot(const std::string& romname); - -/// This function is intended to allow frontends to save and load SRAM -/// without using melonDS APIs. -/// Modifying the emulated SRAM for any other reason is strongly discouraged. -/// The returned pointer may be invalidated if the emulator is reset, -/// or when a new game is loaded. -/// Consequently, don't store the returned pointer for any longer than necessary. -/// @returns Pointer to this cart's SRAM if a cart is loaded and supports SRAM, otherwise \c nullptr. -u8* GetSaveMemory(); - -/// @returns The length of the buffer returned by ::GetSaveMemory() -/// if a cart is loaded and supports SRAM, otherwise zero. -u32 GetSaveMemoryLength(); - -void EjectCart(); - -void ResetCart(); - -void WriteROMCnt(u32 val); -u32 ReadROMData(); -void WriteROMData(u32 val); - -void WriteSPICnt(u16 val); -u8 ReadSPIData(); -void WriteSPIData(u8 val); - -void ROMPrepareData(u32 param); -void ROMEndTransfer(u32 param); -void SPITransferDone(u32 param); - } #endif diff --git a/src/frontend/qt_sdl/ROMInfoDialog.cpp b/src/frontend/qt_sdl/ROMInfoDialog.cpp index 2c1acee7..b381803b 100644 --- a/src/frontend/qt_sdl/ROMInfoDialog.cpp +++ b/src/frontend/qt_sdl/ROMInfoDialog.cpp @@ -43,8 +43,8 @@ ROMInfoDialog::ROMInfoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ROMI ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); - const NDSBanner* banner = NDSCart::Cart->Banner(); - const NDSHeader& header = NDSCart::Cart->GetHeader(); + const NDSBanner* banner = NDS::NDSCartSlot->GetCart()->Banner(); + const NDSHeader& header = NDS::NDSCartSlot->GetCart()->GetHeader(); u32 iconData[32 * 32]; ROMManager::ROMIcon(banner->Icon, banner->Palette, iconData); iconImage = QImage(reinterpret_cast(iconData), 32, 32, QImage::Format_ARGB32).copy();