aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/DSi.cpp322
-rw-r--r--src/DSi_AES.cpp59
-rw-r--r--src/DSi_AES.h2
-rw-r--r--src/DSi_DSP.cpp8
-rw-r--r--src/DSi_I2C.cpp2
-rw-r--r--src/DSi_I2C.h7
-rw-r--r--src/DSi_NAND.cpp71
-rw-r--r--src/DSi_NAND.h3
-rw-r--r--src/NDS.cpp126
-rw-r--r--src/NDSCart.cpp9
-rw-r--r--src/NDS_Header.h2
-rw-r--r--src/SPI.cpp82
-rw-r--r--src/SPI.h2
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]; }
diff --git a/src/SPI.h b/src/SPI.h
index 3df654f..d82485b 100644
--- a/src/SPI.h
+++ b/src/SPI.h
@@ -24,7 +24,7 @@
namespace SPI_Firmware
{
-void SetupDirectBoot();
+void SetupDirectBoot(bool dsi);
u32 FixFirmwareLength(u32 originalLength);