keep only one handle of the NAND file around
This commit is contained in:
parent
53d5def919
commit
1d6cc3c6ef
42
src/DSi.cpp
42
src/DSi.cpp
|
@ -74,6 +74,9 @@ DSi_NDMA* NDMAs[8];
|
||||||
DSi_SDHost* SDMMC;
|
DSi_SDHost* SDMMC;
|
||||||
DSi_SDHost* SDIO;
|
DSi_SDHost* SDIO;
|
||||||
|
|
||||||
|
FILE* SDMMCFile;
|
||||||
|
FILE* SDIOFile;
|
||||||
|
|
||||||
u64 ConsoleID;
|
u64 ConsoleID;
|
||||||
u8 eMMC_CID[16];
|
u8 eMMC_CID[16];
|
||||||
|
|
||||||
|
@ -122,6 +125,8 @@ void DeInit()
|
||||||
|
|
||||||
delete SDMMC;
|
delete SDMMC;
|
||||||
delete SDIO;
|
delete SDIO;
|
||||||
|
|
||||||
|
CloseDSiNAND();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
@ -302,12 +307,11 @@ bool LoadNAND()
|
||||||
memset(NWRAMEnd, 0, sizeof(NWRAMEnd));
|
memset(NWRAMEnd, 0, sizeof(NWRAMEnd));
|
||||||
memset(NWRAMMask, 0, sizeof(NWRAMMask));
|
memset(NWRAMMask, 0, sizeof(NWRAMMask));
|
||||||
|
|
||||||
FILE* f = Platform::OpenLocalFile(Config::DSiNANDPath, "rb");
|
if (SDMMCFile)
|
||||||
if (f)
|
|
||||||
{
|
{
|
||||||
u32 bootparams[8];
|
u32 bootparams[8];
|
||||||
fseek(f, 0x220, SEEK_SET);
|
fseek(SDMMCFile, 0x220, SEEK_SET);
|
||||||
fread(bootparams, 4, 8, f);
|
fread(bootparams, 4, 8, SDMMCFile);
|
||||||
|
|
||||||
printf("ARM9: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n",
|
printf("ARM9: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n",
|
||||||
bootparams[0], bootparams[1], bootparams[2], bootparams[3]);
|
bootparams[0], bootparams[1], bootparams[2], bootparams[3]);
|
||||||
|
@ -320,8 +324,8 @@ bool LoadNAND()
|
||||||
MBK[1][8] = 0;
|
MBK[1][8] = 0;
|
||||||
|
|
||||||
u32 mbk[12];
|
u32 mbk[12];
|
||||||
fseek(f, 0x380, SEEK_SET);
|
fseek(SDMMCFile, 0x380, SEEK_SET);
|
||||||
fread(mbk, 4, 12, f);
|
fread(mbk, 4, 12, SDMMCFile);
|
||||||
|
|
||||||
MapNWRAM_A(0, mbk[0] & 0xFF);
|
MapNWRAM_A(0, mbk[0] & 0xFF);
|
||||||
MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF);
|
MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF);
|
||||||
|
@ -375,12 +379,12 @@ bool LoadNAND()
|
||||||
|
|
||||||
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
|
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
|
||||||
|
|
||||||
fseek(f, bootparams[0], SEEK_SET);
|
fseek(SDMMCFile, bootparams[0], SEEK_SET);
|
||||||
dstaddr = bootparams[2];
|
dstaddr = bootparams[2];
|
||||||
for (u32 i = 0; i < bootparams[3]; i += 16)
|
for (u32 i = 0; i < bootparams[3]; i += 16)
|
||||||
{
|
{
|
||||||
u8 data[16];
|
u8 data[16];
|
||||||
fread(data, 16, 1, f);
|
fread(data, 16, 1, SDMMCFile);
|
||||||
|
|
||||||
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
|
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
|
||||||
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
||||||
|
@ -400,12 +404,12 @@ bool LoadNAND()
|
||||||
|
|
||||||
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
|
AES_init_ctx_iv(&ctx, boot2key, boot2iv);
|
||||||
|
|
||||||
fseek(f, bootparams[4], SEEK_SET);
|
fseek(SDMMCFile, bootparams[4], SEEK_SET);
|
||||||
dstaddr = bootparams[6];
|
dstaddr = bootparams[6];
|
||||||
for (u32 i = 0; i < bootparams[7]; i += 16)
|
for (u32 i = 0; i < bootparams[7]; i += 16)
|
||||||
{
|
{
|
||||||
u8 data[16];
|
u8 data[16];
|
||||||
fread(data, 16, 1, f);
|
fread(data, 16, 1, SDMMCFile);
|
||||||
|
|
||||||
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
|
for (int j = 0; j < 16; j++) tmp[j] = data[15-j];
|
||||||
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
|
||||||
|
@ -427,25 +431,22 @@ bool LoadNAND()
|
||||||
|
|
||||||
// read the nocash footer
|
// read the nocash footer
|
||||||
|
|
||||||
fseek(f, -0x40, SEEK_END);
|
fseek(SDMMCFile, -0x40, SEEK_END);
|
||||||
|
|
||||||
char nand_footer[16];
|
char nand_footer[16];
|
||||||
const char* nand_footer_ref = "DSi eMMC CID/CPU";
|
const char* nand_footer_ref = "DSi eMMC CID/CPU";
|
||||||
fread(nand_footer, 1, 16, f);
|
fread(nand_footer, 1, 16, SDMMCFile);
|
||||||
if (memcmp(nand_footer, nand_footer_ref, 16))
|
if (memcmp(nand_footer, nand_footer_ref, 16))
|
||||||
{
|
{
|
||||||
printf("ERROR: NAND missing nocash footer\n");
|
printf("ERROR: NAND missing nocash footer\n");
|
||||||
fclose(f);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fread(eMMC_CID, 1, 16, f);
|
fread(eMMC_CID, 1, 16, SDMMCFile);
|
||||||
fread(&ConsoleID, 1, 8, f);
|
fread(&ConsoleID, 1, 8, SDMMCFile);
|
||||||
|
|
||||||
printf("eMMC CID: "); printhex(eMMC_CID, 16);
|
printf("eMMC CID: "); printhex(eMMC_CID, 16);
|
||||||
printf("Console ID: %016llX\n", ConsoleID);
|
printf("Console ID: %016llX\n", ConsoleID);
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ITCMInit, 0, 0x8000);
|
memset(ITCMInit, 0, 0x8000);
|
||||||
|
@ -463,6 +464,13 @@ bool LoadNAND()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloseDSiNAND()
|
||||||
|
{
|
||||||
|
if (DSi::SDMMCFile)
|
||||||
|
fclose(DSi::SDMMCFile);
|
||||||
|
if (DSi::SDIOFile)
|
||||||
|
fclose(DSi::SDIOFile);
|
||||||
|
}
|
||||||
|
|
||||||
void RunNDMAs(u32 cpu)
|
void RunNDMAs(u32 cpu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,9 @@ extern u64 ConsoleID;
|
||||||
extern DSi_SDHost* SDMMC;
|
extern DSi_SDHost* SDMMC;
|
||||||
extern DSi_SDHost* SDIO;
|
extern DSi_SDHost* SDIO;
|
||||||
|
|
||||||
|
extern FILE* SDMMCFile;
|
||||||
|
extern FILE* SDIOFile;
|
||||||
|
|
||||||
const u32 NWRAMSize = 0x40000;
|
const u32 NWRAMSize = 0x40000;
|
||||||
|
|
||||||
extern u8* NWRAM_A;
|
extern u8* NWRAM_A;
|
||||||
|
@ -59,6 +62,8 @@ void SoftReset();
|
||||||
bool LoadBIOS();
|
bool LoadBIOS();
|
||||||
bool LoadNAND();
|
bool LoadNAND();
|
||||||
|
|
||||||
|
void CloseDSiNAND();
|
||||||
|
|
||||||
void RunNDMAs(u32 cpu);
|
void RunNDMAs(u32 cpu);
|
||||||
void StallNDMAs();
|
void StallNDMAs();
|
||||||
bool NDMAsInMode(u32 cpu, u32 mode);
|
bool NDMAsInMode(u32 cpu, u32 mode);
|
||||||
|
|
|
@ -114,14 +114,14 @@ void DSi_SDHost::Reset()
|
||||||
|
|
||||||
if (Config::DSiSDEnable)
|
if (Config::DSiSDEnable)
|
||||||
{
|
{
|
||||||
sd = new DSi_MMCStorage(this, false, Config::DSiSDPath);
|
sd = new DSi_MMCStorage(this, false, DSi::SDIOFile);
|
||||||
u8 sd_cid[16] = {0xBD, 0x12, 0x34, 0x56, 0x78, 0x03, 0x4D, 0x30, 0x30, 0x46, 0x50, 0x41, 0x00, 0x00, 0x15, 0x00};
|
u8 sd_cid[16] = {0xBD, 0x12, 0x34, 0x56, 0x78, 0x03, 0x4D, 0x30, 0x30, 0x46, 0x50, 0x41, 0x00, 0x00, 0x15, 0x00};
|
||||||
sd->SetCID(sd_cid);
|
sd->SetCID(sd_cid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sd = nullptr;
|
sd = nullptr;
|
||||||
|
|
||||||
mmc = new DSi_MMCStorage(this, true, Config::DSiNANDPath);
|
mmc = new DSi_MMCStorage(this, true, DSi::SDMMCFile);
|
||||||
mmc->SetCID(DSi::eMMC_CID);
|
mmc->SetCID(DSi::eMMC_CID);
|
||||||
|
|
||||||
Ports[0] = sd;
|
Ports[0] = sd;
|
||||||
|
@ -706,30 +706,14 @@ void DSi_SDHost::CheckSwapFIFO()
|
||||||
|
|
||||||
#define MMC_DESC (Internal?"NAND":"SDcard")
|
#define MMC_DESC (Internal?"NAND":"SDcard")
|
||||||
|
|
||||||
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path) : DSi_SDDevice(host)
|
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, FILE* file) : DSi_SDDevice(host)
|
||||||
{
|
{
|
||||||
Internal = internal;
|
Internal = internal;
|
||||||
strncpy(FilePath, path, 1023); FilePath[1023] = '\0';
|
File = file;
|
||||||
|
|
||||||
File = Platform::OpenLocalFile(path, "r+b");
|
|
||||||
if (!File)
|
|
||||||
{
|
|
||||||
if (internal)
|
|
||||||
{
|
|
||||||
// TODO: proper failure
|
|
||||||
printf("!! MMC file %s does not exist\n", path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File = Platform::OpenLocalFile(path, "w+b");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DSi_MMCStorage::~DSi_MMCStorage()
|
DSi_MMCStorage::~DSi_MMCStorage()
|
||||||
{
|
{}
|
||||||
if (File) fclose(File);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSi_MMCStorage::Reset()
|
void DSi_MMCStorage::Reset()
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,7 +120,7 @@ protected:
|
||||||
class DSi_MMCStorage : public DSi_SDDevice
|
class DSi_MMCStorage : public DSi_SDDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path);
|
DSi_MMCStorage(DSi_SDHost* host, bool internal, FILE* file);
|
||||||
~DSi_MMCStorage();
|
~DSi_MMCStorage();
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
@ -134,7 +134,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Internal;
|
bool Internal;
|
||||||
char FilePath[1024];
|
|
||||||
FILE* File;
|
FILE* File;
|
||||||
|
|
||||||
u8 CID[16];
|
u8 CID[16];
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
|
#include "DSi.h"
|
||||||
#include "GBACart.h"
|
#include "GBACart.h"
|
||||||
|
|
||||||
#include "AREngine.h"
|
#include "AREngine.h"
|
||||||
|
@ -199,18 +200,27 @@ int VerifyDSiFirmware()
|
||||||
return Load_OK;
|
return Load_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VerifyDSiNAND()
|
int SetupDSiNAND()
|
||||||
{
|
{
|
||||||
FILE* f;
|
FILE* f;
|
||||||
long len;
|
long len;
|
||||||
|
|
||||||
f = Platform::OpenLocalFile(Config::DSiNANDPath, "rb");
|
f = Platform::OpenLocalFile(Config::DSiNANDPath, "r+b");
|
||||||
if (!f) return Load_DSiNANDMissing;
|
if (!f) return Load_DSiNANDMissing;
|
||||||
|
|
||||||
// TODO: some basic checks
|
// TODO: some basic checks
|
||||||
// check that it has the nocash footer, and all
|
// check that it has the nocash footer, and all
|
||||||
|
|
||||||
fclose(f);
|
DSi::SDMMCFile = f;
|
||||||
|
|
||||||
|
if (Config::DSiSDEnable)
|
||||||
|
{
|
||||||
|
f = Platform::OpenLocalFile(Config::DSiSDPath, "r+b");
|
||||||
|
if (f)
|
||||||
|
DSi::SDIOFile = f;
|
||||||
|
else
|
||||||
|
DSi::SDIOFile = Platform::OpenLocalFile(Config::DSiSDPath, "w+b");
|
||||||
|
}
|
||||||
|
|
||||||
return Load_OK;
|
return Load_OK;
|
||||||
}
|
}
|
||||||
|
@ -243,6 +253,8 @@ void LoadCheats()
|
||||||
|
|
||||||
int LoadBIOS()
|
int LoadBIOS()
|
||||||
{
|
{
|
||||||
|
DSi::CloseDSiNAND();
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = VerifyDSBIOS();
|
res = VerifyDSBIOS();
|
||||||
|
@ -256,7 +268,7 @@ int LoadBIOS()
|
||||||
res = VerifyDSiFirmware();
|
res = VerifyDSiFirmware();
|
||||||
if (res != Load_OK) return res;
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
res = VerifyDSiNAND();
|
res = SetupDSiNAND();
|
||||||
if (res != Load_OK) return res;
|
if (res != Load_OK) return res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -285,6 +297,8 @@ int LoadBIOS()
|
||||||
|
|
||||||
int LoadROM(const char* file, int slot)
|
int LoadROM(const char* file, int slot)
|
||||||
{
|
{
|
||||||
|
DSi::CloseDSiNAND();
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
bool directboot = Config::DirectBoot != 0;
|
bool directboot = Config::DirectBoot != 0;
|
||||||
|
|
||||||
|
@ -305,7 +319,7 @@ int LoadROM(const char* file, int slot)
|
||||||
res = VerifyDSiFirmware();
|
res = VerifyDSiFirmware();
|
||||||
if (res != Load_OK) return res;
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
res = VerifyDSiNAND();
|
res = SetupDSiNAND();
|
||||||
if (res != Load_OK) return res;
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
GBACart::Eject();
|
GBACart::Eject();
|
||||||
|
@ -376,10 +390,14 @@ void UnloadROM(int slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
ROMPath[slot][0] = '\0';
|
ROMPath[slot][0] = '\0';
|
||||||
|
|
||||||
|
DSi::CloseDSiNAND();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Reset()
|
int Reset()
|
||||||
{
|
{
|
||||||
|
DSi::CloseDSiNAND();
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
bool directboot = Config::DirectBoot != 0;
|
bool directboot = Config::DirectBoot != 0;
|
||||||
|
|
||||||
|
@ -394,7 +412,7 @@ int Reset()
|
||||||
res = VerifyDSiFirmware();
|
res = VerifyDSiFirmware();
|
||||||
if (res != Load_OK) return res;
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
res = VerifyDSiNAND();
|
res = SetupDSiNAND();
|
||||||
if (res != Load_OK) return res;
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
GBACart::Eject();
|
GBACart::Eject();
|
||||||
|
|
Loading…
Reference in New Issue