From 58e3ff61ac31a6ac20e12d03c518a6c16715e83c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 15 Jun 2019 16:58:02 +0200 Subject: add I2C shito --- src/SPI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SPI.cpp') diff --git a/src/SPI.cpp b/src/SPI.cpp index 759bbd9..8bee66f 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -581,7 +581,7 @@ namespace SPI u16 Cnt; -u32 CurDevice; +u32 CurDevice; // remove me bool Init() -- cgit v1.2.3 From f7f4ff0519309669e78b994e7c759d13808f0a87 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 4 Aug 2019 02:16:16 +0200 Subject: wifi: take this shit further. complete wifi init --- src/DSi.cpp | 20 ++-- src/DSi_NWifi.cpp | 328 +++++++++++++++++++++++++++++++++++++++++++++++++++--- src/DSi_NWifi.h | 41 +++++++ src/DSi_SD.cpp | 105 +++++++++++++---- src/DSi_SD.h | 19 +++- src/FIFO.h | 9 ++ src/NDS.h | 1 + src/SPI.cpp | 1 + src/SPI.h | 1 + 9 files changed, 468 insertions(+), 57 deletions(-) (limited to 'src/SPI.cpp') diff --git a/src/DSi.cpp b/src/DSi.cpp index aed6b89..17d7f0d 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -582,7 +582,7 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val) u8 ARM9Read8(u32 addr) -{if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 9 %08X %08X\n", addr, NDS::GetPC(0)); +{ switch (addr & 0xFF000000) { case 0x03000000: @@ -611,7 +611,7 @@ u8 ARM9Read8(u32 addr) } u16 ARM9Read16(u32 addr) -{if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 16 9 %08X %08X\n", addr, NDS::GetPC(0)); +{ switch (addr & 0xFF000000) { case 0x03000000: @@ -640,8 +640,7 @@ u16 ARM9Read16(u32 addr) } u32 ARM9Read32(u32 addr) -{if(addr==0x029D02D8) printf("READ SHITTY VTABLE: %08X\n", NDS::GetPC(0)); -if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 32 9 %08X %08X\n", addr, NDS::GetPC(0)); +{ switch (addr & 0xFF000000) { case 0x03000000: @@ -736,7 +735,7 @@ void ARM9Write16(u32 addr, u16 val) } void ARM9Write32(u32 addr, u32 val) -{if(addr==0x02B05E34) printf("VGONP. %08X, %08X\n", val, NDS::GetPC(0)); +{ switch (addr & 0xFF000000) { case 0x03000000: @@ -792,8 +791,7 @@ bool ARM9GetMemRegion(u32 addr, bool write, NDS::MemRegion* region) u8 ARM7Read8(u32 addr) -{if(addr>=0x3FFC400 && addr<0x3FFE728) printf("OGON 8 %08X %08X\n", addr, NDS::GetPC(1)); -if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 7 %08X %08X\n", addr, NDS::GetPC(1)); +{ switch (addr & 0xFF800000) { case 0x03000000: @@ -822,8 +820,7 @@ if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 8 7 %08X %08X\n", addr, } u16 ARM7Read16(u32 addr) -{if(addr>=0x3FFC400 && addr<0x3FFE728) printf("OGON 16 %08X %08X\n", addr, NDS::GetPC(1)); -if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 16 7 %08X %08X\n", addr, NDS::GetPC(1)); +{ switch (addr & 0xFF800000) { case 0x03000000: @@ -852,8 +849,7 @@ if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 16 7 %08X %08X\n", addr, } u32 ARM7Read32(u32 addr) -{if(addr>=0x3FFC400 && addr<0x3FFE728) printf("OGON 32 %08X %08X\n", addr, NDS::GetPC(1)); -if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 32 7 %08X %08X\n", addr, NDS::GetPC(1)); +{ switch (addr & 0xFF800000) { case 0x03000000: @@ -882,7 +878,7 @@ if (addr>=0x2FFD7BC && addr<0x2FFD800) printf("EMMCGONP 32 7 %08X %08X\n", addr, } void ARM7Write8(u32 addr, u8 val) -{if(addr==0x0228CD74) printf("RAKAKA %02X %08X\n", val, NDS::GetPC(1)); +{ switch (addr & 0xFF800000) { case 0x03000000: diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 6f23740..013173f 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -20,6 +20,7 @@ #include #include "DSi.h" #include "DSi_NWifi.h" +#include "SPI.h" const u8 CIS0[256] = @@ -110,11 +111,25 @@ const u8 CIS1[256] = }; +// hax +DSi_NWifi* hax_wifi; +void triggerirq(u32 param) +{ + hax_wifi->SetIRQ_F1_Counter(0); +} + + DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host) { TransferCmd = 0xFFFFFFFF; RemSize = 0; + F0_IRQEnable = 0; + F0_IRQStatus = 0; + + F1_IRQEnable = 0; F1_IRQEnable_CPU = 0; F1_IRQEnable_Error = 0; F1_IRQEnable_Counter = 0; + F1_IRQStatus = 0; F1_IRQStatus_CPU = 0; F1_IRQStatus_Error = 0; F1_IRQStatus_Counter = 0; + WindowData = 0; WindowReadAddr = 0; WindowWriteAddr = 0; @@ -122,6 +137,30 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host) // TODO: check the actual mailbox size (presumably 0x200) for (int i = 0; i < 8; i++) Mailbox[i] = new FIFO(0x200); + + u8* mac = SPI_Firmware::GetWifiMAC(); + printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + memset(EEPROM, 0, 0x400); + + *(u32*)&EEPROM[0x000] = 0x300; + *(u16*)&EEPROM[0x008] = 0x8348; // TODO: determine properly (country code) + memcpy(&EEPROM[0x00A], mac, 6); + *(u32*)&EEPROM[0x010] = 0x60000000; + + memset(&EEPROM[0x03C], 0xFF, 0x70); + memset(&EEPROM[0x140], 0xFF, 0x8); + + u16 chk = 0xFFFF; + for (int i = 0; i < 0x300; i+=2) + chk ^= *(u16*)&EEPROM[i]; + + *(u16*)&EEPROM[0x004] = chk; + + EEPROMReady = 0; + + BootPhase = 0; } DSi_NWifi::~DSi_NWifi() @@ -131,6 +170,61 @@ DSi_NWifi::~DSi_NWifi() } +// CHECKME +// can IRQ status bits be set when the corresponding IRQs are disabled in the enable register? +// otherwise, does disabling them clear the status register? + +void DSi_NWifi::UpdateIRQ() +{ + F0_IRQStatus = 0; + IRQ = false; + + if (F1_IRQStatus & F1_IRQEnable) + F0_IRQStatus |= (1<<1); + + if (F0_IRQEnable & (1<<0)) + { + if (F0_IRQStatus & F0_IRQEnable) + IRQ = true; + } + + Host->SetCardIRQ(); +} + +void DSi_NWifi::UpdateIRQ_F1() +{ + F1_IRQStatus = 0; + + if (!Mailbox[4]->IsEmpty()) F1_IRQStatus |= (1<<0); + if (!Mailbox[5]->IsEmpty()) F1_IRQStatus |= (1<<1); + if (!Mailbox[6]->IsEmpty()) F1_IRQStatus |= (1<<2); + if (!Mailbox[7]->IsEmpty()) F1_IRQStatus |= (1<<3); + if (F1_IRQStatus_Counter & F1_IRQEnable_Counter) F1_IRQStatus |= (1<<4); + if (F1_IRQStatus_CPU & F1_IRQEnable_CPU) F1_IRQStatus |= (1<<6); + if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7); + + UpdateIRQ(); +} + +void DSi_NWifi::SetIRQ_F1_Counter(u32 n) +{ + F1_IRQStatus_Counter |= (1<Read(); + u8 ret = Mailbox[4]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x200) { - return Mailbox[5]->Read(); + u8 ret = Mailbox[5]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x300) { - return Mailbox[6]->Read(); + u8 ret = Mailbox[6]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x400) { - return Mailbox[7]->Read(); + u8 ret = Mailbox[7]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x800) { switch (addr) { + case 0x00400: return F1_IRQStatus; + case 0x00401: return F1_IRQStatus_CPU; + case 0x00402: return F1_IRQStatus_Error; + case 0x00403: return F1_IRQStatus_Counter; + + case 0x00405: + { + u8 ret = 0; + + if (Mailbox[4]->Level() >= 4) ret |= (1<<0); + if (Mailbox[5]->Level() >= 4) ret |= (1<<1); + if (Mailbox[6]->Level() >= 4) ret |= (1<<2); + if (Mailbox[7]->Level() >= 4) ret |= (1<<3); + + return ret; + } + + case 0x00408: return Mailbox[4]->Peek(0); + case 0x00409: return Mailbox[4]->Peek(1); + case 0x0040A: return Mailbox[4]->Peek(2); + case 0x0040B: return Mailbox[4]->Peek(3); + + case 0x00418: return F1_IRQEnable; + case 0x00419: return F1_IRQEnable_CPU; + case 0x0041A: return F1_IRQEnable_Error; + case 0x0041B: return F1_IRQEnable_Counter; + + // GROSS FUCKING HACK + case 0x00440: ClearIRQ_F1_Counter(0); return 0; case 0x00450: return 1; // HAX!! case 0x00474: return WindowData & 0xFF; @@ -205,23 +347,33 @@ u8 DSi_NWifi::F1_Read(u32 addr) } else if (addr < 0x1000) { - return Mailbox[4]->Read(); + u8 ret = Mailbox[4]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x1800) { - return Mailbox[5]->Read(); + u8 ret = Mailbox[5]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x2000) { - return Mailbox[6]->Read(); + u8 ret = Mailbox[6]->Read(); + UpdateIRQ_F1(); + return ret; } else if (addr < 0x2800) { - return Mailbox[7]->Read(); + u8 ret = Mailbox[7]->Read(); + UpdateIRQ_F1(); + return ret; } else { - return Mailbox[4]->Read(); + u8 ret = Mailbox[4]->Read(); + UpdateIRQ_F1(); + return ret; } printf("NWIFI: unknown func1 read %05X\n", addr); @@ -229,36 +381,48 @@ u8 DSi_NWifi::F1_Read(u32 addr) } void DSi_NWifi::F1_Write(u32 addr, u8 val) -{printf("F1 WRITE %05X %02X\n", addr, val); +{ if (addr < 0x100) { if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); Mailbox[0]->Write(val); - if (addr == 0xFF) BMI_Command(); + if (addr == 0xFF) HandleCommand(); + UpdateIRQ_F1(); return; } else if (addr < 0x200) { if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n"); Mailbox[1]->Write(val); + UpdateIRQ_F1(); return; } else if (addr < 0x300) { if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n"); Mailbox[2]->Write(val); + UpdateIRQ_F1(); return; } else if (addr < 0x400) { if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n"); Mailbox[3]->Write(val); + UpdateIRQ_F1(); return; } else if (addr < 0x800) { switch (addr) { + case 0x00418: F1_IRQEnable = val; UpdateIRQ_F1(); return; + case 0x00419: F1_IRQEnable_CPU = val; UpdateIRQ_F1(); return; + case 0x0041A: F1_IRQEnable_Error = val; UpdateIRQ_F1(); return; + case 0x0041B: F1_IRQEnable_Counter = val; UpdateIRQ_F1(); return; + + // GROSS FUCKING HACK + case 0x00440: ClearIRQ_F1_Counter(0); return; + case 0x00474: WindowData = (WindowData & 0xFFFFFF00) | val; return; case 0x00475: WindowData = (WindowData & 0xFFFF00FF) | (val << 8); return; case 0x00476: WindowData = (WindowData & 0xFF00FFFF) | (val << 16); return; @@ -285,32 +449,37 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val) { if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); Mailbox[0]->Write(val); - if (addr == 0xFFF) BMI_Command(); + if (addr == 0xFFF) HandleCommand(); + UpdateIRQ_F1(); return; } else if (addr < 0x1800) { if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n"); Mailbox[1]->Write(val); + UpdateIRQ_F1(); return; } else if (addr < 0x2000) { if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n"); Mailbox[2]->Write(val); + UpdateIRQ_F1(); return; } else if (addr < 0x2800) { if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n"); Mailbox[3]->Write(val); + UpdateIRQ_F1(); return; } else { if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); Mailbox[0]->Write(val); - if (addr == 0x3FFF) BMI_Command(); // CHECKME + if (addr == 0x3FFF) HandleCommand(); // CHECKME + UpdateIRQ_F1(); return; } @@ -343,7 +512,7 @@ void DSi_NWifi::SDIO_Write(u32 func, u32 addr, u8 val) void DSi_NWifi::SendCMD(u8 cmd, u32 param) -{printf("NWIFI CMD %d %08X %08X\n", cmd, param, NDS::GetPC(1)); +{ switch (cmd) { case 52: // IO_RW_DIRECT @@ -426,6 +595,8 @@ void DSi_NWifi::ReadBlock() u32 func = (TransferCmd >> 28) & 0x7; u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize; + len = Host->GetTransferrableLen(len); + u8 data[0x200]; for (u32 i = 0; i < len; i++) @@ -437,7 +608,7 @@ void DSi_NWifi::ReadBlock() TransferAddr &= 0x1FFFF; // checkme } } - Host->SendData(data, len); + len = Host->SendData(data, len); if (RemSize > 0) { @@ -454,8 +625,10 @@ void DSi_NWifi::WriteBlock() u32 func = (TransferCmd >> 28) & 0x7; u32 len = (TransferCmd & (1<<27)) ? 0x200 : RemSize; + len = Host->GetTransferrableLen(len); + u8 data[0x200]; - if (Host->ReceiveData(data, len)) + if (len = Host->ReceiveData(data, len)) { for (u32 i = 0; i < len; i++) { @@ -479,14 +652,32 @@ void DSi_NWifi::WriteBlock() } +void DSi_NWifi::HandleCommand() +{ + switch (BootPhase) + { + case 0: return BMI_Command(); + case 1: return WMI_Command(); + } +} + void DSi_NWifi::BMI_Command() { // HLE command handling stub u32 cmd = MB_Read32(0); - printf("BMI: cmd %08X\n", cmd); switch (cmd) { + case 0x01: // BMI_DONE + { + printf("BMI_DONE\n"); + EEPROMReady = 1; // GROSS FUCKING HACK + u8 ready_msg[8] = {0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00}; + SendWMIFrame(ready_msg, 8, 0, 0x00, 0x0000); + BootPhase = 1; + } + return; + case 0x03: // BMI_WRITE_MEMORY { u32 addr = MB_Read32(0); @@ -546,16 +737,94 @@ void DSi_NWifi::BMI_Command() { u32 len = MB_Read32(0); printf("BMI LZ write %08X\n", len); + //FILE* f = fopen("wififirm.bin", "ab"); for (int i = 0; i < len; i++) { u8 val = Mailbox[0]->Read(); // TODO: do something with it!! + //fwrite(&val, 1, 1, f); } + //fclose(f); } return; + + default: + printf("unknown BMI command %08X\n", cmd); + return; + } +} + +void DSi_NWifi::WMI_Command() +{ + // HLE command handling stub + u16 h0 = MB_Read16(0); + u16 len = MB_Read16(0); + u16 h2 = MB_Read16(0); + + u16 cmd = MB_Read16(0); + printf("WMI: cmd %04X\n", cmd); + + switch (cmd) + { + case 0x0002: // service connect + { + u16 svc_id = MB_Read16(0); + u16 conn_flags = MB_Read16(0); + + u8 svc_resp[10]; + *(u16*)&svc_resp[0] = 0x0003; + *(u16*)&svc_resp[2] = svc_id; + svc_resp[4] = 0; + svc_resp[5] = (svc_id & 0xFF) + 1; + *(u16*)&svc_resp[6] = 0x0001; + *(u16*)&svc_resp[8] = 0x0001; + SendWMIFrame(svc_resp, 10, 0, 0x00, 0x0000); + } + break; + + case 0x0004: // setup complete + { + u8 ready_evt[14]; + memset(ready_evt, 0, 14); + *(u16*)&ready_evt[0] = 0x1001; + memcpy(&ready_evt[2], SPI_Firmware::GetWifiMAC(), 6); + ready_evt[8] = 0x02; + *(u32*)&ready_evt[10] = 0x23000024; + // ctrl[0] = trailer size + // trailer[1] = trailer extra size + // trailer[0] = trailer type??? + SendWMIFrame(ready_evt, 14, 1, 0x00, 0x0000); + } + break; + + default: + printf("unknown WMI command %04X\n", cmd); + break; + } + + MB_Drain(0); +} + +void DSi_NWifi::SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl) +{ + u32 wlen = 0; + + Mailbox[4]->Write(ep); // eid + Mailbox[4]->Write(flags); // flags + MB_Write16(4, len); // payload length + MB_Write16(4, ctrl); // ctrl + wlen += 6; + + for (int i = 0; i < len; i++) + { + Mailbox[4]->Write(data[i]); + wlen++; } + + for (; wlen & 0x7F; wlen++) + Mailbox[4]->Write(0); } @@ -563,6 +832,29 @@ u32 DSi_NWifi::WindowRead(u32 addr) { printf("NWifi: window read %08X\n", addr); + if ((addr & 0xFFFF00) == 0x520000) + { + // RAM host interest area + // TODO: different base based on hardware version + + switch (addr & 0xFF) + { + case 0x54: + // base address of EEPROM data + // TODO find what the actual address is! + return 0x1FFC00; + case 0x58: return EEPROMReady; // hax + } + + return 0; + } + + // hax + if ((addr & 0x1FFC00) == 0x1FFC00) + { + return *(u32*)&EEPROM[addr & 0x3FF]; + } + switch (addr) { case 0x40EC: // chip ID diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h index 0a36705..e5fe637 100644 --- a/src/DSi_NWifi.h +++ b/src/DSi_NWifi.h @@ -33,11 +33,19 @@ public: void ContinueTransfer(); + void SetIRQ_F1_Counter(u32 n); + private: u32 TransferCmd; u32 TransferAddr; u32 RemSize; + void UpdateIRQ(); + void UpdateIRQ_F1(); + //void SetIRQ_F1_Counter(u32 n); + void ClearIRQ_F1_Counter(u32 n); + void SetIRQ_F1_CPU(u32 n); + u8 F0_Read(u32 addr); void F0_Write(u32 addr, u8 val); @@ -50,11 +58,28 @@ private: void ReadBlock(); void WriteBlock(); + void HandleCommand(); void BMI_Command(); + void WMI_Command(); + + void SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl); u32 WindowRead(u32 addr); void WindowWrite(u32 addr, u32 val); + u16 MB_Read16(int n) + { + u16 ret = Mailbox[n]->Read(); + ret |= (Mailbox[n]->Read() << 8); + return ret; + } + + void MB_Write16(int n, u16 val) + { + Mailbox[n]->Write(val & 0xFF); val >>= 8; + Mailbox[n]->Write(val & 0xFF); + } + u32 MB_Read32(int n) { u32 ret = Mailbox[n]->Read(); @@ -72,9 +97,25 @@ private: Mailbox[n]->Write(val & 0xFF); } + void MB_Drain(int n) + { + while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read(); + } + FIFO* Mailbox[8]; + u8 F0_IRQEnable; + u8 F0_IRQStatus; + + u8 F1_IRQEnable, F1_IRQEnable_CPU, F1_IRQEnable_Error, F1_IRQEnable_Counter; + u8 F1_IRQStatus, F1_IRQStatus_CPU, F1_IRQStatus_Error, F1_IRQStatus_Counter; + u32 WindowData, WindowReadAddr, WindowWriteAddr; + + u8 EEPROM[0x400]; + u32 EEPROMReady; + + u32 BootPhase; }; #endif // DSI_NWIFI_H diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index c9edd78..07eca83 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -73,6 +73,10 @@ void DSi_SDHost::Reset() IRQStatus = 0; IRQMask = 0x8B7F031D; + CardIRQStatus = 0; + CardIRQMask = 0xC007; + CardIRQCtl = 0; + DataCtl = 0; Data32IRQ = 0; DataMode = 0; @@ -145,6 +149,25 @@ void DSi_SDHost::SetIRQ(u32 irq) if (irq == 24 || irq == 25) UpdateData32IRQ(); } +void DSi_SDHost::SetCardIRQ() +{ + if (!(CardIRQCtl & (1<<0))) return; + + u16 oldflags = CardIRQStatus & ~CardIRQMask; + DSi_SDDevice* dev = Ports[PortSelect & 0x1]; + + if (dev->IRQ) CardIRQStatus |= (1<<0); + else CardIRQStatus &= ~(1<<0); + + u16 newflags = CardIRQStatus & ~CardIRQMask; + + if ((oldflags == 0) && (newflags != 0)) // checkme + { + NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO : NDS::IRQ2_DSi_SDMMC); + NDS::SetIRQ2(Num ? NDS::IRQ2_DSi_SDIO_Data1 : NDS::IRQ2_DSi_SD_Data1); + } +} + void DSi_SDHost::SendResponse(u32 val, bool last) { *(u32*)&ResponseBuffer[6] = *(u32*)&ResponseBuffer[4]; @@ -166,10 +189,10 @@ void DSi_SDHost::FinishSend(u32 param) //if (param & 0x2) host->SetIRQ(2); } -void DSi_SDHost::SendData(u8* data, u32 len) +u32 DSi_SDHost::SendData(u8* data, u32 len) { printf("%s: data RX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask); - if (len != BlockLen16) printf("!! BAD BLOCKLEN\n"); + if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; } bool last = (BlockCountInternal == 0); @@ -187,6 +210,8 @@ void DSi_SDHost::SendData(u8* data, u32 len) u32 param = Num | (last << 1); NDS::ScheduleEvent(Num ? NDS::Event_DSi_SDIOTransfer : NDS::Event_DSi_SDMMCTransfer, false, 512, FinishSend, param); + + return len; } void DSi_SDHost::FinishReceive(u32 param) @@ -200,16 +225,16 @@ void DSi_SDHost::FinishReceive(u32 param) if (dev) dev->ContinueTransfer(); } -bool DSi_SDHost::ReceiveData(u8* data, u32 len) +u32 DSi_SDHost::ReceiveData(u8* data, u32 len) { printf("%s: data TX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask); - if (len != BlockLen16) printf("!! BAD BLOCKLEN\n"); + if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; } u32 f = CurFIFO; if ((DataFIFO[f]->Level() << 1) < len) { printf("%s: FIFO not full enough for a transfer (%d / %d)\n", SD_DESC, DataFIFO[f]->Level()<<1, len); - return false; + return 0; } DSi_SDDevice* dev = Ports[PortSelect & 0x1]; @@ -240,7 +265,13 @@ bool DSi_SDHost::ReceiveData(u8* data, u32 len) BlockCountInternal--; } - return true; + return len; +} + +u32 DSi_SDHost::GetTransferrableLen(u32 len) +{ + if (len > BlockLen16) len = BlockLen16; // checkme + return len; } @@ -278,6 +309,10 @@ u16 DSi_SDHost::Read(u32 addr) case 0x02C: return 0; // TODO + case 0x034: return CardIRQCtl; + case 0x036: return CardIRQStatus; + case 0x038: return CardIRQMask; + case 0x030: // FIFO16 { // TODO: decrement BlockLen???? @@ -389,7 +424,7 @@ u32 DSi_SDHost::ReadFIFO32() return ret; } - +int morp = 0; void DSi_SDHost::Write(u32 addr, u16 val) { //if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1)); @@ -470,6 +505,20 @@ void DSi_SDHost::Write(u32 addr, u16 val) } return; + case 0x034: + CardIRQCtl = val & 0x0305; + printf("[%d] CardIRQCtl = %04X\n", Num, val); + SetCardIRQ(); + return; + case 0x036: + CardIRQStatus &= val; + return; + case 0x038: + CardIRQMask = val & 0xC007; + printf("[%d] CardIRQMask = %04X\n", Num, val); + SetCardIRQ(); + return; + case 0x0D8: DataCtl = (val & 0x0022); DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1); @@ -729,42 +778,54 @@ void DSi_MMCStorage::ContinueTransfer() { if (RWCommand == 0) return; + u32 len = 0; + switch (RWCommand) { case 18: - ReadBlock(RWAddress); + len = ReadBlock(RWAddress); break; case 25: - WriteBlock(RWAddress); + len = WriteBlock(RWAddress); break; } - RWAddress += BlockSize; + RWAddress += len; } -void DSi_MMCStorage::ReadBlock(u64 addr) +u32 DSi_MMCStorage::ReadBlock(u64 addr) { - if (!File) return; - printf("SD/MMC: reading block @ %08X, len=%08X\n", addr, BlockSize); + u32 len = BlockSize; + len = Host->GetTransferrableLen(len); + u8 data[0x200]; - fseek(File, addr, SEEK_SET); - fread(data, 1, BlockSize, File); - Host->SendData(data, BlockSize); + if (File) + { + fseek(File, addr, SEEK_SET); + fread(data, 1, len, File); + } + return Host->SendData(data, len); } -void DSi_MMCStorage::WriteBlock(u64 addr) +u32 DSi_MMCStorage::WriteBlock(u64 addr) { - if (!File) return; - printf("SD/MMC: write block @ %08X, len=%08X\n", addr, BlockSize); + u32 len = BlockSize; + len = Host->GetTransferrableLen(len); + u8 data[0x200]; - if (Host->ReceiveData(data, BlockSize)) + if (len = Host->ReceiveData(data, len)) { - fseek(File, addr, SEEK_SET); - fwrite(data, 1, BlockSize, File); + if (File) + { + fseek(File, addr, SEEK_SET); + fwrite(data, 1, len, File); + } } + + return len; } diff --git a/src/DSi_SD.h b/src/DSi_SD.h index 22475d6..149b72a 100644 --- a/src/DSi_SD.h +++ b/src/DSi_SD.h @@ -39,8 +39,11 @@ public: static void FinishSend(u32 param); static void FinishReceive(u32 param); void SendResponse(u32 val, bool last); - void SendData(u8* data, u32 len); - bool ReceiveData(u8* data, u32 len); + u32 SendData(u8* data, u32 len); + u32 ReceiveData(u8* data, u32 len); + u32 GetTransferrableLen(u32 len); + + void SetCardIRQ(); u16 Read(u32 addr); void Write(u32 addr, u16 val); @@ -58,6 +61,10 @@ private: u32 IRQStatus; // IF u32 IRQMask; // ~IE + u16 CardIRQStatus; + u16 CardIRQMask; + u16 CardIRQCtl; + u16 DataCtl; u16 Data32IRQ; u32 DataMode; // 0=16bit 1=32bit @@ -83,12 +90,14 @@ private: class DSi_SDDevice { public: - DSi_SDDevice(DSi_SDHost* host) { Host = host; } + DSi_SDDevice(DSi_SDHost* host) { Host = host; IRQ = false; } ~DSi_SDDevice() {} virtual void SendCMD(u8 cmd, u32 param) = 0; virtual void ContinueTransfer() = 0; + bool IRQ; + protected: DSi_SDHost* Host; }; @@ -127,8 +136,8 @@ private: void SetState(u32 state) { CSR &= ~(0xF << 9); CSR |= (state << 9); } - void ReadBlock(u64 addr); - void WriteBlock(u64 addr); + u32 ReadBlock(u64 addr); + u32 WriteBlock(u64 addr); }; #endif // DSI_SD_H diff --git a/src/FIFO.h b/src/FIFO.h index a9e9ed8..213db7a 100644 --- a/src/FIFO.h +++ b/src/FIFO.h @@ -89,6 +89,15 @@ public: return Entries[ReadPos]; } + T Peek(u32 offset) + { + u32 pos = ReadPos + offset; + if (pos >= NumEntries) + pos -= NumEntries; + + return Entries[pos]; + } + u32 Level() { return NumOccupied; } bool IsEmpty() { return NumOccupied == 0; } bool IsFull() { return NumOccupied >= NumEntries; } diff --git a/src/NDS.h b/src/NDS.h index e32908b..fd94a01 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -45,6 +45,7 @@ enum // DSi Event_DSi_SDMMCTransfer, Event_DSi_SDIOTransfer, + Event_DSi_NWifi, Event_MAX }; diff --git a/src/SPI.cpp b/src/SPI.cpp index 8bee66f..783e638 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -225,6 +225,7 @@ void SetupDirectBoot() u8 GetConsoleType() { return Firmware[0x1D]; } u8 GetWifiVersion() { return Firmware[0x2F]; } u8 GetRFVersion() { return Firmware[0x40]; } +u8* GetWifiMAC() { return &Firmware[0x36]; } u8 Read() { diff --git a/src/SPI.h b/src/SPI.h index 21ad9a6..44de876 100644 --- a/src/SPI.h +++ b/src/SPI.h @@ -29,6 +29,7 @@ void SetupDirectBoot(); u8 GetConsoleType(); u8 GetWifiVersion(); u8 GetRFVersion(); +u8* GetWifiMAC(); } -- cgit v1.2.3 From a6a9f74acc2fe1c0645dae7b06816d7fc6a67f81 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 4 Aug 2019 11:44:36 +0200 Subject: lay base for DSi-mode TSC --- melonDS.cbp | 2 + src/DSi_SPI_TSC.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++++++ src/DSi_SPI_TSC.h | 40 +++++++++++++++++ src/NDS.cpp | 32 ++++++++------ src/NDS.h | 2 - src/SPI.cpp | 14 ++++-- src/libui_sdl/main.cpp | 2 - 7 files changed, 186 insertions(+), 19 deletions(-) create mode 100644 src/DSi_SPI_TSC.cpp create mode 100644 src/DSi_SPI_TSC.h (limited to 'src/SPI.cpp') diff --git a/melonDS.cbp b/melonDS.cbp index 2fd6ed0..cc5357b 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -114,6 +114,8 @@ + + diff --git a/src/DSi_SPI_TSC.cpp b/src/DSi_SPI_TSC.cpp new file mode 100644 index 0000000..253cef8 --- /dev/null +++ b/src/DSi_SPI_TSC.cpp @@ -0,0 +1,113 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include "DSi.h" +#include "DSi_SPI_TSC.h" + + +namespace DSi_SPI_TSC +{ + +u32 DataPos; +u8 Index; +u8 Mode; +u8 Data; + +u16 TouchX, TouchY; + + +bool Init() +{ + return true; +} + +void DeInit() +{ +} + +void Reset() +{ + DataPos = 0; + + Mode = 0; + Index = 0; + Data = 0; +} + +void DoSavestate(Savestate* file) +{ + /*file->Section("SPTi"); + + file->Var32(&DataPos); + file->Var8(&ControlByte); + file->Var8(&Data); + + file->Var16(&ConvResult);*/ + // TODO!! +} + +void SetTouchCoords(u16 x, u16 y) +{ + TouchX = x; + TouchY = y; + + if (y == 0xFFF) return; + + TouchX <<= 4; + TouchY <<= 4; +} + +void MicInputFrame(s16* data, int samples) +{ + // TODO: forward to DS-mode TSC if needed +} + +u8 Read() +{ + return Data; +} + +void Write(u8 val, u32 hold) +{ +#define READWRITE(var) { if (Index & 0x01) Data = var; else var = val; } +printf("TSC: %02X %d\n", val, hold?1:0); + if (DataPos == 0) + { + Index = val; + } + else + { + if ((Index & 0xFE) == 0) + { + READWRITE(Mode); + } + else + { + printf("DSi_SPI_TSC: unknown IO, mode=%02X, index=%02X (%02X %s)\n", Mode, Index, Index>>1, (Index&1)?"read":"write"); + } + + Index += (1<<1); // increment index + } + + if (hold) DataPos++; + else DataPos = 0; +} + +} diff --git a/src/DSi_SPI_TSC.h b/src/DSi_SPI_TSC.h new file mode 100644 index 0000000..f3ffc32 --- /dev/null +++ b/src/DSi_SPI_TSC.h @@ -0,0 +1,40 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef DSI_SPI_TSC +#define DSI_SPI_TSC + +namespace DSi_SPI_TSC +{ + +extern u32 DataPos; + +bool Init(); +void DeInit(); +void Reset(); +void DoSavestate(Savestate* file); + +void SetTouchCoords(u16 x, u16 y); +void MicInputFrame(s16* data, int samples); + +u8 Read(); +void Write(u8 val, u32 hold); + +} + +#endif // DSI_SPI_TSC diff --git a/src/NDS.cpp b/src/NDS.cpp index 61cf547..da7f9f9 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -32,6 +32,7 @@ #include "Platform.h" #include "DSi.h" +#include "DSi_SPI_TSC.h" namespace NDS @@ -519,6 +520,7 @@ void Reset() Wifi::Reset(); DSi::Reset(); + KeyInput &= ~(1 << (16+6)); // TODO } void Stop() @@ -932,24 +934,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)); + } } diff --git a/src/NDS.h b/src/NDS.h index fd94a01..d391cf7 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -180,8 +180,6 @@ void RelocateSave(const char* path, bool write); u32 RunFrame(); -void PressKey(u32 key); -void ReleaseKey(u32 key); void TouchScreen(u16 x, u16 y); void ReleaseScreen(); diff --git a/src/SPI.cpp b/src/SPI.cpp index 783e638..e21ad0c 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -22,6 +22,7 @@ #include "Config.h" #include "NDS.h" #include "SPI.h" +#include "DSi_SPI_TSC.h" #include "Platform.h" @@ -590,6 +591,7 @@ bool Init() if (!SPI_Firmware::Init()) return false; if (!SPI_Powerman::Init()) return false; if (!SPI_TSC::Init()) return false; + if (!DSi_SPI_TSC::Init()) return false; return true; } @@ -599,6 +601,7 @@ void DeInit() SPI_Firmware::DeInit(); SPI_Powerman::DeInit(); SPI_TSC::DeInit(); + DSi_SPI_TSC::DeInit(); } void Reset() @@ -608,6 +611,7 @@ void Reset() SPI_Firmware::Reset(); SPI_Powerman::Reset(); SPI_TSC::Reset(); + DSi_SPI_TSC::Reset(); } void DoSavestate(Savestate* file) @@ -620,6 +624,7 @@ void DoSavestate(Savestate* file) SPI_Firmware::DoSavestate(file); SPI_Powerman::DoSavestate(file); SPI_TSC::DoSavestate(file); + DSi_SPI_TSC::DoSavestate(file); } @@ -633,7 +638,8 @@ 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: SPI_TSC::DataPos = 0; break; + case 0x0200: DSi_SPI_TSC::DataPos = 0; break; } } @@ -659,7 +665,8 @@ u8 ReadData() { case 0x0000: return SPI_Powerman::Read(); case 0x0100: return SPI_Firmware::Read(); - case 0x0200: return SPI_TSC::Read(); + //case 0x0200: return SPI_TSC::Read(); + case 0x0200: return DSi_SPI_TSC::Read(); default: return 0; } } @@ -675,7 +682,8 @@ 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: SPI_TSC::Write(val, Cnt&(1<<11)); break; + case 0x0200: DSi_SPI_TSC::Write(val, Cnt&(1<<11)); break; default: printf("SPI to unknown device %04X %02X\n", Cnt, val); break; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 86949eb..34e838c 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -1088,7 +1088,6 @@ void OnAreaMouseEvent(uiAreaHandler* handler, uiArea* area, uiAreaMouseEvent* ev if (Touching && (evt->Up == 1)) { Touching = false; - NDS::ReleaseKey(16+6); NDS::ReleaseScreen(); } else if (!Touching && (evt->Down == 1) && @@ -1096,7 +1095,6 @@ void OnAreaMouseEvent(uiAreaHandler* handler, uiArea* area, uiAreaMouseEvent* ev (x < (BottomScreenRect.X+BottomScreenRect.Width)) && (y < (BottomScreenRect.Y+BottomScreenRect.Height))) { Touching = true; - NDS::PressKey(16+6); } if (Touching) -- cgit v1.2.3 From 118b3b0f241973a1c667b03ce0d22d64d6b20d31 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 15 Oct 2019 23:30:01 +0200 Subject: don't auto-patch firmware touchscreen coordinates, atleast until we find out whether that causes problems in DSi mode --- src/SPI.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/SPI.cpp') diff --git a/src/SPI.cpp b/src/SPI.cpp index e21ad0c..81b0c04 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -152,6 +152,7 @@ void Reset() UserSettings = userdata; // fix touchscreen coords + #if 0 *(u16*)&Firmware[userdata+0x58] = 0; *(u16*)&Firmware[userdata+0x5A] = 0; Firmware[userdata+0x5C] = 0; @@ -174,12 +175,12 @@ void Reset() Firmware[0x39] = rand()&0xFF; Firmware[0x3A] = rand()&0xFF; Firmware[0x3B] = rand()&0xFF; - +#endif printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", Firmware[0x36], Firmware[0x37], Firmware[0x38], Firmware[0x39], Firmware[0x3A], Firmware[0x3B]); - *(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); + //*(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); // verify shit printf("FW: WIFI CRC16 = %s\n", VerifyCRC16(0x0000, 0x2C, *(u16*)&Firmware[0x2C], 0x2A)?"GOOD":"BAD"); -- cgit v1.2.3 From 43e045357f7d74eecff61b0c8af8068b31e963b3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 1 Jun 2020 20:36:30 +0200 Subject: make it able to switch between DS and DSi modes --- src/ARM.cpp | 46 +++++++++ src/ARM.h | 43 ++++---- src/CP15.cpp | 30 ++---- src/DMA.cpp | 29 ++++-- src/DMA.h | 5 + src/DSi.cpp | 7 +- src/NDS.cpp | 54 +++++++--- src/NDS.h | 5 + src/NDSCart.cpp | 15 ++- src/SPI.cpp | 32 ++++-- src/SPU.cpp | 16 ++- src/SPU.h | 6 ++ src/frontend/FrontendUtil.h | 9 ++ src/frontend/Util_ROM.cpp | 163 +++++++++++++++++++++++++++--- src/frontend/qt_sdl/EmuSettingsDialog.cpp | 2 +- src/frontend/qt_sdl/main.cpp | 45 +++++++-- 16 files changed, 396 insertions(+), 111 deletions(-) (limited to 'src/SPI.cpp') diff --git a/src/ARM.cpp b/src/ARM.cpp index 2d8c807..68cac59 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -18,6 +18,7 @@ #include #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) { diff --git a/src/ARM.h b/src/ARM.h index 95c41d4..e0832e2 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -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]; } diff --git a/src/CP15.cpp b/src/CP15.cpp index b61cc45..d340b9e 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -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); } diff --git a/src/DMA.cpp b/src/DMA.cpp index 8e294fc..cd2df45 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -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; diff --git a/src/DMA.h b/src/DMA.h index 2e7678c..0344fba 100644 --- a/src/DMA.h +++ b/src/DMA.h @@ -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 diff --git a/src/DSi.cpp b/src/DSi.cpp index 58f39c2..520b269 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -18,6 +18,7 @@ #include #include +#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]; diff --git a/src/NDS.cpp b/src/NDS.cpp index 001dfe6..22368ae 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -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]); diff --git a/src/NDS.h b/src/NDS.h index 26931de..9c5fe3d 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -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(); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 9497d33..b326dd6 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -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); diff --git a/src/SPI.cpp b/src/SPI.cpp index 29f3321..ac40707 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -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; } diff --git a/src/SPU.cpp b/src/SPU.cpp index 959de12..9f6b107 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -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; diff --git a/src/SPU.h b/src/SPU.h index 74a4471..8ab17a0 100644 --- a/src/SPU.h +++ b/src/SPU.h @@ -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); }; } diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 6b83cbc..099583f 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -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, }; diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index d410550..8116a93 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -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(); diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 7760a88..09faf4e 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -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); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index ef21bc7..7b3d5cd 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -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_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_ROMLoadError: return "Failed to load the ROM. Make sure the file is accessible and isn't used by another application."; + 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_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_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."; } -- cgit v1.2.3