actually make DSi-mode direct boot work to some extent

This commit is contained in:
Arisotura 2021-08-30 20:26:49 +02:00
parent b84155e891
commit 523552a92d
13 changed files with 500 additions and 213 deletions

View File

@ -25,6 +25,7 @@
#include "ARM.h" #include "ARM.h"
#include "GPU.h" #include "GPU.h"
#include "NDSCart.h" #include "NDSCart.h"
#include "SPI.h"
#include "Platform.h" #include "Platform.h"
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
@ -187,37 +188,310 @@ void Reset()
ARM7Write16(eaddr+0x42, 0x0001); 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() void SetupDirectBoot()
{ {
// If loading a NDS directly, this value should be set bool dsmode = false;
// depending on the console type in the header at offset 12h
switch (NDSCart::Header.UnitCode) // 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; SCFG_BIOS = 0x0303;
break;
case 0x02: /* DSi Enhanced Image */ // no NWRAM Mapping
SCFG_BIOS = 0x0303; for (int i = 0; i < 4; i++)
break; MapNWRAM_A(i, 0);
default: for (int i = 0; i < 8; i++)
SCFG_BIOS = 0x0101; // TODO: should be zero when booting from BIOS MapNWRAM_B(i, 0);
break; 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 else
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); SCFG_BIOS = 0x0101;
MapNWRAMRange(1, i, 0);
// 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() void SoftReset()

View File

@ -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);
}
} }

View File

@ -48,8 +48,6 @@ void WriteKeyY(u32 slot, u32 offset, u32 val, u32 mask);
void Swap16(u8* dst, u8* src); void Swap16(u8* dst, u8* src);
void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey); void DeriveNormalKey(u8* keyX, u8* keyY, u8* normalkey);
void GetModcryptKey(u8* romheader, u8* key);
void ApplyModcrypt(u8* data, u32 len, u8* key, u8* iv);
} }

View File

@ -384,7 +384,7 @@ u16 PDataDMAReadMMIO()
} }
u8 Read8(u32 addr) u8 Read8(u32 addr)
{ {printf("DSP READ8 %08X\n", addr);
if (!(DSi::SCFG_EXT[0] & (1<<18))) if (!(DSi::SCFG_EXT[0] & (1<<18)))
return 0; return 0;
@ -413,7 +413,7 @@ u8 Read8(u32 addr)
return 0; return 0;
} }
u16 Read16(u32 addr) u16 Read16(u32 addr)
{ {printf("DSP READ16 %08X\n", addr);
if (!(DSi::SCFG_EXT[0] & (1<<18))) if (!(DSi::SCFG_EXT[0] & (1<<18)))
return 0; return 0;
@ -466,7 +466,7 @@ u32 Read32(u32 addr)
} }
void Write8(u32 addr, u8 val) void Write8(u32 addr, u8 val)
{ {printf("DSP WRITE8 %08X %02X\n", addr, val);
if (!(DSi::SCFG_EXT[0] & (1<<18))) return; if (!(DSi::SCFG_EXT[0] & (1<<18))) return;
if (!DSPCatchUp()) return; if (!DSPCatchUp()) return;
@ -488,7 +488,7 @@ void Write8(u32 addr, u8 val)
} }
} }
void Write16(u32 addr, u16 val) void Write16(u32 addr, u16 val)
{ {printf("DSP WRITE16 %08X %04X\n", addr, val);
if (!(DSi::SCFG_EXT[0] & (1<<18))) return; if (!(DSi::SCFG_EXT[0] & (1<<18))) return;
if (!DSPCatchUp()) return; if (!DSPCatchUp()) return;

View File

@ -72,6 +72,8 @@ void Reset()
Registers[0x81] = 0x64; Registers[0x81] = 0x64;
} }
u8 GetBootFlag() { return Registers[0x70]; }
void Start() void Start()
{ {
//printf("BPTWL: start\n"); //printf("BPTWL: start\n");

View File

@ -19,6 +19,13 @@
#ifndef DSI_I2C_H #ifndef DSI_I2C_H
#define DSI_I2C_H #define DSI_I2C_H
namespace DSi_BPTWL
{
u8 GetBootFlag();
}
namespace DSi_I2C namespace DSi_I2C
{ {

View File

@ -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() void PatchTSC()
{ {
FRESULT res; FRESULT res;

View File

@ -39,6 +39,9 @@ void DeInit();
void GetIDs(u8* emmc_cid, u64& consoleid); void GetIDs(u8* emmc_cid, u64& consoleid);
void ReadHardwareInfo(u8* dataS, u8* dataN);
void ReadUserData(u8* data);
void PatchTSC(); void PatchTSC();
void ListTitles(u32 category, std::vector<u32>& titlelist); void ListTitles(u32 category, std::vector<u32>& titlelist);

View File

@ -341,94 +341,86 @@ void SetupDirectBoot()
{ {
if (ConsoleType == 1) 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(); DSi::SetupDirectBoot();
} }
else
u32 bootparams[8];
memcpy(bootparams, &NDSCart::CartROM[0x20], 8*4);
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]);
MapSharedWRAM(3);
u32 arm9start = 0;
// load the ARM9 secure area
if (bootparams[0] >= 0x4000 && bootparams[0] < 0x8000)
{ {
u8 securearea[0x800]; MapSharedWRAM(3);
NDSCart::DecryptSecureArea(securearea);
for (u32 i = 0; i < 0x800; i+=4) u32 arm9start = 0;
// load the ARM9 secure area
if (NDSCart::Header.ARM9ROMOffset >= 0x4000 && NDSCart::Header.ARM9ROMOffset < 0x8000)
{ {
ARM9Write32(bootparams[2]+i, *(u32*)&securearea[i]); u8 securearea[0x800];
arm9start += 4; NDSCart::DecryptSecureArea(securearea);
for (u32 i = 0; i < 0x800; i+=4)
{
ARM9Write32(NDSCart::Header.ARM9RAMAddress+i, *(u32*)&securearea[i]);
arm9start += 4;
}
} }
// CHECKME: firmware seems to load this in 0x200 byte chunks
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);
}
for (u32 i = 0; i < 0x170; i+=4)
{
u32 tmp = *(u32*)&NDSCart::CartROM[i];
ARM9Write32(0x027FFE00+i, tmp);
}
ARM9Write32(0x027FF800, NDSCart::CartID);
ARM9Write32(0x027FF804, NDSCart::CartID);
ARM9Write16(0x027FF808, NDSCart::Header.HeaderCRC16);
ARM9Write16(0x027FF80A, NDSCart::Header.SecureAreaCRC16);
ARM9Write16(0x027FF850, 0x5835);
ARM9Write32(0x027FFC00, NDSCart::CartID);
ARM9Write32(0x027FFC04, NDSCart::CartID);
ARM9Write16(0x027FFC08, NDSCart::Header.HeaderCRC16);
ARM9Write16(0x027FFC0A, NDSCart::Header.SecureAreaCRC16);
ARM9Write16(0x027FFC10, 0x5835);
ARM9Write16(0x027FFC30, 0xFFFF);
ARM9Write16(0x027FFC40, 0x0001);
ARM7BIOSProt = 0x1204;
SPI_Firmware::SetupDirectBoot(false);
} }
// CHECKME: firmware seems to load this in 0x200 byte chunks
for (u32 i = arm9start; i < bootparams[3]; i+=4)
{
u32 tmp = *(u32*)&NDSCart::CartROM[bootparams[0]+i];
ARM9Write32(bootparams[2]+i, tmp);
}
for (u32 i = 0; i < bootparams[7]; i+=4)
{
u32 tmp = *(u32*)&NDSCart::CartROM[bootparams[4]+i];
ARM7Write32(bootparams[6]+i, tmp);
}
for (u32 i = 0; i < 0x170; i+=4)
{
u32 tmp = *(u32*)&NDSCart::CartROM[i];
ARM9Write32(0x027FFE00+i, tmp);
}
ARM9Write32(0x027FF800, NDSCart::CartID);
ARM9Write32(0x027FF804, NDSCart::CartID);
ARM9Write16(0x027FF808, *(u16*)&NDSCart::CartROM[0x15E]);
ARM9Write16(0x027FF80A, *(u16*)&NDSCart::CartROM[0x6C]);
ARM9Write16(0x027FF850, 0x5835);
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);
ARM9->CP15Write(0x910, 0x0300000A); ARM9->CP15Write(0x910, 0x0300000A);
ARM9->CP15Write(0x911, 0x00000020); ARM9->CP15Write(0x911, 0x00000020);
ARM9->CP15Write(0x100, ARM9->CP15Read(0x100) | 0x00050000); ARM9->CP15Write(0x100, ARM9->CP15Read(0x100) | 0x00050000);
ARM9->R[12] = bootparams[1]; ARM9->R[12] = NDSCart::Header.ARM9EntryAddress;
ARM9->R[13] = 0x03002F7C; ARM9->R[13] = 0x03002F7C;
ARM9->R[14] = bootparams[1]; ARM9->R[14] = NDSCart::Header.ARM9EntryAddress;
ARM9->R_IRQ[0] = 0x03003F80; ARM9->R_IRQ[0] = 0x03003F80;
ARM9->R_SVC[0] = 0x03003FC0; ARM9->R_SVC[0] = 0x03003FC0;
ARM7->R[12] = bootparams[5]; ARM7->R[12] = NDSCart::Header.ARM7EntryAddress;
ARM7->R[13] = 0x0380FD80; ARM7->R[13] = 0x0380FD80;
ARM7->R[14] = bootparams[5]; ARM7->R[14] = NDSCart::Header.ARM7EntryAddress;
ARM7->R_IRQ[0] = 0x0380FF80; ARM7->R_IRQ[0] = 0x0380FF80;
ARM7->R_SVC[0] = 0x0380FFC0; ARM7->R_SVC[0] = 0x0380FFC0;
ARM9->JumpTo(bootparams[1]); ARM9->JumpTo(NDSCart::Header.ARM9EntryAddress);
ARM7->JumpTo(bootparams[5]); ARM7->JumpTo(NDSCart::Header.ARM7EntryAddress);
PostFlag9 = 0x01; PostFlag9 = 0x01;
PostFlag7 = 0x01; PostFlag7 = 0x01;
@ -444,10 +436,6 @@ void SetupDirectBoot()
SPU::SetBias(0x200); SPU::SetBias(0x200);
SetWifiWaitCnt(0x0030); SetWifiWaitCnt(0x0030);
ARM7BIOSProt = 0x1204;
SPI_Firmware::SetupDirectBoot();
} }
void Reset() void Reset()
@ -1522,7 +1510,7 @@ void MonitorARM9Jump(u32 addr)
if ((!RunningGame) && NDSCart::CartROM) if ((!RunningGame) && NDSCart::CartROM)
{ {
if (addr == *(u32*)&NDSCart::CartROM[0x24]) if (addr == *(u32*)&NDSCart::CartROM[0x24])
{ {debug(0);
printf("Game is now booting\n"); printf("Game is now booting\n");
RunningGame = true; RunningGame = true;
} }
@ -1880,7 +1868,7 @@ void debug(u32 param)
//for (int i = 0; i < 9; i++) //for (int i = 0; i < 9; i++)
// printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]); // printf("VRAM %c: %02X\n", 'A'+i, GPU::VRAMCNT[i]);
FILE* /*FILE*
shit = fopen("debug/construct.bin", "wb"); shit = fopen("debug/construct.bin", "wb");
fwrite(ARM9->ITCM, 0x8000, 1, shit); fwrite(ARM9->ITCM, 0x8000, 1, shit);
for (u32 i = 0x02000000; i < 0x02400000; i+=4) for (u32 i = 0x02000000; i < 0x02400000; i+=4)
@ -1893,23 +1881,23 @@ void debug(u32 param)
u32 val = ARM7Read32(i); u32 val = ARM7Read32(i);
fwrite(&val, 4, 1, shit); fwrite(&val, 4, 1, shit);
} }
fclose(shit); fclose(shit);*/
/*FILE* FILE*
shit = fopen("debug/power9.bin", "wb"); shit = fopen("debug/directboot9.bin", "wb");
for (u32 i = 0x02000000; i < 0x04000000; i+=4) for (u32 i = 0x02000000; i < 0x04000000; i+=4)
{ {
u32 val = DSi::ARM9Read32(i); u32 val = DSi::ARM9Read32(i);
fwrite(&val, 4, 1, shit); fwrite(&val, 4, 1, shit);
} }
fclose(shit); fclose(shit);
shit = fopen("debug/power7.bin", "wb"); shit = fopen("debug/directboot7.bin", "wb");
for (u32 i = 0x02000000; i < 0x04000000; i+=4) for (u32 i = 0x02000000; i < 0x04000000; i+=4)
{ {
u32 val = DSi::ARM7Read32(i); u32 val = DSi::ARM7Read32(i);
fwrite(&val, 4, 1, shit); fwrite(&val, 4, 1, shit);
} }
fclose(shit);*/ fclose(shit);
} }

View File

@ -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) CartCommon::CartCommon(u8* rom, u32 len, u32 chipid)
{ {
ROM = rom; ROM = rom;

View File

@ -105,7 +105,7 @@ struct NDSHeader
u8 DSiWRAMCntSetting; // global WRAMCNT setting u8 DSiWRAMCntSetting; // global WRAMCNT setting
u32 DSiRegionMask; u32 DSiRegionMask;
u32 DSiPermissions; u32 DSiPermissions[2];
u8 Reserved6[3]; u8 Reserved6[3];
u8 AppFlags; // flags at 1BF u8 AppFlags; // flags at 1BF

View File

@ -21,6 +21,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "Config.h" #include "Config.h"
#include "NDS.h" #include "NDS.h"
#include "DSi.h"
#include "SPI.h" #include "SPI.h"
#include "DSi_SPI_TSC.h" #include "DSi_SPI_TSC.h"
#include "Platform.h" #include "Platform.h"
@ -167,35 +168,32 @@ void Reset()
UserSettings = userdata; 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 // replace MAC address with random address
*(u16*)&Firmware[userdata+0x58] = 0; Firmware[0x36] = 0x00;
*(u16*)&Firmware[userdata+0x5A] = 0; Firmware[0x37] = 0x09;
Firmware[userdata+0x5C] = 0; Firmware[0x38] = 0xBF;
Firmware[userdata+0x5D] = 0; Firmware[0x39] = rand()&0xFF;
*(u16*)&Firmware[userdata+0x5E] = 255<<4; Firmware[0x3A] = rand()&0xFF;
*(u16*)&Firmware[userdata+0x60] = 191<<4; Firmware[0x3B] = rand()&0xFF;
Firmware[userdata+0x62] = 255;
Firmware[userdata+0x63] = 191;
// disable autoboot *(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000);
//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);
}
} }
printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
@ -232,16 +230,30 @@ void DoSavestate(Savestate* file)
file->Var32(&Addr); file->Var32(&Addr);
} }
void SetupDirectBoot() void SetupDirectBoot(bool dsi)
{ {
NDS::ARM9Write32(0x027FF864, 0); if (dsi)
NDS::ARM9Write32(0x027FF868, *(u16*)&Firmware[0x20] << 3); {
for (u32 i = 0; i < 6; i += 2)
DSi::ARM9Write16(0x02FFFCF4, *(u16*)&Firmware[0x36+i]); // MAC address
NDS::ARM9Write16(0x027FF874, *(u16*)&Firmware[0x26]); // checkme
NDS::ARM9Write16(0x027FF876, *(u16*)&Firmware[0x04]); DSi::ARM9Write16(0x02FFFCFA, *(u16*)&Firmware[0x3C]); // enabled channels
for (u32 i = 0; i < 0x70; i += 4) for (u32 i = 0; i < 0x70; i += 4)
NDS::ARM9Write32(0x027FFC80+i, *(u32*)&Firmware[UserSettings+i]); 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]; } u8 GetConsoleType() { return Firmware[0x1D]; }

View File

@ -24,7 +24,7 @@
namespace SPI_Firmware namespace SPI_Firmware
{ {
void SetupDirectBoot(); void SetupDirectBoot(bool dsi);
u32 FixFirmwareLength(u32 originalLength); u32 FixFirmwareLength(u32 originalLength);