aboutsummaryrefslogtreecommitdiff
path: root/src/NDS.cpp
diff options
context:
space:
mode:
authorRSDuck <RSDuck@users.noreply.github.com>2020-05-12 16:07:28 +0200
committerRSDuck <rsduck@users.noreply.github.com>2020-06-16 12:06:42 +0200
commite7d076403df7afd6dc8304196211b49e3ed7f464 (patch)
tree1d5ff1e743839f271de77f8bd312c985033c6a89 /src/NDS.cpp
parent4cff4b52286a7d1a7e40817d52a5d271a937ddc2 (diff)
parentc17f7b100e36edb1c728dbf21c77f9484d1820c6 (diff)
Merge branch 'generic_jit' of https://github.com/Arisotura/melonDS into generic_jit
Diffstat (limited to 'src/NDS.cpp')
-rw-r--r--src/NDS.cpp245
1 files changed, 204 insertions, 41 deletions
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 6e989a8..657241f 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -34,6 +34,9 @@
#include "Platform.h"
#include "ARMJIT.h"
+#include "DSi.h"
+#include "DSi_SPI_TSC.h"
+
namespace NDS
{
@@ -60,6 +63,8 @@ namespace NDS
//
// timings for GBA slot and wifi are set up at runtime
+int ConsoleType;
+
u8 ARM9MemTimings[0x40000][4];
u8 ARM7MemTimings[0x20000][4];
@@ -89,7 +94,8 @@ u32 CPUStop;
u8 ARM9BIOS[0x1000];
u8 ARM7BIOS[0x4000];
-u8 MainRAM[MAIN_RAM_SIZE];
+u8 MainRAM[0x1000000];
+u32 MainRAMMask;
u8 SharedWRAM[0x8000];
u8 WRAMCnt;
@@ -109,6 +115,7 @@ u8 ROMSeed1[2*8];
// IO shit
u32 IME[2];
u32 IE[2], IF[2];
+u32 IE2, IF2;
u8 PostFlag9;
u8 PostFlag7;
@@ -186,6 +193,8 @@ bool Init()
if (!RTC::Init()) return false;
if (!Wifi::Init()) return false;
+ if (!DSi::Init()) return false;
+
if (!AREngine::Init()) return false;
return true;
@@ -214,6 +223,8 @@ void DeInit()
RTC::DeInit();
Wifi::DeInit();
+ DSi::DeInit();
+
AREngine::DeInit();
}
@@ -294,6 +305,8 @@ void InitTimings()
// TODO: +3c nonseq waitstate doesn't apply to DMA!
// but of course mainRAM always gets 8c nonseq waitstate
+ // TODO: DSi-specific timings!!
+
SetARM9RegionTimings(0x00000000, 0xFFFFFFFF, 32, 1 + 3, 1); // void
SetARM9RegionTimings(0xFFFF0000, 0xFFFFFFFF, 32, 1 + 3, 1); // BIOS
@@ -319,6 +332,12 @@ void InitTimings()
void SetupDirectBoot()
{
+ if (ConsoleType == 1)
+ {
+ printf("!! DIRECT BOOT NOT SUPPORTED IN DSI MODE\n");
+ return;
+ }
+
u32 bootparams[8];
memcpy(bootparams, &NDSCart::CartROM[0x20], 8*4);
@@ -427,7 +446,13 @@ void Reset()
RunningGame = false;
LastSysClockCycles = 0;
- f = Platform::OpenLocalFile("bios9.bin", "rb");
+ 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(Config::BIOS9Path, "rb");
if (!f)
{
printf("ARM9 BIOS not found\n");
@@ -444,7 +469,7 @@ void Reset()
fclose(f);
}
- f = Platform::OpenLocalFile("bios7.bin", "rb");
+ f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
if (!f)
{
printf("ARM7 BIOS not found\n");
@@ -461,28 +486,38 @@ void Reset()
fclose(f);
}
+ if (ConsoleType == 1)
+ {
+ DSi::LoadBIOS();
+ DSi::LoadNAND();
+
+ ARM9ClockShift = 2;
+ MainRAMMask = 0xFFFFFF;
+ }
+ else
+ {
+ ARM9ClockShift = 1;
+ MainRAMMask = 0x3FFFFF;
+ }
// has to be called before InitTimings
// otherwise some PU settings are completely
// unitialised on the first run
ARM9->CP15Reset();
- // TODO for later: configure this when emulating a DSi
- ARM9ClockShift = 1;
-
ARM9Timestamp = 0; ARM9Target = 0;
ARM7Timestamp = 0; ARM7Target = 0;
SysTimestamp = 0;
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();
@@ -493,6 +528,8 @@ void Reset()
IME[1] = 0;
IE[1] = 0;
IF[1] = 0;
+ IE2 = 0;
+ IF2 = 0;
PostFlag9 = 0x00;
PostFlag7 = 0x00;
@@ -543,6 +580,12 @@ void Reset()
RTC::Reset();
Wifi::Reset();
+ if (ConsoleType == 1)
+ {
+ DSi::Reset();
+ KeyInput &= ~(1 << (16+6));
+ }
+
AREngine::Reset();
#ifdef JIT_ENABLED
@@ -607,7 +650,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;
}
}
@@ -655,6 +698,11 @@ bool DoSavestate(Savestate* file)
{
file->Section("NDSG");
+ // TODO:
+ // * do something for bool's (sizeof=1)
+ // * do something for 'loading DSi-mode savestate in DS mode' and vice-versa
+ // * add IE2/IF2 there
+
file->VarArray(MainRAM, 0x400000);
file->VarArray(SharedWRAM, 0x8000);
file->VarArray(ARM7WRAM, 0x10000);
@@ -764,6 +812,11 @@ bool DoSavestate(Savestate* file)
return true;
}
+void SetConsoleType(int type)
+{
+ ConsoleType = type;
+}
+
bool LoadROM(const char* path, const char* sram, bool direct)
{
if (NDSCart::LoadROM(path, sram, direct))
@@ -876,6 +929,7 @@ u32 RunFrame()
if (!(CPUStop & 0x80000000)) DMAs[1]->Run();
if (!(CPUStop & 0x80000000)) DMAs[2]->Run();
if (!(CPUStop & 0x80000000)) DMAs[3]->Run();
+ if (ConsoleType == 1) DSi::RunNDMAs(0);
}
else
{
@@ -903,6 +957,7 @@ u32 RunFrame()
DMAs[5]->Run();
DMAs[6]->Run();
DMAs[7]->Run();
+ if (ConsoleType == 1) DSi::RunNDMAs(1);
}
else
{
@@ -999,24 +1054,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 (ConsoleType == 1)
+ {
+ DSi_SPI_TSC::SetTouchCoords(x, y);
+ }
+ else
+ {
+ SPI_TSC::SetTouchCoords(x, y);
+ KeyInput &= ~(1 << (16+6));
+ }
}
void ReleaseScreen()
{
- SPI_TSC::SetTouchCoords(0x000, 0xFFF);
+ if (ConsoleType == 1)
+ {
+ DSi_SPI_TSC::SetTouchCoords(0x000, 0xFFF);
+ }
+ else
+ {
+ SPI_TSC::SetTouchCoords(0x000, 0xFFF);
+ KeyInput |= (1 << (16+6));
+ }
}
@@ -1029,6 +1090,12 @@ void SetKeyMask(u32 mask)
KeyInput |= key_lo | (key_hi << 16);
}
+bool IsLidClosed()
+{
+ if (KeyInput & (1<<23)) return true;
+ return false;
+}
+
void SetLidClosed(bool closed)
{
if (closed)
@@ -1151,6 +1218,8 @@ void UpdateIRQ(u32 cpu)
if (IME[cpu] & 0x1)
{
arm->IRQ = !!(IE[cpu] & IF[cpu]);
+ if ((ConsoleType == 1) && cpu)
+ arm->IRQ |= !!(IE2 & IF2);
}
else
{
@@ -1170,6 +1239,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)
@@ -1217,6 +1298,7 @@ void GXFIFOStall()
DMAs[1]->StallIfRunning();
DMAs[2]->StallIfRunning();
DMAs[3]->StallIfRunning();
+ if (ConsoleType == 1) DSi::StallNDMAs();
}
}
@@ -1354,6 +1436,7 @@ void NocashPrint(u32 ncpu, u32 addr)
void MonitorARM9Jump(u32 addr)
{
// checkme: can the entrypoint addr be THUMB?
+ // also TODO: make it work in DSi mode
if ((!RunningGame) && NDSCart::CartROM)
{
@@ -1430,6 +1513,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;
@@ -1437,6 +1543,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 (ConsoleType == 1)
+ {
+ cpu >>= 2;
+ return DSi::NDMAsInMode(cpu, NDMAModes[mode]);
+ }
+
return false;
}
@@ -1447,6 +1560,10 @@ 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 (ConsoleType == 1)
+ {
+ if (DSi::NDMAsRunning(cpu>>2)) return true;
+ }
return false;
}
@@ -1457,6 +1574,12 @@ void CheckDMAs(u32 cpu, u32 mode)
DMAs[cpu+1]->StartIfNeeded(mode);
DMAs[cpu+2]->StartIfNeeded(mode);
DMAs[cpu+3]->StartIfNeeded(mode);
+
+ if (ConsoleType == 1)
+ {
+ cpu >>= 2;
+ DSi::CheckNDMAs(cpu, NDMAModes[mode]);
+ }
}
void StopDMAs(u32 cpu, u32 mode)
@@ -1466,6 +1589,12 @@ void StopDMAs(u32 cpu, u32 mode)
DMAs[cpu+1]->StopIfNeeded(mode);
DMAs[cpu+2]->StopIfNeeded(mode);
DMAs[cpu+3]->StopIfNeeded(mode);
+
+ if (ConsoleType == 1)
+ {
+ cpu >>= 2;
+ DSi::StopNDMAs(cpu, NDMAModes[mode]);
+ }
}
@@ -1658,12 +1787,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)
@@ -1676,6 +1805,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);
}
@@ -1691,7 +1835,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)
@@ -1756,7 +1900,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)
@@ -1821,7 +1965,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)
@@ -1884,7 +2028,10 @@ void ARM9Write8(u32 addr, u8 val)
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
- *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
+ *(u8*)&MainRAM[addr & MainRAMMask] = val;
+#ifdef JIT_ENABLED
+ ARMJIT::InvalidateMainRAMIfNecessary(addr);
+#endif
return;
case 0x03000000:
@@ -1940,7 +2087,10 @@ void ARM9Write16(u32 addr, u16 val)
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
- *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
+ *(u16*)&MainRAM[addr & MainRAMMask] = val;
+#ifdef JIT_ENABLED
+ ARMJIT::InvalidateMainRAMIfNecessary(addr);
+#endif
return;
case 0x03000000:
@@ -2017,7 +2167,10 @@ void ARM9Write32(u32 addr, u32 val)
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
- *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
+ *(u32*)&MainRAM[addr & MainRAMMask] = val;
+#ifdef JIT_ENABLED
+ ARMJIT::InvalidateMainRAMIfNecessary(addr);
+#endif
return ;
case 0x03000000:
@@ -2093,7 +2246,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:
@@ -2123,7 +2276,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;
@@ -2135,7 +2289,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)
@@ -2183,7 +2337,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;
@@ -2195,7 +2349,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)
@@ -2250,7 +2404,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;
@@ -2262,7 +2416,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)
@@ -2322,7 +2476,10 @@ void ARM7Write8(u32 addr, u8 val)
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
- *(u8*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
+ *(u8*)&MainRAM[addr & MainRAMMask] = val;
+#ifdef JIT_ENABLED
+ ARMJIT::InvalidateMainRAMIfNecessary(addr);
+#endif
return;
case 0x03000000:
@@ -2396,7 +2553,10 @@ void ARM7Write16(u32 addr, u16 val)
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
- *(u16*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
+ *(u16*)&MainRAM[addr & MainRAMMask] = val;
+#ifdef JIT_ENABLED
+ ARMJIT::InvalidateMainRAMIfNecessary(addr);
+#endif
return;
case 0x03000000:
@@ -2480,7 +2640,10 @@ void ARM7Write32(u32 addr, u32 val)
#ifdef JIT_ENABLED
ARMJIT::InvalidateMainRAMIfNecessary(addr);
#endif
- *(u32*)&MainRAM[addr & (MAIN_RAM_SIZE - 1)] = val;
+ *(u32*)&MainRAM[addr & MainRAMMask] = val;
+#ifdef JIT_ENABLED
+ ARMJIT::InvalidateMainRAMIfNecessary(addr);
+#endif
return;
case 0x03000000:
@@ -2564,7 +2727,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: