aboutsummaryrefslogtreecommitdiff
path: root/src/NDS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/NDS.cpp')
-rw-r--r--src/NDS.cpp200
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;