diff options
Diffstat (limited to 'src/NDS.cpp')
-rw-r--r-- | src/NDS.cpp | 200 |
1 files changed, 159 insertions, 41 deletions
diff --git a/src/NDS.cpp b/src/NDS.cpp index ceeeb79..18e2ae1 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -31,6 +31,9 @@ #include "Wifi.h" #include "Platform.h" +#include "DSi.h" +#include "DSi_SPI_TSC.h" + namespace NDS { @@ -86,7 +89,8 @@ u32 CPUStop; u8 ARM9BIOS[0x1000]; u8 ARM7BIOS[0x4000]; -u8 MainRAM[MAIN_RAM_SIZE]; +u8 MainRAM[0x1000000]; +u32 MainRAMMask; u8 SharedWRAM[0x8000]; u8 WRAMCnt; @@ -105,6 +109,7 @@ u8 ROMSeed1[2*8]; // IO shit u32 IME[2]; u32 IE[2], IF[2]; +u32 IE2, IF2; u8 PostFlag9; u8 PostFlag7; @@ -175,6 +180,8 @@ bool Init() if (!RTC::Init()) return false; if (!Wifi::Init()) return false; + if (!DSi::Init()) return false; + return true; } @@ -195,6 +202,8 @@ void DeInit() SPI::DeInit(); RTC::DeInit(); Wifi::DeInit(); + + DSi::DeInit(); } @@ -227,7 +236,11 @@ void SetARM9RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, ARM9MemTimings[i][3] = S32; } - ARM9->UpdateRegionTimings(addrstart<<14, addrend<<14); + addrstart <<= 14; + addrend <<= 14; + if (!addrend) addrend = 0xFFFFFFFF; + + ARM9->UpdateRegionTimings(addrstart, addrend); } void SetARM7RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq) @@ -387,6 +400,12 @@ void Reset() LastSysClockCycles = 0; + memset(ARM9BIOS, 0, 0x1000); + memset(ARM7BIOS, 0, 0x4000); + + // DS BIOSes are always loaded, even in DSi mode + // we need them for DS-compatible mode + f = Platform::OpenLocalFile("bios9.bin", "rb"); if (!f) { @@ -421,8 +440,19 @@ void Reset() fclose(f); } - // TODO for later: configure this when emulating a DSi - ARM9ClockShift = 1; + if (true) + { + DSi::LoadBIOS(); + DSi::LoadNAND(); + + ARM9ClockShift = 2; + MainRAMMask = 0xFFFFFF; + } + else + { + ARM9ClockShift = 1; + MainRAMMask = 0x3FFFFF; + } ARM9Timestamp = 0; ARM9Target = 0; ARM7Timestamp = 0; ARM7Target = 0; @@ -430,14 +460,14 @@ void Reset() InitTimings(); - memset(MainRAM, 0, MAIN_RAM_SIZE); + memset(MainRAM, 0, 0x1000000); memset(SharedWRAM, 0, 0x8000); memset(ARM7WRAM, 0, 0x10000); MapSharedWRAM(0); - ExMemCnt[0] = 0; - ExMemCnt[1] = 0; + ExMemCnt[0] = 0x4000; + ExMemCnt[1] = 0x4000; memset(ROMSeed0, 0, 2*8); memset(ROMSeed1, 0, 2*8); SetGBASlotTimings(); @@ -448,6 +478,8 @@ void Reset() IME[1] = 0; IE[1] = 0; IF[1] = 0; + IE2 = 0; + IF2 = 0; PostFlag9 = 0x00; PostFlag7 = 0x00; @@ -496,6 +528,9 @@ void Reset() SPI::Reset(); RTC::Reset(); Wifi::Reset(); + + DSi::Reset(); + KeyInput &= ~(1 << (16+6)); // TODO } void Stop() @@ -555,7 +590,7 @@ bool DoSavestate_Scheduler(Savestate* file) } if (funcid == -1) { - printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK STAPLEBUTTER.\n", i); + printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK ARISOTURA.\n", i); return false; } } @@ -669,7 +704,7 @@ bool DoSavestate(Savestate* file) for (int i = 0; i < 8; i++) DMAs[i]->DoSavestate(file); - file->Var8(&WRAMCnt); + file->Var8(&WRAMCnt); // FIXME!!!!! if (!file->Saving) { @@ -804,6 +839,7 @@ u32 RunFrame() if (!(CPUStop & 0x80000000)) DMAs[1]->Run(); if (!(CPUStop & 0x80000000)) DMAs[2]->Run(); if (!(CPUStop & 0x80000000)) DMAs[3]->Run(); + DSi::RunNDMAs(0); } else { @@ -826,6 +862,7 @@ u32 RunFrame() DMAs[5]->Run(); DMAs[6]->Run(); DMAs[7]->Run(); + DSi::RunNDMAs(1); } else { @@ -907,24 +944,30 @@ void CancelEvent(u32 id) } -void PressKey(u32 key) -{ - KeyInput &= ~(1 << key); -} - -void ReleaseKey(u32 key) -{ - KeyInput |= (1 << key); -} - void TouchScreen(u16 x, u16 y) { - SPI_TSC::SetTouchCoords(x, y); + if (true) // TODO!! + { + DSi_SPI_TSC::SetTouchCoords(x, y); + } + else + { + SPI_TSC::SetTouchCoords(x, y); + KeyInput &= ~(1 << (16+6)); + } } void ReleaseScreen() { - SPI_TSC::SetTouchCoords(0x000, 0xFFF); + if (true) // TODO!! + { + DSi_SPI_TSC::SetTouchCoords(0x000, 0xFFF); + } + else + { + SPI_TSC::SetTouchCoords(0x000, 0xFFF); + KeyInput |= (1 << (16+6)); + } } @@ -1051,6 +1094,7 @@ void UpdateIRQ(u32 cpu) if (IME[cpu] & 0x1) { arm->IRQ = IE[cpu] & IF[cpu]; + if (cpu) arm->IRQ |= (IE2 & IF2); } else { @@ -1070,6 +1114,18 @@ void ClearIRQ(u32 cpu, u32 irq) UpdateIRQ(cpu); } +void SetIRQ2(u32 irq) +{ + IF2 |= (1 << irq); + UpdateIRQ(1); +} + +void ClearIRQ2(u32 irq) +{ + IF2 &= ~(1 << irq); + UpdateIRQ(1); +} + bool HaltInterrupted(u32 cpu) { if (cpu == 0) @@ -1117,6 +1173,7 @@ void GXFIFOStall() DMAs[1]->StallIfRunning(); DMAs[2]->StallIfRunning(); DMAs[3]->StallIfRunning(); + DSi::StallNDMAs(); } } @@ -1314,6 +1371,29 @@ void RunTimers(u32 cpu) +// matching NDMA modes for DSi +const u32 NDMAModes[] = +{ + // ARM9 + + 0x10, // immediate + 0x06, // VBlank + 0x07, // HBlank + 0x08, // scanline start + 0x09, // mainmem FIFO + 0x04, // DS cart slot + 0xFF, // GBA cart slot + 0x0A, // GX FIFO + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + + // ARM7 + + 0x30, // immediate + 0x26, // VBlank + 0x24, // DS cart slot + 0xFF, // wifi / GBA cart slot (TODO) +}; + bool DMAsInMode(u32 cpu, u32 mode) { cpu <<= 2; @@ -1321,6 +1401,13 @@ bool DMAsInMode(u32 cpu, u32 mode) if (DMAs[cpu+1]->IsInMode(mode)) return true; if (DMAs[cpu+2]->IsInMode(mode)) return true; if (DMAs[cpu+3]->IsInMode(mode)) return true; + + if (true) + { + cpu >>= 2; + return DSi::NDMAsInMode(cpu, NDMAModes[mode]); + } + return false; } @@ -1331,6 +1418,7 @@ bool DMAsRunning(u32 cpu) if (DMAs[cpu+1]->IsRunning()) return true; if (DMAs[cpu+2]->IsRunning()) return true; if (DMAs[cpu+3]->IsRunning()) return true; + if (DSi::NDMAsRunning(cpu>>2)) return true; return false; } @@ -1341,6 +1429,12 @@ void CheckDMAs(u32 cpu, u32 mode) DMAs[cpu+1]->StartIfNeeded(mode); DMAs[cpu+2]->StartIfNeeded(mode); DMAs[cpu+3]->StartIfNeeded(mode); + + if (true) + { + cpu >>= 2; + DSi::CheckNDMAs(cpu, NDMAModes[mode]); + } } void StopDMAs(u32 cpu, u32 mode) @@ -1350,6 +1444,12 @@ void StopDMAs(u32 cpu, u32 mode) DMAs[cpu+1]->StopIfNeeded(mode); DMAs[cpu+2]->StopIfNeeded(mode); DMAs[cpu+3]->StopIfNeeded(mode); + + if (true) + { + cpu >>= 2; + DSi::StopNDMAs(cpu, NDMAModes[mode]); + } } @@ -1542,12 +1642,12 @@ void debug(u32 param) printf("ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]); printf("ARM9 IME=%08X IE=%08X IF=%08X\n", IME[0], IE[0], IF[0]); - printf("ARM7 IME=%08X IE=%08X IF=%08X\n", IME[1], IE[1], IF[1]); + printf("ARM7 IME=%08X IE=%08X IF=%08X IE2=%04X IF2=%04X\n", IME[1], IE[1], IF[1], IE2, IF2); //for (int i = 0; i < 9; i++) // printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]); - FILE* + /*FILE* shit = fopen("debug/party.bin", "wb"); fwrite(ARM9->ITCM, 0x8000, 1, shit); for (u32 i = 0x02000000; i < 0x02400000; i+=4) @@ -1560,6 +1660,21 @@ void debug(u32 param) u32 val = ARM7Read32(i); fwrite(&val, 4, 1, shit); } + fclose(shit);*/ + FILE* + /*shit = fopen("debug/dump9.bin", "wb"); + for (u32 i = 0x02000000; i < 0x04000000; i+=4) + { + u32 val = DSi::ARM9Read32(i); + fwrite(&val, 4, 1, shit); + } + fclose(shit);*/ + shit = fopen("debug/dump7_2.bin", "wb"); + for (u32 i = 0x02000000; i < 0x04000000; i+=4) + { + u32 val = DSi::ARM7Read32(i); + fwrite(&val, 4, 1, shit); + } fclose(shit); } @@ -1575,7 +1690,7 @@ u8 ARM9Read8(u32 addr) switch (addr & 0xFF000000) { case 0x02000000: - return *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)]; + return *(u8*)&MainRAM[addr & MainRAMMask]; case 0x03000000: if (SWRAM_ARM9) @@ -1636,7 +1751,7 @@ u16 ARM9Read16(u32 addr) switch (addr & 0xFF000000) { case 0x02000000: - return *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)]; + return *(u16*)&MainRAM[addr & MainRAMMask]; case 0x03000000: if (SWRAM_ARM9) @@ -1697,7 +1812,7 @@ u32 ARM9Read32(u32 addr) switch (addr & 0xFF000000) { case 0x02000000: - return *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)]; + return *(u32*)&MainRAM[addr & MainRAMMask]; case 0x03000000: if (SWRAM_ARM9) @@ -1753,7 +1868,7 @@ void ARM9Write8(u32 addr, u8 val) switch (addr & 0xFF000000) { case 0x02000000: - *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; + *(u8*)&MainRAM[addr & MainRAMMask] = val; return; case 0x03000000: @@ -1782,7 +1897,7 @@ void ARM9Write16(u32 addr, u16 val) switch (addr & 0xFF000000) { case 0x02000000: - *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; + *(u16*)&MainRAM[addr & MainRAMMask] = val; return; case 0x03000000: @@ -1825,7 +1940,7 @@ void ARM9Write32(u32 addr, u32 val) switch (addr & 0xFF000000) { case 0x02000000: - *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; + *(u32*)&MainRAM[addr & MainRAMMask] = val; return ; case 0x03000000: @@ -1869,7 +1984,7 @@ bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region) { case 0x02000000: region->Mem = MainRAM; - region->Mask = MAIN_RAM_SIZE-1; + region->Mask = MainRAMMask; return true; case 0x03000000: @@ -1899,7 +2014,8 @@ u8 ARM7Read8(u32 addr) { if (addr < 0x00004000) { - if (ARM7->R[15] >= 0x4000) + // TODO: check the boundary? is it 4000 or higher on regular DS? + if (ARM7->R[15] >= 0x00004000) return 0xFF; if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt) return 0xFF; @@ -1911,7 +2027,7 @@ u8 ARM7Read8(u32 addr) { case 0x02000000: case 0x02800000: - return *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)]; + return *(u8*)&MainRAM[addr & MainRAMMask]; case 0x03000000: if (SWRAM_ARM7) @@ -1955,7 +2071,7 @@ u16 ARM7Read16(u32 addr) { if (addr < 0x00004000) { - if (ARM7->R[15] >= 0x4000) + if (ARM7->R[15] >= 0x00004000) return 0xFFFF; if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt) return 0xFFFF; @@ -1967,7 +2083,7 @@ u16 ARM7Read16(u32 addr) { case 0x02000000: case 0x02800000: - return *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)]; + return *(u16*)&MainRAM[addr & MainRAMMask]; case 0x03000000: if (SWRAM_ARM7) @@ -2018,7 +2134,7 @@ u32 ARM7Read32(u32 addr) { if (addr < 0x00004000) { - if (ARM7->R[15] >= 0x4000) + if (ARM7->R[15] >= 0x00004000) return 0xFFFFFFFF; if (addr < ARM7BIOSProt && ARM7->R[15] >= ARM7BIOSProt) return 0xFFFFFFFF; @@ -2030,7 +2146,7 @@ u32 ARM7Read32(u32 addr) { case 0x02000000: case 0x02800000: - return *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)]; + return *(u32*)&MainRAM[addr & MainRAMMask]; case 0x03000000: if (SWRAM_ARM7) @@ -2083,7 +2199,7 @@ void ARM7Write8(u32 addr, u8 val) { case 0x02000000: case 0x02800000: - *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; + *(u8*)&MainRAM[addr & MainRAMMask] = val; return; case 0x03000000: @@ -2121,7 +2237,7 @@ void ARM7Write16(u32 addr, u16 val) { case 0x02000000: case 0x02800000: - *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; + *(u16*)&MainRAM[addr & MainRAMMask] = val; return; case 0x03000000: @@ -2167,7 +2283,7 @@ void ARM7Write32(u32 addr, u32 val) { case 0x02000000: case 0x02800000: - *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val; + *(u32*)&MainRAM[addr & MainRAMMask] = val; return; case 0x03000000: @@ -2215,7 +2331,7 @@ bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region) case 0x02000000: case 0x02800000: region->Mem = MainRAM; - region->Mask = MAIN_RAM_SIZE-1; + region->Mask = MainRAMMask; return true; case 0x03000000: @@ -2492,7 +2608,7 @@ u32 ARM9IORead32(u32 addr) case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt << 16); - case 0x04000180: return IPCSync9; + case 0x04000180: /*printf("ARM9 read IPCSYNC: %04X\n", IPCSync9);*/ return IPCSync9; case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); case 0x040001A4: return NDSCart::ROMCnt; @@ -2701,6 +2817,7 @@ void ARM9IOWrite16(u32 addr, u16 val) return; case 0x04000180: + printf("ARM9 IPCSYNC = %04X\n", val); IPCSync7 &= 0xFFF0; IPCSync7 |= ((val & 0x0F00) >> 8); IPCSync9 &= 0xB0FF; @@ -3290,6 +3407,7 @@ void ARM7IOWrite16(u32 addr, u16 val) case 0x04000138: RTC::Write(val, false); return; case 0x04000180: + printf("ARM7 IPCSYNC = %04X\n", val); IPCSync9 &= 0xFFF0; IPCSync9 |= ((val & 0x0F00) >> 8); IPCSync7 &= 0xB0FF; |