Merge branch 'generic_jit' of https://github.com/Arisotura/melonDS into generic_jit

This commit is contained in:
RSDuck
2020-05-12 16:07:28 +02:00
committed by RSDuck
367 changed files with 28319 additions and 39850 deletions

View File

@ -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: