[Disk] Support D64 Master Disk Format

This commit is contained in:
LuigiBlood 2019-08-11 18:13:52 +02:00
parent ce868c57f8
commit 075c82a3e3
10 changed files with 172 additions and 53 deletions

View File

@ -190,9 +190,9 @@ void DiskBMUpdate()
//Write Data
if (dd_current < SECTORS_PER_BLOCK)
{
DiskBMWrite();
dd_current += 1;
if (!DiskBMReadWrite(true))
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
dd_current += 1;
}
else if (dd_current < SECTORS_PER_BLOCK + 1)
{
@ -200,10 +200,10 @@ void DiskBMUpdate()
{
dd_start_block = 1 - dd_start_block;
dd_current = 0;
DiskBMWrite();
if (!DiskBMReadWrite(true))
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
dd_current += 1;
g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK;
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
}
else
{
@ -222,14 +222,15 @@ void DiskBMUpdate()
//Read Data
if (((g_Reg->ASIC_CUR_TK >> 16) & 0x1FFF) == 6 && g_Reg->ASIC_CUR_SECTOR == 0 && g_Reg->ASIC_ID_REG != 0x00040000)
{
//Copy Protection
g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ;
g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO;
}
else if (dd_current < SECTORS_PER_BLOCK)
{
DiskBMRead();
dd_current += 1;
if (!DiskBMReadWrite(false))
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
dd_current += 1;
}
else if (dd_current < SECTORS_PER_BLOCK + 4)
{
@ -258,18 +259,9 @@ void DiskBMUpdate()
}
}
void DiskBMRead()
{
DiskBMReadWrite(false);
}
void DiskBMWrite()
{
DiskBMReadWrite(true);
}
void DiskBMReadWrite(bool write)
bool DiskBMReadWrite(bool write)
{
//Returns true if error
uint16_t head = ((g_Reg->ASIC_CUR_TK >> 16) / 0x1000) & 1;
uint16_t track = (g_Reg->ASIC_CUR_TK >> 16) & 0xFFF;
uint16_t block = dd_start_block;
@ -277,7 +269,17 @@ void DiskBMReadWrite(bool write)
uint16_t sectorsize = (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1);
uint32_t addr = g_Disk->GetDiskAddressBlock(head, track, block, sector, sectorsize);
if (addr == 0xFFFFFFFF)
{
//Error
return true;
}
else
{
g_Disk->SetDiskAddressBuffer(addr);
return false;
}
}
void DiskDMACheck(void)

View File

@ -18,9 +18,7 @@ void DiskReset(void);
void DiskBMControl(void);
void DiskGapSectorCheck(void);
void DiskBMUpdate(void);
void DiskBMRead(void);
void DiskBMWrite(void);
void DiskBMReadWrite(bool write);
bool DiskBMReadWrite(bool write);
void DiskDMACheck(void);
extern bool dd_write;

View File

@ -24,7 +24,9 @@ m_DiskImageBase(NULL),
m_DiskHeader(NULL),
m_DiskHeaderBase(NULL),
m_ErrorMsg(EMPTY_STRING),
m_DiskBufAddress(0)
m_DiskBufAddress(0),
m_DiskSysAddress(0),
m_DiskIDAddress(0)
{
}
@ -37,7 +39,7 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
UnallocateDiskImage();
m_ErrorMsg = EMPTY_STRING;
//Assume the file extension is *.ndd (it is the only case where it is loaded)
//Assume the file extension is *.ndd or *.d64
stdstr ext = CPath(FileLoc).GetExtension();
stdstr ShadowFile = FileLoc;
ShadowFile[ShadowFile.length() - 1] = 'r';
@ -55,14 +57,14 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
char RomName[5];
m_FileName = FileLoc;
if (*(uint32_t *)(&m_DiskImage[0x43670]) != 0)
if (*(uint32_t *)(&GetDiskAddressID()[0]) != 0)
{
m_DiskIdent.Format("%08X-%08X-C:%X", *(uint32_t *)(&m_DiskImage[0]), *(uint32_t *)(&m_DiskImage[0x43670]), m_DiskImage[0x43670]);
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
RomName[0] = (char)*(m_DiskImage + 0x43673);
RomName[1] = (char)*(m_DiskImage + 0x43672);
RomName[2] = (char)*(m_DiskImage + 0x43671);
RomName[3] = (char)*(m_DiskImage + 0x43670);
RomName[0] = (char)*(GetDiskAddressID() + 3);
RomName[1] = (char)*(GetDiskAddressID() + 2);
RomName[2] = (char)*(GetDiskAddressID() + 1);
RomName[3] = (char)*(GetDiskAddressID() + 0);
RomName[4] = '\0';
}
else
@ -72,7 +74,7 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
{
crc += *(uint32_t *)(m_DiskImage + i);
}
m_DiskIdent.Format("%08X-%08X-C:%X", *(uint32_t *)(&m_DiskImage[0]), crc, m_DiskImage[0x43670]);
m_DiskIdent.Format("%08X-%08X-C:%X", *(uint32_t *)(GetDiskAddressSys()[0]), crc, GetDiskAddressID()[0]);
//Get the disk ID from the disk image
RomName[0] = m_DiskIdent[12];
@ -87,9 +89,10 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
}
}
m_RomName = RomName;
m_Country = (Country)m_DiskImage[0x43670];
m_DiskType = m_DiskImage[5 ^ 3] & 0x0F;
m_Country = (Country)GetDiskAddressID()[0];
m_DiskType = GetDiskAddressSys()[5 ^ 3] & 0x0F;
GenerateLBAToPhysTable();
InitSysDataD64();
if (g_Disk == this)
{
@ -101,6 +104,8 @@ bool CN64Disk::LoadDiskImage(const char * FileLoc)
bool CN64Disk::SaveDiskImage()
{
DeinitSysDataD64();
//NO NEED TO SAVE IF DISK TYPE IS 6
if (m_DiskType == 6)
{
@ -156,6 +161,7 @@ bool CN64Disk::IsValidDiskImage(uint8_t Test[4])
{
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; }
return false;
}
@ -251,10 +257,11 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc)
return false;
}
uint32_t DiskFileSize = m_DiskFile.GetLength();
stdstr ext = CPath(FileLoc).GetExtension();
WriteTrace(TraceN64System, TraceDebug, "Successfully Opened, size: 0x%X", DiskFileSize);
//Check Disk File Format
if ((DiskFileSize == MameFormatSize) || (DiskFileSize == SDKFormatSize))
if (((DiskFileSize == MameFormatSize) || (DiskFileSize == SDKFormatSize)) && (ext.compare("ndr") || ext.compare("ndd")))
{
if (DiskFileSize == MameFormatSize)
{
@ -305,6 +312,60 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc)
WriteTrace(TraceN64System, TraceError, "Expected to read: 0x%X, read: 0x%X", TotalRead, DiskFileSize);
return false;
}
m_DiskSysAddress = 0;
m_DiskIDAddress = 0x43670;
g_Notify->DisplayMessage(5, MSG_BYTESWAP);
ByteSwapDisk();
}
else if ((DiskFileSize > 0x4F08) && (ext.compare("d6r") || ext.compare("d64")))
{
m_DiskFormat = DiskFormatD64;
WriteTrace(TraceN64System, TraceDebug, "Disk File is D64 Format");
if (!AllocateDiskImage(DiskFileSize))
{
m_DiskFile.Close();
return false;
}
//Load the n64 disk to the allocated memory
g_Notify->DisplayMessage(5, MSG_LOADING);
m_DiskFile.SeekToBegin();
uint32_t count, TotalRead = 0;
for (count = 0; count < (int)DiskFileSize; count += ReadFromRomSection)
{
uint32_t dwToRead = DiskFileSize - count;
if (dwToRead > ReadFromRomSection) { dwToRead = ReadFromRomSection; }
if (m_DiskFile.Read(&m_DiskImage[count], dwToRead) != dwToRead)
{
m_DiskFile.Close();
SetError(MSG_FAIL_IMAGE);
WriteTrace(TraceN64System, TraceError, "Failed to read file (TotalRead: 0x%X)", TotalRead);
return false;
}
TotalRead += dwToRead;
//Show Message of how much % wise of the rom has been loaded
g_Notify->DisplayMessage(0, stdstr_f("%s: %.2f%c", GS(MSG_LOADED), ((float)TotalRead / (float)DiskFileSize) * 100.0f, '%').c_str());
}
if (DiskFileSize != TotalRead)
{
m_DiskFile.Close();
SetError(MSG_FAIL_IMAGE);
WriteTrace(TraceN64System, TraceError, "Expected to read: 0x%X, read: 0x%X", TotalRead, DiskFileSize);
return false;
}
m_DiskSysAddress = 0;
m_DiskIDAddress = 0x100;
g_Notify->DisplayMessage(5, MSG_BYTESWAP);
ForceByteSwapDisk();
}
else
{
@ -314,15 +375,12 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc)
return false;
}
g_Notify->DisplayMessage(5, MSG_BYTESWAP);
ByteSwapDisk();
ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE);
AllocateDiskHeader();
memcpy(m_DiskHeader, m_DiskImage, 0x20);
memcpy(m_DiskHeader + 0x20, m_DiskImage + 0x43670, 0x20);
memcpy(m_DiskHeader + 0x3B, m_DiskImage + 0x43670, 5);
memcpy(m_DiskHeader, GetDiskAddressSys(), 0x20);
memcpy(m_DiskHeader + 0x20, GetDiskAddressID(), 0x20);
memcpy(m_DiskHeader + 0x3B, GetDiskAddressID(), 5);
return true;
}
@ -397,6 +455,7 @@ uint32_t CN64Disk::GetDiskAddressBlock(uint16_t head, uint16_t track, uint16_t b
uint32_t offset = 0;
if (m_DiskFormat == DiskFormatMAME)
{
//MAME
uint32_t tr_off = 0;
uint16_t dd_zone = 0;
@ -445,12 +504,65 @@ uint32_t CN64Disk::GetDiskAddressBlock(uint16_t head, uint16_t track, uint16_t b
}
else if (m_DiskFormat == DiskFormatSDK)
{
//SDK
offset = LBAToByte(0, PhysToLBA(head, track, block)) + sector * sectorsize;
}
//WriteTrace(TraceN64System, TraceDebug, "Head %d Track %d Block %d - LBA %d - Address %08X", head, track, block, PhysToLBA(head, track, block), offset);
else
{
//D64
uint16_t ROM_LBA_END = *(uint16_t*)(&GetDiskAddressSys()[0xE2]);
uint16_t RAM_LBA_START = *(uint16_t*)(&GetDiskAddressSys()[0xE0]);
uint16_t RAM_LBA_END = *(uint16_t*)(&GetDiskAddressSys()[0xE6]);
uint16_t LBA = PhysToLBA(head, track, block);
if (LBA < DISKID_LBA)
{
offset = m_DiskSysAddress;
}
else if ((LBA >= DISKID_LBA) && (LBA < SYSTEM_LBAS))
{
offset = m_DiskIDAddress;
}
else if (LBA <= (ROM_LBA_END + SYSTEM_LBAS))
{
offset = 0x200 + LBAToByte(SYSTEM_LBAS, LBA - SYSTEM_LBAS) + (sector * sectorsize);
}
else if (((LBA - SYSTEM_LBAS) <= RAM_LBA_END) && ((LBA - SYSTEM_LBAS) >= RAM_LBA_START))
{
offset = 0x200 + LBAToByte(SYSTEM_LBAS, ROM_LBA_END + 1);
offset += LBAToByte(RAM_LBA_START + SYSTEM_LBAS, LBA - RAM_LBA_START - SYSTEM_LBAS) + (sector * sectorsize);
}
else
{
offset = 0xFFFFFFFF;
}
}
if (sector == 0)
{
WriteTrace(TraceN64System, TraceDebug, "Head %d Track %d Block %d - LBA %d - Address %08X", head, track, block, PhysToLBA(head, track, block), offset);
}
return offset;
}
void CN64Disk::InitSysDataD64()
{
//Else the disk will not work properly.
if (m_DiskFormat != DiskFormatD64)
return;
GetDiskAddressSys()[4^3] = 0x10;
GetDiskAddressSys()[5^3] |= 0x10;
}
void CN64Disk::DeinitSysDataD64()
{
//Restore the data
if (m_DiskFormat != DiskFormatD64)
return;
GetDiskAddressSys()[4^3] = 0x00;
GetDiskAddressSys()[5^3] &= 0x0F;
}
void CN64Disk::GenerateLBAToPhysTable()
{
for (uint32_t lba = 0; lba < SIZE_LBA; lba++)

View File

@ -27,7 +27,8 @@ public:
void ClearDiskSettingID();
uint8_t * GetDiskAddress() { return m_DiskImage; }
uint8_t * GetDiskAddressBuffer() { return m_DiskImage + m_DiskBufAddress; }
uint8_t * GetDiskAddressSys() { return m_DiskImage; }
uint8_t * GetDiskAddressSys() { return m_DiskImage + m_DiskSysAddress; }
uint8_t * GetDiskAddressID() { return m_DiskImage + m_DiskIDAddress; }
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);
@ -46,6 +47,8 @@ private:
void ByteSwapDisk();
void ForceByteSwapDisk();
void SetError(LanguageStringID ErrorMsg);
void InitSysDataD64();
void DeinitSysDataD64();
void GenerateLBAToPhysTable();
uint32_t LBAToVZone(uint32_t lba);
uint32_t LBAToByte(uint32_t lba, uint32_t nlbas);
@ -64,6 +67,8 @@ private:
uint8_t * m_DiskHeaderBase;
uint32_t m_DiskFileSize;
uint32_t m_DiskBufAddress;
uint32_t m_DiskSysAddress;
uint32_t m_DiskIDAddress;
LanguageStringID m_ErrorMsg;
Country m_Country;
stdstr m_RomName, m_FileName, m_DiskIdent;
@ -74,6 +79,7 @@ private:
#define MAX_LBA 0x10DB
#define SIZE_LBA MAX_LBA+1
#define SYSTEM_LBAS 24
#define DISKID_LBA 14
#define SECTORS_PER_BLOCK 85
#define BLOCKS_PER_TRACK 2

View File

@ -34,6 +34,7 @@ static const char* ROM_extensions[] =
"eur",
"bin",
"ndd",
"d64",
};
CRomList::CRomList() :
@ -461,7 +462,7 @@ bool CRomList::FillRomInfo(ROM_INFO * pRomInfo)
strncpy(pRomInfo->FileName, g_Settings->LoadBool(RomList_ShowFileExtensions) ? CPath(pRomInfo->szFullFileName).GetNameExtension().c_str() : CPath(pRomInfo->szFullFileName).GetName().c_str(), sizeof(pRomInfo->FileName) / sizeof(pRomInfo->FileName[0]));
}
if (CPath(pRomInfo->szFullFileName).GetExtension() != "ndd")
if ((CPath(pRomInfo->szFullFileName).GetExtension() != "ndd") && (CPath(pRomInfo->szFullFileName).GetExtension() != "d64"))
{
char InternalName[22];
memcpy(InternalName, (void *)(RomData + 0x20), 20);

View File

@ -118,7 +118,7 @@ void CMainMenu::OnOpenRom(HWND hWnd)
return;
}
stdstr ext = CPath(File).GetExtension();
if (_stricmp(ext.c_str(), "ndd") != 0)
if ((_stricmp(ext.c_str(), "ndd") != 0) && (_stricmp(ext.c_str(), "d64") != 0))
{
delete g_DDRom;
g_DDRom = NULL;
@ -303,7 +303,7 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
{
// Open Disk
CPath FileName;
const char * Filter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0";
const char * Filter = "N64DD Disk Image (*.ndd, *.d64)\0*.ndd;*.d64\0All files (*.*)\0*.*\0";
if (FileName.SelectFile(hWnd, g_Settings->LoadStringVal(RomList_GameDir).c_str(), Filter, true))
{
g_Disk->SaveDiskImage();
@ -547,7 +547,7 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
if (UISettingsLoadStringIndex(File_RecentGameFileIndex, MenuID - ID_RECENT_ROM_START, FileName) &&
FileName.length() > 0)
{
if (CPath(FileName).GetExtension() != "ndd")
if ((CPath(FileName).GetExtension() != "ndd") && (CPath(FileName).GetExtension() != "d64"))
g_BaseSystem->RunFileImage(FileName.c_str());
else
{

View File

@ -987,7 +987,7 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO
switch (LOWORD(wParam)) {
case ID_POPUPMENU_PLAYGAME:
{
if (CPath(_this->CurrentedSelectedRom()).GetExtension() != "ndd")
if ((CPath(_this->CurrentedSelectedRom()).GetExtension() != "ndd") && (CPath(_this->CurrentedSelectedRom()).GetExtension() != "d64"))
{
g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom());
}
@ -1010,7 +1010,7 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO
case ID_POPUPMENU_PLAYGAMEWITHDISK:
{
CPath FileName;
const char * Filter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0";
const char * Filter = "N64DD Disk Image (*.ndd, *.d64)\0*.ndd;*.d64\0All files (*.*)\0*.*\0";
if (FileName.SelectFile(hWnd, g_Settings->LoadStringVal(RomList_GameDir).c_str(), Filter, true))
{
if (!CPath(g_Settings->LoadStringVal(File_DiskIPLPath)).Exists() || !g_BaseSystem->RunDiskComboImage(_this->CurrentedSelectedRom(), FileName))
@ -1039,7 +1039,7 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO
case ID_POPUPMENU_EDITCHEATS:
case ID_POPUPMENU_CHOOSEENHANCEMENT:
{
if (CPath(_this->CurrentedSelectedRom()).GetExtension() != "ndd")
if ((CPath(_this->CurrentedSelectedRom()).GetExtension() != "ndd") && (CPath(_this->CurrentedSelectedRom()).GetExtension() != "d64"))
{
CN64Rom Rom;
Rom.LoadN64Image(_this->CurrentedSelectedRom(), true);
@ -1172,7 +1172,7 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO
DragFinish(hDrop);
stdstr ext = CPath(filename).GetExtension();
if (!(_stricmp(ext.c_str(), "ndd") == 0))
if ((!(_stricmp(ext.c_str(), "ndd") == 0)) && (!(_stricmp(ext.c_str(), "d64") == 0)))
{
delete g_DDRom;
g_DDRom = NULL;

View File

@ -807,7 +807,7 @@ void CRomBrowser::RomList_OpenRom(uint32_t /*pnmh*/)
delete g_DDRom;
g_DDRom = NULL;
if (CPath(pRomInfo->szFullFileName).GetExtension() != "ndd")
if ((CPath(pRomInfo->szFullFileName).GetExtension() != "ndd") && (CPath(pRomInfo->szFullFileName).GetExtension() != "d64"))
CN64System::RunFileImage(pRomInfo->szFullFileName);
else
{
@ -885,7 +885,7 @@ void CRomBrowser::RomList_PopupMenu(uint32_t /*pnmh*/)
if (inBasicMode) { DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); }
if (inBasicMode && !CheatsRemembered) { DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); }
DeleteMenu(hPopupMenu, 7, MF_BYPOSITION);
if (CPath(m_SelectedRom).GetExtension() == "ndd") { DeleteMenu(hPopupMenu, 1, MF_BYPOSITION); }
if ((CPath(m_SelectedRom).GetExtension() == "ndd") && (CPath(m_SelectedRom).GetExtension() == "d64")) { DeleteMenu(hPopupMenu, 1, MF_BYPOSITION); }
if (!inBasicMode && g_Plugins && g_Plugins->Gfx() && g_Plugins->Gfx()->GetRomBrowserMenu != NULL)
{
HMENU GfxMenu = (HMENU)g_Plugins->Gfx()->GetRomBrowserMenu();

View File

@ -20,7 +20,7 @@ m_pRomInfo(NULL),
m_pDiskInfo(NULL)
{
if (m_FileName.length() == 0) { return; }
if (CPath(m_FileName).GetExtension() != "ndd")
if ((CPath(m_FileName).GetExtension() != "ndd") && (CPath(m_FileName).GetExtension() != "d64"))
{
m_pRomInfo = new CN64Rom;
if (!m_pRomInfo->LoadN64Image(m_FileName.c_str()))

View File

@ -29,7 +29,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
MainWindow.Show(true); //Show the main window
//N64 ROM or 64DD Disk
stdstr ext = CPath(g_Settings->LoadStringVal(Cmd_RomFile)).GetExtension();
if (!(_stricmp(ext.c_str(), "ndd") == 0))
if ((!(_stricmp(ext.c_str(), "ndd") == 0)) && (!(_stricmp(ext.c_str(), "d64") == 0)))
{
//File Extension is not *.ndd so it should be a N64 ROM
CN64System::RunFileImage(g_Settings->LoadStringVal(Cmd_RomFile).c_str());