- fix load ROM with GBA Loader (*.ds.gba);
This commit is contained in:
mtabachenko 2013-11-09 17:20:35 +00:00
parent 0fdac4d989
commit 742bc11da3
3 changed files with 37 additions and 39 deletions

View File

@ -403,21 +403,19 @@ void GameInfo::populate()
}
static std::vector<char> buffer;
static std::vector<char> v;
bool GameInfo::loadROM(std::string fname)
bool GameInfo::loadROM(std::string fname, u32 type)
{
printf("ROM %s\n", CommonSettings.loadToMemory?"loaded to RAM":"stream from disk");
//printf("ROM %s\n", CommonSettings.loadToMemory?"loaded to RAM":"stream from disk");
closeROM();
fROM = fopen(fname.c_str(), "rb");
if (!fROM) return false;
headerOffset = (type == ROM_DSGBA)?DSGBA_LOADER_SIZE:0;
fseek(fROM, 0, SEEK_END);
romsize = ftell(fROM);
fseek(fROM, 0, SEEK_SET);
romsize = ftell(fROM) - headerOffset;
fseek(fROM, headerOffset, SEEK_SET);
bool res = (fread(&header, 1, sizeof(header), fROM) == sizeof(header));
@ -431,12 +429,15 @@ bool GameInfo::loadROM(std::string fname)
mask |= (mask >>8);
mask |= (mask >>16);
fseek(fROM, 0x4000, SEEK_SET);
fread(&secureArea[0], 1, 0x4000, fROM);
if (type == ROM_NDS)
{
fseek(fROM, 0x4000 + headerOffset, SEEK_SET);
fread(&secureArea[0], 1, 0x4000, fROM);
}
if (CommonSettings.loadToMemory)
{
fseek(fROM, 0, SEEK_SET);
fseek(fROM, headerOffset, SEEK_SET);
romdata = new u8[romsize + 4];
if (fread(romdata, 1, romsize, fROM) != romsize)
@ -457,10 +458,10 @@ bool GameInfo::loadROM(std::string fname)
_isDSiEnhanced = ((readROM(0x180) == 0x8D898581U) && (readROM(0x184) == 0x8C888480U));
if (hasRomBanner())
{
fseek(fROM, header.IconOff, SEEK_SET);
fseek(fROM, header.IconOff + headerOffset, SEEK_SET);
fread(&banner, 1, sizeof(RomBanner), fROM);
}
fseek(fROM, 0, SEEK_SET);
fseek(fROM, headerOffset, SEEK_SET);
lastReadPos = 0;
return true;
}
@ -494,7 +495,7 @@ u32 GameInfo::readROM(u32 pos)
{
u32 data;
if (lastReadPos != pos)
fseek(fROM, pos, SEEK_SET);
fseek(fROM, pos + headerOffset, SEEK_SET);
u32 num = fread(&data, 1, 4, fROM);
lastReadPos = (pos + num);
return data;
@ -505,17 +506,17 @@ u32 GameInfo::readROM(u32 pos)
static int rom_init_path(const char *filename, const char *physicalName, const char *logicalFilename)
{
int type = ROM_NDS;
u32 type = ROM_NDS;
path.init(logicalFilename? logicalFilename : filename);
if ( path.isdsgba(path.path)) {
type = ROM_DSGBA;
gameInfo.loadROM(path.path);
gameInfo.loadROM(path.path, type);
}
else if ( !strcasecmp(path.extension().c_str(), "nds")) {
type = ROM_NDS;
gameInfo.loadROM(physicalName ? physicalName : path.path); //n.b. this does nothing if the file can't be found (i.e. if it was an extracted tempfile)...
gameInfo.loadROM(physicalName ? physicalName : path.path, type); //n.b. this does nothing if the file can't be found (i.e. if it was an extracted tempfile)...
//...but since the data was extracted to gameInfo then it is ok
}
//ds.gba in archives, it's already been loaded into memory at this point
@ -524,18 +525,9 @@ static int rom_init_path(const char *filename, const char *physicalName, const c
} else {
//well, try to load it as an nds rom anyway
type = ROM_NDS;
gameInfo.loadROM(physicalName ? physicalName : path.path);
gameInfo.loadROM(physicalName ? physicalName : path.path, type);
}
// TODO: !!!!!
#if 0
if(type == ROM_DSGBA)
{
std::vector<char> v(gameInfo.romdata + DSGBA_LOADER_SIZE, gameInfo.romdata + gameInfo.romsize);
gameInfo.loadData(&v[0],gameInfo.romsize - DSGBA_LOADER_SIZE);
}
#endif
//check that size is at least the size of the header
if (gameInfo.romsize < 352) {
return -1;
@ -2163,7 +2155,8 @@ bool NDS_LegitBoot()
//since firmware only boots encrypted roms, we have to make sure it's encrypted first
//this has not been validated on big endian systems. it almost positively doesn't work.
EncryptSecureArea((u8*)&gameInfo.header, (u8*)gameInfo.secureArea);
if (gameInfo.header.CRC16 != 0)
EncryptSecureArea((u8*)&gameInfo.header, (u8*)gameInfo.secureArea);
//boot processors from their bios entrypoints
armcpu_init(&NDS_ARM7, 0x00000000);
@ -2183,16 +2176,16 @@ bool NDS_FakeBoot()
nds.isFakeBooted = true;
//crazymax: how would it have got whacked? dont think we need this
//gameInfo.restoreSecureArea();
//since we're bypassing the code to decrypt the secure area, we need to make sure its decrypted first
//this has not been validated on big endian systems. it almost positively doesn't work.
bool okRom = DecryptSecureArea((u8*)&gameInfo.header, (u8*)gameInfo.secureArea);
if (gameInfo.header.CRC16 != 0)
{
bool okRom = DecryptSecureArea((u8*)&gameInfo.header, (u8*)gameInfo.secureArea);
if(!okRom) {
printf("Specified file is not a valid rom\n");
return false;
if(!okRom) {
printf("Specified file is not a valid rom\n");
return false;
}
}
//bios (or firmware) sets this default, which is generally not important for retail games but some homebrews are depending on

View File

@ -337,6 +337,7 @@ struct GameInfo
u32 chipID;
u32 lastReadPos;
u32 romType;
u32 headerOffset;
char ROMserial[20];
char ROMname[20];
bool _isDSiEnhanced;
@ -356,6 +357,7 @@ struct GameInfo
mask(0),
lastReadPos(0xFFFFFFFF),
romType(ROM_NDS),
headerOffset(0),
_isDSiEnhanced(false)
{
memset(&header, 0, sizeof(header));
@ -365,7 +367,7 @@ struct GameInfo
~GameInfo() { closeROM(); }
bool loadROM(std::string fname);
bool loadROM(std::string fname, u32 type = ROM_NDS);
void closeROM();
u32 readROM(u32 pos);
void populate();

View File

@ -421,7 +421,7 @@ static void init0(u32 cardheader_gamecode)
/*
* decrypt_arm9
*/
static void decrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
static bool decrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
{
u32 *p = (u32*)data;
@ -435,7 +435,7 @@ static void decrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
if (p[0] != MAGIC30 || p[1] != MAGIC34)
{
fprintf(stderr, "Decryption failed!\n");
exit(1);
return false;
}
*p++ = 0xE7FFDEFF;
@ -447,6 +447,8 @@ static void decrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
p += 2;
size -= 8;
}
return true;
}
static void encrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
@ -512,7 +514,8 @@ bool DecryptSecureArea(u8 *romheader, u8 *secure)
//// write secure 0x800
//memcpy(romdata+0x4000,data,0x800);
decrypt_arm9(*(u32 *)header->gamecode, secure);
if (!decrypt_arm9(*(u32 *)header->gamecode, secure))
return false;
printf("Decrypted.\n");
}