verify BIOS and firmware before booting games/firmware
This commit is contained in:
parent
49b24ea2b3
commit
c5c9434ac9
|
@ -587,7 +587,7 @@ bool DoSavestate_Scheduler(Savestate* file)
|
||||||
}
|
}
|
||||||
if (funcid == -1)
|
if (funcid == -1)
|
||||||
{
|
{
|
||||||
printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK STAPLEBUTTER.\n", i);
|
printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK ARISOTURA.\n", i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,24 @@ enum
|
||||||
ROMSlot_MAX
|
ROMSlot_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Load_OK = 0,
|
||||||
|
|
||||||
|
Load_BIOS9Missing,
|
||||||
|
Load_BIOS9Bad,
|
||||||
|
|
||||||
|
Load_BIOS7Missing,
|
||||||
|
Load_BIOS7Bad,
|
||||||
|
|
||||||
|
Load_FirmwareMissing,
|
||||||
|
Load_FirmwareBad,
|
||||||
|
Load_FirmwareNotBootable,
|
||||||
|
|
||||||
|
// TODO: more precise errors for ROM loading
|
||||||
|
Load_ROMLoadError,
|
||||||
|
};
|
||||||
|
|
||||||
extern char ROMPath [ROMSlot_MAX][1024];
|
extern char ROMPath [ROMSlot_MAX][1024];
|
||||||
extern char SRAMPath[ROMSlot_MAX][1024];
|
extern char SRAMPath[ROMSlot_MAX][1024];
|
||||||
extern bool SavestateLoaded;
|
extern bool SavestateLoaded;
|
||||||
|
@ -41,11 +59,11 @@ extern bool SavestateLoaded;
|
||||||
void Init_ROM();
|
void Init_ROM();
|
||||||
|
|
||||||
// load the BIOS/firmware and boot from it
|
// load the BIOS/firmware and boot from it
|
||||||
bool LoadBIOS();
|
int LoadBIOS();
|
||||||
|
|
||||||
// load a ROM file to the specified cart slot
|
// load a ROM file to the specified cart slot
|
||||||
// note: loading a ROM to the NDS slot resets emulation
|
// note: loading a ROM to the NDS slot resets emulation
|
||||||
bool LoadROM(const char* file, int slot);
|
int LoadROM(const char* file, int slot);
|
||||||
|
|
||||||
// get the filename associated with the given savestate slot (1-8)
|
// get the filename associated with the given savestate slot (1-8)
|
||||||
void GetSavestateName(int slot, char* filename, int len);
|
void GetSavestateName(int slot, char* filename, int len);
|
||||||
|
|
|
@ -57,8 +57,77 @@ void SetupSRAMPath(int slot)
|
||||||
strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3);
|
strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadBIOS()
|
int VerifyDSBIOS()
|
||||||
{
|
{
|
||||||
|
FILE* f;
|
||||||
|
long len;
|
||||||
|
|
||||||
|
f = Platform::OpenLocalFile(Config::BIOS9Path, "rb");
|
||||||
|
if (!f) return Load_BIOS9Missing;
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
len = ftell(f);
|
||||||
|
if (len != 0x1000)
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
return Load_BIOS9Bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
f = Platform::OpenLocalFile(Config::BIOS7Path, "rb");
|
||||||
|
if (!f) return Load_BIOS7Missing;
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
len = ftell(f);
|
||||||
|
if (len != 0x4000)
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
return Load_BIOS7Bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return Load_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VerifyDSFirmware()
|
||||||
|
{
|
||||||
|
FILE* f;
|
||||||
|
long len;
|
||||||
|
|
||||||
|
f = Platform::OpenLocalFile(Config::FirmwarePath, "rb");
|
||||||
|
if (!f) return Load_FirmwareMissing;
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
len = ftell(f);
|
||||||
|
if (len == 0x20000)
|
||||||
|
{
|
||||||
|
// 128KB firmware, not bootable
|
||||||
|
fclose(f);
|
||||||
|
return Load_FirmwareNotBootable;
|
||||||
|
}
|
||||||
|
else if (len != 0x40000 && len != 0x80000)
|
||||||
|
{
|
||||||
|
fclose(f);
|
||||||
|
return Load_FirmwareBad;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return Load_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoadBIOS()
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = VerifyDSBIOS();
|
||||||
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
|
res = VerifyDSFirmware();
|
||||||
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// original code in the libui frontend called NDS::LoadGBAROM() if needed
|
// original code in the libui frontend called NDS::LoadGBAROM() if needed
|
||||||
// should this be carried over here?
|
// should this be carried over here?
|
||||||
|
@ -71,12 +140,26 @@ bool LoadBIOS()
|
||||||
|
|
||||||
SavestateLoaded = false;
|
SavestateLoaded = false;
|
||||||
|
|
||||||
// TODO: error reporting?
|
return Load_OK;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadROM(const char* file, int slot)
|
int LoadROM(const char* file, int slot)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
|
bool directboot = Config::DirectBoot != 0;
|
||||||
|
|
||||||
|
res = VerifyDSBIOS();
|
||||||
|
if (res != Load_OK) return res;
|
||||||
|
|
||||||
|
res = VerifyDSFirmware();
|
||||||
|
if (res != Load_OK)
|
||||||
|
{
|
||||||
|
if (res == Load_FirmwareNotBootable)
|
||||||
|
directboot = true;
|
||||||
|
else
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
char oldpath[1024];
|
char oldpath[1024];
|
||||||
char oldsram[1024];
|
char oldsram[1024];
|
||||||
strncpy(oldpath, ROMPath[slot], 1024);
|
strncpy(oldpath, ROMPath[slot], 1024);
|
||||||
|
@ -88,28 +171,29 @@ bool LoadROM(const char* file, int slot)
|
||||||
SetupSRAMPath(0);
|
SetupSRAMPath(0);
|
||||||
SetupSRAMPath(1);
|
SetupSRAMPath(1);
|
||||||
|
|
||||||
if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], Config::DirectBoot))
|
if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot))
|
||||||
{
|
{
|
||||||
SavestateLoaded = false;
|
SavestateLoaded = false;
|
||||||
|
|
||||||
// Reload the inserted GBA cartridge (if any)
|
// Reload the inserted GBA cartridge (if any)
|
||||||
|
// TODO: report failure there??
|
||||||
if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]);
|
if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]);
|
||||||
|
|
||||||
strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
|
strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
|
||||||
return true;
|
return Load_OK;
|
||||||
}
|
}
|
||||||
else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot]))
|
else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot]))
|
||||||
{
|
{
|
||||||
SavestateLoaded = false;
|
SavestateLoaded = false;
|
||||||
|
|
||||||
strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
|
strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety
|
||||||
return true;
|
return Load_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strncpy(ROMPath[slot], oldpath, 1024);
|
strncpy(ROMPath[slot], oldpath, 1024);
|
||||||
strncpy(SRAMPath[slot], oldsram, 1024);
|
strncpy(SRAMPath[slot], oldsram, 1024);
|
||||||
return false;
|
return Load_ROMLoadError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -570,6 +570,27 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString MainWindow::loadErrorStr(int error)
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case Frontend::Load_BIOS9Missing: return "DS ARM9 BIOS was not found or could not be accessed.";
|
||||||
|
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.";
|
||||||
|
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.";
|
||||||
|
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.";
|
||||||
|
|
||||||
|
default: return "Unknown error during launch; smack Arisotura.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::onOpenFile()
|
void MainWindow::onOpenFile()
|
||||||
{
|
{
|
||||||
emuThread->emuPause(true);
|
emuThread->emuPause(true);
|
||||||
|
@ -584,6 +605,11 @@ void MainWindow::onOpenFile()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: validate the input file!!
|
||||||
|
// * check that it is a proper ROM
|
||||||
|
// * ensure the binary offsets are sane
|
||||||
|
// * etc
|
||||||
|
|
||||||
// this shit is stupid
|
// this shit is stupid
|
||||||
char file[1024];
|
char file[1024];
|
||||||
strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0';
|
strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0';
|
||||||
|
@ -594,7 +620,7 @@ void MainWindow::onOpenFile()
|
||||||
Config::LastROMFolder[pos] = '\0';
|
Config::LastROMFolder[pos] = '\0';
|
||||||
char* ext = &file[strlen(file)-3];
|
char* ext = &file[strlen(file)-3];
|
||||||
|
|
||||||
int slot; bool res;
|
int slot; int res;
|
||||||
if (!strcasecmp(ext, "gba"))
|
if (!strcasecmp(ext, "gba"))
|
||||||
{
|
{
|
||||||
slot = 1;
|
slot = 1;
|
||||||
|
@ -606,11 +632,11 @@ void MainWindow::onOpenFile()
|
||||||
res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS);
|
res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res)
|
if (res != Frontend::Load_OK)
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this,
|
QMessageBox::critical(this,
|
||||||
"melonDS",
|
"melonDS",
|
||||||
"Failed to load the ROM.\n\nMake sure the file is accessible and isn't used by another application.");
|
loadErrorStr(res));
|
||||||
emuThread->emuUnpause();
|
emuThread->emuUnpause();
|
||||||
}
|
}
|
||||||
else if (slot == 1)
|
else if (slot == 1)
|
||||||
|
@ -631,11 +657,12 @@ void MainWindow::onBootFirmware()
|
||||||
|
|
||||||
emuThread->emuPause(true);
|
emuThread->emuPause(true);
|
||||||
|
|
||||||
bool res = Frontend::LoadBIOS();
|
int res = Frontend::LoadBIOS();
|
||||||
if (!res)
|
if (res != Frontend::Load_OK)
|
||||||
{
|
{
|
||||||
// TODO!
|
QMessageBox::critical(this,
|
||||||
|
"melonDS",
|
||||||
|
loadErrorStr(res));
|
||||||
emuThread->emuUnpause();
|
emuThread->emuUnpause();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -110,6 +110,8 @@ private slots:
|
||||||
void onOpenEmuSettings();
|
void onOpenEmuSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString loadErrorStr(int error);
|
||||||
|
|
||||||
MainWindowPanel* panel;
|
MainWindowPanel* panel;
|
||||||
|
|
||||||
QAction* actOpenROM;
|
QAction* actOpenROM;
|
||||||
|
|
Loading…
Reference in New Issue