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/ARM.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ARM.cpp') diff --git a/src/ARM.cpp b/src/ARM.cpp index f50af25..870c455 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -175,6 +175,7 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr) // aging cart debug crap //if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]); //if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]); + if (addr==0x037CA0D0) printf("VLORP %08X\n", R[15]); u32 oldregion = R[15] >> 24; u32 newregion = addr >> 24; -- cgit v1.2.3 From 4d3f346edcd8b7edff2415d7c90903c54d4ee34f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 15 Jun 2019 18:30:12 +0200 Subject: get it to do more interesting things --- src/ARM.cpp | 4 +++- src/DSi.cpp | 1 + src/DSi_I2C.cpp | 19 ++++++++++++------- 3 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src/ARM.cpp') diff --git a/src/ARM.cpp b/src/ARM.cpp index 870c455..ee72fbe 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -175,7 +175,7 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr) // aging cart debug crap //if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]); //if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]); - if (addr==0x037CA0D0) printf("VLORP %08X\n", R[15]); + //if (addr==0x037CA0D0) printf("VLORP %08X\n", R[15]); u32 oldregion = R[15] >> 24; u32 newregion = addr >> 24; @@ -243,6 +243,8 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr) else addr &= ~0x1; } + //if (addr==0x037D5A18) printf("SHITTY FUNC. %08X\n", R[15]); + u32 oldregion = R[15] >> 23; u32 newregion = addr >> 23; diff --git a/src/DSi.cpp b/src/DSi.cpp index 3ec5ab1..0472f1d 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -817,6 +817,7 @@ u16 ARM9IORead16(u32 addr) { switch (addr) { + case 0x04004004: return 0; // TODO } return NDS::ARM9IORead16(addr); diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index 03fe85e..4a4f1e7 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -133,7 +133,6 @@ void WriteCnt(u8 val) { printf("I2C: write CNT %02X\n", val); - val &= 0xF7; // TODO: check ACK flag // TODO: transfer delay // TODO: IRQ @@ -141,41 +140,47 @@ void WriteCnt(u8 val) if (val & (1<<7)) { - bool islast = Cnt & (1<<0); + bool islast = val & (1<<0); if (val & (1<<5)) { // read - printf("I2C read, device=%02X, cnt=%02X, last=%d\n", Device, Cnt, islast); + val &= 0xF7; switch (Device) { case 0x4A: Data = DSi_BPTWL::Read(islast); break; default: Data = 0; break; } + + printf("I2C read, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); } else { // write - printf("I2C write, device=%02X, cnt=%02X, last=%d\n", Device, Cnt, islast); + val &= 0xE7; if (val & (1<<1)) { - Device = Data; - printf("I2C: start, device=%02X\n", Device); + Device = Data & 0xFE; + printf("I2C: %s start, device=%02X\n", (Data&0x01)?"read":"write", Device); switch (Device) { - case 0x4A: DSi_BPTWL::Start(); return; + case 0x4A: DSi_BPTWL::Start(); break; } } else { + printf("I2C write, device=%02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); + switch (Device) { case 0x4A: DSi_BPTWL::Write(Data, islast); break; } } + + val |= (1<<4); } val &= 0x7F; -- cgit v1.2.3 From 78c41736c391f65d8e6af5492ee621c956c6ed01 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 16 Jun 2019 14:26:54 +0200 Subject: fix fucking ass-stupid bug with new-WRAM handling --- src/ARM.cpp | 6 ------ src/DSi.cpp | 27 ++++++++++++++++++++++++++- src/DSi_I2C.cpp | 1 + 3 files changed, 27 insertions(+), 7 deletions(-) (limited to 'src/ARM.cpp') diff --git a/src/ARM.cpp b/src/ARM.cpp index ee72fbe..b7fe3c7 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -175,7 +175,6 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr) // aging cart debug crap //if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]); //if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]); - //if (addr==0x037CA0D0) printf("VLORP %08X\n", R[15]); u32 oldregion = R[15] >> 24; u32 newregion = addr >> 24; @@ -222,9 +221,6 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr) CPSR &= ~0x20; } - // TODO: investigate this - // firmware jumps to region 01FFxxxx, but region 5 (01000000-02000000) is set to non-executable - // is melonDS fucked up somewhere, or is the DS PU just incomplete/crapoed? /*if (!(PU_Map[addr>>12] & 0x04)) { printf("jumped to %08X. very bad\n", addr); @@ -243,8 +239,6 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr) else addr &= ~0x1; } - //if (addr==0x037D5A18) printf("SHITTY FUNC. %08X\n", R[15]); - u32 oldregion = R[15] >> 23; u32 newregion = addr >> 23; diff --git a/src/DSi.cpp b/src/DSi.cpp index 0472f1d..ae1bed2 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -484,16 +484,19 @@ void ARM9Write8(u32 addr, u8 val) { u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]]; if (ptr) *(u8*)&ptr[addr & 0xFFFF] = val; + return; } if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1]) { u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]]; if (ptr) *(u8*)&ptr[addr & 0x7FFF] = val; + return; } if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2]) { u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]]; if (ptr) *(u8*)&ptr[addr & 0x7FFF] = val; + return; } return NDS::ARM9Write8(addr, val); @@ -514,16 +517,19 @@ void ARM9Write16(u32 addr, u16 val) { u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]]; if (ptr) *(u16*)&ptr[addr & 0xFFFF] = val; + return; } if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1]) { u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]]; if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val; + return; } if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2]) { u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]]; if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val; + return; } return NDS::ARM9Write16(addr, val); @@ -544,16 +550,19 @@ void ARM9Write32(u32 addr, u32 val) { u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]]; if (ptr) *(u32*)&ptr[addr & 0xFFFF] = val; + return; } if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1]) { u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]]; if (ptr) *(u32*)&ptr[addr & 0x7FFF] = val; + return; } if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2]) { u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]]; if (ptr) *(u32*)&ptr[addr & 0x7FFF] = val; + return; } return NDS::ARM9Write32(addr, val); @@ -684,16 +693,19 @@ void ARM7Write8(u32 addr, u8 val) { u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]]; if (ptr) *(u8*)&ptr[addr & 0xFFFF] = val; + return; } if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1]) { u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]]; if (ptr) *(u8*)&ptr[addr & 0x7FFF] = val; + return; } if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2]) { u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]]; if (ptr) *(u8*)&ptr[addr & 0x7FFF] = val; + return; } return NDS::ARM7Write8(addr, val); @@ -714,16 +726,19 @@ void ARM7Write16(u32 addr, u16 val) { u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]]; if (ptr) *(u16*)&ptr[addr & 0xFFFF] = val; + return; } if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1]) { u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]]; if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val; + return; } if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2]) { u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]]; if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val; + return; } return NDS::ARM7Write16(addr, val); @@ -744,16 +759,19 @@ void ARM7Write32(u32 addr, u32 val) { u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]]; if (ptr) *(u32*)&ptr[addr & 0xFFFF] = val; + return; } if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1]) { u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]]; if (ptr) *(u32*)&ptr[addr & 0x7FFF] = val; + return; } if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2]) { u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]]; if (ptr) *(u32*)&ptr[addr & 0x7FFF] = val; + return; } return NDS::ARM7Write32(addr, val); @@ -827,6 +845,7 @@ u32 ARM9IORead32(u32 addr) { switch (addr) { + case 0x04004010: return 1; // todo } return NDS::ARM9IORead32(addr); @@ -864,8 +883,11 @@ u8 ARM7IORead8(u32 addr) { switch (addr) { + case 0x04004000: return 0x01; + case 0x04004001: return 0x01; + case 0x04004500: return DSi_I2C::ReadData(); - case 0x04004501: return DSi_I2C::Cnt; + case 0x04004501: printf("read I2C CNT %02X\n", DSi_I2C::Cnt); return DSi_I2C::Cnt; } return NDS::ARM7IORead8(addr); @@ -875,6 +897,8 @@ u16 ARM7IORead16(u32 addr) { switch (addr) { + case 0x04004004: return 0x0187; + case 0x04004006: return 0; // JTAG register } return NDS::ARM7IORead16(addr); @@ -884,6 +908,7 @@ u32 ARM7IORead32(u32 addr) { switch (addr) { + case 0x04004008: return 0x80000000; // HAX } return NDS::ARM7IORead32(addr); diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index b7b7022..8b01b0e 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -212,6 +212,7 @@ void WriteCnt(u8 val) u8 ReadData() { + printf("I2C: read the data: %02X\n", Data); return Data; } -- cgit v1.2.3 From 606a40e6b8f05bbc13d08e6e68fcf477c9a4a0e7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 18 Jun 2019 22:57:37 +0200 Subject: y'know, actually running the DMA units might yield better results. --- src/ARM.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/DSi.cpp | 10 ++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) (limited to 'src/ARM.cpp') diff --git a/src/ARM.cpp b/src/ARM.cpp index b7fe3c7..60dec9a 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -239,6 +239,36 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr) else addr &= ~0x1; } + /*if (addr==0x037D4668) printf("MYSTERY START\n"); + if (addr==0x037CA71C) printf("MYSTERY END\n"); + if (addr==0x037CCD68) printf("atomic_store %08X %08X, %08X\n", R[0], R[1], R[15]); + if (addr==0x037CDD00) printf("zog %08X\n", R[15]);*/ + /*if (addr==0x037CDC00) printf("sendcmd %08X %08X\n", R[0], R[15]); + if (addr==0x037CA700) printf("prepare CID, %08X\n", R[15]); + if(addr==0x037D4498) printf("READ SHITTY FIFO. %08X\n", R[15]); + if (addr==0x037CCD68) printf("atomic_store %08X %08X, %08X\n", R[0], R[1], R[15]); + if (addr>=0x037CEE00 && addr<=0x037CEE30) printf("shitty loop: %08X->%08X\n", R[15], addr); + if (R[15]==0x037CCD8C) printf("BERG!!! %08X\n", addr); + if (addr==0x037CD600) printf("XFER IRQ HANDLER\n"); + if (R[15]==0x037CD62C) printf("TERRIBLE HANDLER: %08X\n", addr); + if (addr==0x037CCE24) printf("SD IRQ HANDLER\n"); + if (addr==0x037CCD94) printf("atomic_load %08X %08X, %08X\n", R[0], R[1], R[15]); + if (addr==0x037CEB7C) printf("CHECK CSR RESULT. %08X %08X %08X, %08X\n", R[0], R[1], R[2], R[15]); + if (R[15]==0x037CEC6C) printf("RETURN FROM CSR CHECK: %08X %08X\n", R[0], R[3]+0x38); + if (addr==0x037CB2AC) printf("ZOG!\n"); + if (addr==0x037CB2A0) printf("GONP %08X %08X, %08X\n", R[1]+0x28, R[3]+0x34, R[15]); + if (addr==0x037CCFC0) printf("SDMMC TIMEOUT. %08X\n", R[15]); + if (addr==0x037D68A8) printf("BARKBARKBARK. %08X\n", R[15]); + if (addr==0x037CCF04) printf("BAKAAA\n"); + if (addr==0x037D6988) printf("MORPMORPMORPMORPMORPMORPMORPMORPMORP %08X\n", R[15]); + if (addr==0x37D6904) printf("TIMEOUT FARTORED! %08X, %08X %08X, %08X\n", R[4], R[3], R[12], R[15]); + // TIMEOUT FARTORED! 037E89B8, 00000000 00200BFB, 037D68FC + if (addr==0x037CD660) printf("BRAAAAAAAAAAAP %08X\n", R[15]); + if (addr==0x037CD798) printf("BRAAPP SHATORED. %08X, %08X %08X\n", R[0], R[1], R[2]); + if (addr==0x037CCD34) printf("atomic_and %08X %08X, %08X\n", R[0], R[1], R[15]);*/ + // atomic_and 0400481C 0000FFE7, 037CD850 + + u32 oldregion = R[15] >> 23; u32 newregion = addr >> 23; @@ -577,6 +607,13 @@ void ARMv4::Execute() } else AddCycles_C(); + + /*if (R[15]==0x037CEE18) printf("SHITTY POINTER = %08X\n", R[0]+0x34); + if (R[15]==0x037CEE1C) printf("SHITTY FLAG = %08X\n", R[0]); + if (R[15]==0x037D68F0) printf("TIMESTAMP THING = %08X:%08X, CUR=%08X:%08X, ptr=%08X\n", + R[3], R[12], R[1], R[0], R[4]); + //if (R[15]==0x037CB29C) printf("GLORG!!! %08X\n", R[3]+0x34); 037E8A8C + if (R[15]==0x037CD730) printf("COUNT OF SHITO. %08X %08X\n", R[0], R[2]);*/ } // TODO optimize this shit!!! diff --git a/src/DSi.cpp b/src/DSi.cpp index 0c9c26c..e6e3c5a 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -305,13 +305,19 @@ void RunNDMAs(u32 cpu) { if (NDS::ARM9Timestamp >= NDS::ARM9Target) return; - // + if (!(NDS::CPUStop & 0x80000000)) NDMAs[0]->Run(); + if (!(NDS::CPUStop & 0x80000000)) NDMAs[1]->Run(); + if (!(NDS::CPUStop & 0x80000000)) NDMAs[2]->Run(); + if (!(NDS::CPUStop & 0x80000000)) NDMAs[3]->Run(); } else { if (NDS::ARM7Timestamp >= NDS::ARM7Target) return; - // + NDMAs[4]->Run(); + NDMAs[5]->Run(); + NDMAs[6]->Run(); + NDMAs[7]->Run(); } } -- cgit v1.2.3 From 81dde71ebac19cf9a68dd7a2a41561cbcbfacc68 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 19 Jun 2019 14:24:49 +0200 Subject: add AES, fix a bunch of bugs we're getting an error screen! wee --- src/ARM.cpp | 37 ------- src/DSi.cpp | 55 ++++++++++ src/DSi.h | 3 + src/DSi_AES.cpp | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/DSi_AES.h | 26 ++++- src/DSi_NDMA.cpp | 21 ++-- src/DSi_SD.cpp | 21 ++-- src/NDS.cpp | 6 +- 8 files changed, 416 insertions(+), 56 deletions(-) (limited to 'src/ARM.cpp') diff --git a/src/ARM.cpp b/src/ARM.cpp index 60dec9a..b7fe3c7 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -239,36 +239,6 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr) else addr &= ~0x1; } - /*if (addr==0x037D4668) printf("MYSTERY START\n"); - if (addr==0x037CA71C) printf("MYSTERY END\n"); - if (addr==0x037CCD68) printf("atomic_store %08X %08X, %08X\n", R[0], R[1], R[15]); - if (addr==0x037CDD00) printf("zog %08X\n", R[15]);*/ - /*if (addr==0x037CDC00) printf("sendcmd %08X %08X\n", R[0], R[15]); - if (addr==0x037CA700) printf("prepare CID, %08X\n", R[15]); - if(addr==0x037D4498) printf("READ SHITTY FIFO. %08X\n", R[15]); - if (addr==0x037CCD68) printf("atomic_store %08X %08X, %08X\n", R[0], R[1], R[15]); - if (addr>=0x037CEE00 && addr<=0x037CEE30) printf("shitty loop: %08X->%08X\n", R[15], addr); - if (R[15]==0x037CCD8C) printf("BERG!!! %08X\n", addr); - if (addr==0x037CD600) printf("XFER IRQ HANDLER\n"); - if (R[15]==0x037CD62C) printf("TERRIBLE HANDLER: %08X\n", addr); - if (addr==0x037CCE24) printf("SD IRQ HANDLER\n"); - if (addr==0x037CCD94) printf("atomic_load %08X %08X, %08X\n", R[0], R[1], R[15]); - if (addr==0x037CEB7C) printf("CHECK CSR RESULT. %08X %08X %08X, %08X\n", R[0], R[1], R[2], R[15]); - if (R[15]==0x037CEC6C) printf("RETURN FROM CSR CHECK: %08X %08X\n", R[0], R[3]+0x38); - if (addr==0x037CB2AC) printf("ZOG!\n"); - if (addr==0x037CB2A0) printf("GONP %08X %08X, %08X\n", R[1]+0x28, R[3]+0x34, R[15]); - if (addr==0x037CCFC0) printf("SDMMC TIMEOUT. %08X\n", R[15]); - if (addr==0x037D68A8) printf("BARKBARKBARK. %08X\n", R[15]); - if (addr==0x037CCF04) printf("BAKAAA\n"); - if (addr==0x037D6988) printf("MORPMORPMORPMORPMORPMORPMORPMORPMORP %08X\n", R[15]); - if (addr==0x37D6904) printf("TIMEOUT FARTORED! %08X, %08X %08X, %08X\n", R[4], R[3], R[12], R[15]); - // TIMEOUT FARTORED! 037E89B8, 00000000 00200BFB, 037D68FC - if (addr==0x037CD660) printf("BRAAAAAAAAAAAP %08X\n", R[15]); - if (addr==0x037CD798) printf("BRAAPP SHATORED. %08X, %08X %08X\n", R[0], R[1], R[2]); - if (addr==0x037CCD34) printf("atomic_and %08X %08X, %08X\n", R[0], R[1], R[15]);*/ - // atomic_and 0400481C 0000FFE7, 037CD850 - - u32 oldregion = R[15] >> 23; u32 newregion = addr >> 23; @@ -607,13 +577,6 @@ void ARMv4::Execute() } else AddCycles_C(); - - /*if (R[15]==0x037CEE18) printf("SHITTY POINTER = %08X\n", R[0]+0x34); - if (R[15]==0x037CEE1C) printf("SHITTY FLAG = %08X\n", R[0]); - if (R[15]==0x037D68F0) printf("TIMESTAMP THING = %08X:%08X, CUR=%08X:%08X, ptr=%08X\n", - R[3], R[12], R[1], R[0], R[4]); - //if (R[15]==0x037CB29C) printf("GLORG!!! %08X\n", R[3]+0x34); 037E8A8C - if (R[15]==0x037CD730) printf("COUNT OF SHITO. %08X %08X\n", R[0], R[2]);*/ } // TODO optimize this shit!!! diff --git a/src/DSi.cpp b/src/DSi.cpp index fc590e1..fd58872 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -28,6 +28,7 @@ #include "DSi_NDMA.h" #include "DSi_I2C.h" #include "DSi_SD.h" +#include "DSi_AES.h" namespace NDS @@ -71,6 +72,7 @@ u8 eMMC_CID[16]; bool Init() { if (!DSi_I2C::Init()) return false; + if (!DSi_AES::Init()) return false; NDMAs[0] = new DSi_NDMA(0, 0); NDMAs[1] = new DSi_NDMA(0, 1); @@ -90,6 +92,7 @@ bool Init() void DeInit() { DSi_I2C::DeInit(); + DSi_AES::DeInit(); for (int i = 0; i < 8; i++) delete NDMAs[i]; @@ -110,6 +113,7 @@ void Reset() for (int i = 0; i < 8; i++) NDMAs[i]->Reset(); DSi_I2C::Reset(); + DSi_AES::Reset(); SDMMC->Reset(); SDIO->Reset(); @@ -336,6 +340,24 @@ bool NDMAsRunning(u32 cpu) return false; } +void CheckNDMAs(u32 cpu, u32 mode) +{ + cpu <<= 2; + NDMAs[cpu+0]->StartIfNeeded(mode); + NDMAs[cpu+1]->StartIfNeeded(mode); + NDMAs[cpu+2]->StartIfNeeded(mode); + NDMAs[cpu+3]->StartIfNeeded(mode); +} + +void StopNDMAs(u32 cpu, u32 mode) +{ + cpu <<= 2; + NDMAs[cpu+0]->StopIfNeeded(mode); + NDMAs[cpu+1]->StopIfNeeded(mode); + NDMAs[cpu+2]->StopIfNeeded(mode); + NDMAs[cpu+3]->StopIfNeeded(mode); +} + // new WRAM mapping // TODO: find out what happens upon overlapping slots!! @@ -1097,6 +1119,9 @@ u32 ARM7IORead32(u32 addr) case 0x04004168: return NDMAs[7]->SubblockTimer; case 0x0400416C: return NDMAs[7]->FillData; case 0x04004170: return NDMAs[7]->Cnt; + + case 0x04004400: return DSi_AES::ReadCnt(); + case 0x0400440C: return DSi_AES::ReadOutputFIFO(); } if (addr >= 0x04004800 && addr < 0x04004A00) @@ -1182,6 +1207,36 @@ void ARM7IOWrite32(u32 addr, u32 val) case 0x04004168: NDMAs[7]->SubblockTimer = val & 0x0003FFFF; return; case 0x0400416C: NDMAs[7]->FillData = val; return; case 0x04004170: NDMAs[7]->WriteCnt(val); return; + + case 0x04004400: DSi_AES::WriteCnt(val); return; + case 0x04004404: DSi_AES::WriteBlkCnt(val); return; + case 0x04004408: DSi_AES::WriteInputFIFO(val); return; + } + + if (addr >= 0x04004420 && addr < 0x04004430) + { + addr -= 0x04004420; + DSi_AES::WriteIV(addr, val, 0xFFFFFFFF); + return; + } + if (addr >= 0x04004430 && addr < 0x04004440) + { + addr -= 0x04004430; + DSi_AES::WriteMAC(addr, val, 0xFFFFFFFF); + return; + } + if (addr >= 0x04004440 && addr < 0x04004500) + { + addr -= 0x04004440; + int n = 0; + while (addr > 0x30) { addr -= 0x30; n++; } + + switch (addr >> 4) + { + case 0: DSi_AES::WriteKeyNormal(n, addr&0xF, val, 0xFFFFFFFF); return; + case 1: DSi_AES::WriteKeyX(n, addr&0xF, val, 0xFFFFFFFF); return; + case 2: DSi_AES::WriteKeyY(n, addr&0xF, val, 0xFFFFFFFF); return; + } } if (addr >= 0x04004800 && addr < 0x04004A00) diff --git a/src/DSi.h b/src/DSi.h index 32253a7..642a56a 100644 --- a/src/DSi.h +++ b/src/DSi.h @@ -26,6 +26,7 @@ namespace DSi { extern u8 eMMC_CID[16]; +extern u64 ConsoleID; extern DSi_SDHost* SDMMC; extern DSi_SDHost* SDIO; @@ -41,6 +42,8 @@ bool LoadNAND(); void RunNDMAs(u32 cpu); void StallNDMAs(); bool NDMAsRunning(u32 cpu); +void CheckNDMAs(u32 cpu, u32 mode); +void StopNDMAs(u32 cpu, u32 mode); void MapNWRAM_A(u32 num, u8 val); void MapNWRAM_B(u32 num, u8 val); diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index 6a524dd..8271e3e 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -15,3 +15,306 @@ 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_AES.h" +#include "FIFO.h" +#include "tiny-AES-c/aes.hpp" + + +namespace DSi_AES +{ + +u32 Cnt; + +u32 BlkCnt; +u32 RemBlocks; + +u32 InputDMASize, OutputDMASize; +u32 AESMode; + +FIFO* InputFIFO; +FIFO* OutputFIFO; + +u8 IV[16]; + +u8 KeyNormal[4][16]; +u8 KeyX[4][16]; +u8 KeyY[4][16]; + +u8 CurKey[16]; + +AES_ctx Ctx; + + +void Swap16(u8* dst, u8* src) +{ + for (int i = 0; i < 16; i++) + dst[i] = src[15-i]; +} + +void ROL16(u8* val, u32 n) +{ + u32 n_coarse = n >> 3; + u32 n_fine = n & 7; + u8 tmp[16]; + + for (u32 i = 0; i < 16; i++) + { + tmp[i] = val[(i - n_coarse) & 0xF]; + } + + for (u32 i = 0; i < 16; i++) + { + val[i] = (tmp[i] << n_fine) | (tmp[(i - 1) & 0xF] >> (8-n_fine)); + } +} + +#define _printhex(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); printf("\n"); } + + +bool Init() +{ + InputFIFO = new FIFO(16); + OutputFIFO = new FIFO(16); + + const u8 zero[16] = {0}; + AES_init_ctx_iv(&Ctx, zero, zero); + + return true; +} + +void DeInit() +{ + delete InputFIFO; + delete OutputFIFO; +} + +void Reset() +{ + Cnt = 0; + + BlkCnt = 0; + RemBlocks = 0; + + InputDMASize = 0; + OutputDMASize = 0; + AESMode = 0; + + InputFIFO->Clear(); + OutputFIFO->Clear(); + + memset(KeyNormal, 0, sizeof(KeyNormal)); + memset(KeyX, 0, sizeof(KeyX)); + memset(KeyY, 0, sizeof(KeyY)); + + memset(CurKey, 0, sizeof(CurKey)); + + // initialize keys, as per GBAtek + + // slot 3: console-unique eMMC crypto + *(u32*)&KeyX[3][0] = (u32)DSi::ConsoleID; + *(u32*)&KeyX[3][4] = (u32)DSi::ConsoleID ^ 0x24EE6906; + *(u32*)&KeyX[3][8] = (u32)(DSi::ConsoleID >> 32) ^ 0xE65B601D; + *(u32*)&KeyX[3][12] = (u32)(DSi::ConsoleID >> 32); + *(u32*)&KeyY[3][0] = 0x0AB9DC76; + *(u32*)&KeyY[3][4] = 0xBD4DC4D3; + *(u32*)&KeyY[3][8] = 0x202DDD1D; +} + + +void ProcessBlock_CTR() +{ + u8 data[16]; + u8 data_rev[16]; + + *(u32*)&data[0] = InputFIFO->Read(); + *(u32*)&data[4] = InputFIFO->Read(); + *(u32*)&data[8] = InputFIFO->Read(); + *(u32*)&data[12] = InputFIFO->Read(); + + //printf("AES-CTR: INPUT: "); _printhex(data, 16); + + Swap16(data_rev, data); + AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16); + Swap16(data, data_rev); + + //printf("AES-CTR: OUTPUT: "); _printhex(data, 16); + + OutputFIFO->Write(*(u32*)&data[0]); + OutputFIFO->Write(*(u32*)&data[4]); + OutputFIFO->Write(*(u32*)&data[8]); + OutputFIFO->Write(*(u32*)&data[12]); +} + + +u32 ReadCnt() +{ + u32 ret = Cnt; + + ret |= InputFIFO->Level(); + ret |= (OutputFIFO->Level() << 5); + + return ret; +} + +void WriteCnt(u32 val) +{ + u32 oldcnt = Cnt; + Cnt = val & 0xFC1FF000; + + if (val & (1<<10)) InputFIFO->Clear(); + if (val & (1<<11)) OutputFIFO->Clear(); + + u32 dmasize[4] = {4, 8, 12, 16}; + InputDMASize = dmasize[3 - ((val >> 12) & 0x3)]; + OutputDMASize = dmasize[(val >> 14) & 0x3]; + + AESMode = (val >> 28) & 0x3; + if (AESMode < 2) printf("AES-CCM TODO\n"); + + if (val & (1<<24)) + { + u32 slot = (val >> 26) & 0x3; + memcpy(CurKey, KeyNormal[slot], 16); + + //printf("AES: key(%d): ", slot); _printhex(CurKey, 16); + + u8 tmp[16]; + Swap16(tmp, CurKey); + AES_init_ctx(&Ctx, tmp); + } + + if (!(oldcnt & (1<<31)) && (val & (1<<31))) + { + // transfer start (checkme) + RemBlocks = BlkCnt >> 16; + } + + printf("AES CNT: %08X / mode=%d inDMA=%d outDMA=%d blocks=%d\n", + val, AESMode, InputDMASize, OutputDMASize, RemBlocks); +} + +void WriteBlkCnt(u32 val) +{ + BlkCnt = val; +} + +u32 ReadOutputFIFO() +{ + return OutputFIFO->Read(); +} + +void WriteInputFIFO(u32 val) +{ + // TODO: add some delay to processing + + InputFIFO->Write(val); + + if (!(Cnt & (1<<31))) return; + + while (InputFIFO->Level() >= 4 && RemBlocks > 0) + { + switch (AESMode) + { + case 2: + case 3: ProcessBlock_CTR(); break; + default: + // dorp + OutputFIFO->Write(InputFIFO->Read()); + OutputFIFO->Write(InputFIFO->Read()); + OutputFIFO->Write(InputFIFO->Read()); + OutputFIFO->Write(InputFIFO->Read()); + } + + RemBlocks--; + } + + if (OutputFIFO->Level() >= OutputDMASize) + { + // trigger DMA + DSi::CheckNDMAs(1, 0x2B); + } + // TODO: DMA the other way around + + if (RemBlocks == 0) + { + Cnt &= ~(1<<31); + if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES); + } +} + + +void WriteIV(u32 offset, u32 val, u32 mask) +{ + u32 old = *(u32*)&IV[offset]; + + *(u32*)&IV[offset] = (old & ~mask) | (val & mask); + + //printf("AES: IV: "); _printhex(IV, 16); + + u8 tmp[16]; + Swap16(tmp, IV); + AES_ctx_set_iv(&Ctx, tmp); +} + +void WriteMAC(u32 offset, u32 val, u32 mask) +{ + // +} + +void DeriveNormalKey(u32 slot) +{ + const u8 key_const[16] = {0xFF, 0xFE, 0xFB, 0x4E, 0x29, 0x59, 0x02, 0x58, 0x2A, 0x68, 0x0F, 0x5F, 0x1A, 0x4F, 0x3E, 0x79}; + u8 tmp[16]; + + //printf("keyX: "); _printhex(KeyX[slot], 16); + //printf("keyY: "); _printhex(KeyY[slot], 16); + + for (int i = 0; i < 16; i++) + tmp[i] = KeyX[slot][i] ^ KeyY[slot][i]; + + u32 carry = 0; + for (int i = 0; i < 16; i++) + { + u32 res = tmp[i] + key_const[15-i] + carry; + tmp[i] = res & 0xFF; + carry = res >> 8; + } + + ROL16(tmp, 42); + + //printf("derive normalkey %d\n", slot); _printhex(tmp, 16); + + memcpy(KeyNormal[slot], tmp, 16); +} + +void WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask) +{ + u32 old = *(u32*)&KeyNormal[slot][offset]; + + *(u32*)&KeyNormal[slot][offset] = (old & ~mask) | (val & mask); +} + +void WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask) +{ + u32 old = *(u32*)&KeyX[slot][offset]; + + *(u32*)&KeyX[slot][offset] = (old & ~mask) | (val & mask); +} + +void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask) +{ + u32 old = *(u32*)&KeyY[slot][offset]; + + *(u32*)&KeyY[slot][offset] = (old & ~mask) | (val & mask); + + if (offset >= 0xC) + { + DeriveNormalKey(slot); + } +} + +} diff --git a/src/DSi_AES.h b/src/DSi_AES.h index 028523a..7c388f5 100644 --- a/src/DSi_AES.h +++ b/src/DSi_AES.h @@ -19,6 +19,30 @@ #ifndef DSI_AES_H #define DSI_AES_H -// +#include "types.h" + +namespace DSi_AES +{ + +extern u32 Cnt; + +bool Init(); +void DeInit(); +void Reset(); + +u32 ReadCnt(); +void WriteCnt(u32 val); +void WriteBlkCnt(u32 val); + +u32 ReadOutputFIFO(); +void WriteInputFIFO(u32 val); + +void WriteIV(u32 offset, u32 val, u32 mask); +void WriteMAC(u32 offset, u32 val, u32 mask); +void WriteKeyNormal(u32 slot, u32 offset, u32 val, u32 mask); +void WriteKeyX(u32 slot, u32 offset, u32 val, u32 mask); +void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask); + +} #endif // DSI_AES_H diff --git a/src/DSi_NDMA.cpp b/src/DSi_NDMA.cpp index 7c0b2a1..aed78af 100644 --- a/src/DSi_NDMA.cpp +++ b/src/DSi_NDMA.cpp @@ -99,7 +99,8 @@ void DSi_NDMA::WriteCnt(u32 val) if ((StartMode & 0x1F) == 0x10) Start(); - if (StartMode != 0x10 && StartMode != 0x30) + if (StartMode != 0x10 && StartMode != 0x30 && + StartMode != 0x2B) printf("UNIMPLEMENTED ARM%d NDMA%d START MODE %02X, %08X->%08X\n", CPU?7:9, Num, StartMode, SrcAddr, DstAddr); } } @@ -223,16 +224,19 @@ void DSi_NDMA::Run9() } if ((StartMode & 0x1F) == 0x10) // CHECKME + { Cnt &= ~(1<<31); + if (Cnt & (1<<30)) NDS::SetIRQ(0, NDS::IRQ_DSi_NDMA0 + Num); + } else if (!(Cnt & (1<<29))) { if (TotalRemCount == 0) + { Cnt &= ~(1<<31); + if (Cnt & (1<<30)) NDS::SetIRQ(0, NDS::IRQ_DSi_NDMA0 + Num); + } } - if (Cnt & (1<<30)) - NDS::SetIRQ(0, NDS::IRQ_DSi_NDMA0 + Num); - Running = 0; InProgress = false; NDS::ResumeCPU(0, 1<<(Num+4)); @@ -305,16 +309,19 @@ void DSi_NDMA::Run7() } if ((StartMode & 0x1F) == 0x10) // CHECKME + { Cnt &= ~(1<<31); + if (Cnt & (1<<30)) NDS::SetIRQ(1, NDS::IRQ_DSi_NDMA0 + Num); + } else if (!(Cnt & (1<<29))) { if (TotalRemCount == 0) + { Cnt &= ~(1<<31); + if (Cnt & (1<<30)) NDS::SetIRQ(1, NDS::IRQ_DSi_NDMA0 + Num); + } } - if (Cnt & (1<<30)) - NDS::SetIRQ(1, NDS::IRQ_DSi_NDMA0 + Num); - Running = 0; InProgress = false; NDS::ResumeCPU(1, 1<<(Num+4)); diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index 42b515c..bb3c4a4 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -473,10 +473,10 @@ void DSi_MMCStorage::SendCMD(u8 cmd, u32 param) case 2: case 10: // get CID - Host->SendResponse(*(u32*)&CID[0], false); - Host->SendResponse(*(u32*)&CID[1], false); - Host->SendResponse(*(u32*)&CID[2], false); - Host->SendResponse(*(u32*)&CID[3], true); + Host->SendResponse(*(u32*)&CID[12], false); + Host->SendResponse(*(u32*)&CID[8], false); + Host->SendResponse(*(u32*)&CID[4], false); + Host->SendResponse(*(u32*)&CID[0], true); //if (cmd == 2) SetState(0x02); return; @@ -502,13 +502,18 @@ void DSi_MMCStorage::SendCMD(u8 cmd, u32 param) return; case 9: // get CSD - Host->SendResponse(*(u32*)&CSD[0], false); - Host->SendResponse(*(u32*)&CSD[1], false); - Host->SendResponse(*(u32*)&CSD[2], false); - Host->SendResponse(*(u32*)&CSD[3], true); + Host->SendResponse(*(u32*)&CSD[12], false); + Host->SendResponse(*(u32*)&CSD[8], false); + Host->SendResponse(*(u32*)&CSD[4], false); + Host->SendResponse(*(u32*)&CSD[0], true); return; case 12: // stop operation + // TODO + Host->SendResponse(CSR, true); + return; + + case 13: // get status Host->SendResponse(CSR, true); return; diff --git a/src/NDS.cpp b/src/NDS.cpp index e20f62f..7513d57 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1582,12 +1582,12 @@ void debug(u32 param) printf("ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]); printf("ARM9 IME=%08X IE=%08X IF=%08X\n", IME[0], IE[0], IF[0]); - printf("ARM7 IME=%08X IE=%08X IF=%08X\n", IME[1], IE[1], IF[1]); + printf("ARM7 IME=%08X IE=%08X IF=%08X IE2=%04X IF2=%04X\n", IME[1], IE[1], IF[1], IE2, IF2); //for (int i = 0; i < 9; i++) // printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]); - FILE* + /*FILE* shit = fopen("debug/card.bin", "wb"); for (u32 i = 0x02000000; i < 0x02400000; i+=4) { @@ -1599,7 +1599,7 @@ void debug(u32 param) u32 val = ARM7Read32(i); fwrite(&val, 4, 1, shit); } - fclose(shit); + fclose(shit);*/ } -- 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/ARM.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