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 "NDS.h"
#include "DSi.h"
#include "ARM.h"
#include "ARMInterpreter.h"
#include "AREngine.h"
@ -101,10 +102,55 @@ void ARM::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();
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)
{

View File

@ -23,7 +23,6 @@
#include "types.h"
#include "NDS.h"
#include "DSi.h"
#define ROR(x, n) (((x) >> (n)) | ((x) << (32-(n))))
@ -133,6 +132,14 @@ public:
NDS::MemRegion CodeMem;
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
@ -260,6 +267,8 @@ public:
s32 RegionCodeCycles;
u8* CurICacheLine;
bool (*GetMemRegion)(u32 addr, bool write, NDS::MemRegion* region);
};
class ARMv4 : public ARM
@ -267,26 +276,25 @@ class ARMv4 : public ARM
public:
ARMv4();
void Reset();
void JumpTo(u32 addr, bool restorecpsr = false);
void Execute();
u16 CodeRead16(u32 addr)
{
//return NDS::ARM7Read16(addr);
return DSi::ARM7Read16(addr);
return BusRead16(addr);
}
u32 CodeRead32(u32 addr)
{
//return NDS::ARM7Read32(addr);
return DSi::ARM7Read32(addr);
return BusRead32(addr);
}
void DataRead8(u32 addr, u32* val)
{
*val = DSi::ARM7Read8(addr);
//*val = NDS::ARM7Read8(addr);
*val = BusRead8(addr);
DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0];
}
@ -295,8 +303,7 @@ public:
{
addr &= ~1;
*val = DSi::ARM7Read16(addr);
//*val = NDS::ARM7Read16(addr);
*val = BusRead16(addr);
DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0];
}
@ -305,8 +312,7 @@ public:
{
addr &= ~3;
*val = DSi::ARM7Read32(addr);
//*val = NDS::ARM7Read32(addr);
*val = BusRead32(addr);
DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][2];
}
@ -315,15 +321,13 @@ public:
{
addr &= ~3;
*val = DSi::ARM7Read32(addr);
//*val = NDS::ARM7Read32(addr);
*val = BusRead32(addr);
DataCycles += NDS::ARM7MemTimings[DataRegion][3];
}
void DataWrite8(u32 addr, u8 val)
{
DSi::ARM7Write8(addr, val);
//NDS::ARM7Write8(addr, val);
BusWrite8(addr, val);
DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0];
}
@ -332,8 +336,7 @@ public:
{
addr &= ~1;
DSi::ARM7Write16(addr, val);
//NDS::ARM7Write16(addr, val);
BusWrite16(addr, val);
DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][0];
}
@ -342,8 +345,7 @@ public:
{
addr &= ~3;
DSi::ARM7Write32(addr, val);
//NDS::ARM7Write32(addr, val);
BusWrite32(addr, val);
DataRegion = addr >> 24;
DataCycles = NDS::ARM7MemTimings[DataRegion][2];
}
@ -352,8 +354,7 @@ public:
{
addr &= ~3;
DSi::ARM7Write32(addr, val);
//NDS::ARM7Write32(addr, val);
BusWrite32(addr, val);
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];
//return NDS::ARM9Read32(addr);
return DSi::ARM9Read32(addr);
return BusRead32(addr);
}
@ -740,8 +739,7 @@ void ARMv5::DataRead8(u32 addr, u32* val)
return;
}
*val = DSi::ARM9Read8(addr);
//*val = NDS::ARM9Read8(addr);
*val = BusRead8(addr);
DataCycles = MemTimings[addr >> 12][1];
}
@ -762,8 +760,7 @@ void ARMv5::DataRead16(u32 addr, u32* val)
return;
}
*val = DSi::ARM9Read16(addr);
//*val = NDS::ARM9Read16(addr);
*val = BusRead16(addr);
DataCycles = MemTimings[addr >> 12][1];
}
@ -784,8 +781,7 @@ void ARMv5::DataRead32(u32 addr, u32* val)
return;
}
*val = DSi::ARM9Read32(addr);
//*val = NDS::ARM9Read32(addr);
*val = BusRead32(addr);
DataCycles = MemTimings[addr >> 12][2];
}
@ -806,8 +802,7 @@ void ARMv5::DataRead32S(u32 addr, u32* val)
return;
}
*val = DSi::ARM9Read32(addr);
//*val = NDS::ARM9Read32(addr);
*val = BusRead32(addr);
DataCycles += MemTimings[addr >> 12][3];
}
@ -826,8 +821,7 @@ void ARMv5::DataWrite8(u32 addr, u8 val)
return;
}
DSi::ARM9Write8(addr, val);
//NDS::ARM9Write8(addr, val);
BusWrite8(addr, val);
DataCycles = MemTimings[addr >> 12][1];
}
@ -848,8 +842,7 @@ void ARMv5::DataWrite16(u32 addr, u16 val)
return;
}
DSi::ARM9Write16(addr, val);
//NDS::ARM9Write16(addr, val);
BusWrite16(addr, val);
DataCycles = MemTimings[addr >> 12][1];
}
@ -870,8 +863,7 @@ void ARMv5::DataWrite32(u32 addr, u32 val)
return;
}
DSi::ARM9Write32(addr, val);
//NDS::ARM9Write32(addr, val);
BusWrite32(addr, val);
DataCycles = MemTimings[addr >> 12][2];
}
@ -892,8 +884,7 @@ void ARMv5::DataWrite32S(u32 addr, u32 val)
return;
}
DSi::ARM9Write32(addr, val);
//NDS::ARM9Write32(addr, val);
BusWrite32(addr, val);
DataCycles += MemTimings[addr >> 12][3];
}
@ -906,7 +897,6 @@ void ARMv5::GetCodeMemRegion(u32 addr, NDS::MemRegion* region)
return;
}*/
DSi::ARM9GetMemRegion(addr, false, &CodeMem);
//NDS::ARM9GetMemRegion(addr, false, &CodeMem);
GetMemRegion(addr, false, &CodeMem);
}

View File

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

View File

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

View File

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

View File

@ -62,6 +62,8 @@ namespace NDS
//
// timings for GBA slot and wifi are set up at runtime
int ConsoleType;
u8 ARM9MemTimings[0x40000][4];
u8 ARM7MemTimings[0x20000][4];
@ -296,6 +298,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
@ -321,6 +325,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);
@ -469,7 +479,7 @@ void Reset()
fclose(f);
}
if (true)
if (ConsoleType == 1)
{
DSi::LoadBIOS();
DSi::LoadNAND();
@ -559,8 +569,11 @@ void Reset()
RTC::Reset();
Wifi::Reset();
DSi::Reset();
KeyInput &= ~(1 << (16+6)); // TODO
if (ConsoleType == 1)
{
DSi::Reset();
KeyInput &= ~(1 << (16+6));
}
AREngine::Reset();
}
@ -670,6 +683,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);
@ -772,6 +790,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))
@ -883,7 +906,7 @@ u32 RunFrame()
if (!(CPUStop & 0x80000000)) DMAs[1]->Run();
if (!(CPUStop & 0x80000000)) DMAs[2]->Run();
if (!(CPUStop & 0x80000000)) DMAs[3]->Run();
DSi::RunNDMAs(0);
if (ConsoleType == 1) DSi::RunNDMAs(0);
}
else
{
@ -906,7 +929,7 @@ u32 RunFrame()
DMAs[5]->Run();
DMAs[6]->Run();
DMAs[7]->Run();
DSi::RunNDMAs(1);
if (ConsoleType == 1) DSi::RunNDMAs(1);
}
else
{
@ -990,7 +1013,7 @@ void CancelEvent(u32 id)
void TouchScreen(u16 x, u16 y)
{
if (true) // TODO!!
if (ConsoleType == 1)
{
DSi_SPI_TSC::SetTouchCoords(x, y);
}
@ -1003,7 +1026,7 @@ void TouchScreen(u16 x, u16 y)
void ReleaseScreen()
{
if (true) // TODO!!
if (ConsoleType == 1)
{
DSi_SPI_TSC::SetTouchCoords(0x000, 0xFFF);
}
@ -1144,7 +1167,8 @@ void UpdateIRQ(u32 cpu)
if (IME[cpu] & 0x1)
{
arm->IRQ = IE[cpu] & IF[cpu];
if (cpu) arm->IRQ |= (IE2 & IF2);
if ((ConsoleType == 1) && cpu)
arm->IRQ |= (IE2 & IF2);
}
else
{
@ -1223,7 +1247,7 @@ void GXFIFOStall()
DMAs[1]->StallIfRunning();
DMAs[2]->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)
{
// checkme: can the entrypoint addr be THUMB?
// also TODO: make it work in DSi mode
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+3]->IsInMode(mode)) return true;
if (true)
if (ConsoleType == 1)
{
cpu >>= 2;
return DSi::NDMAsInMode(cpu, NDMAModes[mode]);
@ -1484,7 +1509,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 (DSi::NDMAsRunning(cpu>>2)) return true;
if (ConsoleType == 1)
{
if (DSi::NDMAsRunning(cpu>>2)) return true;
}
return false;
}
@ -1496,7 +1524,7 @@ void CheckDMAs(u32 cpu, u32 mode)
DMAs[cpu+2]->StartIfNeeded(mode);
DMAs[cpu+3]->StartIfNeeded(mode);
if (true)
if (ConsoleType == 1)
{
cpu >>= 2;
DSi::CheckNDMAs(cpu, NDMAModes[mode]);
@ -1511,7 +1539,7 @@ void StopDMAs(u32 cpu, u32 mode)
DMAs[cpu+2]->StopIfNeeded(mode);
DMAs[cpu+3]->StopIfNeeded(mode);
if (true)
if (ConsoleType == 1)
{
cpu >>= 2;
DSi::StopNDMAs(cpu, NDMAModes[mode]);

View File

@ -133,6 +133,8 @@ typedef struct
} MemRegion;
extern int ConsoleType;
extern u8 ARM9MemTimings[0x40000][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 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 LoadGBAROM(const char* path, const char* sram);
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)
{
//memcpy(Key1_KeyBuf, &NDS::ARM7BIOS[0x30], 0x1048); // hax
if (dsi)
memcpy(Key1_KeyBuf, &DSi::ARM7Init[0x254], 0x1048); // hax
// TODO: source the key data from different possible places
if (NDS::ConsoleType == 1)
{
if (dsi)
memcpy(Key1_KeyBuf, &DSi::ARM7Init[0x254], 0x1048); // hax
else
memcpy(Key1_KeyBuf, &DSi::ITCMInit[0x4894], 0x1048); // hax
}
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};
if (level >= 1) Key1_ApplyKeycode(keycode, mod);

View File

@ -93,7 +93,10 @@ void Reset()
if (Firmware) delete[] Firmware;
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");
if (!f)
@ -620,7 +623,7 @@ void Reset()
SPI_Firmware::Reset();
SPI_Powerman::Reset();
SPI_TSC::Reset();
DSi_SPI_TSC::Reset();
if (NDS::ConsoleType == 1) DSi_SPI_TSC::Reset();
}
void DoSavestate(Savestate* file)
@ -633,7 +636,7 @@ void DoSavestate(Savestate* file)
SPI_Firmware::DoSavestate(file);
SPI_Powerman::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 0x0100: SPI_Firmware::Hold = 0; break;
//case 0x0200: SPI_TSC::DataPos = 0; break;
case 0x0200: DSi_SPI_TSC::DataPos = 0; break;
case 0x0200:
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 0x0100: return SPI_Firmware::Read();
//case 0x0200: return SPI_TSC::Read();
case 0x0200: return DSi_SPI_TSC::Read();
case 0x0200:
if (NDS::ConsoleType == 1)
return DSi_SPI_TSC::Read();
else
return SPI_TSC::Read();
default: return 0;
}
}
@ -691,8 +701,12 @@ void WriteData(u8 val)
{
case 0x0000: SPI_Powerman::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: DSi_SPI_TSC::Write(val, Cnt&(1<<11)); break;
case 0x0200:
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;
}

View File

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

View File

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

View File

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

View File

@ -96,6 +96,42 @@ int VerifyDSBIOS()
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()
{
FILE* f;
@ -110,7 +146,6 @@ int VerifyDSFirmware()
{
// 128KB firmware, not bootable
fclose(f);
return Load_OK; // FIXME!!!!
return Load_FirmwareNotBootable;
}
else if (len != 0x40000 && len != 0x80000)
@ -124,6 +159,45 @@ int VerifyDSFirmware()
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 res;
@ -131,8 +205,22 @@ int LoadBIOS()
res = VerifyDSBIOS();
if (res != Load_OK) return res;
res = VerifyDSFirmware();
if (res != Load_OK) return res;
if (Config::ConsoleType == 1)
{
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:
// original code in the libui frontend called NDS::LoadGBAROM() if needed
@ -142,6 +230,7 @@ int LoadBIOS()
ROMPath[ROMSlot_NDS][0] = '\0';
SRAMPath[ROMSlot_NDS][0] = '\0';
NDS::SetConsoleType(Config::ConsoleType);
NDS::LoadBIOS();
SavestateLoaded = false;
@ -154,16 +243,39 @@ int LoadROM(const char* file, int slot)
int res;
bool directboot = Config::DirectBoot != 0;
if (Config::ConsoleType == 1 && slot == 1)
{
// cannot load a GBA ROM into a DSi
return Load_ROMLoadError;
}
res = VerifyDSBIOS();
if (res != Load_OK) return res;
res = VerifyDSFirmware();
if (res != Load_OK)
if (Config::ConsoleType == 1)
{
if (res == Load_FirmwareNotBootable)
directboot = true;
else
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;
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];
@ -177,6 +289,8 @@ int LoadROM(const char* file, int slot)
SetupSRAMPath(0);
SetupSRAMPath(1);
NDS::SetConsoleType(Config::ConsoleType);
if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot))
{
SavestateLoaded = false;
@ -225,17 +339,36 @@ int Reset()
res = VerifyDSBIOS();
if (res != Load_OK) return res;
res = VerifyDSFirmware();
if (res != Load_OK)
if (Config::ConsoleType == 1)
{
if (res == Load_FirmwareNotBootable)
directboot = true;
else
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;
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;
NDS::SetConsoleType(Config::ConsoleType);
if (ROMPath[ROMSlot_NDS][0] == '\0')
{
NDS::LoadBIOS();

View File

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

View File

@ -1360,17 +1360,40 @@ QString MainWindow::loadErrorStr(int 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_BIOS9Bad: return "DS ARM9 BIOS is not a valid BIOS dump.";
case Frontend::Load_BIOS9Missing:
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_BIOS7Bad: return "DS ARM7 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_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_FirmwareBad: return "DS firmware is not a valid firmware dump.";
case Frontend::Load_FirmwareNotBootable: return "DS firmware is not bootable.";
case Frontend::Load_FirmwareMissing:
return "DS firmware was not found or could not be accessed. Check your emu settings.";
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.";
}