diff options
Diffstat (limited to 'src/NDS.cpp')
-rw-r--r-- | src/NDS.cpp | 334 |
1 files changed, 277 insertions, 57 deletions
diff --git a/src/NDS.cpp b/src/NDS.cpp index 18e2ae1..e04df01 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1,5 +1,5 @@ /* - Copyright 2016-2019 Arisotura + Copyright 2016-2020 Arisotura This file is part of melonDS. @@ -22,6 +22,7 @@ #include "NDS.h" #include "ARM.h" #include "NDSCart.h" +#include "GBACart.h" #include "DMA.h" #include "FIFO.h" #include "GPU.h" @@ -29,6 +30,7 @@ #include "SPI.h" #include "RTC.h" #include "Wifi.h" +#include "AREngine.h" #include "Platform.h" #include "DSi.h" @@ -103,6 +105,7 @@ u8 ARM7WRAM[0x10000]; u16 ExMemCnt[2]; +// TODO: these belong in NDSCart! u8 ROMSeed0[2*8]; u8 ROMSeed1[2*8]; @@ -148,6 +151,8 @@ u16 RCnt; bool Running; +bool RunningGame; + void DivDone(u32 param); void SqrtDone(u32 param); @@ -174,6 +179,7 @@ bool Init() IPCFIFO7 = new FIFO<u32>(16); if (!NDSCart::Init()) return false; + if (!GBACart::Init()) return false; if (!GPU::Init()) return false; if (!SPU::Init()) return false; if (!SPI::Init()) return false; @@ -182,6 +188,8 @@ bool Init() if (!DSi::Init()) return false; + if (!AREngine::Init()) return false; + return true; } @@ -197,6 +205,7 @@ void DeInit() delete IPCFIFO7; NDSCart::DeInit(); + GBACart::DeInit(); GPU::DeInit(); SPU::DeInit(); SPI::DeInit(); @@ -204,6 +213,8 @@ void DeInit() Wifi::DeInit(); DSi::DeInit(); + + AREngine::DeInit(); } @@ -320,7 +331,24 @@ void SetupDirectBoot() MapSharedWRAM(3); - for (u32 i = 0; i < bootparams[3]; i+=4) + u32 arm9start = 0; + + // load the ARM9 secure area + if (bootparams[0] >= 0x4000 && bootparams[0] < 0x8000) + { + u8 securearea[0x800]; + NDSCart::DecryptSecureArea(securearea); + + for (u32 i = 0; i < 0x800; i+=4) + { + ARM9Write32(bootparams[2]+i, *(u32*)&securearea[i]); + arm9start += 4; + } + } + + // CHECKME: firmware seems to load this in 0x200 byte chunks + + for (u32 i = arm9start; i < bootparams[3]; i+=4) { u32 tmp = *(u32*)&NDSCart::CartROM[bootparams[0]+i]; ARM9Write32(bootparams[2]+i, tmp); @@ -398,6 +426,7 @@ void Reset() FILE* f; u32 i; + RunningGame = false; LastSysClockCycles = 0; memset(ARM9BIOS, 0, 0x1000); @@ -523,6 +552,7 @@ void Reset() RCnt = 0; NDSCart::Reset(); + GBACart::Reset(); GPU::Reset(); SPU::Reset(); SPI::Reset(); @@ -531,6 +561,8 @@ void Reset() DSi::Reset(); KeyInput &= ~(1 << (16+6)); // TODO + + AREngine::Reset(); } void Stop() @@ -700,21 +732,16 @@ bool DoSavestate(Savestate* file) file->Var16(&KeyCnt); file->Var16(&RCnt); + file->Var8(&WRAMCnt); - for (int i = 0; i < 8; i++) - DMAs[i]->DoSavestate(file); - - file->Var8(&WRAMCnt); // FIXME!!!!! + file->Var32((u32*)&RunningGame); if (!file->Saving) { // 'dept of redundancy dept' // but we do need to update the mappings MapSharedWRAM(WRAMCnt); - } - if (!file->Saving) - { InitTimings(); SetGBASlotTimings(); @@ -723,10 +750,14 @@ bool DoSavestate(Savestate* file) SetWifiWaitCnt(tmp); // force timing table update } + for (int i = 0; i < 8; i++) + DMAs[i]->DoSavestate(file); + ARM9->DoSavestate(file); ARM7->DoSavestate(file); NDSCart::DoSavestate(file); + GBACart::DoSavestate(file); GPU::DoSavestate(file); SPU::DoSavestate(file); SPI::DoSavestate(file); @@ -755,6 +786,19 @@ bool LoadROM(const char* path, const char* sram, bool direct) } } +bool LoadGBAROM(const char* path, const char* sram) +{ + if (GBACart::LoadROM(path, sram)) + { + return true; + } + else + { + printf("Failed to load ROM %s\n", path); + return false; + } +} + void LoadBIOS() { Reset(); @@ -1308,6 +1352,22 @@ void NocashPrint(u32 ncpu, u32 addr) +void MonitorARM9Jump(u32 addr) +{ + // checkme: can the entrypoint addr be THUMB? + + if ((!RunningGame) && NDSCart::CartROM) + { + if (addr == *(u32*)&NDSCart::CartROM[0x24]) + { + printf("Game is now booting\n"); + RunningGame = true; + } + } +} + + + void HandleTimerOverflow(u32 tid) { Timer* timer = &Timers[tid]; @@ -1725,16 +1785,20 @@ u8 ARM9Read8(u32 addr) case 0x08000000: case 0x09000000: - if (ExMemCnt[0] & (1<<7)) return 0xFF; // TODO: proper open bus - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! - return 0xFF; + if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return *(u8*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } + return 0xFF; // TODO: proper open bus case 0x0A000000: - if (ExMemCnt[0] & (1<<7)) return 0xFF; // TODO: proper open bus - // TODO!!! - return 0xFF; + if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return GBACart_SRAM::Read8(addr & (GBACart_SRAM::SRAMLength-1)); + } + return 0xFF; // TODO: proper open bus } printf("unknown arm9 read8 %08X\n", addr); @@ -1786,16 +1850,20 @@ u16 ARM9Read16(u32 addr) case 0x08000000: case 0x09000000: - if (ExMemCnt[0] & (1<<7)) return 0xFFFF; // TODO: proper open bus - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! - return 0xFFFF; + if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return *(u16*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } + return 0xFFFF; // TODO: proper open bus case 0x0A000000: - if (ExMemCnt[0] & (1<<7)) return 0xFFFF; // TODO: proper open bus - // TODO!!! - return 0xFFFF; + if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return GBACart_SRAM::Read16(addr & (GBACart_SRAM::SRAMLength-1)); + } + return 0xFFFF; // TODO: proper open bus } //printf("unknown arm9 read16 %08X %08X\n", addr, ARM9->R[15]); @@ -1847,16 +1915,20 @@ u32 ARM9Read32(u32 addr) case 0x08000000: case 0x09000000: - if (ExMemCnt[0] & (1<<7)) return 0xFFFFFFFF; // TODO: proper open bus - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! - return 0xFFFFFFFF; + if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return *(u32*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } + return 0xFFFFFFFF; // TODO: proper open bus case 0x0A000000: - if (ExMemCnt[0] & (1<<7)) return 0xFFFFFFFF; // TODO: proper open bus - // TODO!!! - return 0xFFFFFFFF; + if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return GBACart_SRAM::Read32(addr & (GBACart_SRAM::SRAMLength-1)); + } + return 0xFFFFFFFF; // TODO: proper open bus } printf("unknown arm9 read32 %08X | %08X %08X\n", addr, ARM9->R[15], ARM9->R[12]); @@ -1887,6 +1959,27 @@ void ARM9Write8(u32 addr, u8 val) case 0x07000000: // checkme return; + + case 0x08000000: + case 0x09000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + if ((addr & 0x00FFFFFF) >= 0xC4 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + + case 0x0A000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + GBACart_SRAM::Write8(addr & (GBACart_SRAM::SRAMLength-1), val); + } + return; } printf("unknown arm9 write8 %08X %02X\n", addr, val); @@ -1930,6 +2023,29 @@ void ARM9Write16(u32 addr, u16 val) if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; *(u16*)&GPU::OAM[addr & 0x7FF] = val; return; + + case 0x08000000: + case 0x09000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC3 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + + case 0x0A000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + GBACart_SRAM::Write16(addr & (GBACart_SRAM::SRAMLength-1), val); + } + return; } //printf("unknown arm9 write16 %08X %04X\n", addr, val); @@ -1973,6 +2089,30 @@ void ARM9Write32(u32 addr, u32 val) if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; *(u32*)&GPU::OAM[addr & 0x7FF] = val; return; + + case 0x08000000: + case 0x09000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC1 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val & 0xFF); + GBACart::WriteGPIO((addr + 2) & (GBACart::CartROMSize-1), (val >> 16) & 0xFF); + return; + } + } + break; + + case 0x0A000000: + if (ExMemCnt[0] & (1<<7)) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + GBACart_SRAM::Write32(addr & (GBACart_SRAM::SRAMLength-1), val); + } + return; } printf("unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9->R[15]); @@ -2051,16 +2191,20 @@ u8 ARM7Read8(u32 addr) case 0x08000000: case 0x09000000: - if (!(ExMemCnt[0] & (1<<7))) return 0xFF; // TODO: proper open bus - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! - return 0xFF; + if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return *(u8*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } + return 0xFF; // TODO: proper open bus case 0x0A000000: - if (!(ExMemCnt[0] & (1<<7))) return 0xFF; // TODO: proper open bus - // TODO!!! - return 0xFF; + if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return GBACart_SRAM::Read8(addr & (GBACart_SRAM::SRAMLength-1)); + } + return 0xFF; // TODO: proper open bus } printf("unknown arm7 read8 %08X %08X %08X/%08X\n", addr, ARM7->R[15], ARM7->R[0], ARM7->R[1]); @@ -2114,16 +2258,20 @@ u16 ARM7Read16(u32 addr) case 0x08000000: case 0x09000000: - if (!(ExMemCnt[0] & (1<<7))) return 0xFFFF; // TODO: proper open bus - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! - return 0xFFFF; + if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return *(u16*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } + return 0xFFFF; // TODO: proper open bus case 0x0A000000: - if (!(ExMemCnt[0] & (1<<7))) return 0xFFFF; // TODO: proper open bus - // TODO!!! - return 0xFFFF; + if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return GBACart_SRAM::Read16(addr & (GBACart_SRAM::SRAMLength-1)); + } + return 0xFFFF; // TODO: proper open bus } printf("unknown arm7 read16 %08X %08X\n", addr, ARM7->R[15]); @@ -2177,16 +2325,20 @@ u32 ARM7Read32(u32 addr) case 0x08000000: case 0x09000000: - if (!(ExMemCnt[0] & (1<<7))) return 0xFFFFFFFF; // TODO: proper open bus - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! - return 0xFFFFFFFF; + if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return *(u32*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } + return 0xFFFFFFFF; // TODO: proper open bus case 0x0A000000: - if (!(ExMemCnt[0] & (1<<7))) return 0xFFFFFFFF; // TODO: proper open bus - // TODO!!! - return 0xFFFFFFFF; + if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled + if (GBACart::CartInserted) + { + return GBACart_SRAM::Read32(addr & (GBACart_SRAM::SRAMLength-1)); + } + return 0xFFFFFFFF; // TODO: proper open bus } printf("unknown arm7 read32 %08X | %08X\n", addr, ARM7->R[15]); @@ -2226,6 +2378,27 @@ void ARM7Write8(u32 addr, u8 val) case 0x06800000: GPU::WriteVRAM_ARM7<u8>(addr, val); return; + + case 0x08000000: + case 0x09000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + if ((addr & 0x00FFFFFF) >= 0xC4 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + + case 0x0A000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + GBACart_SRAM::Write8(addr & (GBACart_SRAM::SRAMLength-1), val); + } + return; } printf("unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7->R[15]); @@ -2272,6 +2445,29 @@ void ARM7Write16(u32 addr, u16 val) case 0x06800000: GPU::WriteVRAM_ARM7<u16>(addr, val); return; + + case 0x08000000: + case 0x09000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC3 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val); + return; + } + } + break; + + case 0x0A000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + GBACart_SRAM::Write16(addr & (GBACart_SRAM::SRAMLength-1), val); + } + return; } //printf("unknown arm7 write16 %08X %04X @ %08X\n", addr, val, ARM7->R[15]); @@ -2319,6 +2515,30 @@ void ARM7Write32(u32 addr, u32 val) case 0x06800000: GPU::WriteVRAM_ARM7<u32>(addr, val); return; + + case 0x08000000: + case 0x09000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + // Note: the lower bound is adjusted such that a write starting + // there will hit the first byte of the GPIO region. + if ((addr & 0x00FFFFFF) >= 0xC1 && (addr & 0x00FFFFFF) <= 0xC9) + { + GBACart::WriteGPIO(addr & (GBACart::CartROMSize-1), val & 0xFF); + GBACart::WriteGPIO((addr + 2) & (GBACart::CartROMSize-1), (val >> 16) & 0xFF); + return; + } + } + break; + + case 0x0A000000: + if (!(ExMemCnt[0] & (1<<7))) return; // deselected CPU, skip the write + if (GBACart::CartInserted) + { + GBACart_SRAM::Write32(addr & (GBACart_SRAM::SRAMLength-1), val); + } + return; } //printf("unknown arm7 write32 %08X %08X @ %08X\n", addr, val, ARM7->R[15]); |