make it able to switch between DS and DSi modes

This commit is contained in:
Arisotura
2020-06-01 20:36:30 +02:00
parent d7b846619b
commit 43e045357f
16 changed files with 393 additions and 108 deletions

View File

@ -18,6 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#include "ARM.h" #include "ARM.h"
#include "ARMInterpreter.h" #include "ARMInterpreter.h"
#include "AREngine.h" #include "AREngine.h"
@ -101,10 +102,55 @@ void ARM::Reset()
void ARMv5::Reset() void ARMv5::Reset()
{ {
if (NDS::ConsoleType == 1)
{
BusRead8 = DSi::ARM9Read8;
BusRead16 = DSi::ARM9Read16;
BusRead32 = DSi::ARM9Read32;
BusWrite8 = DSi::ARM9Write8;
BusWrite16 = DSi::ARM9Write16;
BusWrite32 = DSi::ARM9Write32;
GetMemRegion = DSi::ARM9GetMemRegion;
}
else
{
BusRead8 = NDS::ARM9Read8;
BusRead16 = NDS::ARM9Read16;
BusRead32 = NDS::ARM9Read32;
BusWrite8 = NDS::ARM9Write8;
BusWrite16 = NDS::ARM9Write16;
BusWrite32 = NDS::ARM9Write32;
GetMemRegion = NDS::ARM9GetMemRegion;
}
CP15Reset(); CP15Reset();
ARM::Reset(); ARM::Reset();
} }
void ARMv4::Reset()
{
if (NDS::ConsoleType)
{
BusRead8 = DSi::ARM7Read8;
BusRead16 = DSi::ARM7Read16;
BusRead32 = DSi::ARM7Read32;
BusWrite8 = DSi::ARM7Write8;
BusWrite16 = DSi::ARM7Write16;
BusWrite32 = DSi::ARM7Write32;
}
else
{
BusRead8 = NDS::ARM7Read8;
BusRead16 = NDS::ARM7Read16;
BusRead32 = NDS::ARM7Read32;
BusWrite8 = NDS::ARM7Write8;
BusWrite16 = NDS::ARM7Write16;
BusWrite32 = NDS::ARM7Write32;
}
ARM::Reset();
}
void ARM::DoSavestate(Savestate* file) void ARM::DoSavestate(Savestate* file)
{ {

View File

@ -23,7 +23,6 @@
#include "types.h" #include "types.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#define ROR(x, n) (((x) >> (n)) | ((x) << (32-(n)))) #define ROR(x, n) (((x) >> (n)) | ((x) << (32-(n))))
@ -133,6 +132,14 @@ public:
NDS::MemRegion CodeMem; NDS::MemRegion CodeMem;
static u32 ConditionTable[16]; static u32 ConditionTable[16];
protected:
u8 (*BusRead8)(u32 addr);
u16 (*BusRead16)(u32 addr);
u32 (*BusRead32)(u32 addr);
void (*BusWrite8)(u32 addr, u8 val);
void (*BusWrite16)(u32 addr, u16 val);
void (*BusWrite32)(u32 addr, u32 val);
}; };
class ARMv5 : public ARM class ARMv5 : public ARM
@ -260,6 +267,8 @@ public:
s32 RegionCodeCycles; s32 RegionCodeCycles;
u8* CurICacheLine; u8* CurICacheLine;
bool (*GetMemRegion)(u32 addr, bool write, NDS::MemRegion* region);
}; };
class ARMv4 : public ARM class ARMv4 : public ARM
@ -267,26 +276,25 @@ class ARMv4 : public ARM
public: public:
ARMv4(); ARMv4();
void Reset();
void JumpTo(u32 addr, bool restorecpsr = false); void JumpTo(u32 addr, bool restorecpsr = false);
void Execute(); void Execute();
u16 CodeRead16(u32 addr) u16 CodeRead16(u32 addr)
{ {
//return NDS::ARM7Read16(addr); return BusRead16(addr);
return DSi::ARM7Read16(addr);
} }
u32 CodeRead32(u32 addr) u32 CodeRead32(u32 addr)
{ {
//return NDS::ARM7Read32(addr); return BusRead32(addr);
return DSi::ARM7Read32(addr);
} }
void DataRead8(u32 addr, u32* val) void DataRead8(u32 addr, u32* val)
{ {
*val = DSi::ARM7Read8(addr); *val = BusRead8(addr);
//*val = NDS::ARM7Read8(addr);
DataRegion = addr >> 24; DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0]; DataCycles = NDS::ARM7MemTimings[DataRegion][0];
} }
@ -295,8 +303,7 @@ public:
{ {
addr &= ~1; addr &= ~1;
*val = DSi::ARM7Read16(addr); *val = BusRead16(addr);
//*val = NDS::ARM7Read16(addr);
DataRegion = addr >> 24; DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0]; DataCycles = NDS::ARM7MemTimings[DataRegion][0];
} }
@ -305,8 +312,7 @@ public:
{ {
addr &= ~3; addr &= ~3;
*val = DSi::ARM7Read32(addr); *val = BusRead32(addr);
//*val = NDS::ARM7Read32(addr);
DataRegion = addr >> 24; DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][2]; DataCycles = NDS::ARM7MemTimings[DataRegion][2];
} }
@ -315,15 +321,13 @@ public:
{ {
addr &= ~3; addr &= ~3;
*val = DSi::ARM7Read32(addr); *val = BusRead32(addr);
//*val = NDS::ARM7Read32(addr);
DataCycles += NDS::ARM7MemTimings[DataRegion][3]; DataCycles += NDS::ARM7MemTimings[DataRegion][3];
} }
void DataWrite8(u32 addr, u8 val) void DataWrite8(u32 addr, u8 val)
{ {
DSi::ARM7Write8(addr, val); BusWrite8(addr, val);
//NDS::ARM7Write8(addr, val);
DataRegion = addr >> 24; DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0]; DataCycles = NDS::ARM7MemTimings[DataRegion][0];
} }
@ -332,8 +336,7 @@ public:
{ {
addr &= ~1; addr &= ~1;
DSi::ARM7Write16(addr, val); BusWrite16(addr, val);
//NDS::ARM7Write16(addr, val);
DataRegion = addr >> 24; DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0]; DataCycles = NDS::ARM7MemTimings[DataRegion][0];
} }
@ -342,8 +345,7 @@ public:
{ {
addr &= ~3; addr &= ~3;
DSi::ARM7Write32(addr, val); BusWrite32(addr, val);
//NDS::ARM7Write32(addr, val);
DataRegion = addr >> 24; DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][2]; DataCycles = NDS::ARM7MemTimings[DataRegion][2];
} }
@ -352,8 +354,7 @@ public:
{ {
addr &= ~3; addr &= ~3;
DSi::ARM7Write32(addr, val); BusWrite32(addr, val);
//NDS::ARM7Write32(addr, val);
DataCycles += NDS::ARM7MemTimings[DataRegion][3]; DataCycles += NDS::ARM7MemTimings[DataRegion][3];
} }

View File

@ -720,8 +720,7 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
if (CodeMem.Mem) return *(u32*)&CodeMem.Mem[addr & CodeMem.Mask]; if (CodeMem.Mem) return *(u32*)&CodeMem.Mem[addr & CodeMem.Mask];
//return NDS::ARM9Read32(addr); return BusRead32(addr);
return DSi::ARM9Read32(addr);
} }
@ -740,8 +739,7 @@ void ARMv5::DataRead8(u32 addr, u32* val)
return; return;
} }
*val = DSi::ARM9Read8(addr); *val = BusRead8(addr);
//*val = NDS::ARM9Read8(addr);
DataCycles = MemTimings[addr >> 12][1]; DataCycles = MemTimings[addr >> 12][1];
} }
@ -762,8 +760,7 @@ void ARMv5::DataRead16(u32 addr, u32* val)
return; return;
} }
*val = DSi::ARM9Read16(addr); *val = BusRead16(addr);
//*val = NDS::ARM9Read16(addr);
DataCycles = MemTimings[addr >> 12][1]; DataCycles = MemTimings[addr >> 12][1];
} }
@ -784,8 +781,7 @@ void ARMv5::DataRead32(u32 addr, u32* val)
return; return;
} }
*val = DSi::ARM9Read32(addr); *val = BusRead32(addr);
//*val = NDS::ARM9Read32(addr);
DataCycles = MemTimings[addr >> 12][2]; DataCycles = MemTimings[addr >> 12][2];
} }
@ -806,8 +802,7 @@ void ARMv5::DataRead32S(u32 addr, u32* val)
return; return;
} }
*val = DSi::ARM9Read32(addr); *val = BusRead32(addr);
//*val = NDS::ARM9Read32(addr);
DataCycles += MemTimings[addr >> 12][3]; DataCycles += MemTimings[addr >> 12][3];
} }
@ -826,8 +821,7 @@ void ARMv5::DataWrite8(u32 addr, u8 val)
return; return;
} }
DSi::ARM9Write8(addr, val); BusWrite8(addr, val);
//NDS::ARM9Write8(addr, val);
DataCycles = MemTimings[addr >> 12][1]; DataCycles = MemTimings[addr >> 12][1];
} }
@ -848,8 +842,7 @@ void ARMv5::DataWrite16(u32 addr, u16 val)
return; return;
} }
DSi::ARM9Write16(addr, val); BusWrite16(addr, val);
//NDS::ARM9Write16(addr, val);
DataCycles = MemTimings[addr >> 12][1]; DataCycles = MemTimings[addr >> 12][1];
} }
@ -870,8 +863,7 @@ void ARMv5::DataWrite32(u32 addr, u32 val)
return; return;
} }
DSi::ARM9Write32(addr, val); BusWrite32(addr, val);
//NDS::ARM9Write32(addr, val);
DataCycles = MemTimings[addr >> 12][2]; DataCycles = MemTimings[addr >> 12][2];
} }
@ -892,8 +884,7 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)
return; return;
} }
DSi::ARM9Write32(addr, val); BusWrite32(addr, val);
//NDS::ARM9Write32(addr, val);
DataCycles += MemTimings[addr >> 12][3]; DataCycles += MemTimings[addr >> 12][3];
} }
@ -906,7 +897,6 @@ void ARMv5::GetCodeMemRegion(u32 addr, NDS::MemRegion* region)
return; return;
}*/ }*/
DSi::ARM9GetMemRegion(addr, false, &CodeMem); GetMemRegion(addr, false, &CodeMem);
//NDS::ARM9GetMemRegion(addr, false, &CodeMem);
} }

View File

@ -53,8 +53,6 @@ DMA::DMA(u32 cpu, u32 num)
CountMask = 0x001FFFFF; CountMask = 0x001FFFFF;
else else
CountMask = (num==3 ? 0x0000FFFF : 0x00003FFF); CountMask = (num==3 ? 0x0000FFFF : 0x00003FFF);
Reset();
} }
DMA::~DMA() DMA::~DMA()
@ -77,6 +75,21 @@ void DMA::Reset()
Running = false; Running = false;
InProgress = false; InProgress = false;
if (NDS::ConsoleType == 1)
{
BusRead16 = (CPU==0) ? DSi::ARM9Read16 : DSi::ARM7Read16;
BusRead32 = (CPU==0) ? DSi::ARM9Read32 : DSi::ARM7Read32;
BusWrite16 = (CPU==0) ? DSi::ARM9Write16 : DSi::ARM7Write16;
BusWrite32 = (CPU==0) ? DSi::ARM9Write32 : DSi::ARM7Write32;
}
else
{
BusRead16 = (CPU==0) ? NDS::ARM9Read16 : NDS::ARM7Read16;
BusRead32 = (CPU==0) ? NDS::ARM9Read32 : NDS::ARM7Read32;
BusWrite16 = (CPU==0) ? NDS::ARM9Write16 : NDS::ARM7Write16;
BusWrite32 = (CPU==0) ? NDS::ARM9Write32 : NDS::ARM7Write32;
}
} }
void DMA::DoSavestate(Savestate* file) void DMA::DoSavestate(Savestate* file)
@ -227,8 +240,7 @@ void DMA::Run9()
{ {
NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift); NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift);
//NDS::ARM9Write16(CurDstAddr, NDS::ARM9Read16(CurSrcAddr)); BusWrite16(CurDstAddr, BusRead16(CurSrcAddr));
DSi::ARM9Write16(CurDstAddr, DSi::ARM9Read16(CurSrcAddr));
CurSrcAddr += SrcAddrInc<<1; CurSrcAddr += SrcAddrInc<<1;
CurDstAddr += DstAddrInc<<1; CurDstAddr += DstAddrInc<<1;
@ -264,8 +276,7 @@ void DMA::Run9()
{ {
NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift); NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift);
//NDS::ARM9Write32(CurDstAddr, NDS::ARM9Read32(CurSrcAddr)); BusWrite32(CurDstAddr, BusRead32(CurSrcAddr));
DSi::ARM9Write32(CurDstAddr, DSi::ARM9Read32(CurSrcAddr));
CurSrcAddr += SrcAddrInc<<2; CurSrcAddr += SrcAddrInc<<2;
CurDstAddr += DstAddrInc<<2; CurDstAddr += DstAddrInc<<2;
@ -341,8 +352,7 @@ void DMA::Run7()
{ {
NDS::ARM7Timestamp += unitcycles; NDS::ARM7Timestamp += unitcycles;
//NDS::ARM7Write16(CurDstAddr, NDS::ARM7Read16(CurSrcAddr)); BusWrite16(CurDstAddr, BusRead16(CurSrcAddr));
DSi::ARM7Write16(CurDstAddr, DSi::ARM7Read16(CurSrcAddr));
CurSrcAddr += SrcAddrInc<<1; CurSrcAddr += SrcAddrInc<<1;
CurDstAddr += DstAddrInc<<1; CurDstAddr += DstAddrInc<<1;
@ -378,8 +388,7 @@ void DMA::Run7()
{ {
NDS::ARM7Timestamp += unitcycles; NDS::ARM7Timestamp += unitcycles;
//NDS::ARM7Write32(CurDstAddr, NDS::ARM7Read32(CurSrcAddr)); BusWrite32(CurDstAddr, BusRead32(CurSrcAddr));
DSi::ARM7Write32(CurDstAddr, DSi::ARM7Read32(CurSrcAddr));
CurSrcAddr += SrcAddrInc<<2; CurSrcAddr += SrcAddrInc<<2;
CurDstAddr += DstAddrInc<<2; CurDstAddr += DstAddrInc<<2;

View File

@ -86,6 +86,11 @@ private:
bool Stall; bool Stall;
bool IsGXFIFODMA; bool IsGXFIFODMA;
u16 (*BusRead16)(u32 addr);
u32 (*BusRead32)(u32 addr);
void (*BusWrite16)(u32 addr, u16 val);
void (*BusWrite32)(u32 addr, u32 val);
}; };
#endif #endif

View File

@ -18,6 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "Config.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h" #include "DSi.h"
#include "ARM.h" #include "ARM.h"
@ -221,7 +222,7 @@ bool LoadBIOS()
memset(ARM9iBIOS, 0, 0x10000); memset(ARM9iBIOS, 0, 0x10000);
memset(ARM7iBIOS, 0, 0x10000); memset(ARM7iBIOS, 0, 0x10000);
f = Platform::OpenLocalFile("bios9i.bin", "rb"); f = Platform::OpenLocalFile(Config::DSiBIOS9Path, "rb");
if (!f) if (!f)
{ {
printf("ARM9i BIOS not found\n"); printf("ARM9i BIOS not found\n");
@ -238,7 +239,7 @@ bool LoadBIOS()
fclose(f); fclose(f);
} }
f = Platform::OpenLocalFile("bios7i.bin", "rb"); f = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
if (!f) if (!f)
{ {
printf("ARM7i BIOS not found\n"); printf("ARM7i BIOS not found\n");
@ -283,7 +284,7 @@ bool LoadNAND()
memset(NWRAMEnd, 0, sizeof(NWRAMEnd)); memset(NWRAMEnd, 0, sizeof(NWRAMEnd));
memset(NWRAMMask, 0, sizeof(NWRAMMask)); memset(NWRAMMask, 0, sizeof(NWRAMMask));
FILE* f = Platform::OpenLocalFile("nand.bin", "rb"); FILE* f = Platform::OpenLocalFile(Config::DSiNANDPath, "rb");
if (f) if (f)
{ {
u32 bootparams[8]; u32 bootparams[8];

View File

@ -62,6 +62,8 @@ namespace NDS
// //
// timings for GBA slot and wifi are set up at runtime // timings for GBA slot and wifi are set up at runtime
int ConsoleType;
u8 ARM9MemTimings[0x40000][4]; u8 ARM9MemTimings[0x40000][4];
u8 ARM7MemTimings[0x20000][4]; u8 ARM7MemTimings[0x20000][4];
@ -296,6 +298,8 @@ void InitTimings()
// TODO: +3c nonseq waitstate doesn't apply to DMA! // TODO: +3c nonseq waitstate doesn't apply to DMA!
// but of course mainRAM always gets 8c nonseq waitstate // but of course mainRAM always gets 8c nonseq waitstate
// TODO: DSi-specific timings!!
SetARM9RegionTimings(0x00000000, 0xFFFFFFFF, 32, 1 + 3, 1); // void SetARM9RegionTimings(0x00000000, 0xFFFFFFFF, 32, 1 + 3, 1); // void
SetARM9RegionTimings(0xFFFF0000, 0xFFFFFFFF, 32, 1 + 3, 1); // BIOS SetARM9RegionTimings(0xFFFF0000, 0xFFFFFFFF, 32, 1 + 3, 1); // BIOS
@ -321,6 +325,12 @@ void InitTimings()
void SetupDirectBoot() void SetupDirectBoot()
{ {
if (ConsoleType == 1)
{
printf("!! DIRECT BOOT NOT SUPPORTED IN DSI MODE\n");
return;
}
u32 bootparams[8]; u32 bootparams[8];
memcpy(bootparams, &NDSCart::CartROM[0x20], 8*4); memcpy(bootparams, &NDSCart::CartROM[0x20], 8*4);
@ -469,7 +479,7 @@ void Reset()
fclose(f); fclose(f);
} }
if (true) if (ConsoleType == 1)
{ {
DSi::LoadBIOS(); DSi::LoadBIOS();
DSi::LoadNAND(); DSi::LoadNAND();
@ -559,8 +569,11 @@ void Reset()
RTC::Reset(); RTC::Reset();
Wifi::Reset(); Wifi::Reset();
DSi::Reset(); if (ConsoleType == 1)
KeyInput &= ~(1 << (16+6)); // TODO {
DSi::Reset();
KeyInput &= ~(1 << (16+6));
}
AREngine::Reset(); AREngine::Reset();
} }
@ -670,6 +683,11 @@ bool DoSavestate(Savestate* file)
{ {
file->Section("NDSG"); 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(MainRAM, 0x400000);
file->VarArray(SharedWRAM, 0x8000); file->VarArray(SharedWRAM, 0x8000);
file->VarArray(ARM7WRAM, 0x10000); file->VarArray(ARM7WRAM, 0x10000);
@ -772,6 +790,11 @@ bool DoSavestate(Savestate* file)
return true; return true;
} }
void SetConsoleType(int type)
{
ConsoleType = type;
}
bool LoadROM(const char* path, const char* sram, bool direct) bool LoadROM(const char* path, const char* sram, bool direct)
{ {
if (NDSCart::LoadROM(path, sram, direct)) if (NDSCart::LoadROM(path, sram, direct))
@ -883,7 +906,7 @@ u32 RunFrame()
if (!(CPUStop & 0x80000000)) DMAs[1]->Run(); if (!(CPUStop & 0x80000000)) DMAs[1]->Run();
if (!(CPUStop & 0x80000000)) DMAs[2]->Run(); if (!(CPUStop & 0x80000000)) DMAs[2]->Run();
if (!(CPUStop & 0x80000000)) DMAs[3]->Run(); if (!(CPUStop & 0x80000000)) DMAs[3]->Run();
DSi::RunNDMAs(0); if (ConsoleType == 1) DSi::RunNDMAs(0);
} }
else else
{ {
@ -906,7 +929,7 @@ u32 RunFrame()
DMAs[5]->Run(); DMAs[5]->Run();
DMAs[6]->Run(); DMAs[6]->Run();
DMAs[7]->Run(); DMAs[7]->Run();
DSi::RunNDMAs(1); if (ConsoleType == 1) DSi::RunNDMAs(1);
} }
else else
{ {
@ -990,7 +1013,7 @@ void CancelEvent(u32 id)
void TouchScreen(u16 x, u16 y) void TouchScreen(u16 x, u16 y)
{ {
if (true) // TODO!! if (ConsoleType == 1)
{ {
DSi_SPI_TSC::SetTouchCoords(x, y); DSi_SPI_TSC::SetTouchCoords(x, y);
} }
@ -1003,7 +1026,7 @@ void TouchScreen(u16 x, u16 y)
void ReleaseScreen() void ReleaseScreen()
{ {
if (true) // TODO!! if (ConsoleType == 1)
{ {
DSi_SPI_TSC::SetTouchCoords(0x000, 0xFFF); DSi_SPI_TSC::SetTouchCoords(0x000, 0xFFF);
} }
@ -1144,7 +1167,8 @@ void UpdateIRQ(u32 cpu)
if (IME[cpu] & 0x1) if (IME[cpu] & 0x1)
{ {
arm->IRQ = IE[cpu] & IF[cpu]; arm->IRQ = IE[cpu] & IF[cpu];
if (cpu) arm->IRQ |= (IE2 & IF2); if ((ConsoleType == 1) && cpu)
arm->IRQ |= (IE2 & IF2);
} }
else else
{ {
@ -1223,7 +1247,7 @@ void GXFIFOStall()
DMAs[1]->StallIfRunning(); DMAs[1]->StallIfRunning();
DMAs[2]->StallIfRunning(); DMAs[2]->StallIfRunning();
DMAs[3]->StallIfRunning(); DMAs[3]->StallIfRunning();
DSi::StallNDMAs(); if (ConsoleType == 1) DSi::StallNDMAs();
} }
} }
@ -1361,6 +1385,7 @@ void NocashPrint(u32 ncpu, u32 addr)
void MonitorARM9Jump(u32 addr) void MonitorARM9Jump(u32 addr)
{ {
// checkme: can the entrypoint addr be THUMB? // checkme: can the entrypoint addr be THUMB?
// also TODO: make it work in DSi mode
if ((!RunningGame) && NDSCart::CartROM) if ((!RunningGame) && NDSCart::CartROM)
{ {
@ -1468,7 +1493,7 @@ bool DMAsInMode(u32 cpu, u32 mode)
if (DMAs[cpu+2]->IsInMode(mode)) return true; if (DMAs[cpu+2]->IsInMode(mode)) return true;
if (DMAs[cpu+3]->IsInMode(mode)) return true; if (DMAs[cpu+3]->IsInMode(mode)) return true;
if (true) if (ConsoleType == 1)
{ {
cpu >>= 2; cpu >>= 2;
return DSi::NDMAsInMode(cpu, NDMAModes[mode]); return DSi::NDMAsInMode(cpu, NDMAModes[mode]);
@ -1484,7 +1509,10 @@ bool DMAsRunning(u32 cpu)
if (DMAs[cpu+1]->IsRunning()) return true; if (DMAs[cpu+1]->IsRunning()) return true;
if (DMAs[cpu+2]->IsRunning()) return true; if (DMAs[cpu+2]->IsRunning()) return true;
if (DMAs[cpu+3]->IsRunning()) return true; if (DMAs[cpu+3]->IsRunning()) return true;
if (DSi::NDMAsRunning(cpu>>2)) return true; if (ConsoleType == 1)
{
if (DSi::NDMAsRunning(cpu>>2)) return true;
}
return false; return false;
} }
@ -1496,7 +1524,7 @@ void CheckDMAs(u32 cpu, u32 mode)
DMAs[cpu+2]->StartIfNeeded(mode); DMAs[cpu+2]->StartIfNeeded(mode);
DMAs[cpu+3]->StartIfNeeded(mode); DMAs[cpu+3]->StartIfNeeded(mode);
if (true) if (ConsoleType == 1)
{ {
cpu >>= 2; cpu >>= 2;
DSi::CheckNDMAs(cpu, NDMAModes[mode]); DSi::CheckNDMAs(cpu, NDMAModes[mode]);
@ -1511,7 +1539,7 @@ void StopDMAs(u32 cpu, u32 mode)
DMAs[cpu+2]->StopIfNeeded(mode); DMAs[cpu+2]->StopIfNeeded(mode);
DMAs[cpu+3]->StopIfNeeded(mode); DMAs[cpu+3]->StopIfNeeded(mode);
if (true) if (ConsoleType == 1)
{ {
cpu >>= 2; cpu >>= 2;
DSi::StopNDMAs(cpu, NDMAModes[mode]); DSi::StopNDMAs(cpu, NDMAModes[mode]);

View File

@ -133,6 +133,8 @@ typedef struct
} MemRegion; } MemRegion;
extern int ConsoleType;
extern u8 ARM9MemTimings[0x40000][4]; extern u8 ARM9MemTimings[0x40000][4];
extern u8 ARM7MemTimings[0x20000][4]; extern u8 ARM7MemTimings[0x20000][4];
@ -174,6 +176,9 @@ bool DoSavestate(Savestate* file);
void SetARM9RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq); void SetARM9RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq);
void SetARM7RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq); void SetARM7RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq);
// 0=DS 1=DSi
void SetConsoleType(int type);
bool LoadROM(const char* path, const char* sram, bool direct); bool LoadROM(const char* path, const char* sram, bool direct);
bool LoadGBAROM(const char* path, const char* sram); bool LoadGBAROM(const char* path, const char* sram);
void LoadBIOS(); void LoadBIOS();

View File

@ -561,11 +561,18 @@ void Key1_ApplyKeycode(u32* keycode, u32 mod)
void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod) void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod)
{ {
//memcpy(Key1_KeyBuf, &NDS::ARM7BIOS[0x30], 0x1048); // hax // TODO: source the key data from different possible places
if (dsi) if (NDS::ConsoleType == 1)
memcpy(Key1_KeyBuf, &DSi::ARM7Init[0x254], 0x1048); // hax {
if (dsi)
memcpy(Key1_KeyBuf, &DSi::ARM7Init[0x254], 0x1048); // hax
else
memcpy(Key1_KeyBuf, &DSi::ITCMInit[0x4894], 0x1048); // hax
}
else else
memcpy(Key1_KeyBuf, &DSi::ITCMInit[0x4894], 0x1048); // hax {
memcpy(Key1_KeyBuf, &NDS::ARM7BIOS[0x30], 0x1048); // hax
}
u32 keycode[3] = {idcode, idcode>>1, idcode<<1}; u32 keycode[3] = {idcode, idcode>>1, idcode<<1};
if (level >= 1) Key1_ApplyKeycode(keycode, mod); if (level >= 1) Key1_ApplyKeycode(keycode, mod);

View File

@ -93,7 +93,10 @@ void Reset()
if (Firmware) delete[] Firmware; if (Firmware) delete[] Firmware;
Firmware = NULL; Firmware = NULL;
strncpy(FirmwarePath, Config::FirmwarePath, 1023); if (NDS::ConsoleType == 1)
strncpy(FirmwarePath, Config::DSiFirmwarePath, 1023);
else
strncpy(FirmwarePath, Config::FirmwarePath, 1023);
FILE* f = Platform::OpenLocalFile(FirmwarePath, "rb"); FILE* f = Platform::OpenLocalFile(FirmwarePath, "rb");
if (!f) if (!f)
@ -620,7 +623,7 @@ void Reset()
SPI_Firmware::Reset(); SPI_Firmware::Reset();
SPI_Powerman::Reset(); SPI_Powerman::Reset();
SPI_TSC::Reset(); SPI_TSC::Reset();
DSi_SPI_TSC::Reset(); if (NDS::ConsoleType == 1) DSi_SPI_TSC::Reset();
} }
void DoSavestate(Savestate* file) void DoSavestate(Savestate* file)
@ -633,7 +636,7 @@ void DoSavestate(Savestate* file)
SPI_Firmware::DoSavestate(file); SPI_Firmware::DoSavestate(file);
SPI_Powerman::DoSavestate(file); SPI_Powerman::DoSavestate(file);
SPI_TSC::DoSavestate(file); SPI_TSC::DoSavestate(file);
DSi_SPI_TSC::DoSavestate(file); if (NDS::ConsoleType == 1) DSi_SPI_TSC::DoSavestate(file);
} }
@ -647,8 +650,12 @@ void WriteCnt(u16 val)
{ {
case 0x0000: SPI_Powerman::Hold = 0; break; case 0x0000: SPI_Powerman::Hold = 0; break;
case 0x0100: SPI_Firmware::Hold = 0; break; case 0x0100: SPI_Firmware::Hold = 0; break;
//case 0x0200: SPI_TSC::DataPos = 0; break; case 0x0200:
case 0x0200: DSi_SPI_TSC::DataPos = 0; break; if (NDS::ConsoleType == 1)
DSi_SPI_TSC::DataPos = 0;
else
SPI_TSC::DataPos = 0;
break;
} }
} }
@ -674,8 +681,11 @@ u8 ReadData()
{ {
case 0x0000: return SPI_Powerman::Read(); case 0x0000: return SPI_Powerman::Read();
case 0x0100: return SPI_Firmware::Read(); case 0x0100: return SPI_Firmware::Read();
//case 0x0200: return SPI_TSC::Read(); case 0x0200:
case 0x0200: return DSi_SPI_TSC::Read(); if (NDS::ConsoleType == 1)
return DSi_SPI_TSC::Read();
else
return SPI_TSC::Read();
default: return 0; default: return 0;
} }
} }
@ -691,8 +701,12 @@ void WriteData(u8 val)
{ {
case 0x0000: SPI_Powerman::Write(val, Cnt&(1<<11)); break; case 0x0000: SPI_Powerman::Write(val, Cnt&(1<<11)); break;
case 0x0100: SPI_Firmware::Write(val, Cnt&(1<<11)); break; case 0x0100: SPI_Firmware::Write(val, Cnt&(1<<11)); break;
//case 0x0200: SPI_TSC::Write(val, Cnt&(1<<11)); break; case 0x0200:
case 0x0200: DSi_SPI_TSC::Write(val, Cnt&(1<<11)); break; if (NDS::ConsoleType == 1)
DSi_SPI_TSC::Write(val, Cnt&(1<<11));
else
SPI_TSC::Write(val, Cnt&(1<<11));
break;
default: printf("SPI to unknown device %04X %02X\n", Cnt, val); break; default: printf("SPI to unknown device %04X %02X\n", Cnt, val); break;
} }

View File

@ -155,6 +155,11 @@ Channel::~Channel()
void Channel::Reset() void Channel::Reset()
{ {
if (NDS::ConsoleType == 1)
BusRead32 = DSi::ARM7Read32;
else
BusRead32 = NDS::ARM7Read32;
SetCnt(0); SetCnt(0);
SrcAddr = 0; SrcAddr = 0;
TimerReload = 0; TimerReload = 0;
@ -217,8 +222,7 @@ void Channel::FIFO_BufferData()
for (u32 i = 0; i < burstlen; i += 4) for (u32 i = 0; i < burstlen; i += 4)
{ {
//FIFO[FIFOWritePos] = NDS::ARM7Read32(SrcAddr + FIFOReadOffset); FIFO[FIFOWritePos] = BusRead32(SrcAddr + FIFOReadOffset);
FIFO[FIFOWritePos] = DSi::ARM7Read32(SrcAddr + FIFOReadOffset);
FIFOReadOffset += 4; FIFOReadOffset += 4;
FIFOWritePos++; FIFOWritePos++;
FIFOWritePos &= 0x7; FIFOWritePos &= 0x7;
@ -466,6 +470,11 @@ CaptureUnit::~CaptureUnit()
void CaptureUnit::Reset() void CaptureUnit::Reset()
{ {
if (NDS::ConsoleType == 1)
BusWrite32 = DSi::ARM7Write32;
else
BusWrite32 = NDS::ARM7Write32;
SetCnt(0); SetCnt(0);
DstAddr = 0; DstAddr = 0;
TimerReload = 0; TimerReload = 0;
@ -501,8 +510,7 @@ void CaptureUnit::FIFO_FlushData()
{ {
for (u32 i = 0; i < 4; i++) for (u32 i = 0; i < 4; i++)
{ {
//NDS::ARM7Write32(DstAddr + FIFOWriteOffset, FIFO[FIFOReadPos]); BusWrite32(DstAddr + FIFOWriteOffset, FIFO[FIFOReadPos]);
DSi::ARM7Write32(DstAddr + FIFOWriteOffset, FIFO[FIFOReadPos]);
FIFOReadPos++; FIFOReadPos++;
FIFOReadPos &= 0x3; FIFOReadPos &= 0x3;

View File

@ -142,6 +142,9 @@ public:
} }
void PanOutput(s32* inbuf, u32 samples, s32* leftbuf, s32* rightbuf); void PanOutput(s32* inbuf, u32 samples, s32* leftbuf, s32* rightbuf);
private:
u32 (*BusRead32)(u32 addr);
}; };
class CaptureUnit class CaptureUnit
@ -196,6 +199,9 @@ public:
} }
void Run(s32 sample); void Run(s32 sample);
private:
void (*BusWrite32)(u32 addr, u32 val);
}; };
} }

View File

@ -46,6 +46,15 @@ enum
Load_FirmwareBad, Load_FirmwareBad,
Load_FirmwareNotBootable, Load_FirmwareNotBootable,
Load_DSiBIOS9Missing,
Load_DSiBIOS9Bad,
Load_DSiBIOS7Missing,
Load_DSiBIOS7Bad,
Load_DSiNANDMissing,
Load_DSiNANDBad,
// TODO: more precise errors for ROM loading // TODO: more precise errors for ROM loading
Load_ROMLoadError, Load_ROMLoadError,
}; };

View File

@ -96,6 +96,42 @@ int VerifyDSBIOS()
return Load_OK; return Load_OK;
} }
int VerifyDSiBIOS()
{
FILE* f;
long len;
// TODO: check the first 32 bytes
f = Platform::OpenLocalFile(Config::DSiBIOS9Path, "rb");
if (!f) return Load_DSiBIOS9Missing;
fseek(f, 0, SEEK_END);
len = ftell(f);
if (len != 0x10000)
{
fclose(f);
return Load_DSiBIOS9Bad;
}
fclose(f);
f = Platform::OpenLocalFile(Config::DSiBIOS7Path, "rb");
if (!f) return Load_DSiBIOS7Missing;
fseek(f, 0, SEEK_END);
len = ftell(f);
if (len != 0x10000)
{
fclose(f);
return Load_DSiBIOS7Bad;
}
fclose(f);
return Load_OK;
}
int VerifyDSFirmware() int VerifyDSFirmware()
{ {
FILE* f; FILE* f;
@ -110,7 +146,6 @@ int VerifyDSFirmware()
{ {
// 128KB firmware, not bootable // 128KB firmware, not bootable
fclose(f); fclose(f);
return Load_OK; // FIXME!!!!
return Load_FirmwareNotBootable; return Load_FirmwareNotBootable;
} }
else if (len != 0x40000 && len != 0x80000) else if (len != 0x40000 && len != 0x80000)
@ -124,6 +159,45 @@ int VerifyDSFirmware()
return Load_OK; return Load_OK;
} }
int VerifyDSiFirmware()
{
FILE* f;
long len;
f = Platform::OpenLocalFile(Config::DSiFirmwarePath, "rb");
if (!f) return Load_FirmwareMissing;
fseek(f, 0, SEEK_END);
len = ftell(f);
if (len != 0x20000)
{
// not 128KB
// TODO: check whether those work
fclose(f);
return Load_FirmwareBad;
}
fclose(f);
return Load_OK;
}
int VerifyDSiNAND()
{
FILE* f;
long len;
f = Platform::OpenLocalFile(Config::DSiNANDPath, "rb");
if (!f) return Load_DSiNANDMissing;
// TODO: some basic checks
// check that it has the nocash footer, and all
fclose(f);
return Load_OK;
}
int LoadBIOS() int LoadBIOS()
{ {
int res; int res;
@ -131,8 +205,22 @@ int LoadBIOS()
res = VerifyDSBIOS(); res = VerifyDSBIOS();
if (res != Load_OK) return res; if (res != Load_OK) return res;
res = VerifyDSFirmware(); if (Config::ConsoleType == 1)
if (res != Load_OK) return res; {
res = VerifyDSiBIOS();
if (res != Load_OK) return res;
res = VerifyDSiFirmware();
if (res != Load_OK) return res;
res = VerifyDSiNAND();
if (res != Load_OK) return res;
}
else
{
res = VerifyDSFirmware();
if (res != Load_OK) return res;
}
// TODO: // TODO:
// original code in the libui frontend called NDS::LoadGBAROM() if needed // original code in the libui frontend called NDS::LoadGBAROM() if needed
@ -142,6 +230,7 @@ int LoadBIOS()
ROMPath[ROMSlot_NDS][0] = '\0'; ROMPath[ROMSlot_NDS][0] = '\0';
SRAMPath[ROMSlot_NDS][0] = '\0'; SRAMPath[ROMSlot_NDS][0] = '\0';
NDS::SetConsoleType(Config::ConsoleType);
NDS::LoadBIOS(); NDS::LoadBIOS();
SavestateLoaded = false; SavestateLoaded = false;
@ -154,16 +243,39 @@ int LoadROM(const char* file, int slot)
int res; int res;
bool directboot = Config::DirectBoot != 0; bool directboot = Config::DirectBoot != 0;
if (Config::ConsoleType == 1 && slot == 1)
{
// cannot load a GBA ROM into a DSi
return Load_ROMLoadError;
}
res = VerifyDSBIOS(); res = VerifyDSBIOS();
if (res != Load_OK) return res; if (res != Load_OK) return res;
res = VerifyDSFirmware(); if (Config::ConsoleType == 1)
if (res != Load_OK)
{ {
if (res == Load_FirmwareNotBootable) res = VerifyDSiBIOS();
directboot = true; if (res != Load_OK) return res;
else
return res; res = VerifyDSiFirmware();
if (res != Load_OK) return res;
res = VerifyDSiNAND();
if (res != Load_OK) return res;
GBACart::Eject();
ROMPath[ROMSlot_GBA][0] = '\0';
}
else
{
res = VerifyDSFirmware();
if (res != Load_OK)
{
if (res == Load_FirmwareNotBootable)
directboot = true;
else
return res;
}
} }
char oldpath[1024]; char oldpath[1024];
@ -177,6 +289,8 @@ int LoadROM(const char* file, int slot)
SetupSRAMPath(0); SetupSRAMPath(0);
SetupSRAMPath(1); SetupSRAMPath(1);
NDS::SetConsoleType(Config::ConsoleType);
if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot)) if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot))
{ {
SavestateLoaded = false; SavestateLoaded = false;
@ -225,17 +339,36 @@ int Reset()
res = VerifyDSBIOS(); res = VerifyDSBIOS();
if (res != Load_OK) return res; if (res != Load_OK) return res;
res = VerifyDSFirmware(); if (Config::ConsoleType == 1)
if (res != Load_OK)
{ {
if (res == Load_FirmwareNotBootable) res = VerifyDSiBIOS();
directboot = true; if (res != Load_OK) return res;
else
return res; res = VerifyDSiFirmware();
if (res != Load_OK) return res;
res = VerifyDSiNAND();
if (res != Load_OK) return res;
GBACart::Eject();
ROMPath[ROMSlot_GBA][0] = '\0';
}
else
{
res = VerifyDSFirmware();
if (res != Load_OK)
{
if (res == Load_FirmwareNotBootable)
directboot = true;
else
return res;
}
} }
SavestateLoaded = false; SavestateLoaded = false;
NDS::SetConsoleType(Config::ConsoleType);
if (ROMPath[ROMSlot_NDS][0] == '\0') if (ROMPath[ROMSlot_NDS][0] == '\0')
{ {
NDS::LoadBIOS(); NDS::LoadBIOS();

View File

@ -49,7 +49,7 @@ EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new
ui->txtDSiNANDPath->setText(Config::DSiNANDPath); ui->txtDSiNANDPath->setText(Config::DSiNANDPath);
ui->cbxConsoleType->addItem("DS"); ui->cbxConsoleType->addItem("DS");
ui->cbxConsoleType->addItem("DSi"); ui->cbxConsoleType->addItem("DSi (experimental)");
ui->cbxConsoleType->setCurrentIndex(Config::ConsoleType); ui->cbxConsoleType->setCurrentIndex(Config::ConsoleType);
ui->chkDirectBoot->setChecked(Config::DirectBoot != 0); ui->chkDirectBoot->setChecked(Config::DirectBoot != 0);

View File

@ -1360,17 +1360,40 @@ QString MainWindow::loadErrorStr(int error)
{ {
switch (error) switch (error)
{ {
case Frontend::Load_BIOS9Missing: return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings."; case Frontend::Load_BIOS9Missing:
case Frontend::Load_BIOS9Bad: return "DS ARM9 BIOS is not a valid BIOS dump."; return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
case Frontend::Load_BIOS9Bad:
return "DS ARM9 BIOS is not a valid BIOS dump.";
case Frontend::Load_BIOS7Missing: return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings."; case Frontend::Load_BIOS7Missing:
case Frontend::Load_BIOS7Bad: return "DS ARM7 BIOS is not a valid BIOS dump."; return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
case Frontend::Load_BIOS7Bad:
return "DS ARM7 BIOS is not a valid BIOS dump.";
case Frontend::Load_FirmwareMissing: return "DS firmware was not found or could not be accessed. Check your emu settings."; case Frontend::Load_FirmwareMissing:
case Frontend::Load_FirmwareBad: return "DS firmware is not a valid firmware dump."; return "DS firmware was not found or could not be accessed. Check your emu settings.";
case Frontend::Load_FirmwareNotBootable: return "DS firmware is not bootable."; case Frontend::Load_FirmwareBad:
return "DS firmware is not a valid firmware dump.";
case Frontend::Load_FirmwareNotBootable:
return "DS firmware is not bootable.";
case Frontend::Load_ROMLoadError: return "Failed to load the ROM. Make sure the file is accessible and isn't used by another application."; case Frontend::Load_DSiBIOS9Missing:
return "DSi ARM9 BIOS was not found or could not be accessed. Check your emu settings.";
case Frontend::Load_DSiBIOS9Bad:
return "DSi ARM9 BIOS is not a valid BIOS dump.";
case Frontend::Load_DSiBIOS7Missing:
return "DSi ARM7 BIOS was not found or could not be accessed. Check your emu settings.";
case Frontend::Load_DSiBIOS7Bad:
return "DSi ARM7 BIOS is not a valid BIOS dump.";
case Frontend::Load_DSiNANDMissing:
return "DSi NAND was not found or could not be accessed. Check your emu settings.";
case Frontend::Load_DSiNANDBad:
return "DSi NAND is not a valid NAND dump.";
case Frontend::Load_ROMLoadError:
return "Failed to load the ROM. Make sure the file is accessible and isn't used by another application.";
default: return "Unknown error during launch; smack Arisotura."; default: return "Unknown error during launch; smack Arisotura.";
} }