diff options
author | Arisotura <thetotalworm@gmail.com> | 2021-08-30 20:26:49 +0200 |
---|---|---|
committer | Arisotura <thetotalworm@gmail.com> | 2021-08-30 20:26:49 +0200 |
commit | 523552a92d16fb1f3a367cd2f7ee382bb09a0772 (patch) | |
tree | 8e7ed32de0eb6bf9c8e741be431556cf736378d0 /src | |
parent | b84155e8913b837a5b82688165a4029b38c8c055 (diff) |
actually make DSi-mode direct boot work to some extent
Diffstat (limited to 'src')
-rw-r--r-- | src/DSi.cpp | 322 | ||||
-rw-r--r-- | src/DSi_AES.cpp | 59 | ||||
-rw-r--r-- | src/DSi_AES.h | 2 | ||||
-rw-r--r-- | src/DSi_DSP.cpp | 8 | ||||
-rw-r--r-- | src/DSi_I2C.cpp | 2 | ||||
-rw-r--r-- | src/DSi_I2C.h | 7 | ||||
-rw-r--r-- | src/DSi_NAND.cpp | 71 | ||||
-rw-r--r-- | src/DSi_NAND.h | 3 | ||||
-rw-r--r-- | src/NDS.cpp | 126 | ||||
-rw-r--r-- | src/NDSCart.cpp | 9 | ||||
-rw-r--r-- | src/NDS_Header.h | 2 | ||||
-rw-r--r-- | src/SPI.cpp | 82 | ||||
-rw-r--r-- | src/SPI.h | 2 |
13 files changed, 491 insertions, 204 deletions
diff --git a/src/DSi.cpp b/src/DSi.cpp index 2f272e9..8346a1a 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -25,6 +25,7 @@ #include "ARM.h" #include "GPU.h" #include "NDSCart.h" +#include "SPI.h" #include "Platform.h" #ifdef JIT_ENABLED @@ -187,37 +188,310 @@ void Reset() ARM7Write16(eaddr+0x42, 0x0001); } +void DecryptModcryptArea(u32 offset, u32 size, u8* iv) +{ + AES_ctx ctx; + u8 key[16]; + u8 tmp[16]; + + if ((offset == 0) || (size == 0)) + return; + + if ((NDSCart::Header.DSiCryptoFlags & (1<<4)) || + (NDSCart::Header.AppFlags & (1<<7))) + { + // dev key + memcpy(key, &NDSCart::CartROM[0], 16); + } + else + { + u8 keyX[16], keyY[16]; + + *(u32*)&keyX[0] = 0x746E694E; + *(u32*)&keyX[4] = 0x6F646E65; + keyX[8] = NDSCart::Header.GameCode[0]; + keyX[9] = NDSCart::Header.GameCode[1]; + keyX[10] = NDSCart::Header.GameCode[2]; + keyX[11] = NDSCart::Header.GameCode[3]; + keyX[12] = NDSCart::Header.GameCode[3]; + keyX[13] = NDSCart::Header.GameCode[2]; + keyX[14] = NDSCart::Header.GameCode[1]; + keyX[15] = NDSCart::Header.GameCode[0]; + + memcpy(keyY, NDSCart::Header.DSiARM9iHash, 16); + + DSi_AES::DeriveNormalKey(keyX, keyY, tmp); + } + + DSi_AES::Swap16(key, tmp); + DSi_AES::Swap16(tmp, iv); + AES_init_ctx_iv(&ctx, key, tmp); + + // find a matching binary area + + u32 binaryaddr, binarysize; + + // CHECKME: GBAtek says the modcrypt area should be the same size, or bigger, + // than the binary area being considered + // but I have seen modcrypt areas smaller than the ARM9i binary +#define BINARY_GOOD(name) \ + ((offset >= NDSCart::Header.name##ROMOffset) && \ + (offset+size) <= (NDSCart::Header.name##ROMOffset+NDSCart::Header.name##Size)) + + if (BINARY_GOOD(ARM9)) + { + binaryaddr = NDSCart::Header.ARM9RAMAddress; + binarysize = NDSCart::Header.ARM9Size; + } + else if (BINARY_GOOD(ARM7)) + { + binaryaddr = NDSCart::Header.ARM7RAMAddress; + binarysize = NDSCart::Header.ARM7Size; + } + else if (BINARY_GOOD(DSiARM9i)) + { + binaryaddr = NDSCart::Header.DSiARM9iRAMAddress; + binarysize = NDSCart::Header.DSiARM9iSize; + } + else if (BINARY_GOOD(DSiARM7i)) + { + binaryaddr = NDSCart::Header.DSiARM7iRAMAddress; + binarysize = NDSCart::Header.DSiARM7iSize; + } + else + return; + +#undef BINARY_GOOD + + for (u32 i = 0; i < size; i+=16) + { + u8 data[16]; + + *(u32*)&data[0] = ARM9Read32(binaryaddr+i); + *(u32*)&data[4] = ARM9Read32(binaryaddr+i+4); + *(u32*)&data[8] = ARM9Read32(binaryaddr+i+8); + *(u32*)&data[12] = ARM9Read32(binaryaddr+i+12); + + DSi_AES::Swap16(tmp, data); + AES_CTR_xcrypt_buffer(&ctx, tmp, 16); + DSi_AES::Swap16(data, tmp); + + ARM9Write32(binaryaddr+i, *(u32*)&data[0]); + ARM9Write32(binaryaddr+i+4, *(u32*)&data[4]); + ARM9Write32(binaryaddr+i+8, *(u32*)&data[8]); + ARM9Write32(binaryaddr+i+12, *(u32*)&data[12]); + } +} + void SetupDirectBoot() { - // If loading a NDS directly, this value should be set - // depending on the console type in the header at offset 12h - switch (NDSCart::Header.UnitCode) + bool dsmode = false; + + // TODO: add controls for forcing DS or DSi mode? + if (!(NDSCart::Header.UnitCode & 0x02)) + dsmode = true; + + // TODO: RAM size!! + + if (dsmode) { - case 0x00: /* NDS Image */ - // on a pure NDS Image, we disable all extended features - // TODO: For now keep the features enabled, as you can run pure NDS in NDS Emulation anyway - SCFG_BIOS = 0x0303; - break; - case 0x02: /* DSi Enhanced Image */ SCFG_BIOS = 0x0303; - break; - default: - SCFG_BIOS = 0x0101; // TODO: should be zero when booting from BIOS - break; + + // no NWRAM Mapping + for (int i = 0; i < 4; i++) + MapNWRAM_A(i, 0); + for (int i = 0; i < 8; i++) + MapNWRAM_B(i, 0); + for (int i = 0; i < 8; i++) + MapNWRAM_C(i, 0); + + // No NWRAM Window + for (int i = 0; i < 3; i++) + { + MapNWRAMRange(0, i, 0); + MapNWRAMRange(1, i, 0); + } + + NDS::MapSharedWRAM(3); + + // TODO: clock speed! } - // no NWRAM Mapping - for (int i = 0; i < 4; i++) - MapNWRAM_A(i, 0); - for (int i = 0; i < 8; i++) - MapNWRAM_B(i, 0); - for (int i = 0; i < 8; i++) - MapNWRAM_C(i, 0); - // No NWRAM Window - for (int i = 0; i < 3; i++) + else { - MapNWRAMRange(0, i, 0); - MapNWRAMRange(1, i, 0); + SCFG_BIOS = 0x0101; + + // WRAM mapping + + MBK[0][8] = 0; + MBK[1][8] = 0; + + u32 mbk[12]; + memcpy(mbk, &NDSCart::CartROM[0x180], 12*4); + + MapNWRAM_A(0, mbk[0] & 0xFF); + MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF); + MapNWRAM_A(2, (mbk[0] >> 16) & 0xFF); + MapNWRAM_A(3, mbk[0] >> 24); + + MapNWRAM_B(0, mbk[1] & 0xFF); + MapNWRAM_B(1, (mbk[1] >> 8) & 0xFF); + MapNWRAM_B(2, (mbk[1] >> 16) & 0xFF); + MapNWRAM_B(3, mbk[1] >> 24); + MapNWRAM_B(4, mbk[2] & 0xFF); + MapNWRAM_B(5, (mbk[2] >> 8) & 0xFF); + MapNWRAM_B(6, (mbk[2] >> 16) & 0xFF); + MapNWRAM_B(7, mbk[2] >> 24); + + MapNWRAM_C(0, mbk[3] & 0xFF); + MapNWRAM_C(1, (mbk[3] >> 8) & 0xFF); + MapNWRAM_C(2, (mbk[3] >> 16) & 0xFF); + MapNWRAM_C(3, mbk[3] >> 24); + MapNWRAM_C(4, mbk[4] & 0xFF); + MapNWRAM_C(5, (mbk[4] >> 8) & 0xFF); + MapNWRAM_C(6, (mbk[4] >> 16) & 0xFF); + MapNWRAM_C(7, mbk[4] >> 24); + + MapNWRAMRange(0, 0, mbk[5]); + MapNWRAMRange(0, 1, mbk[6]); + MapNWRAMRange(0, 2, mbk[7]); + + MapNWRAMRange(1, 0, mbk[8]); + MapNWRAMRange(1, 1, mbk[9]); + MapNWRAMRange(1, 2, mbk[10]); + + MBK[0][8] = mbk[11] & 0x00FFFF0F; + MBK[1][8] = mbk[11] & 0x00FFFF0F; + + NDS::MapSharedWRAM(mbk[11] >> 24); + } + + u32 arm9start = 0; + + // load the ARM9 secure area + if (NDSCart::Header.ARM9ROMOffset >= 0x4000 && NDSCart::Header.ARM9ROMOffset < 0x8000) + { + u8 securearea[0x800]; + NDSCart::DecryptSecureArea(securearea); + + for (u32 i = 0; i < 0x800; i+=4) + { + ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, *(u32*)&securearea[i]); + arm9start += 4; + } + } + + for (u32 i = arm9start; i < NDSCart::Header.ARM9Size; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.ARM9ROMOffset+i]; + ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, tmp); + } + + for (u32 i = 0; i < NDSCart::Header.ARM7Size; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.ARM7ROMOffset+i]; + ARM7Write32(NDSCart::Header.ARM7RAMAddress+i, tmp); + } + + if ((!dsmode) && (NDSCart::Header.DSiCryptoFlags & (1<<0))) + { + // load DSi-specific regions + + for (u32 i = 0; i < NDSCart::Header.DSiARM9iSize; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.DSiARM9iROMOffset+i]; + ARM9Write32(NDSCart::Header.DSiARM9iRAMAddress+i, tmp); + } + + for (u32 i = 0; i < NDSCart::Header.DSiARM7iSize; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.DSiARM7iROMOffset+i]; + ARM7Write32(NDSCart::Header.DSiARM7iRAMAddress+i, tmp); + } + + // decrypt any modcrypt areas + + if (NDSCart::Header.DSiCryptoFlags & (1<<1)) + { + DecryptModcryptArea(NDSCart::Header.DSiModcrypt1Offset, + NDSCart::Header.DSiModcrypt1Size, + NDSCart::Header.DSiARM9Hash); + DecryptModcryptArea(NDSCart::Header.DSiModcrypt2Offset, + NDSCart::Header.DSiModcrypt2Size, + NDSCart::Header.DSiARM7Hash); + } + } + + // CHECKME: some of these are 'only for NDS ROM', presumably + // only for when loading a cart? (as opposed to DSiWare) + + for (u32 i = 0; i < 0x160; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[i]; + ARM9Write32(0x02FFFA80+i, tmp); + ARM9Write32(0x02FFFE00+i, tmp); } + + for (u32 i = 0; i < 0x1000; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[i]; + ARM9Write32(0x02FFC000+i, tmp); + ARM9Write32(0x02FFE000+i, tmp); + } + + if (DSi_NAND::Init(SDMMCFile, &DSi::ARM7iBIOS[0x8308])) + { + u8 userdata[0x1B0]; + DSi_NAND::ReadUserData(userdata); + for (u32 i = 0; i < 0x128; i+=4) + ARM9Write32(0x02000400+i, *(u32*)&userdata[0x88+i]); + + u8 hwinfoS[0xA4]; + u8 hwinfoN[0x9C]; + DSi_NAND::ReadHardwareInfo(hwinfoS, hwinfoN); + + for (u32 i = 0; i < 0x14; i+=4) + ARM9Write32(0x02000600+i, *(u32*)&hwinfoN[0x88+i]); + + for (u32 i = 0; i < 0x18; i+=4) + ARM9Write32(0x02FFFD68+i, *(u32*)&hwinfoS[0x88+i]); + + DSi_NAND::DeInit(); + } + + u8 nwifiver = SPI_Firmware::GetNWifiVersion(); + ARM9Write8(0x020005E0, nwifiver); + + // TODO: these should be taken from the wifi firmware in NAND + // but, hey, this works too. + if (nwifiver == 1) + { + ARM9Write16(0x020005E2, 0xB57E); + ARM9Write32(0x020005E4, 0x00500400); + ARM9Write32(0x020005E8, 0x00500000); + ARM9Write32(0x020005EC, 0x0002E000); + } + else + { + ARM9Write16(0x020005E2, 0x5BCA); + ARM9Write32(0x020005E4, 0x00520000); + ARM9Write32(0x020005E8, 0x00520000); + ARM9Write32(0x020005EC, 0x00020000); + } + + // TODO: the shit at 02FFD7B0..02FFDC00 + // and some other extra shit? + + ARM9Write32(0x02FFFC00, NDSCart::CartID); + ARM9Write16(0x02FFFC40, 0x0001); // boot indicator + + ARM9Write8(0x02FFFDFA, DSi_BPTWL::GetBootFlag() | 0x80); + ARM9Write8(0x02FFFDFB, 0x01); + + NDS::ARM7BIOSProt = 0x20; + + // TODO: SCFG setup, permissions, etc + + SPI_Firmware::SetupDirectBoot(true); } void SoftReset() diff --git a/src/DSi_AES.cpp b/src/DSi_AES.cpp index c2312fa..02e4f1c 100644 --- a/src/DSi_AES.cpp +++ b/src/DSi_AES.cpp @@ -576,63 +576,4 @@ void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask) } } - -// utility - -void GetModcryptKey(u8* romheader, u8* key) -{ - if ((romheader[0x01C] & 0x04) || (romheader[0x1BF] & 0x80)) - { - // dev key - memcpy(key, &romheader[0x000], 16); - return; - } - - /*u8 oldkeys[16*3]; - memcpy(&oldkeys[16*0], KeyX[0], 16); - memcpy(&oldkeys[16*1], KeyY[0], 16); - memcpy(&oldkeys[16*2], KeyNormal[0], 16); - - KeyX[0][8] = romheader[0x00C]; - KeyX[0][9] = romheader[0x00D]; - KeyX[0][10] = romheader[0x00E]; - KeyX[0][11] = romheader[0x00F]; - KeyX[0][12] = romheader[0x00F]; - KeyX[0][13] = romheader[0x00E]; - KeyX[0][14] = romheader[0x00D]; - KeyX[0][15] = romheader[0x00C]; - - memcpy(KeyY[0], &romheader[0x350], 16); - - DeriveNormalKey(0); - memcpy(key, KeyNormal[0], 16); - - memcpy(KeyX[0], &oldkeys[16*0], 16); - memcpy(KeyY[0], &oldkeys[16*1], 16); - memcpy(KeyNormal[0], &oldkeys[16*2], 16);*/ -} - -void ApplyModcrypt(u8* data, u32 len, u8* key, u8* iv) -{ - u8 key_rev[16], iv_rev[16]; - u8 data_rev[16]; - u8 oldkeys[16*2]; - memcpy(&oldkeys[16*0], Ctx.RoundKey, 16); - memcpy(&oldkeys[16*1], Ctx.Iv, 16); - - Swap16(key_rev, key); - Swap16(iv_rev, iv); - AES_init_ctx_iv(&Ctx, key_rev, iv_rev); - - for (u32 i = 0; i < len; i += 16) - { - Swap16(data_rev, &data[i]); - AES_CTR_xcrypt_buffer(&Ctx, data_rev, 16); - Swap16(&data[i], data_rev); - } - - memcpy(Ctx.RoundKey, &oldkeys[16*0], 16); - memcpy(Ctx.Iv, &oldkeys[16*1], 16); -} - } diff --git a/src/DSi_AES.h b/src/DSi_AES.h index 4793b74..27f8e64 100644 --- a/src/DSi_AES.h +++ b/src/DSi_AES.h @@ -48,8 +48,6 @@ void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask); void Swap16(u8* dst, u8* src); void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey); -void GetModcryptKey(u8* romheader, u8* key); -void ApplyModcrypt(u8* data, u32 len, u8* key, u8* iv); } diff --git a/src/DSi_DSP.cpp b/src/DSi_DSP.cpp index 6b216f8..41fbc70 100644 --- a/src/DSi_DSP.cpp +++ b/src/DSi_DSP.cpp @@ -384,7 +384,7 @@ u16 PDataDMAReadMMIO() } u8 Read8(u32 addr) -{ +{printf("DSP READ8 %08X\n", addr); if (!(DSi::SCFG_EXT[0] & (1<<18))) return 0; @@ -413,7 +413,7 @@ u8 Read8(u32 addr) return 0; } u16 Read16(u32 addr) -{ +{printf("DSP READ16 %08X\n", addr); if (!(DSi::SCFG_EXT[0] & (1<<18))) return 0; @@ -466,7 +466,7 @@ u32 Read32(u32 addr) } void Write8(u32 addr, u8 val) -{ +{printf("DSP WRITE8 %08X %02X\n", addr, val); if (!(DSi::SCFG_EXT[0] & (1<<18))) return; if (!DSPCatchUp()) return; @@ -488,7 +488,7 @@ void Write8(u32 addr, u8 val) } } void Write16(u32 addr, u16 val) -{ +{printf("DSP WRITE16 %08X %04X\n", addr, val); if (!(DSi::SCFG_EXT[0] & (1<<18))) return; if (!DSPCatchUp()) return; diff --git a/src/DSi_I2C.cpp b/src/DSi_I2C.cpp index 4bb7df9..6f5f2e5 100644 --- a/src/DSi_I2C.cpp +++ b/src/DSi_I2C.cpp @@ -72,6 +72,8 @@ void Reset() Registers[0x81] = 0x64; } +u8 GetBootFlag() { return Registers[0x70]; } + void Start() { //printf("BPTWL: start\n"); diff --git a/src/DSi_I2C.h b/src/DSi_I2C.h index ca027f8..c064366 100644 --- a/src/DSi_I2C.h +++ b/src/DSi_I2C.h @@ -19,6 +19,13 @@ #ifndef DSI_I2C_H #define DSI_I2C_H +namespace DSi_BPTWL +{ + +u8 GetBootFlag(); + +} + namespace DSi_I2C { diff --git a/src/DSi_NAND.cpp b/src/DSi_NAND.cpp index 3ecf64f..917578e 100644 --- a/src/DSi_NAND.cpp +++ b/src/DSi_NAND.cpp @@ -436,6 +436,77 @@ bool ESDecrypt(u8* data, u32 len) } +void ReadHardwareInfo(u8* dataS, u8* dataN) +{ + FIL file; + FRESULT res; + u32 nread; + + res = f_open(&file, "0:/sys/HWINFO_S.dat", FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) + { + f_read(&file, dataS, 0xA4, &nread); + f_close(&file); + } + + res = f_open(&file, "0:/sys/HWINFO_N.dat", FA_OPEN_EXISTING | FA_READ); + if (res == FR_OK) + { + f_read(&file, dataN, 0x9C, &nread); + f_close(&file); + } +} + + +void ReadUserData(u8* data) +{ + FIL file; + FRESULT res; + u32 nread; + + FIL f1, f2; + int v1, v2; + + res = f_open(&f1, "0:/shared1/TWLCFG0.dat", FA_OPEN_EXISTING | FA_READ); + if (res != FR_OK) + v1 = -1; + else + { + u8 tmp; + f_lseek(&f1, 0x81); + f_read(&f1, &tmp, 1, &nread); + v1 = tmp; + } + + res = f_open(&f2, "0:/shared1/TWLCFG1.dat", FA_OPEN_EXISTING | FA_READ); + if (res != FR_OK) + v2 = -1; + else + { + u8 tmp; + f_lseek(&f2, 0x81); + f_read(&f2, &tmp, 1, &nread); + v2 = tmp; + } + + if (v1 < 0 && v2 < 0) return; + + if (v2 > v1) + { + file = f2; + f_close(&f1); + } + else + { + file = f1; + f_close(&f2); + } + + f_lseek(&file, 0); + f_read(&file, data, 0x1B0, &nread); + f_close(&file); +} + void PatchTSC() { FRESULT res; diff --git a/src/DSi_NAND.h b/src/DSi_NAND.h index 8c46434..d80f298 100644 --- a/src/DSi_NAND.h +++ b/src/DSi_NAND.h @@ -39,6 +39,9 @@ void DeInit(); void GetIDs(u8* emmc_cid, u64& consoleid); +void ReadHardwareInfo(u8* dataS, u8* dataN); + +void ReadUserData(u8* data); void PatchTSC(); void ListTitles(u32 category, std::vector<u32>& titlelist); diff --git a/src/NDS.cpp b/src/NDS.cpp index f172677..ee174d1 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -341,94 +341,86 @@ void SetupDirectBoot() { if (ConsoleType == 1) { - // With the BIOS select in SCFG_BIOS and the initialization od - // SCFG_BIOS depending on the Header->UnitType, we can now boot - // directly in the roms. - // There are some more SCFG Settings that change depending on - // the unit type, so this is experimental - printf("!! DIRECT BOOT NOT STABLE IN DSI MODE\n"); DSi::SetupDirectBoot(); } + else + { + MapSharedWRAM(3); - u32 bootparams[8]; - memcpy(bootparams, &NDSCart::CartROM[0x20], 8*4); + u32 arm9start = 0; - printf("ARM9: offset=%08X entry=%08X RAM=%08X size=%08X\n", - bootparams[0], bootparams[1], bootparams[2], bootparams[3]); - printf("ARM7: offset=%08X entry=%08X RAM=%08X size=%08X\n", - bootparams[4], bootparams[5], bootparams[6], bootparams[7]); + // load the ARM9 secure area + if (NDSCart::Header.ARM9ROMOffset >= 0x4000 && NDSCart::Header.ARM9ROMOffset < 0x8000) + { + u8 securearea[0x800]; + NDSCart::DecryptSecureArea(securearea); - MapSharedWRAM(3); + for (u32 i = 0; i < 0x800; i+=4) + { + ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, *(u32*)&securearea[i]); + arm9start += 4; + } + } - u32 arm9start = 0; + // CHECKME: firmware seems to load this in 0x200 byte chunks - // load the ARM9 secure area - if (bootparams[0] >= 0x4000 && bootparams[0] < 0x8000) - { - u8 securearea[0x800]; - NDSCart::DecryptSecureArea(securearea); + for (u32 i = arm9start; i < NDSCart::Header.ARM9Size; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.ARM9ROMOffset+i]; + ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, tmp); + } - for (u32 i = 0; i < 0x800; i+=4) + for (u32 i = 0; i < NDSCart::Header.ARM7Size; i+=4) { - ARM9Write32(bootparams[2]+i, *(u32*)&securearea[i]); - arm9start += 4; + u32 tmp = *(u32*)&NDSCart::CartROM[NDSCart::Header.ARM7ROMOffset+i]; + ARM7Write32(NDSCart::Header.ARM7RAMAddress+i, tmp); } - } - // CHECKME: firmware seems to load this in 0x200 byte chunks + for (u32 i = 0; i < 0x170; i+=4) + { + u32 tmp = *(u32*)&NDSCart::CartROM[i]; + ARM9Write32(0x027FFE00+i, tmp); + } - for (u32 i = arm9start; i < bootparams[3]; i+=4) - { - u32 tmp = *(u32*)&NDSCart::CartROM[bootparams[0]+i]; - ARM9Write32(bootparams[2]+i, tmp); - } + ARM9Write32(0x027FF800, NDSCart::CartID); + ARM9Write32(0x027FF804, NDSCart::CartID); + ARM9Write16(0x027FF808, NDSCart::Header.HeaderCRC16); + ARM9Write16(0x027FF80A, NDSCart::Header.SecureAreaCRC16); - for (u32 i = 0; i < bootparams[7]; i+=4) - { - u32 tmp = *(u32*)&NDSCart::CartROM[bootparams[4]+i]; - ARM7Write32(bootparams[6]+i, tmp); - } + ARM9Write16(0x027FF850, 0x5835); - for (u32 i = 0; i < 0x170; i+=4) - { - u32 tmp = *(u32*)&NDSCart::CartROM[i]; - ARM9Write32(0x027FFE00+i, tmp); - } + ARM9Write32(0x027FFC00, NDSCart::CartID); + ARM9Write32(0x027FFC04, NDSCart::CartID); + ARM9Write16(0x027FFC08, NDSCart::Header.HeaderCRC16); + ARM9Write16(0x027FFC0A, NDSCart::Header.SecureAreaCRC16); - ARM9Write32(0x027FF800, NDSCart::CartID); - ARM9Write32(0x027FF804, NDSCart::CartID); - ARM9Write16(0x027FF808, *(u16*)&NDSCart::CartROM[0x15E]); - ARM9Write16(0x027FF80A, *(u16*)&NDSCart::CartROM[0x6C]); + ARM9Write16(0x027FFC10, 0x5835); + ARM9Write16(0x027FFC30, 0xFFFF); + ARM9Write16(0x027FFC40, 0x0001); - ARM9Write16(0x027FF850, 0x5835); + ARM7BIOSProt = 0x1204; - ARM9Write32(0x027FFC00, NDSCart::CartID); - ARM9Write32(0x027FFC04, NDSCart::CartID); - ARM9Write16(0x027FFC08, *(u16*)&NDSCart::CartROM[0x15E]); - ARM9Write16(0x027FFC0A, *(u16*)&NDSCart::CartROM[0x6C]); - - ARM9Write16(0x027FFC10, 0x5835); - ARM9Write16(0x027FFC30, 0xFFFF); - ARM9Write16(0x027FFC40, 0x0001); + SPI_Firmware::SetupDirectBoot(false); + } ARM9->CP15Write(0x910, 0x0300000A); ARM9->CP15Write(0x911, 0x00000020); ARM9->CP15Write(0x100, ARM9->CP15Read(0x100) | 0x00050000); - ARM9->R[12] = bootparams[1]; + ARM9->R[12] = NDSCart::Header.ARM9EntryAddress; ARM9->R[13] = 0x03002F7C; - ARM9->R[14] = bootparams[1]; + ARM9->R[14] = NDSCart::Header.ARM9EntryAddress; ARM9->R_IRQ[0] = 0x03003F80; ARM9->R_SVC[0] = 0x03003FC0; - ARM7->R[12] = bootparams[5]; + ARM7->R[12] = NDSCart::Header.ARM7EntryAddress; ARM7->R[13] = 0x0380FD80; - ARM7->R[14] = bootparams[5]; + ARM7->R[14] = NDSCart::Header.ARM7EntryAddress; ARM7->R_IRQ[0] = 0x0380FF80; ARM7->R_SVC[0] = 0x0380FFC0; - ARM9->JumpTo(bootparams[1]); - ARM7->JumpTo(bootparams[5]); + ARM9->JumpTo(NDSCart::Header.ARM9EntryAddress); + ARM7->JumpTo(NDSCart::Header.ARM7EntryAddress); PostFlag9 = 0x01; PostFlag7 = 0x01; @@ -444,10 +436,6 @@ void SetupDirectBoot() SPU::SetBias(0x200); SetWifiWaitCnt(0x0030); - - ARM7BIOSProt = 0x1204; - - SPI_Firmware::SetupDirectBoot(); } void Reset() @@ -1522,7 +1510,7 @@ void MonitorARM9Jump(u32 addr) if ((!RunningGame) && NDSCart::CartROM) { if (addr == *(u32*)&NDSCart::CartROM[0x24]) - { + {debug(0); printf("Game is now booting\n"); RunningGame = true; } @@ -1880,7 +1868,7 @@ void debug(u32 param) //for (int i = 0; i < 9; i++) // printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]); - FILE* + /*FILE* shit = fopen("debug/construct.bin", "wb"); fwrite(ARM9->ITCM, 0x8000, 1, shit); for (u32 i = 0x02000000; i < 0x02400000; i+=4) @@ -1893,23 +1881,23 @@ void debug(u32 param) u32 val = ARM7Read32(i); fwrite(&val, 4, 1, shit); } - fclose(shit); + fclose(shit);*/ - /*FILE* - shit = fopen("debug/power9.bin", "wb"); + FILE* + shit = fopen("debug/directboot9.bin", "wb"); for (u32 i = 0x02000000; i < 0x04000000; i+=4) { u32 val = DSi::ARM9Read32(i); fwrite(&val, 4, 1, shit); } fclose(shit); - shit = fopen("debug/power7.bin", "wb"); + shit = fopen("debug/directboot7.bin", "wb"); for (u32 i = 0x02000000; i < 0x04000000; i+=4) { u32 val = DSi::ARM7Read32(i); fwrite(&val, 4, 1, shit); } - fclose(shit);*/ + fclose(shit); } diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index b87139a..a88ba59 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -176,15 +176,6 @@ void Key2_Encrypt(u8* data, u32 len) } -void ApplyModcrypt(u32 addr, u32 len, u8* iv) -{return; - u8 key[16]; - - DSi_AES::GetModcryptKey(&CartROM[0], key); - DSi_AES::ApplyModcrypt(&CartROM[addr], len, key, iv); -} - - CartCommon::CartCommon(u8* rom, u32 len, u32 chipid) { ROM = rom; diff --git a/src/NDS_Header.h b/src/NDS_Header.h index 48009ed..c2079bf 100644 --- a/src/NDS_Header.h +++ b/src/NDS_Header.h @@ -105,7 +105,7 @@ struct NDSHeader u8 DSiWRAMCntSetting; // global WRAMCNT setting
u32 DSiRegionMask;
- u32 DSiPermissions;
+ u32 DSiPermissions[2];
u8 Reserved6[3];
u8 AppFlags; // flags at 1BF
diff --git a/src/SPI.cpp b/src/SPI.cpp index cbdbfe6..54444d9 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -21,6 +21,7 @@ #include <stdlib.h> #include "Config.h" #include "NDS.h" +#include "DSi.h" #include "SPI.h" #include "DSi_SPI_TSC.h" #include "Platform.h" @@ -167,35 +168,32 @@ void Reset() UserSettings = userdata; - if (NDS::ConsoleType == 0) + // fix touchscreen coords + *(u16*)&Firmware[userdata+0x58] = 0; + *(u16*)&Firmware[userdata+0x5A] = 0; + Firmware[userdata+0x5C] = 0; + Firmware[userdata+0x5D] = 0; + *(u16*)&Firmware[userdata+0x5E] = 255<<4; + *(u16*)&Firmware[userdata+0x60] = 191<<4; + Firmware[userdata+0x62] = 255; + Firmware[userdata+0x63] = 191; + + // disable autoboot + //Firmware[userdata+0x64] &= 0xBF; + + *(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF); + + if (Config::RandomizeMAC) { - // fix touchscreen coords - *(u16*)&Firmware[userdata+0x58] = 0; - *(u16*)&Firmware[userdata+0x5A] = 0; - Firmware[userdata+0x5C] = 0; - Firmware[userdata+0x5D] = 0; - *(u16*)&Firmware[userdata+0x5E] = 255<<4; - *(u16*)&Firmware[userdata+0x60] = 191<<4; - Firmware[userdata+0x62] = 255; - Firmware[userdata+0x63] = 191; - - // disable autoboot - //Firmware[userdata+0x64] &= 0xBF; - - *(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF); - - if (Config::RandomizeMAC) - { - // replace MAC address with random address - Firmware[0x36] = 0x00; - Firmware[0x37] = 0x09; - Firmware[0x38] = 0xBF; - Firmware[0x39] = rand()&0xFF; - Firmware[0x3A] = rand()&0xFF; - Firmware[0x3B] = rand()&0xFF; - - *(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); - } + // replace MAC address with random address + Firmware[0x36] = 0x00; + Firmware[0x37] = 0x09; + Firmware[0x38] = 0xBF; + Firmware[0x39] = rand()&0xFF; + Firmware[0x3A] = rand()&0xFF; + Firmware[0x3B] = rand()&0xFF; + + *(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); } printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", @@ -232,16 +230,30 @@ void DoSavestate(Savestate* file) file->Var32(&Addr); } -void SetupDirectBoot() +void SetupDirectBoot(bool dsi) { - NDS::ARM9Write32(0x027FF864, 0); - NDS::ARM9Write32(0x027FF868, *(u16*)&Firmware[0x20] << 3); + if (dsi) + { + for (u32 i = 0; i < 6; i += 2) + DSi::ARM9Write16(0x02FFFCF4, *(u16*)&Firmware[0x36+i]); // MAC address - NDS::ARM9Write16(0x027FF874, *(u16*)&Firmware[0x26]); - NDS::ARM9Write16(0x027FF876, *(u16*)&Firmware[0x04]); + // checkme + DSi::ARM9Write16(0x02FFFCFA, *(u16*)&Firmware[0x3C]); // enabled channels - for (u32 i = 0; i < 0x70; i += 4) - NDS::ARM9Write32(0x027FFC80+i, *(u32*)&Firmware[UserSettings+i]); + for (u32 i = 0; i < 0x70; i += 4) + DSi::ARM9Write32(0x02FFFC80+i, *(u32*)&Firmware[UserSettings+i]); + } + else + { + NDS::ARM9Write32(0x027FF864, 0); + NDS::ARM9Write32(0x027FF868, *(u16*)&Firmware[0x20] << 3); // user settings offset + + NDS::ARM9Write16(0x027FF874, *(u16*)&Firmware[0x26]); // CRC16 for data/gfx + NDS::ARM9Write16(0x027FF876, *(u16*)&Firmware[0x04]); // CRC16 for GUI/wifi code + + for (u32 i = 0; i < 0x70; i += 4) + NDS::ARM9Write32(0x027FFC80+i, *(u32*)&Firmware[UserSettings+i]); + } } u8 GetConsoleType() { return Firmware[0x1D]; } @@ -24,7 +24,7 @@ namespace SPI_Firmware { -void SetupDirectBoot(); +void SetupDirectBoot(bool dsi); u32 FixFirmwareLength(u32 originalLength); |