[Core] Perform more thorough disk validity checks & change DiskIdent for Config/RDB
- It didn't detect NUD-4567-JPN dump.
This commit is contained in:
parent
0cee922767
commit
0c6936d67e
|
@ -26,7 +26,8 @@ m_DiskHeaderBase(NULL),
|
|||
m_ErrorMsg(EMPTY_STRING),
|
||||
m_DiskBufAddress(0),
|
||||
m_DiskSysAddress(0),
|
||||
m_DiskIDAddress(0)
|
||||
m_DiskIDAddress(0),
|
||||
m_DiskRomAddress(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -57,10 +58,13 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
|
|||
|
||||
char RomName[5];
|
||||
m_FileName = FileLoc;
|
||||
uint32_t crc1 = CalculateCrc();
|
||||
uint32_t crc2 = ~crc1;
|
||||
m_DiskIdent.Format("%08X-%08X-C:%X", crc1, crc2, GetDiskAddressID()[0]);
|
||||
//Get the disk ID from the disk image
|
||||
if (*(uint32_t *)(&GetDiskAddressID()[0]) != 0)
|
||||
{
|
||||
m_DiskIdent.Format("%08X-%08X-C:%X", *(uint32_t *)(&GetDiskAddressSys()[0]), *(uint32_t *)(&GetDiskAddressID()[0]), GetDiskAddressID()[0]);
|
||||
//Get the disk ID from the disk image
|
||||
//if not 0x00000000
|
||||
RomName[0] = (char)*(GetDiskAddressID() + 3);
|
||||
RomName[1] = (char)*(GetDiskAddressID() + 2);
|
||||
RomName[2] = (char)*(GetDiskAddressID() + 1);
|
||||
|
@ -69,14 +73,7 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
for (uint8_t i = 0; i < 0xE8; i += 4)
|
||||
{
|
||||
crc += *(uint32_t *)(m_DiskImage + i);
|
||||
}
|
||||
m_DiskIdent.Format("%08X-%08X-C:%X", *(uint32_t *)(&GetDiskAddressSys()[0]), crc, GetDiskAddressID()[0]);
|
||||
|
||||
//Get the disk ID from the disk image
|
||||
//if 0x00000000 then use a made up one
|
||||
RomName[0] = m_DiskIdent[12];
|
||||
RomName[1] = m_DiskIdent[11];
|
||||
RomName[2] = m_DiskIdent[10];
|
||||
|
@ -158,8 +155,21 @@ void CN64Disk::SwapDiskImage(const char * FileLoc)
|
|||
LoadDiskImage(FileLoc);
|
||||
}
|
||||
|
||||
bool CN64Disk::IsValidDiskImage(uint8_t Test[4])
|
||||
bool CN64Disk::IsValidDiskImage(uint8_t Test[0x20])
|
||||
{
|
||||
//Basic System Data Check (first 0x20 bytes is enough)
|
||||
//Disk Type
|
||||
if ((Test[0x05] & 0xEF) > 6) return false;
|
||||
|
||||
//IPL Load Block
|
||||
uint16_t ipl_load_blk = ((Test[0x06] << 16) | Test[0x07]);
|
||||
if (ipl_load_blk > 0x10C3 || ipl_load_blk == 0x0000) return false;
|
||||
|
||||
//IPL Load Address
|
||||
uint32_t ipl_load_addr = (Test[0x1C] << 32) | (Test[0x1D] << 24) | (Test[0x1E] << 16) | Test[0x1F];
|
||||
if (ipl_load_addr < 0x80000000 && ipl_load_addr >= 0x80800000) return false;
|
||||
|
||||
//Country Code
|
||||
if (*((uint32_t *)&Test[0]) == 0x16D348E8) { return true; }
|
||||
else if (*((uint32_t *)&Test[0]) == 0x56EE6322) { return true; }
|
||||
else if (*((uint32_t *)&Test[0]) == 0x00000000) { return true; }
|
||||
|
@ -242,19 +252,29 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc)
|
|||
return false;
|
||||
}
|
||||
|
||||
//Read the first 4 bytes and make sure it is a valid disk image
|
||||
uint8_t Test[4];
|
||||
m_DiskFile.SeekToBegin();
|
||||
if (m_DiskFile.Read(Test, sizeof(Test)) != sizeof(Test))
|
||||
//Make sure it is a valid disk image
|
||||
uint8_t Test[0x20];
|
||||
bool isValidDisk = false;
|
||||
|
||||
const uint8_t blocks[8] = { 0, 1, 2, 3, 8, 9, 10, 11 };
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_DiskFile.Close();
|
||||
WriteTrace(TraceN64System, TraceError, "Failed to read ident bytes");
|
||||
return false;
|
||||
m_DiskFile.Seek(0x4D08 * blocks[i], CFileBase::SeekPosition::begin);
|
||||
if (m_DiskFile.Read(Test, sizeof(Test)) != sizeof(Test))
|
||||
{
|
||||
m_DiskFile.Close();
|
||||
WriteTrace(TraceN64System, TraceError, "Failed to read ident bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
isValidDisk = IsValidDiskImage(Test);
|
||||
if (isValidDisk)
|
||||
break;
|
||||
}
|
||||
if (!IsValidDiskImage(Test))
|
||||
if (!isValidDisk)
|
||||
{
|
||||
m_DiskFile.Close();
|
||||
WriteTrace(TraceN64System, TraceError, "invalid image file %X %X %X %X", Test[0], Test[1], Test[2], Test[3]);
|
||||
WriteTrace(TraceN64System, TraceError, "invalid disk image file");
|
||||
return false;
|
||||
}
|
||||
uint32_t DiskFileSize = m_DiskFile.GetLength();
|
||||
|
@ -387,10 +407,10 @@ void CN64Disk::ByteSwapDisk()
|
|||
{
|
||||
uint32_t count;
|
||||
|
||||
switch (*((uint32_t *)&m_DiskImage[0]))
|
||||
switch (*((uint32_t *)&GetDiskAddressSys()[8]))
|
||||
{
|
||||
case 0x16D348E8:
|
||||
case 0x56EE6322:
|
||||
case 0x281E140A:
|
||||
case 0x3024180C:
|
||||
for (count = 0; count < m_DiskFileSize; count += 4)
|
||||
{
|
||||
m_DiskImage[count] ^= m_DiskImage[count + 3];
|
||||
|
@ -401,10 +421,10 @@ void CN64Disk::ByteSwapDisk()
|
|||
m_DiskImage[count + 1] ^= m_DiskImage[count + 2];
|
||||
}
|
||||
break;
|
||||
case 0xE848D316: break;
|
||||
case 0x2263EE56: break;
|
||||
case 0x0A141E28: break;
|
||||
case 0x0C182430: break;
|
||||
default:
|
||||
g_Notify->DisplayError(stdstr_f("ByteSwapDisk: %X", m_DiskImage[0]).c_str());
|
||||
g_Notify->DisplayError(stdstr_f("ByteSwapDisk: %08X - %08X", *((uint32_t *)&GetDiskAddressSys()[8]), m_DiskSysAddress).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,6 +469,17 @@ void CN64Disk::UnallocateDiskImage()
|
|||
m_DiskImage = NULL;
|
||||
}
|
||||
|
||||
uint32_t CN64Disk::CalculateCrc()
|
||||
{
|
||||
//Custom CRC
|
||||
int crc = 0;
|
||||
for (int i = 0; i < 0x200; i += 4)
|
||||
{
|
||||
crc += *(uint32_t*)(&GetDiskAddressRom()[i]);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t CN64Disk::GetDiskAddressBlock(uint16_t head, uint16_t track, uint16_t block, uint16_t sector, uint16_t sectorsize)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
|
@ -549,6 +580,7 @@ void CN64Disk::DetectSystemArea()
|
|||
//MAME / SDK (System Area can be handled identically)
|
||||
m_DiskSysAddress = 0;
|
||||
m_DiskIDAddress = DISKID_LBA * 0x4D08;
|
||||
m_DiskRomAddress = SYSTEM_LBAS * 0x4D08;
|
||||
|
||||
//Handle System Data
|
||||
const uint16_t sysblocks[4] = { 9, 8, 1, 0 };
|
||||
|
@ -590,6 +622,7 @@ void CN64Disk::DetectSystemArea()
|
|||
//D64 (uses fixed addresses)
|
||||
m_DiskSysAddress = 0x000;
|
||||
m_DiskIDAddress = 0x100;
|
||||
m_DiskRomAddress = 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,16 +22,18 @@ public:
|
|||
bool LoadDiskImage(const char * FileLoc);
|
||||
bool SaveDiskImage();
|
||||
void SwapDiskImage(const char * FileLoc);
|
||||
static bool IsValidDiskImage(uint8_t Test[4]);
|
||||
static bool IsValidDiskImage(uint8_t Test[0x20]);
|
||||
void SaveDiskSettingID(bool temp);
|
||||
void ClearDiskSettingID();
|
||||
uint8_t * GetDiskAddress() { return m_DiskImage; }
|
||||
uint8_t * GetDiskAddressBuffer() { return m_DiskImage + m_DiskBufAddress; }
|
||||
uint8_t * GetDiskAddressSys() { return m_DiskImage + m_DiskSysAddress; }
|
||||
uint8_t * GetDiskAddressID() { return m_DiskImage + m_DiskIDAddress; }
|
||||
uint8_t * GetDiskAddressRom() { return m_DiskImage + m_DiskRomAddress; }
|
||||
uint8_t * GetDiskHeader() { return m_DiskHeader; }
|
||||
void SetDiskAddressBuffer(uint32_t address) { m_DiskBufAddress = address; }
|
||||
uint32_t GetDiskAddressBlock(uint16_t head, uint16_t track, uint16_t block, uint16_t sector, uint16_t sectorsize);
|
||||
uint32_t CalculateCrc();
|
||||
stdstr GetRomName() const { return m_RomName; }
|
||||
stdstr GetFileName() const { return m_FileName; }
|
||||
stdstr GetDiskIdent() const { return m_DiskIdent; }
|
||||
|
@ -73,6 +75,7 @@ private:
|
|||
uint32_t m_DiskBufAddress;
|
||||
uint32_t m_DiskSysAddress;
|
||||
uint32_t m_DiskIDAddress;
|
||||
uint32_t m_DiskRomAddress;
|
||||
LanguageStringID m_ErrorMsg;
|
||||
Country m_Country;
|
||||
stdstr m_RomName, m_FileName, m_DiskIdent;
|
||||
|
|
|
@ -341,7 +341,7 @@ void CRomList::RefreshRomListStatic(CRomList * _this)
|
|||
|
||||
bool CRomList::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat)
|
||||
{
|
||||
uint8_t Test[4];
|
||||
uint8_t Test[0x20];
|
||||
|
||||
if (_strnicmp(&FileName[strlen(FileName) - 4], ".ZIP", 4) == 0)
|
||||
{
|
||||
|
@ -412,10 +412,6 @@ bool CRomList::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (!CN64Rom::IsValidRomImage(Test) && !CN64Disk::IsValidDiskImage(Test))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CN64Rom::IsValidRomImage(Test))
|
||||
{
|
||||
|
@ -425,21 +421,85 @@ bool CRomList::LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (CN64Disk::IsValidDiskImage(Test))
|
||||
else if (!CN64Disk::IsValidDiskImage(Test) && (File.GetLength() == DISKSIZE_MAME || File.GetLength() == DISKSIZE_SDK))
|
||||
{
|
||||
//Is a Disk Image
|
||||
File.SeekToBegin();
|
||||
uint32_t sysdataoffset = 0;
|
||||
uint32_t diskidoffset = 0x43670;
|
||||
uint32_t romdataoffset = 0x738C0;
|
||||
bool isValidDisk = false;
|
||||
//Could still be a Disk Image
|
||||
|
||||
//System Data
|
||||
const uint8_t blocks[7] = { 2, 3, 10, 11, 1, 8, 9 };
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
sysdataoffset = 0x4D08 * blocks[i];
|
||||
File.Seek(sysdataoffset, CFileBase::begin);
|
||||
if (File.Read(Test, sizeof(Test)) != sizeof(Test))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
isValidDisk = CN64Disk::IsValidDiskImage(Test);
|
||||
if (isValidDisk)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isValidDisk)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
File.Seek(sysdataoffset, CFileBase::begin);
|
||||
if (!File.Read(Data, 0x100))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
File.Seek(0x43670, CFileBase::begin);
|
||||
File.Seek(diskidoffset, CFileBase::begin);
|
||||
if (!File.Read(Data + 0x100, 0x20))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
File.Seek(romdataoffset, CFileBase::begin);
|
||||
if (!File.Read(Data + 0x200, 0x200))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (CN64Disk::IsValidDiskImage(Test))
|
||||
{
|
||||
//Is a Disk Image
|
||||
uint32_t sysdataoffset = 0;
|
||||
uint32_t diskidoffset = 0x100;
|
||||
uint32_t romdataoffset = 0x200;
|
||||
|
||||
if ((File.GetLength() == DISKSIZE_MAME) || (File.GetLength() == DISKSIZE_SDK))
|
||||
{
|
||||
diskidoffset = 0x43670;
|
||||
romdataoffset = 0x738C0;
|
||||
}
|
||||
|
||||
File.Seek(sysdataoffset, CFileBase::begin);
|
||||
if (!File.Read(Data, 0x100))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
File.Seek(diskidoffset, CFileBase::begin);
|
||||
if (!File.Read(Data + 0x100, 0x20))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
File.Seek(romdataoffset, CFileBase::begin);
|
||||
if (!File.Read(Data + 0x200, 0x200))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*RomSize = File.GetLength();
|
||||
FileFormat = Format_Uncompressed;
|
||||
}
|
||||
|
@ -494,15 +554,12 @@ bool CRomList::FillRomInfo(ROM_INFO * pRomInfo)
|
|||
pRomInfo->CartID[2] = *(RomData + 0x102);
|
||||
pRomInfo->Manufacturer = '\0';
|
||||
pRomInfo->Country = *(RomData + 0x100);
|
||||
pRomInfo->CRC1 = *(uint32_t *)(RomData + 0x00);
|
||||
pRomInfo->CRC2 = *(uint32_t *)(RomData + 0x100);
|
||||
if (pRomInfo->CRC2 == 0)
|
||||
pRomInfo->CRC1 = 0;
|
||||
for (uint32_t i = 0; i < 0x200; i += 4)
|
||||
{
|
||||
for (uint8_t i = 0; i < 0xE8; i += 4)
|
||||
{
|
||||
pRomInfo->CRC2 += *(uint32_t *)(RomData + i);
|
||||
}
|
||||
pRomInfo->CRC1 += *(uint32_t *)(&RomData[0x200 + i]);
|
||||
}
|
||||
pRomInfo->CRC2 = ~pRomInfo->CRC1;
|
||||
pRomInfo->CicChip = CIC_NUS_8303;
|
||||
FillRomExtensionInfo(pRomInfo);
|
||||
}
|
||||
|
@ -582,6 +639,7 @@ void CRomList::ByteSwapRomData(uint8_t * Data, int32_t DataLen)
|
|||
case 0x07408027: //64DD IPL
|
||||
case 0xD316E848: //64DD JP Disk
|
||||
case 0xEE562263: //64DD US Disk
|
||||
case 0x00000000: //64DD DEV Disk
|
||||
for (count = 0; count < DataLen; count += 4)
|
||||
{
|
||||
Data[count] ^= Data[count + 2];
|
||||
|
|
|
@ -85,7 +85,7 @@ private:
|
|||
static void RefreshSettings(CRomList *);
|
||||
static void NotificationCB(const char * Status, CRomList * _this);
|
||||
static void RefreshRomListStatic(CRomList * _this);
|
||||
static void ByteSwapRomData(uint8_t * Data, int DataLen);
|
||||
static void ByteSwapRomData(uint8_t * Data, int32_t DataLen);
|
||||
|
||||
CPath m_GameDir;
|
||||
CIniFile * m_NotesIniFile;
|
||||
|
@ -95,4 +95,7 @@ private:
|
|||
CIniFile * m_ZipIniFile;
|
||||
#endif
|
||||
CThread m_RefreshThread;
|
||||
|
||||
#define DISKSIZE_MAME 0x0435B0C0
|
||||
#define DISKSIZE_SDK 0x03DEC800
|
||||
};
|
||||
|
|
|
@ -189,7 +189,7 @@ DWORD CALLBACK RomInfoProc(HWND hDlg, DWORD uMsg, DWORD wParam, DWORD lParam)
|
|||
//SetDlgItemTextW(hDlg, IDC_INFO_MD5, _this->m_pRomInfo->GetRomMD5().ToUTF16().c_str());
|
||||
//SetDlgItemTextW(hDlg, IDC_INFO_ROMSIZE, stdstr_f("%.1f MBit", (float)_this->m_pDiskInfo->GetRomSize() / 0x20000).ToUTF16().c_str());
|
||||
|
||||
BYTE * DiskHeader = _this->m_pDiskInfo->GetDiskAddress() + 0x43670;
|
||||
BYTE * DiskHeader = _this->m_pDiskInfo->GetDiskAddressID();
|
||||
SetDlgItemTextW(hDlg, IDC_INFO_CARTID, stdstr_f("%c%c", DiskHeader[0x02], DiskHeader[0x01]).ToUTF16().c_str());
|
||||
|
||||
/*switch (DiskHeader[0x00])
|
||||
|
@ -217,8 +217,8 @@ DWORD CALLBACK RomInfoProc(HWND hDlg, DWORD uMsg, DWORD wParam, DWORD lParam)
|
|||
default:
|
||||
SetDlgItemTextW(hDlg, IDC_INFO_COUNTRY, stdstr_f(" Unknown %c (%02X)", DiskHeader[0x03], DiskHeader[0x03]).ToUTF16().c_str());
|
||||
}
|
||||
SetDlgItemTextW(hDlg, IDC_INFO_CRC1, stdstr_f("0x%08X", *(uint32_t *)(_this->m_pDiskInfo->GetDiskAddress())).ToUTF16().c_str());
|
||||
SetDlgItemTextW(hDlg, IDC_INFO_CRC2, stdstr_f("0x%08X", *(DWORD *)(DiskHeader)).ToUTF16().c_str());
|
||||
SetDlgItemTextW(hDlg, IDC_INFO_CRC1, stdstr_f("0x%08X", (_this->m_pDiskInfo->CalculateCrc())).ToUTF16().c_str());
|
||||
SetDlgItemTextW(hDlg, IDC_INFO_CRC2, stdstr_f("0x%08X", (~_this->m_pDiskInfo->CalculateCrc())).ToUTF16().c_str());
|
||||
/*
|
||||
std::wstring CicChip;
|
||||
switch (_this->m_pRomInfo->CicChipID())
|
||||
|
|
Loading…
Reference in New Issue