From 25f56e688774680def9e0fef2fc04fbb4c469a23 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Wed, 20 Jan 2016 01:14:18 +0100 Subject: [PATCH 01/12] Added CN64Disk class with basic functions --- Source/Project64-core/N64System/Mips/Disk.h | 1 - .../Project64-core/N64System/N64DiskClass.cpp | 182 ++++++++++++++++++ .../Project64-core/N64System/N64DiskClass.h | 41 ++++ .../N64System/SystemGlobals.cpp | 1 + .../Project64-core/N64System/SystemGlobals.h | 3 + Source/Project64-core/Project64-core.vcxproj | 2 + .../Project64-core.vcxproj.filters | 6 + 7 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 Source/Project64-core/N64System/N64DiskClass.cpp create mode 100644 Source/Project64-core/N64System/N64DiskClass.h diff --git a/Source/Project64-core/N64System/Mips/Disk.h b/Source/Project64-core/N64System/Mips/Disk.h index 04cd43dd1..dc591c807 100644 --- a/Source/Project64-core/N64System/Mips/Disk.h +++ b/Source/Project64-core/N64System/Mips/Disk.h @@ -9,7 +9,6 @@ * * ****************************************************************************/ #pragma once -#include "stdafx.h" void DiskCommand(void); void DiskReset(void); diff --git a/Source/Project64-core/N64System/N64DiskClass.cpp b/Source/Project64-core/N64System/N64DiskClass.cpp new file mode 100644 index 000000000..ab0cfa921 --- /dev/null +++ b/Source/Project64-core/N64System/N64DiskClass.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include "stdafx.h" +#include "N64DiskClass.h" +#include "SystemGlobals.h" +#include +#include + +CN64Disk::CN64Disk() : +m_DiskImage(NULL), +m_DiskImageBase(NULL), +m_ErrorMsg(EMPTY_STRING) +{ +} + +CN64Disk::~CN64Disk() +{ +} + +bool CN64Disk::LoadDiskImage(const char * FileLoc) +{ + UnallocateRomImage(); + + if (!AllocateAndLoadDiskImage(FileLoc)) + { + return false; + } + + if (g_Disk == this) + { + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + } + + return true; +} + +bool CN64Disk::IsValidRomImage(uint8_t Test[4]) +{ + if (*((uint32_t *)&Test[0]) == 0x16D348E8) { return true; } + return false; +} + +bool CN64Disk::AllocateDiskImage(uint32_t DiskFileSize) +{ + WriteTrace(TraceN64System, TraceDebug, "Allocating memory for disk"); + std::auto_ptr ImageBase(new uint8_t[DiskFileSize + 0x1000]); + if (ImageBase.get() == NULL) + { + SetError(MSG_MEM_ALLOC_ERROR); + WriteTrace(TraceN64System, TraceError, "Failed to allocate memory for disk (size: 0x%X)", DiskFileSize); + return false; + } + uint8_t * Image = (uint8_t *)(((uint64_t)ImageBase.get() + 0xFFF) & ~0xFFF); // start at begining of memory page + WriteTrace(TraceN64System, TraceDebug, "Allocated disk memory (%p)", Image); + + //save information about the disk loaded + m_DiskImageBase = ImageBase.release(); + m_DiskImage = Image; + m_DiskFileSize = DiskFileSize; + return true; +} + +bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc) +{ + WriteTrace(TraceN64System, TraceDebug, "Trying to open %s", FileLoc); + if (!m_DiskFile.Open(FileLoc, CFileBase::modeRead)) + { + WriteTrace(TraceN64System, TraceError, "Failed to open %s", 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)) + { + m_DiskFile.Close(); + WriteTrace(TraceN64System, TraceError, "Failed to read ident bytes"); + return false; + } + if (!IsValidRomImage(Test)) + { + m_DiskFile.Close(); + WriteTrace(TraceN64System, TraceError, "invalid image file %X %X %X %X", Test[0], Test[1], Test[2], Test[3]); + return false; + } + uint32_t DiskFileSize = m_DiskFile.GetLength(); + WriteTrace(TraceN64System, TraceDebug, "Successfully Opened, size: 0x%X", DiskFileSize); + + 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; + } + + g_Notify->DisplayMessage(5, MSG_BYTESWAP); + ByteSwapDisk(); + + ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE); + return true; +} + +void CN64Disk::ByteSwapDisk() +{ + uint32_t count; + + switch (*((uint32_t *)&m_DiskImage[0])) + { + case 0x16D348E8: + for (count = 0; count < m_DiskFileSize; count += 4) + { + m_DiskImage[count] ^= m_DiskImage[count + 3]; + m_DiskImage[count + 3] ^= m_DiskImage[count]; + m_DiskImage[count] ^= m_DiskImage[count + 3]; + m_DiskImage[count + 1] ^= m_DiskImage[count + 2]; + m_DiskImage[count + 2] ^= m_DiskImage[count + 1]; + m_DiskImage[count + 1] ^= m_DiskImage[count + 2]; + } + break; + case 0xE848D316: break; + default: + g_Notify->DisplayError(stdstr_f("ByteSwapDisk: %X", m_DiskImage[0]).c_str()); + } +} + +void CN64Disk::SetError(LanguageStringID ErrorMsg) +{ + m_ErrorMsg = ErrorMsg; +} + +void CN64Disk::UnallocateRomImage() +{ + m_DiskFile.Close(); + + if (m_DiskImageBase) + { + ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE); + delete[] m_DiskImageBase; + m_DiskImageBase = NULL; + } + m_DiskImage = NULL; +} \ No newline at end of file diff --git a/Source/Project64-core/N64System/N64DiskClass.h b/Source/Project64-core/N64System/N64DiskClass.h new file mode 100644 index 000000000..ed71edce6 --- /dev/null +++ b/Source/Project64-core/N64System/N64DiskClass.h @@ -0,0 +1,41 @@ +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CN64Disk +{ +public: + CN64Disk(); + ~CN64Disk(); + + bool LoadDiskImage(const char * FileLoc); + static bool IsValidRomImage(uint8_t Test[4]); + uint8_t * GetDiskAddress() { return m_DiskImage; } + void UnallocateRomImage(); + +private: + bool AllocateDiskImage(uint32_t DiskFileSize); + bool AllocateAndLoadDiskImage(const char * FileLoc); + void ByteSwapDisk(); + void SetError(LanguageStringID ErrorMsg); + + //constant values + enum { ReadFromRomSection = 0x400000 }; + + //class variables + CFile m_DiskFile; + uint8_t * m_DiskImage; + uint8_t * m_DiskImageBase; + uint32_t m_DiskFileSize; + LanguageStringID m_ErrorMsg; + stdstr m_FileName, m_DiskIdent; +}; \ No newline at end of file diff --git a/Source/Project64-core/N64System/SystemGlobals.cpp b/Source/Project64-core/N64System/SystemGlobals.cpp index 6ab72f809..f46c5a754 100644 --- a/Source/Project64-core/N64System/SystemGlobals.cpp +++ b/Source/Project64-core/N64System/SystemGlobals.cpp @@ -22,6 +22,7 @@ CNotification * g_Notify = NULL; CPlugins * g_Plugins = NULL; CN64Rom * g_Rom = NULL; //The current rom that this system is executing.. it can only execute one file at the time CN64Rom * g_DDRom = NULL; //64DD IPL ROM +CN64Disk * g_Disk = NULL; //64DD DISK CAudio * g_Audio = NULL; CSystemTimer * g_SystemTimer = NULL; CTransVaddr * g_TransVaddr = NULL; diff --git a/Source/Project64-core/N64System/SystemGlobals.h b/Source/Project64-core/N64System/SystemGlobals.h index cd279afaf..de4086076 100644 --- a/Source/Project64-core/N64System/SystemGlobals.h +++ b/Source/Project64-core/N64System/SystemGlobals.h @@ -37,6 +37,9 @@ class CN64Rom; extern CN64Rom * g_Rom; //The current rom that this system is executing.. it can only execute one file at the time extern CN64Rom * g_DDRom; //64DD IPL ROM +class CN64Disk; +extern CN64Disk * g_Disk; //64DD DISK + class CAudio; extern CAudio * g_Audio; diff --git a/Source/Project64-core/Project64-core.vcxproj b/Source/Project64-core/Project64-core.vcxproj index 5dd24c683..3c5e643be 100644 --- a/Source/Project64-core/Project64-core.vcxproj +++ b/Source/Project64-core/Project64-core.vcxproj @@ -61,6 +61,7 @@ + @@ -148,6 +149,7 @@ + diff --git a/Source/Project64-core/Project64-core.vcxproj.filters b/Source/Project64-core/Project64-core.vcxproj.filters index 0bac0a923..207c34c9a 100644 --- a/Source/Project64-core/Project64-core.vcxproj.filters +++ b/Source/Project64-core/Project64-core.vcxproj.filters @@ -297,6 +297,9 @@ Source Files\N64 System\Mips + + Source Files\N64 System + @@ -578,5 +581,8 @@ Header Files\N64 System\Mips + + Header Files\N64 System + \ No newline at end of file From 002cb7f5ce17ac1ceae3871efe62d581593cd109 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Wed, 20 Jan 2016 14:31:29 +0100 Subject: [PATCH 02/12] 64DD support tentative --- Source/Project64-core/N64System/Mips/Disk.cpp | 355 +++++++++++++++--- Source/Project64-core/N64System/Mips/Disk.h | 24 ++ Source/Project64-core/N64System/Mips/Dma.cpp | 85 ++++- .../N64System/Mips/MemoryVirtualMem.cpp | 7 +- Source/Project64-core/N64System/N64Class.cpp | 12 + .../Project64-core/N64System/N64DiskClass.cpp | 228 +++++------ .../Project64-core/N64System/N64DiskClass.h | 38 +- Source/Project64-core/Settings/Settings.h | 2 + .../Project64-core/Settings/SettingsClass.cpp | 2 + 9 files changed, 559 insertions(+), 194 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Disk.cpp b/Source/Project64-core/N64System/Mips/Disk.cpp index 8a13c8a22..74f8fe870 100644 --- a/Source/Project64-core/N64System/Mips/Disk.cpp +++ b/Source/Project64-core/N64System/Mips/Disk.cpp @@ -10,75 +10,330 @@ ****************************************************************************/ #pragma once #include "stdafx.h" +#include "Disk.h" +#include #include #include +bool dd_write; +bool dd_reset_hold; +uint32_t dd_track_offset, dd_zone; + +uint8_t dd_buffer[0x100]; + void DiskCommand() { - //ASIC_CMD_STATUS - Commands - uint32_t cmd = g_Reg->ASIC_CMD; + //ASIC_CMD_STATUS - Commands + uint32_t cmd = g_Reg->ASIC_CMD; #ifdef _WIN32 - SYSTEMTIME sysTime; - ::GetLocalTime(&sysTime); - //stdstr_f timestamp("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d,", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds, GetCurrentThreadId()); + SYSTEMTIME sysTime; + ::GetLocalTime(&sysTime); + //stdstr_f timestamp("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d,", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds, GetCurrentThreadId()); - //BCD format needed for 64DD RTC - uint8_t year = (uint8_t)(((sysTime.wYear / 10) << 4) | (sysTime.wYear % 10)); - uint8_t month = (uint8_t)(((sysTime.wMonth / 10) << 4) | (sysTime.wMonth % 10)); - uint8_t day = (uint8_t)(((sysTime.wDay / 10) << 4) | (sysTime.wDay % 10)); - uint8_t hour = (uint8_t)(((sysTime.wHour / 10) << 4) | (sysTime.wHour % 10)); - uint8_t minute = (uint8_t)(((sysTime.wMinute / 10) << 4) | (sysTime.wMinute % 10)); - uint8_t second = (uint8_t)(((sysTime.wSecond / 10) << 4) | (sysTime.wSecond % 10)); + //BCD format needed for 64DD RTC + uint8_t year = (uint8_t)(((sysTime.wYear / 10) << 4) | (sysTime.wYear % 10)); + uint8_t month = (uint8_t)(((sysTime.wMonth / 10) << 4) | (sysTime.wMonth % 10)); + uint8_t day = (uint8_t)(((sysTime.wDay / 10) << 4) | (sysTime.wDay % 10)); + uint8_t hour = (uint8_t)(((sysTime.wHour / 10) << 4) | (sysTime.wHour % 10)); + uint8_t minute = (uint8_t)(((sysTime.wMinute / 10) << 4) | (sysTime.wMinute % 10)); + uint8_t second = (uint8_t)(((sysTime.wSecond / 10) << 4) | (sysTime.wSecond % 10)); #else - time_t ltime; - ltime = time(<ime); - - struct tm result = { 0 }; - localtime_r(<ime, &result); + time_t ltime; + ltime = time(<ime); + + struct tm result = { 0 }; + localtime_r(<ime, &result); - //stdstr_f timestamp("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d,", result.tm_year + 1900, result.tm_mon + 1, result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec, milliseconds, GetCurrentThreadId()); + //stdstr_f timestamp("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d,", result.tm_year + 1900, result.tm_mon + 1, result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec, milliseconds, GetCurrentThreadId()); - //BCD format needed for 64DD RTC - uint8_t year = (uint8_t)(((result.tm_year / 10) << 4) | (result.tm_year % 10)); - uint8_t month = (uint8_t)(((result.tm_mon / 10) << 4) | (result.tm_mon % 10)); - uint8_t day = (uint8_t)(((result.tm_mday / 10) << 4) | (result.tm_mday % 10)); - uint8_t hour = (uint8_t)(((result.tm_hour / 10) << 4) | (result.tm_hour % 10)); - uint8_t minute = (uint8_t)(((result.tm_min / 10) << 4) | (result.tm_min % 10)); - uint8_t second = (uint8_t)(((result.tm_sec / 10) << 4) | (result.tm_sec % 10)); + //BCD format needed for 64DD RTC + uint8_t year = (uint8_t)(((result.tm_year / 10) << 4) | (result.tm_year % 10)); + uint8_t month = (uint8_t)(((result.tm_mon / 10) << 4) | (result.tm_mon % 10)); + uint8_t day = (uint8_t)(((result.tm_mday / 10) << 4) | (result.tm_mday % 10)); + uint8_t hour = (uint8_t)(((result.tm_hour / 10) << 4) | (result.tm_hour % 10)); + uint8_t minute = (uint8_t)(((result.tm_min / 10) << 4) | (result.tm_min % 10)); + uint8_t second = (uint8_t)(((result.tm_sec / 10) << 4) | (result.tm_sec % 10)); #endif - switch (cmd & 0xFFFF0000) - { - case 0x00080000: - //Unset Disk Changed Bit - g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; break; - case 0x00090000: - //Unset Reset Bit - g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE; break; - case 0x00120000: - //RTC Get Year & Month - g_Reg->ASIC_DATA = (year << 24) | (month << 16); break; - case 0x00130000: - //RTC Get Day & Hour - g_Reg->ASIC_DATA = (day << 24) | (hour << 16); break; - case 0x00140000: - //RTC Get Minute & Second - g_Reg->ASIC_DATA = (minute << 24) | (second << 16); break; - } + switch (cmd & 0xFFFF0000) + { + case 0x00010000: + //Seek Read + g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; + dd_write = false; + break; + case 0x00020000: + //Seek Write + g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; + dd_write = true; + break; + case 0x00080000: + //Unset Disk Changed Bit + g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; break; + case 0x00090000: + //Unset Reset Bit + g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE; break; + case 0x00120000: + //RTC Get Year & Month + g_Reg->ASIC_DATA = (year << 24) | (month << 16); break; + case 0x00130000: + //RTC Get Day & Hour + g_Reg->ASIC_DATA = (day << 24) | (hour << 16); break; + case 0x00140000: + //RTC Get Minute & Second + g_Reg->ASIC_DATA = (minute << 24) | (second << 16); break; + case 0x001B0000: + //Disk Inquiry + g_Reg->ASIC_DATA = 0x00000000; break; + } } void DiskReset(void) { - //ASIC_HARD_RESET 0xAAAA0000 - g_Reg->ASIC_STATUS |= DD_STATUS_RST_STATE; + //ASIC_HARD_RESET 0xAAAA0000 + g_Reg->ASIC_STATUS |= DD_STATUS_RST_STATE; } void DiskBMControl(void) { - if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_MECHA_RST) - { - g_Reg->ASIC_STATUS &= ~DD_STATUS_MECHA_INT; - g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; - } + g_Reg->ASIC_CUR_SECTOR = g_Reg->ASIC_BM_CTL & 0x00FF0000; + /* + if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x00) + { + + } + else if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x5A) + { + + } + */ + if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_BLK_TRANS) + g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_BLOCK; + + if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_MECHA_RST) + g_Reg->ASIC_STATUS &= ~DD_STATUS_MECHA_INT; + + if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_RESET) + dd_reset_hold = true; + + if (!(g_Reg->ASIC_BM_CTL & DD_BM_CTL_RESET) && dd_reset_hold) + { + dd_reset_hold = false; + g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_DATA_RQ | DD_STATUS_C2_XFER); + g_Reg->ASIC_BM_STATUS = 0; + g_Reg->ASIC_CUR_SECTOR = 0; + } + + if (!(g_Reg->ASIC_STATUS & DD_STATUS_MECHA_INT) && !(g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)) + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + + if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_START) + { + g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_RUNNING; + DiskBMUpdate(); + } +} + +void DiskGapSectorCheck() +{ + if (g_Reg->ASIC_STATUS & DD_STATUS_BM_INT) + { + uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); + if (testsector >= 0x5A) + testsector -= 0x5A; + + if (SECTORS_PER_BLOCK < testsector) + { + g_Reg->ASIC_STATUS &= ~DD_STATUS_BM_INT; + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + DiskBMUpdate(); + } + } +} + +void DiskBMUpdate() +{ + if (!(g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_RUNNING)) + return; + + uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); + if (testsector >= 0x5A) + testsector -= 0x5A; + + if (dd_write) + { + //Write Data + if (testsector == 0) + { + g_Reg->ASIC_CUR_SECTOR += 0x00010000; + g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; + } + else if (testsector < SECTORS_PER_BLOCK) + { + DiskBMWrite(); + g_Reg->ASIC_CUR_SECTOR += 0x00010000; + g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; + } + else if (testsector < SECTORS_PER_BLOCK + 1) + { + if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) + { + DiskBMWrite(); + g_Reg->ASIC_CUR_SECTOR += 0x00010000; + if (g_Reg->ASIC_CUR_SECTOR >> 16 >= 0xB4) + g_Reg->ASIC_CUR_SECTOR = 0x00010000; + g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; + g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; + } + else + { + DiskBMWrite(); + g_Reg->ASIC_CUR_SECTOR += 0x00010000; + g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_RUNNING; + } + } + + g_Reg->ASIC_STATUS |= DD_STATUS_BM_INT; + g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3; + g_Reg->CheckInterrupts(); + return; + } + else + { + //Read Data + if (((g_Reg->ASIC_CUR_TK >> 16) & 0xFFF) == 6 && g_Reg->ASIC_CUR_SECTOR == 0) + { + g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ; + g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO; + } + else if (testsector == 0) + { + DiskBMRead(); + g_Reg->ASIC_CUR_SECTOR += 0x00010000; + g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; + } + else if (testsector < SECTORS_PER_BLOCK + 4) + { + //READ C2 (00!) + g_Reg->ASIC_CUR_SECTOR += 0x00010000; + if ((g_Reg->ASIC_CUR_SECTOR >> 16) == SECTORS_PER_BLOCK + 4) + g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER; + } + else if (testsector == SECTORS_PER_BLOCK + 4) + { + if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) + { + if (g_Reg->ASIC_CUR_SECTOR >> 16 >= 0xB4) + g_Reg->ASIC_CUR_SECTOR = 0x00000000; + g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; + } + else + { + g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_RUNNING; + } + } + + g_Reg->ASIC_STATUS |= DD_STATUS_BM_INT; + g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3; + g_Reg->CheckInterrupts(); + } +} + +void DiskBMRead() +{ + uint8_t * sector; + sector = (uint8_t*)g_Disk->GetDiskAddress(); + sector += dd_track_offset; + uint16_t block = 0; + if (g_Reg->ASIC_CUR_SECTOR >= 0x005A0000) + block = 1; + sector += block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; + uint16_t block2 = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); + if (block2 >= 0x5A) + block -= 0x5A; + sector += block * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); + + for (int i = 0; i < ((g_Reg->ASIC_SEC_BYTE >> 16) + 1) / 4; i++) + { + dd_buffer[i] = sector[(i * 4 + 0)] << 24 | sector[(i * 4 + 1)] << 16 | + sector[(i * 4 + 2)] << 8 | sector[(i * 4 + 3)]; + } + + return; +} + +void DiskBMWrite() +{ + uint8_t * sector; + sector = (uint8_t*)g_Disk->GetDiskAddress(); + sector += dd_track_offset; + uint16_t block = 0; + if (g_Reg->ASIC_CUR_SECTOR >= 0x005A0000) + block = 1; + sector += block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; + uint16_t block2 = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); + if (block2 >= 0x5A) + block -= 0x5A; + sector += block * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); + + for (int i = 0; i < ddZoneSecSize[dd_zone] / 4; i++) + { + sector[i * 4 + 0] = (dd_buffer[i] >> 24) & 0xFF; + sector[i * 4 + 1] = (dd_buffer[i] >> 16) & 0xFF; + sector[i * 4 + 2] = (dd_buffer[i] >> 8) & 0xFF; + sector[i * 4 + 3] = (dd_buffer[i] >> 0) & 0xFF; + } + + return; +} + +void DiskSetOffset() +{ + uint16_t head = ((g_Reg->ASIC_CUR_TK >> 16) & 0x1000) >> 9; // Head * 8 + uint16_t track = (g_Reg->ASIC_CUR_TK >> 16) & 0xFFF; + uint16_t tr_off = 0; + + if (track >= 0x425) + { + dd_zone = 7 + head; + tr_off = track - 0x425; + } + else if (track >= 0x390) + { + dd_zone = 6 + head; + tr_off = track - 0x390; + } + else if (track >= 0x2FB) + { + dd_zone = 5 + head; + tr_off = track - 0x2FB; + } + else if (track >= 0x266) + { + dd_zone = 4 + head; + tr_off = track - 0x266; + } + else if (track >= 0x1D1) + { + dd_zone = 3 + head; + tr_off = track - 0x1D1; + } + else if (track >= 0x13C) + { + dd_zone = 2 + head; + tr_off = track - 0x13C; + } + else if (track >= 0x9E) + { + dd_zone = 1 + head; + tr_off = track - 0x9E; + } + else + { + dd_zone = 0 + head; + tr_off = track; + } + + dd_track_offset = ddStartOffset[dd_zone] + tr_off * ddZoneSecSize[dd_zone] * SECTORS_PER_BLOCK * BLOCKS_PER_TRACK; } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Mips/Disk.h b/Source/Project64-core/N64System/Mips/Disk.h index dc591c807..d583e0ead 100644 --- a/Source/Project64-core/N64System/Mips/Disk.h +++ b/Source/Project64-core/N64System/Mips/Disk.h @@ -10,6 +10,30 @@ ****************************************************************************/ #pragma once +#include + void DiskCommand(void); void DiskReset(void); void DiskBMControl(void); +void DiskGapSectorCheck(void); +void DiskBMUpdate(void); +void DiskBMRead(void); +void DiskBMWrite(void); +void DiskSetOffset(void); + +extern bool dd_write; +extern bool dd_reset_hold; +extern uint32_t dd_track_offset, dd_zone; + +extern uint8_t dd_buffer[0x100]; + +const uint32_t ddZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128, + 216, 208, 192, 176, 160, 144, 128, 112 }; +const uint32_t ddZoneTrackSize[16] = { 158, 158, 149, 149, 149, 149, 149, 114, + 158, 158, 149, 149, 149, 149, 149, 114 }; +const uint32_t ddStartOffset[16] = + { 0x0, 0x5F15E0, 0xB79D00, 0x10801A0, 0x1523720, 0x1963D80, 0x1D414C0, 0x20BBCE0, + 0x23196E0, 0x28A1E00, 0x2DF5DC0, 0x3299340, 0x36D99A0, 0x3AB70E0, 0x3E31900, 0x4149200 }; + +#define SECTORS_PER_BLOCK 85 +#define BLOCKS_PER_TRACK 2 diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index 5a5ba3794..d867b94fa 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include CDMA::CDMA(CFlashram & FlashRam, CSram & Sram) : @@ -69,6 +70,40 @@ void CDMA::PI_DMA_READ() return; } + //64DD Buffers Write + if (g_Reg->PI_CART_ADDR_REG >= 0x05000000 && g_Reg->PI_CART_ADDR_REG <= 0x050003FF) + { + //64DD C2 Sectors (don't care) + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + g_Reg->MI_INTR_REG |= MI_INTR_PI; + DiskBMUpdate(); + return; + } + + if (g_Reg->PI_CART_ADDR_REG >= 0x05000400 && g_Reg->PI_CART_ADDR_REG <= 0x050004FF) + { + //64DD User Sector + uint32_t i; + uint8_t * RDRAM = g_MMU->Rdram(); + for (i = 0; i < PI_RD_LEN_REG; i++) + { + dd_buffer[i ^ 3] = * (RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)); + } + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + g_Reg->MI_INTR_REG |= MI_INTR_PI; + DiskBMUpdate(); + return; + } + + if (g_Reg->PI_CART_ADDR_REG >= 0x05000580 && g_Reg->PI_CART_ADDR_REG <= 0x050005BF) + { + //64DD MSEQ (don't care) + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + g_Reg->MI_INTR_REG |= MI_INTR_PI; + g_Reg->CheckInterrupts(); + return; + } + //Write ROM Area (for 64DD Convert) if (g_Reg->PI_CART_ADDR_REG >= 0x10000000 && g_Reg->PI_CART_ADDR_REG <= 0x1FBFFFFF && g_Settings->LoadBool(Game_AllowROMWrites)) { @@ -182,21 +217,51 @@ void CDMA::PI_DMA_WRITE() return; } + //64DD Buffers Read + if (g_Reg->PI_CART_ADDR_REG >= 0x05000000 && g_Reg->PI_CART_ADDR_REG <= 0x050003FF) + { + //64DD C2 Sectors (just read 0) + uint32_t i; + uint8_t * RDRAM = g_MMU->Rdram(); + for (i = 0; i < PI_WR_LEN_REG; i++) + { + *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = 0; + } + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + g_Reg->MI_INTR_REG |= MI_INTR_PI; + g_Reg->CheckInterrupts(); + return; + } + + if (g_Reg->PI_CART_ADDR_REG >= 0x05000400 && g_Reg->PI_CART_ADDR_REG <= 0x050004FF) + { + //64DD User Sector + uint32_t i; + uint8_t * RDRAM = g_MMU->Rdram(); + for (i = 0; i < PI_WR_LEN_REG; i++) + { + *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = dd_buffer[i ^ 3]; + } + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + g_Reg->MI_INTR_REG |= MI_INTR_PI; + g_Reg->CheckInterrupts(); + return; + } + + if (g_Reg->PI_CART_ADDR_REG >= 0x05000580 && g_Reg->PI_CART_ADDR_REG <= 0x050005BF) + { + //64DD MSEQ (don't care) + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + g_Reg->MI_INTR_REG |= MI_INTR_PI; + g_Reg->CheckInterrupts(); + return; + } + //64DD IPL ROM if (g_Reg->PI_CART_ADDR_REG >= 0x06000000 && g_Reg->PI_CART_ADDR_REG <= 0x063FFFFF) { uint32_t i; -#ifdef legacycode -#ifdef ROM_IN_MAPSPACE - if (WrittenToRom) - { - uint32_t OldProtect; - VirtualProtect(ROM, m_RomFileSize, PAGE_READONLY, &OldProtect); - } -#endif -#endif - uint8_t * ROM = g_DDRom->GetRomAddress(); uint8_t * RDRAM = g_MMU->Rdram(); g_Reg->PI_CART_ADDR_REG -= 0x06000000; diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index 61d98531f..c17647302 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -4827,7 +4827,12 @@ void CMipsMemoryVM::Load32CartridgeDomain2Address1(void) { case 0x05000500: m_MemLookupValue.UW[0] = g_Reg->ASIC_DATA; break; case 0x05000504: m_MemLookupValue.UW[0] = g_Reg->ASIC_MISC_REG; break; - case 0x05000508: m_MemLookupValue.UW[0] = g_Reg->ASIC_STATUS; break; + case 0x05000508: + if (g_Disk != NULL) + g_Reg->ASIC_STATUS |= DD_STATUS_DISK_PRES; + m_MemLookupValue.UW[0] = g_Reg->ASIC_STATUS; + DiskGapSectorCheck(); + break; case 0x0500050C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_TK; break; case 0x05000510: m_MemLookupValue.UW[0] = g_Reg->ASIC_BM_STATUS; break; case 0x05000514: m_MemLookupValue.UW[0] = g_Reg->ASIC_ERR_SECTOR; break; diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index 0f8134e84..dec10366e 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -216,6 +217,17 @@ bool CN64System::RunFileImage(const char * FileLoc) { //64DD IPL g_DDRom = g_Rom; + + if (g_Disk == NULL) + { + g_Disk = new CN64Disk(); + } + + if (!g_Disk->LoadDiskImage(g_Settings->LoadStringVal(SupportFile_DiskTest).c_str())); + { + delete g_Disk; + g_Disk = NULL; + } } g_System->RefreshGameSettings(); diff --git a/Source/Project64-core/N64System/N64DiskClass.cpp b/Source/Project64-core/N64System/N64DiskClass.cpp index ab0cfa921..4fa2e5933 100644 --- a/Source/Project64-core/N64System/N64DiskClass.cpp +++ b/Source/Project64-core/N64System/N64DiskClass.cpp @@ -28,155 +28,155 @@ CN64Disk::~CN64Disk() bool CN64Disk::LoadDiskImage(const char * FileLoc) { - UnallocateRomImage(); + UnallocateDiskImage(); - if (!AllocateAndLoadDiskImage(FileLoc)) - { - return false; - } + if (!AllocateAndLoadDiskImage(FileLoc)) + { + return false; + } - if (g_Disk == this) - { - g_Settings->SaveBool(GameRunning_LoadingInProgress, false); - } + if (g_Disk == this) + { + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + } - return true; + return true; } -bool CN64Disk::IsValidRomImage(uint8_t Test[4]) +bool CN64Disk::IsValidDiskImage(uint8_t Test[4]) { - if (*((uint32_t *)&Test[0]) == 0x16D348E8) { return true; } - return false; + if (*((uint32_t *)&Test[0]) == 0x16D348E8) { return true; } + return false; } bool CN64Disk::AllocateDiskImage(uint32_t DiskFileSize) { - WriteTrace(TraceN64System, TraceDebug, "Allocating memory for disk"); - std::auto_ptr ImageBase(new uint8_t[DiskFileSize + 0x1000]); - if (ImageBase.get() == NULL) - { - SetError(MSG_MEM_ALLOC_ERROR); - WriteTrace(TraceN64System, TraceError, "Failed to allocate memory for disk (size: 0x%X)", DiskFileSize); - return false; - } - uint8_t * Image = (uint8_t *)(((uint64_t)ImageBase.get() + 0xFFF) & ~0xFFF); // start at begining of memory page - WriteTrace(TraceN64System, TraceDebug, "Allocated disk memory (%p)", Image); + WriteTrace(TraceN64System, TraceDebug, "Allocating memory for disk"); + std::auto_ptr ImageBase(new uint8_t[DiskFileSize + 0x1000]); + if (ImageBase.get() == NULL) + { + SetError(MSG_MEM_ALLOC_ERROR); + WriteTrace(TraceN64System, TraceError, "Failed to allocate memory for disk (size: 0x%X)", DiskFileSize); + return false; + } + uint8_t * Image = (uint8_t *)(((uint64_t)ImageBase.get() + 0xFFF) & ~0xFFF); // start at begining of memory page + WriteTrace(TraceN64System, TraceDebug, "Allocated disk memory (%p)", Image); - //save information about the disk loaded - m_DiskImageBase = ImageBase.release(); - m_DiskImage = Image; - m_DiskFileSize = DiskFileSize; - return true; + //save information about the disk loaded + m_DiskImageBase = ImageBase.release(); + m_DiskImage = Image; + m_DiskFileSize = DiskFileSize; + return true; } bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc) { - WriteTrace(TraceN64System, TraceDebug, "Trying to open %s", FileLoc); - if (!m_DiskFile.Open(FileLoc, CFileBase::modeRead)) - { - WriteTrace(TraceN64System, TraceError, "Failed to open %s", FileLoc); - return false; - } + WriteTrace(TraceN64System, TraceDebug, "Trying to open %s", FileLoc); + if (!m_DiskFile.Open(FileLoc, CFileBase::modeRead)) + { + WriteTrace(TraceN64System, TraceError, "Failed to open %s", 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)) - { - m_DiskFile.Close(); - WriteTrace(TraceN64System, TraceError, "Failed to read ident bytes"); - return false; - } - if (!IsValidRomImage(Test)) - { - m_DiskFile.Close(); - WriteTrace(TraceN64System, TraceError, "invalid image file %X %X %X %X", Test[0], Test[1], Test[2], Test[3]); - return false; - } - uint32_t DiskFileSize = m_DiskFile.GetLength(); - WriteTrace(TraceN64System, TraceDebug, "Successfully Opened, size: 0x%X", DiskFileSize); + //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)) + { + m_DiskFile.Close(); + WriteTrace(TraceN64System, TraceError, "Failed to read ident bytes"); + return false; + } + if (!IsValidDiskImage(Test)) + { + m_DiskFile.Close(); + WriteTrace(TraceN64System, TraceError, "invalid image file %X %X %X %X", Test[0], Test[1], Test[2], Test[3]); + return false; + } + uint32_t DiskFileSize = m_DiskFile.GetLength(); + WriteTrace(TraceN64System, TraceDebug, "Successfully Opened, size: 0x%X", DiskFileSize); - if (!AllocateDiskImage(DiskFileSize)) - { - m_DiskFile.Close(); - return false; - } + 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(); + //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; } + 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; + 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()); - } + //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; - } + 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; + } - g_Notify->DisplayMessage(5, MSG_BYTESWAP); - ByteSwapDisk(); + g_Notify->DisplayMessage(5, MSG_BYTESWAP); + ByteSwapDisk(); - ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE); - return true; + ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE); + return true; } void CN64Disk::ByteSwapDisk() { - uint32_t count; + uint32_t count; - switch (*((uint32_t *)&m_DiskImage[0])) - { - case 0x16D348E8: - for (count = 0; count < m_DiskFileSize; count += 4) - { - m_DiskImage[count] ^= m_DiskImage[count + 3]; - m_DiskImage[count + 3] ^= m_DiskImage[count]; - m_DiskImage[count] ^= m_DiskImage[count + 3]; - m_DiskImage[count + 1] ^= m_DiskImage[count + 2]; - m_DiskImage[count + 2] ^= m_DiskImage[count + 1]; - m_DiskImage[count + 1] ^= m_DiskImage[count + 2]; - } - break; - case 0xE848D316: break; - default: - g_Notify->DisplayError(stdstr_f("ByteSwapDisk: %X", m_DiskImage[0]).c_str()); - } + switch (*((uint32_t *)&m_DiskImage[0])) + { + case 0x16D348E8: + for (count = 0; count < m_DiskFileSize; count += 4) + { + m_DiskImage[count] ^= m_DiskImage[count + 3]; + m_DiskImage[count + 3] ^= m_DiskImage[count]; + m_DiskImage[count] ^= m_DiskImage[count + 3]; + m_DiskImage[count + 1] ^= m_DiskImage[count + 2]; + m_DiskImage[count + 2] ^= m_DiskImage[count + 1]; + m_DiskImage[count + 1] ^= m_DiskImage[count + 2]; + } + break; + case 0xE848D316: break; + default: + g_Notify->DisplayError(stdstr_f("ByteSwapDisk: %X", m_DiskImage[0]).c_str()); + } } void CN64Disk::SetError(LanguageStringID ErrorMsg) { - m_ErrorMsg = ErrorMsg; + m_ErrorMsg = ErrorMsg; } -void CN64Disk::UnallocateRomImage() +void CN64Disk::UnallocateDiskImage() { - m_DiskFile.Close(); + m_DiskFile.Close(); - if (m_DiskImageBase) - { - ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE); - delete[] m_DiskImageBase; - m_DiskImageBase = NULL; - } - m_DiskImage = NULL; + if (m_DiskImageBase) + { + ProtectMemory(m_DiskImage, m_DiskFileSize, MEM_READWRITE); + delete[] m_DiskImageBase; + m_DiskImageBase = NULL; + } + m_DiskImage = NULL; } \ No newline at end of file diff --git a/Source/Project64-core/N64System/N64DiskClass.h b/Source/Project64-core/N64System/N64DiskClass.h index ed71edce6..3a15ca8cf 100644 --- a/Source/Project64-core/N64System/N64DiskClass.h +++ b/Source/Project64-core/N64System/N64DiskClass.h @@ -14,28 +14,28 @@ class CN64Disk { public: - CN64Disk(); - ~CN64Disk(); + CN64Disk(); + ~CN64Disk(); - bool LoadDiskImage(const char * FileLoc); - static bool IsValidRomImage(uint8_t Test[4]); - uint8_t * GetDiskAddress() { return m_DiskImage; } - void UnallocateRomImage(); + bool LoadDiskImage(const char * FileLoc); + static bool IsValidDiskImage(uint8_t Test[4]); + uint8_t * GetDiskAddress() { return m_DiskImage; } + void UnallocateDiskImage(); private: - bool AllocateDiskImage(uint32_t DiskFileSize); - bool AllocateAndLoadDiskImage(const char * FileLoc); - void ByteSwapDisk(); - void SetError(LanguageStringID ErrorMsg); + bool AllocateDiskImage(uint32_t DiskFileSize); + bool AllocateAndLoadDiskImage(const char * FileLoc); + void ByteSwapDisk(); + void SetError(LanguageStringID ErrorMsg); - //constant values - enum { ReadFromRomSection = 0x400000 }; + //constant values + enum { ReadFromRomSection = 0x400000 }; - //class variables - CFile m_DiskFile; - uint8_t * m_DiskImage; - uint8_t * m_DiskImageBase; - uint32_t m_DiskFileSize; - LanguageStringID m_ErrorMsg; - stdstr m_FileName, m_DiskIdent; + //class variables + CFile m_DiskFile; + uint8_t * m_DiskImage; + uint8_t * m_DiskImageBase; + uint32_t m_DiskFileSize; + LanguageStringID m_ErrorMsg; + stdstr m_FileName, m_DiskIdent; }; \ No newline at end of file diff --git a/Source/Project64-core/Settings/Settings.h b/Source/Project64-core/Settings/Settings.h index 504dc81b8..869aa9d0d 100644 --- a/Source/Project64-core/Settings/Settings.h +++ b/Source/Project64-core/Settings/Settings.h @@ -48,6 +48,8 @@ enum SettingID SupportFile_RomListCacheDefault, SupportFile_7zipCache, SupportFile_7zipCacheDefault, + //64DD TEST + SupportFile_DiskTest, //Settings Setting_ApplicationName, diff --git a/Source/Project64-core/Settings/SettingsClass.cpp b/Source/Project64-core/Settings/SettingsClass.cpp index 65bda69eb..bec50785c 100644 --- a/Source/Project64-core/Settings/SettingsClass.cpp +++ b/Source/Project64-core/Settings/SettingsClass.cpp @@ -114,6 +114,8 @@ void CSettings::AddHowToHandleSetting() AddHandler(SupportFile_7zipCache, new CSettingTypeApplicationPath("", "7zipCache", SupportFile_7zipCacheDefault)); AddHandler(SupportFile_7zipCacheDefault, new CSettingTypeRelativePath("Config", "Project64.zcache")); + AddHandler(SupportFile_DiskTest, new CSettingTypeRelativePath("Config", "DMPJ.ndd")); + //AddHandler(SyncPluginDir, new CSettingTypeRelativePath("SyncPlugin","")); //Settings location From 0501eb70da5fe8e2f10476a23701a5301451dc84 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Wed, 20 Jan 2016 17:43:23 +0100 Subject: [PATCH 03/12] 64DD Sector Read working --- Source/Project64-core/N64System/Mips/Disk.cpp | 102 +++++++++--------- Source/Project64-core/N64System/Mips/Disk.h | 1 + Source/Project64-core/N64System/Mips/Dma.cpp | 7 +- Source/Project64-core/N64System/N64Class.cpp | 19 ++-- .../Project64-core/N64System/N64DiskClass.cpp | 3 +- .../Project64-core/N64System/N64DiskClass.h | 5 + 6 files changed, 75 insertions(+), 62 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Disk.cpp b/Source/Project64-core/N64System/Mips/Disk.cpp index 74f8fe870..9205c6433 100644 --- a/Source/Project64-core/N64System/Mips/Disk.cpp +++ b/Source/Project64-core/N64System/Mips/Disk.cpp @@ -18,6 +18,7 @@ bool dd_write; bool dd_reset_hold; uint32_t dd_track_offset, dd_zone; +uint32_t dd_start_block, dd_current; uint8_t dd_buffer[0x100]; @@ -61,11 +62,13 @@ void DiskCommand() case 0x00010000: //Seek Read g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; + DiskSetOffset(); dd_write = false; break; case 0x00020000: //Seek Write g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; + DiskSetOffset(); dd_write = true; break; case 0x00080000: @@ -98,16 +101,18 @@ void DiskReset(void) void DiskBMControl(void) { g_Reg->ASIC_CUR_SECTOR = g_Reg->ASIC_BM_CTL & 0x00FF0000; - /* + if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x00) { - + dd_start_block = 0; + dd_current = 0; } else if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x5A) { - + dd_start_block = 1; + dd_current = 0; } - */ + if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_BLK_TRANS) g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_BLOCK; @@ -123,6 +128,8 @@ void DiskBMControl(void) g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_DATA_RQ | DD_STATUS_C2_XFER); g_Reg->ASIC_BM_STATUS = 0; g_Reg->ASIC_CUR_SECTOR = 0; + dd_start_block = 0; + dd_current = 0; } if (!(g_Reg->ASIC_STATUS & DD_STATUS_MECHA_INT) && !(g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)) @@ -139,11 +146,7 @@ void DiskGapSectorCheck() { if (g_Reg->ASIC_STATUS & DD_STATUS_BM_INT) { - uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); - if (testsector >= 0x5A) - testsector -= 0x5A; - - if (SECTORS_PER_BLOCK < testsector) + if (SECTORS_PER_BLOCK < dd_current) { g_Reg->ASIC_STATUS &= ~DD_STATUS_BM_INT; g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; @@ -156,40 +159,44 @@ void DiskBMUpdate() { if (!(g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_RUNNING)) return; - + /* uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); if (testsector >= 0x5A) testsector -= 0x5A; - + */ if (dd_write) { //Write Data - if (testsector == 0) + if (dd_current == 0) { - g_Reg->ASIC_CUR_SECTOR += 0x00010000; + dd_current += 1; + //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } - else if (testsector < SECTORS_PER_BLOCK) + else if (dd_current < SECTORS_PER_BLOCK) { DiskBMWrite(); - g_Reg->ASIC_CUR_SECTOR += 0x00010000; + dd_current += 1; + //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } - else if (testsector < SECTORS_PER_BLOCK + 1) + else if (dd_current < SECTORS_PER_BLOCK + 1) { if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) { DiskBMWrite(); - g_Reg->ASIC_CUR_SECTOR += 0x00010000; - if (g_Reg->ASIC_CUR_SECTOR >> 16 >= 0xB4) - g_Reg->ASIC_CUR_SECTOR = 0x00010000; + dd_current += 1; + //g_Reg->ASIC_CUR_SECTOR += 0x00010000; + dd_start_block = 1 - dd_start_block; + dd_current = 1; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } else { DiskBMWrite(); - g_Reg->ASIC_CUR_SECTOR += 0x00010000; + dd_current += 1; + //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_RUNNING; } } @@ -207,25 +214,27 @@ void DiskBMUpdate() g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ; g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO; } - else if (testsector == 0) + else if (dd_current == 0) { DiskBMRead(); - g_Reg->ASIC_CUR_SECTOR += 0x00010000; + dd_current += 1; + //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } - else if (testsector < SECTORS_PER_BLOCK + 4) + else if (dd_current < SECTORS_PER_BLOCK + 4) { //READ C2 (00!) - g_Reg->ASIC_CUR_SECTOR += 0x00010000; - if ((g_Reg->ASIC_CUR_SECTOR >> 16) == SECTORS_PER_BLOCK + 4) + dd_current += 1; + //g_Reg->ASIC_CUR_SECTOR += 0x00010000; + if (dd_current == SECTORS_PER_BLOCK + 4) g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER; } - else if (testsector == SECTORS_PER_BLOCK + 4) + else if (dd_current == SECTORS_PER_BLOCK + 4) { if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) { - if (g_Reg->ASIC_CUR_SECTOR >> 16 >= 0xB4) - g_Reg->ASIC_CUR_SECTOR = 0x00000000; + dd_start_block = 1 - dd_start_block; + dd_current = 0; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; } else @@ -242,41 +251,34 @@ void DiskBMUpdate() void DiskBMRead() { - uint8_t * sector; - sector = (uint8_t*)g_Disk->GetDiskAddress(); + uint32_t sector = 0; + //sector = (uint8_t*)g_Disk->GetDiskAddress(); sector += dd_track_offset; - uint16_t block = 0; - if (g_Reg->ASIC_CUR_SECTOR >= 0x005A0000) - block = 1; - sector += block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; - uint16_t block2 = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); - if (block2 >= 0x5A) - block -= 0x5A; - sector += block * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); + sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; + sector += (dd_current) * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); + g_Disk->SetDiskAddressBuffer(sector); + + /* for (int i = 0; i < ((g_Reg->ASIC_SEC_BYTE >> 16) + 1) / 4; i++) { dd_buffer[i] = sector[(i * 4 + 0)] << 24 | sector[(i * 4 + 1)] << 16 | sector[(i * 4 + 2)] << 8 | sector[(i * 4 + 3)]; } - + */ return; } void DiskBMWrite() { - uint8_t * sector; - sector = (uint8_t*)g_Disk->GetDiskAddress(); + uint32_t sector = 0; + //sector = (uint8_t*)g_Disk->GetDiskAddress(); sector += dd_track_offset; - uint16_t block = 0; - if (g_Reg->ASIC_CUR_SECTOR >= 0x005A0000) - block = 1; - sector += block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; - uint16_t block2 = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); - if (block2 >= 0x5A) - block -= 0x5A; - sector += block * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); + sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; + sector += (dd_current - 1) * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); + g_Disk->SetDiskAddressBuffer(sector); + /* for (int i = 0; i < ddZoneSecSize[dd_zone] / 4; i++) { sector[i * 4 + 0] = (dd_buffer[i] >> 24) & 0xFF; @@ -284,7 +286,7 @@ void DiskBMWrite() sector[i * 4 + 2] = (dd_buffer[i] >> 8) & 0xFF; sector[i * 4 + 3] = (dd_buffer[i] >> 0) & 0xFF; } - + */ return; } diff --git a/Source/Project64-core/N64System/Mips/Disk.h b/Source/Project64-core/N64System/Mips/Disk.h index d583e0ead..b7742ab72 100644 --- a/Source/Project64-core/N64System/Mips/Disk.h +++ b/Source/Project64-core/N64System/Mips/Disk.h @@ -24,6 +24,7 @@ void DiskSetOffset(void); extern bool dd_write; extern bool dd_reset_hold; extern uint32_t dd_track_offset, dd_zone; +extern uint32_t dd_start_block, dd_current; extern uint8_t dd_buffer[0x100]; diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index d867b94fa..1ccc377d8 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include CDMA::CDMA(CFlashram & FlashRam, CSram & Sram) : @@ -85,9 +86,10 @@ void CDMA::PI_DMA_READ() //64DD User Sector uint32_t i; uint8_t * RDRAM = g_MMU->Rdram(); + uint8_t * DISK = g_Disk->GetDiskAddressBuffer(); for (i = 0; i < PI_RD_LEN_REG; i++) { - dd_buffer[i ^ 3] = * (RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)); + *(DISK + (i ^ 3)) = *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)); } g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; g_Reg->MI_INTR_REG |= MI_INTR_PI; @@ -238,9 +240,10 @@ void CDMA::PI_DMA_WRITE() //64DD User Sector uint32_t i; uint8_t * RDRAM = g_MMU->Rdram(); + uint8_t * DISK = g_Disk->GetDiskAddressBuffer(); for (i = 0; i < PI_WR_LEN_REG; i++) { - *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = dd_buffer[i ^ 3]; + *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(DISK + (i ^ 3)); } g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; g_Reg->MI_INTR_REG |= MI_INTR_PI; diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index dec10366e..c8b1e0598 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -217,17 +217,18 @@ bool CN64System::RunFileImage(const char * FileLoc) { //64DD IPL g_DDRom = g_Rom; + } - if (g_Disk == NULL) - { - g_Disk = new CN64Disk(); - } + if (g_Disk == NULL) + { + g_Disk = new CN64Disk(); + } - if (!g_Disk->LoadDiskImage(g_Settings->LoadStringVal(SupportFile_DiskTest).c_str())); - { - delete g_Disk; - g_Disk = NULL; - } + if (!g_Disk->LoadDiskImage(g_Settings->LoadStringVal(SupportFile_DiskTest).c_str())) + { + g_Notify->DisplayError(g_Disk->GetError()); + delete g_Disk; + g_Disk = NULL; } g_System->RefreshGameSettings(); diff --git a/Source/Project64-core/N64System/N64DiskClass.cpp b/Source/Project64-core/N64System/N64DiskClass.cpp index 4fa2e5933..2a25ceca8 100644 --- a/Source/Project64-core/N64System/N64DiskClass.cpp +++ b/Source/Project64-core/N64System/N64DiskClass.cpp @@ -18,7 +18,8 @@ CN64Disk::CN64Disk() : m_DiskImage(NULL), m_DiskImageBase(NULL), -m_ErrorMsg(EMPTY_STRING) +m_ErrorMsg(EMPTY_STRING), +m_DiskBufAddress(0) { } diff --git a/Source/Project64-core/N64System/N64DiskClass.h b/Source/Project64-core/N64System/N64DiskClass.h index 3a15ca8cf..36a440e74 100644 --- a/Source/Project64-core/N64System/N64DiskClass.h +++ b/Source/Project64-core/N64System/N64DiskClass.h @@ -20,8 +20,12 @@ public: bool LoadDiskImage(const char * FileLoc); static bool IsValidDiskImage(uint8_t Test[4]); uint8_t * GetDiskAddress() { return m_DiskImage; } + uint8_t * GetDiskAddressBuffer() { return m_DiskImage + m_DiskBufAddress; } + void SetDiskAddressBuffer(uint32_t address) { m_DiskBufAddress = address; } void UnallocateDiskImage(); + LanguageStringID GetError() const { return m_ErrorMsg; } + private: bool AllocateDiskImage(uint32_t DiskFileSize); bool AllocateAndLoadDiskImage(const char * FileLoc); @@ -36,6 +40,7 @@ private: uint8_t * m_DiskImage; uint8_t * m_DiskImageBase; uint32_t m_DiskFileSize; + uint32_t m_DiskBufAddress; LanguageStringID m_ErrorMsg; stdstr m_FileName, m_DiskIdent; }; \ No newline at end of file From 305f4cfb16e6df09bd10912c93cd335010c3656c Mon Sep 17 00:00:00 2001 From: luigiblood Date: Fri, 22 Jan 2016 03:17:25 +0100 Subject: [PATCH 04/12] Fixed code and credited Happy_ Good timing needed to fully work. (Not figured out) --- Source/Project64-core/N64System/Mips/Disk.cpp | 8 ++++---- Source/Project64-core/N64System/Mips/Disk.h | 3 +-- Source/Project64-core/N64System/Mips/Dma.cpp | 4 ++-- Source/Project64-core/Settings/SettingsClass.cpp | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Disk.cpp b/Source/Project64-core/N64System/Mips/Disk.cpp index 9205c6433..8b8bf6e7f 100644 --- a/Source/Project64-core/N64System/Mips/Disk.cpp +++ b/Source/Project64-core/N64System/Mips/Disk.cpp @@ -8,6 +8,7 @@ * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ +// Based from MAME's N64DD driver code by Happy_ #pragma once #include "stdafx.h" #include "Disk.h" @@ -20,8 +21,6 @@ bool dd_reset_hold; uint32_t dd_track_offset, dd_zone; uint32_t dd_start_block, dd_current; -uint8_t dd_buffer[0x100]; - void DiskCommand() { //ASIC_CMD_STATUS - Commands @@ -149,7 +148,8 @@ void DiskGapSectorCheck() if (SECTORS_PER_BLOCK < dd_current) { g_Reg->ASIC_STATUS &= ~DD_STATUS_BM_INT; - g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + if (!(g_Reg->ASIC_STATUS & DD_STATUS_MECHA_INT) && !(g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)) + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; DiskBMUpdate(); } } @@ -214,7 +214,7 @@ void DiskBMUpdate() g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ; g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO; } - else if (dd_current == 0) + else if (dd_current < SECTORS_PER_BLOCK) { DiskBMRead(); dd_current += 1; diff --git a/Source/Project64-core/N64System/Mips/Disk.h b/Source/Project64-core/N64System/Mips/Disk.h index b7742ab72..27084a63b 100644 --- a/Source/Project64-core/N64System/Mips/Disk.h +++ b/Source/Project64-core/N64System/Mips/Disk.h @@ -8,6 +8,7 @@ * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ +// Based from MAME's N64DD driver code by Happy_ #pragma once #include @@ -26,8 +27,6 @@ extern bool dd_reset_hold; extern uint32_t dd_track_offset, dd_zone; extern uint32_t dd_start_block, dd_current; -extern uint8_t dd_buffer[0x100]; - const uint32_t ddZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128, 216, 208, 192, 176, 160, 144, 128, 112 }; const uint32_t ddZoneTrackSize[16] = { 158, 158, 149, 149, 149, 149, 149, 114, diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index 1ccc377d8..e2d6cb6f8 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -77,7 +77,7 @@ void CDMA::PI_DMA_READ() //64DD C2 Sectors (don't care) g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; g_Reg->MI_INTR_REG |= MI_INTR_PI; - DiskBMUpdate(); + g_Reg->CheckInterrupts(); return; } @@ -93,7 +93,7 @@ void CDMA::PI_DMA_READ() } g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; g_Reg->MI_INTR_REG |= MI_INTR_PI; - DiskBMUpdate(); + g_Reg->CheckInterrupts(); return; } diff --git a/Source/Project64-core/Settings/SettingsClass.cpp b/Source/Project64-core/Settings/SettingsClass.cpp index bec50785c..bd9aa60fc 100644 --- a/Source/Project64-core/Settings/SettingsClass.cpp +++ b/Source/Project64-core/Settings/SettingsClass.cpp @@ -134,7 +134,7 @@ void CSettings::AddHowToHandleSetting() AddHandler(Setting_RememberCheats, new CSettingTypeApplication("", "Remember Cheats", (uint32_t)false)); AddHandler(Setting_CurrentLanguage, new CSettingTypeApplication("", "Current Language", "")); - AddHandler(Setting_EnableDisk, new CSettingTypeApplication("", "Enable Disk", (uint32_t)false)); + AddHandler(Setting_EnableDisk, new CSettingTypeApplication("", "Enable Disk", (uint32_t)true)); AddHandler(Setting_LanguageDirDefault, new CSettingTypeRelativePath("Lang", "")); AddHandler(Setting_LanguageDir, new CSettingTypeApplicationPath("Directory", "Lang", Setting_LanguageDirDefault)); From b31d18d8c4c2ab628087c7aa80f8149a66888326 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Sat, 23 Jan 2016 22:44:58 +0100 Subject: [PATCH 05/12] Working Read (Interpreter only) Write is slightly buggy for some reason. Conflicts: Source/Project64-core/N64System/Mips/Disk.cpp Source/Project64-core/N64System/Mips/Dma.cpp Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp --- Source/Project64-core/N64System/Mips/Disk.cpp | 47 ++++--------------- Source/Project64-core/N64System/Mips/Dma.cpp | 20 ++++---- .../N64System/Mips/MemoryVirtualMem.cpp | 16 ++++++- .../N64System/Mips/SystemTiming.cpp | 8 ++++ .../N64System/Mips/SystemTiming.h | 1 + 5 files changed, 40 insertions(+), 52 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Disk.cpp b/Source/Project64-core/N64System/Mips/Disk.cpp index 8b8bf6e7f..04c749bbc 100644 --- a/Source/Project64-core/N64System/Mips/Disk.cpp +++ b/Source/Project64-core/N64System/Mips/Disk.cpp @@ -15,6 +15,7 @@ #include #include #include +#include bool dd_write; bool dd_reset_hold; @@ -29,7 +30,6 @@ void DiskCommand() #ifdef _WIN32 SYSTEMTIME sysTime; ::GetLocalTime(&sysTime); - //stdstr_f timestamp("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d,", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds, GetCurrentThreadId()); //BCD format needed for 64DD RTC uint8_t year = (uint8_t)(((sysTime.wYear / 10) << 4) | (sysTime.wYear % 10)); @@ -45,8 +45,6 @@ void DiskCommand() struct tm result = { 0 }; localtime_r(<ime, &result); - //stdstr_f timestamp("%04d/%02d/%02d %02d:%02d:%02d.%03d %05d,", result.tm_year + 1900, result.tm_mon + 1, result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec, milliseconds, GetCurrentThreadId()); - //BCD format needed for 64DD RTC uint8_t year = (uint8_t)(((result.tm_year / 10) << 4) | (result.tm_year % 10)); uint8_t month = (uint8_t)(((result.tm_mon / 10) << 4) | (result.tm_mon % 10)); @@ -148,8 +146,8 @@ void DiskGapSectorCheck() if (SECTORS_PER_BLOCK < dd_current) { g_Reg->ASIC_STATUS &= ~DD_STATUS_BM_INT; - if (!(g_Reg->ASIC_STATUS & DD_STATUS_MECHA_INT) && !(g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)) - g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + g_Reg->CheckInterrupts(); DiskBMUpdate(); } } @@ -159,25 +157,19 @@ void DiskBMUpdate() { if (!(g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_RUNNING)) return; - /* - uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); - if (testsector >= 0x5A) - testsector -= 0x5A; - */ + if (dd_write) { //Write Data if (dd_current == 0) { dd_current += 1; - //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } else if (dd_current < SECTORS_PER_BLOCK) { DiskBMWrite(); dd_current += 1; - //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } else if (dd_current < SECTORS_PER_BLOCK + 1) @@ -186,7 +178,6 @@ void DiskBMUpdate() { DiskBMWrite(); dd_current += 1; - //g_Reg->ASIC_CUR_SECTOR += 0x00010000; dd_start_block = 1 - dd_start_block; dd_current = 1; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; @@ -196,7 +187,6 @@ void DiskBMUpdate() { DiskBMWrite(); dd_current += 1; - //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_RUNNING; } } @@ -218,14 +208,12 @@ void DiskBMUpdate() { DiskBMRead(); dd_current += 1; - //g_Reg->ASIC_CUR_SECTOR += 0x00010000; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } else if (dd_current < SECTORS_PER_BLOCK + 4) { //READ C2 (00!) dd_current += 1; - //g_Reg->ASIC_CUR_SECTOR += 0x00010000; if (dd_current == SECTORS_PER_BLOCK + 4) g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER; } @@ -252,41 +240,22 @@ void DiskBMUpdate() void DiskBMRead() { uint32_t sector = 0; - //sector = (uint8_t*)g_Disk->GetDiskAddress(); sector += dd_track_offset; sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; - sector += (dd_current) * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); - + sector += (dd_current) * (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1); + WriteTrace(TraceN64System, TraceDebug, "READ Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current, sector); g_Disk->SetDiskAddressBuffer(sector); - - /* - for (int i = 0; i < ((g_Reg->ASIC_SEC_BYTE >> 16) + 1) / 4; i++) - { - dd_buffer[i] = sector[(i * 4 + 0)] << 24 | sector[(i * 4 + 1)] << 16 | - sector[(i * 4 + 2)] << 8 | sector[(i * 4 + 3)]; - } - */ return; } void DiskBMWrite() { uint32_t sector = 0; - //sector = (uint8_t*)g_Disk->GetDiskAddress(); sector += dd_track_offset; sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; - sector += (dd_current - 1) * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1); - + sector += (dd_current - 1) * (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1); + WriteTrace(TraceN64System, TraceDebug, "WRITE Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current - 1, sector); g_Disk->SetDiskAddressBuffer(sector); - /* - for (int i = 0; i < ddZoneSecSize[dd_zone] / 4; i++) - { - sector[i * 4 + 0] = (dd_buffer[i] >> 24) & 0xFF; - sector[i * 4 + 1] = (dd_buffer[i] >> 16) & 0xFF; - sector[i * 4 + 2] = (dd_buffer[i] >> 8) & 0xFF; - sector[i * 4 + 3] = (dd_buffer[i] >> 0) & 0xFF; - } - */ return; } diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index e2d6cb6f8..86d7fde61 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -75,9 +75,7 @@ void CDMA::PI_DMA_READ() if (g_Reg->PI_CART_ADDR_REG >= 0x05000000 && g_Reg->PI_CART_ADDR_REG <= 0x050003FF) { //64DD C2 Sectors (don't care) - g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; - g_Reg->MI_INTR_REG |= MI_INTR_PI; - g_Reg->CheckInterrupts(); + g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_RD_LEN_REG * 63) / 25, false); return; } @@ -91,9 +89,7 @@ void CDMA::PI_DMA_READ() { *(DISK + (i ^ 3)) = *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)); } - g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; - g_Reg->MI_INTR_REG |= MI_INTR_PI; - g_Reg->CheckInterrupts(); + g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_RD_LEN_REG * 63) / 25, false); return; } @@ -229,9 +225,9 @@ void CDMA::PI_DMA_WRITE() { *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = 0; } - g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; - g_Reg->MI_INTR_REG |= MI_INTR_PI; - g_Reg->CheckInterrupts(); + + //Timer is needed for Track Read + g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_WR_LEN_REG * 63) / 25, false); return; } @@ -245,9 +241,9 @@ void CDMA::PI_DMA_WRITE() { *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(DISK + (i ^ 3)); } - g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; - g_Reg->MI_INTR_REG |= MI_INTR_PI; - g_Reg->CheckInterrupts(); + + //Timer is needed for Track Read + g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_WR_LEN_REG * 63) / 25, false); return; } diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index c17647302..96c180918 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -5412,7 +5412,21 @@ void CMipsMemoryVM::Write32PeripheralInterface(void) switch (m_MemLookupAddress & 0xFFFFFFF) { case 0x04600000: g_Reg->PI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break; - case 0x04600004: g_Reg->PI_CART_ADDR_REG = m_MemLookupValue.UW[0]; break; + case 0x04600004: + g_Reg->PI_CART_ADDR_REG = m_MemLookupValue.UW[0]; + if (g_Reg->PI_CART_ADDR_REG == 0x05000000) + { + g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_C2_XFER); + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + g_Reg->CheckInterrupts(); + } + else if (g_Reg->PI_CART_ADDR_REG == 0x05000400) + { + g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_DATA_RQ); + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + g_Reg->CheckInterrupts(); + } + break; case 0x04600008: g_Reg->PI_RD_LEN_REG = m_MemLookupValue.UW[0]; g_MMU->PI_DMA_READ(); diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.cpp b/Source/Project64-core/N64System/Mips/SystemTiming.cpp index 0bc492da3..9d301bdc6 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.cpp +++ b/Source/Project64-core/N64System/Mips/SystemTiming.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -207,6 +208,13 @@ void CSystemTimer::TimerDone() g_Reg->MI_INTR_REG |= MI_INTR_PI; g_Reg->CheckInterrupts(); break; + case CSystemTimer::DDPiTimer: + g_SystemTimer->StopTimer(CSystemTimer::DDPiTimer); + g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY; + DiskBMUpdate(); + g_Reg->MI_INTR_REG |= MI_INTR_PI; + g_Reg->CheckInterrupts(); + break; case CSystemTimer::ViTimer: try { diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.h b/Source/Project64-core/N64System/Mips/SystemTiming.h index a9b98efb9..85969a2cc 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.h +++ b/Source/Project64-core/N64System/Mips/SystemTiming.h @@ -29,6 +29,7 @@ public: PiTimer, RspTimer, RSPTimerDlist, + DDPiTimer, MaxTimer }; From 82779033d3fc916698e93a20473ccfe597a6e216 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Mon, 25 Jan 2016 15:47:12 +0100 Subject: [PATCH 06/12] Disk Write fixed, Recompiler support tentative Unfortunately there's an opcode that Recompiler doesn't recognize. However once it's implemented, there's no reason it shouldn't work. For Disk Writing, so far it works, it seems to not have any trouble so far. --- Source/Project64-core/N64System/Mips/Disk.cpp | 35 +++++++++++++------ Source/Project64-core/N64System/Mips/Disk.h | 1 + .../N64System/Mips/MemoryVirtualMem.cpp | 33 ++++++++--------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/Source/Project64-core/N64System/Mips/Disk.cpp b/Source/Project64-core/N64System/Mips/Disk.cpp index 04c749bbc..332056d17 100644 --- a/Source/Project64-core/N64System/Mips/Disk.cpp +++ b/Source/Project64-core/N64System/Mips/Disk.cpp @@ -24,6 +24,9 @@ uint32_t dd_start_block, dd_current; void DiskCommand() { + if (g_Disk != NULL) + g_Reg->ASIC_STATUS |= DD_STATUS_DISK_PRES; + //ASIC_CMD_STATUS - Commands uint32_t cmd = g_Reg->ASIC_CMD; @@ -161,12 +164,7 @@ void DiskBMUpdate() if (dd_write) { //Write Data - if (dd_current == 0) - { - dd_current += 1; - g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; - } - else if (dd_current < SECTORS_PER_BLOCK) + if (dd_current < SECTORS_PER_BLOCK) { DiskBMWrite(); dd_current += 1; @@ -176,16 +174,15 @@ void DiskBMUpdate() { if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) { + dd_start_block = 1 - dd_start_block; + dd_current = 0; DiskBMWrite(); dd_current += 1; - dd_start_block = 1 - dd_start_block; - dd_current = 1; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; } else { - DiskBMWrite(); dd_current += 1; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_RUNNING; } @@ -253,8 +250,8 @@ void DiskBMWrite() uint32_t sector = 0; sector += dd_track_offset; sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone]; - sector += (dd_current - 1) * (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1); - WriteTrace(TraceN64System, TraceDebug, "WRITE Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current - 1, sector); + sector += (dd_current) * (((g_Reg->ASIC_HOST_SECBYTE & 0x00FF0000) >> 16) + 1); + WriteTrace(TraceN64System, TraceDebug, "WRITE Block %d Sector %02X - %08X", ((g_Reg->ASIC_CUR_TK & 0x0FFF0000) >> 15) | dd_start_block, dd_current, sector); g_Disk->SetDiskAddressBuffer(sector); return; } @@ -307,4 +304,20 @@ void DiskSetOffset() } dd_track_offset = ddStartOffset[dd_zone] + tr_off * ddZoneSecSize[dd_zone] * SECTORS_PER_BLOCK * BLOCKS_PER_TRACK; +} + +void DiskDMACheck(void) +{ + if (g_Reg->PI_CART_ADDR_REG == 0x05000000) + { + g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_C2_XFER); + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + g_Reg->CheckInterrupts(); + } + else if (g_Reg->PI_CART_ADDR_REG == 0x05000400) + { + g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_DATA_RQ); + g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; + g_Reg->CheckInterrupts(); + } } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Mips/Disk.h b/Source/Project64-core/N64System/Mips/Disk.h index 27084a63b..7776664ac 100644 --- a/Source/Project64-core/N64System/Mips/Disk.h +++ b/Source/Project64-core/N64System/Mips/Disk.h @@ -21,6 +21,7 @@ void DiskBMUpdate(void); void DiskBMRead(void); void DiskBMWrite(void); void DiskSetOffset(void); +void DiskDMACheck(void); extern bool dd_write; extern bool dd_reset_hold; diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index 96c180918..0da3988e1 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -959,7 +959,12 @@ void CMipsMemoryVM::Compile_LW(x86Reg Reg, uint32_t VAddr) { case 0x05000500: MoveVariableToX86reg(&g_Reg->ASIC_DATA, "ASIC_DATA", Reg); break; case 0x05000504: MoveVariableToX86reg(&g_Reg->ASIC_MISC_REG, "ASIC_MISC_REG", Reg); break; - case 0x05000508: MoveVariableToX86reg(&g_Reg->ASIC_STATUS, "ASIC_STATUS", Reg); break; + case 0x05000508: + MoveVariableToX86reg(&g_Reg->ASIC_STATUS, "ASIC_STATUS", Reg); + BeforeCallDirect(m_RegWorkingSet); + Call_Direct(AddressOf(&DiskGapSectorCheck), "DiskGapSectorCheck"); + AfterCallDirect(m_RegWorkingSet); + break; case 0x0500050C: MoveVariableToX86reg(&g_Reg->ASIC_CUR_TK, "ASIC_CUR_TK", Reg); break; case 0x05000510: MoveVariableToX86reg(&g_Reg->ASIC_BM_STATUS, "ASIC_BM_STATUS", Reg); break; case 0x05000514: MoveVariableToX86reg(&g_Reg->ASIC_ERR_SECTOR, "ASIC_ERR_SECTOR", Reg); break; @@ -1922,7 +1927,15 @@ void CMipsMemoryVM::Compile_SW_Register(x86Reg Reg, uint32_t VAddr) switch (PAddr) { case 0x04600000: MoveX86regToVariable(Reg, &g_Reg->PI_DRAM_ADDR_REG, "PI_DRAM_ADDR_REG"); break; - case 0x04600004: MoveX86regToVariable(Reg, &g_Reg->PI_CART_ADDR_REG, "PI_CART_ADDR_REG"); break; + case 0x04600004: + MoveX86regToVariable(Reg, &g_Reg->PI_CART_ADDR_REG, "PI_CART_ADDR_REG"); + if (g_Settings->LoadBool(Setting_EnableDisk)) + { + BeforeCallDirect(m_RegWorkingSet); + Call_Direct(AddressOf(&DiskDMACheck), "DiskDMACheck"); + AfterCallDirect(m_RegWorkingSet); + } + break; case 0x04600008: MoveX86regToVariable(Reg, &g_Reg->PI_RD_LEN_REG, "PI_RD_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); @@ -4828,8 +4841,6 @@ void CMipsMemoryVM::Load32CartridgeDomain2Address1(void) case 0x05000500: m_MemLookupValue.UW[0] = g_Reg->ASIC_DATA; break; case 0x05000504: m_MemLookupValue.UW[0] = g_Reg->ASIC_MISC_REG; break; case 0x05000508: - if (g_Disk != NULL) - g_Reg->ASIC_STATUS |= DD_STATUS_DISK_PRES; m_MemLookupValue.UW[0] = g_Reg->ASIC_STATUS; DiskGapSectorCheck(); break; @@ -5414,18 +5425,8 @@ void CMipsMemoryVM::Write32PeripheralInterface(void) case 0x04600000: g_Reg->PI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break; case 0x04600004: g_Reg->PI_CART_ADDR_REG = m_MemLookupValue.UW[0]; - if (g_Reg->PI_CART_ADDR_REG == 0x05000000) - { - g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_C2_XFER); - g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; - g_Reg->CheckInterrupts(); - } - else if (g_Reg->PI_CART_ADDR_REG == 0x05000400) - { - g_Reg->ASIC_STATUS &= ~(DD_STATUS_BM_INT | DD_STATUS_BM_ERR | DD_STATUS_DATA_RQ); - g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; - g_Reg->CheckInterrupts(); - } + if (g_Settings->LoadBool(Setting_EnableDisk)) + DiskDMACheck(); break; case 0x04600008: g_Reg->PI_RD_LEN_REG = m_MemLookupValue.UW[0]; From 39a1c9f407dd0466c2f51c04ed26dd2ec310c4c7 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Mon, 25 Jan 2016 20:58:57 +0100 Subject: [PATCH 07/12] Added "Play Game with Disk" option --- Lang/English.pj.Lang | 1 + Source/Project64-core/Multilanguage.h | 1 + .../Multilanguage/LanguageClass.cpp | 1 + Source/Project64-core/N64System/N64Class.cpp | 114 +++++++++-- Source/Project64-core/N64System/N64Class.h | 2 + .../Project64-core/N64System/N64RomClass.cpp | 177 ++++++++++++++++++ Source/Project64-core/N64System/N64RomClass.h | 1 + Source/Project64-core/Settings/Settings.h | 3 +- .../Project64-core/Settings/SettingsClass.cpp | 3 +- Source/Project64/UserInterface/GuiClass.cpp | 58 ++++++ .../UserInterface/RomBrowserClass.cpp | 26 +-- Source/Project64/UserInterface/UIResources.rc | 1 + Source/Project64/UserInterface/resource.h | 3 +- 13 files changed, 362 insertions(+), 29 deletions(-) diff --git a/Lang/English.pj.Lang b/Lang/English.pj.Lang index ab609e861..f17aa2489 100644 --- a/Lang/English.pj.Lang +++ b/Lang/English.pj.Lang @@ -96,6 +96,7 @@ #212# "Edit Game Settings" #213# "Edit Cheats" #214# "Graphics Plugin" +#215# "Play Game with Disk" //Alternate Name to save Slot #220# "Save Slot - Default" diff --git a/Source/Project64-core/Multilanguage.h b/Source/Project64-core/Multilanguage.h index 85c139832..6795c07cd 100644 --- a/Source/Project64-core/Multilanguage.h +++ b/Source/Project64-core/Multilanguage.h @@ -125,6 +125,7 @@ enum LanguageStringID{ POPUP_SETTINGS = 212, POPUP_CHEATS = 213, POPUP_GFX_PLUGIN = 214, + POPUP_PLAYDISK = 215, //selecting save slot SAVE_SLOT_DEFAULT = 220, diff --git a/Source/Project64-core/Multilanguage/LanguageClass.cpp b/Source/Project64-core/Multilanguage/LanguageClass.cpp index cc6d99e16..861c1f186 100644 --- a/Source/Project64-core/Multilanguage/LanguageClass.cpp +++ b/Source/Project64-core/Multilanguage/LanguageClass.cpp @@ -133,6 +133,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(POPUP_SETTINGS, "Edit Game Settings"); DEF_STR(POPUP_CHEATS, "Edit Cheats"); DEF_STR(POPUP_GFX_PLUGIN, "Graphics Plugin"); + DEF_STR(POPUP_PLAYDISK, "Play Game with Disk"); //Alternate Name to save Slot DEF_STR(SAVE_SLOT_DEFAULT, "Save Slot - Default"); diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index c8b1e0598..c8196ac77 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -217,18 +217,7 @@ bool CN64System::RunFileImage(const char * FileLoc) { //64DD IPL g_DDRom = g_Rom; - } - - if (g_Disk == NULL) - { - g_Disk = new CN64Disk(); - } - - if (!g_Disk->LoadDiskImage(g_Settings->LoadStringVal(SupportFile_DiskTest).c_str())) - { - g_Notify->DisplayError(g_Disk->GetError()); - delete g_Disk; - g_Disk = NULL; + g_Settings->SaveString(File_DiskIPLPath, FileLoc); } g_System->RefreshGameSettings(); @@ -257,6 +246,107 @@ bool CN64System::RunFileImage(const char * FileLoc) return true; } +bool CN64System::RunFileImageIPL(const char * FileLoc) +{ + CloseSystem(); + if (g_Settings->LoadBool(GameRunning_LoadingInProgress)) + { + return false; + } + + //Mark the rom as loading + WriteTrace(TraceN64System, TraceDebug, "Mark DDRom as loading"); + //g_Settings->SaveString(Game_File, ""); + g_Settings->SaveBool(GameRunning_LoadingInProgress, true); + + //Try to load the passed N64 DDrom + if (g_DDRom == NULL) + { + WriteTrace(TraceN64System, TraceDebug, "Allocating global DDrom object"); + g_DDRom = new CN64Rom(); + } + else + { + WriteTrace(TraceN64System, TraceDebug, "Use existing global DDrom object"); + } + + WriteTrace(TraceN64System, TraceDebug, "Loading \"%s\"", FileLoc); + if (g_DDRom->LoadN64ImageIPL(FileLoc)) + { + if (g_DDRom->CicChipID() != CIC_NUS_8303) + { + //If not 64DD IPL then it's wrong + WriteTrace(TraceN64System, TraceError, "LoadN64ImageIPL failed (\"%s\")", FileLoc); + g_Notify->DisplayError(g_DDRom->GetError()); + delete g_DDRom; + g_DDRom = NULL; + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + return false; + } + + g_System->RefreshGameSettings(); + + g_Settings->SaveString(File_DiskIPLPath, FileLoc); + + //g_Settings->SaveString(Game_File, FileLoc); + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + } + else + { + WriteTrace(TraceN64System, TraceError, "LoadN64ImageIPL failed (\"%s\")", FileLoc); + g_Notify->DisplayError(g_DDRom->GetError()); + delete g_DDRom; + g_DDRom = NULL; + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + return false; + } + return true; +} + +bool CN64System::RunDiskImage(const char * FileLoc) +{ + CloseSystem(); + if (g_Settings->LoadBool(GameRunning_LoadingInProgress)) + { + return false; + } + + //Mark the rom as loading + WriteTrace(TraceN64System, TraceDebug, "Mark Disk as loading"); + //g_Settings->SaveString(Game_File, ""); + g_Settings->SaveBool(GameRunning_LoadingInProgress, true); + + //Try to load the passed N64 Disk + if (g_Disk == NULL) + { + WriteTrace(TraceN64System, TraceDebug, "Allocating global Disk object"); + g_Disk = new CN64Disk(); + } + else + { + WriteTrace(TraceN64System, TraceDebug, "Use existing global Disk object"); + } + + WriteTrace(TraceN64System, TraceDebug, "Loading \"%s\"", FileLoc); + if (g_Disk->LoadDiskImage(FileLoc)) + { + g_System->RefreshGameSettings(); + + //g_Settings->SaveString(Game_File, FileLoc); + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + } + else + { + WriteTrace(TraceN64System, TraceError, "LoadDiskImage failed (\"%s\")", FileLoc); + g_Notify->DisplayError(g_Disk->GetError()); + delete g_Disk; + g_Disk = NULL; + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + return false; + } + return true; +} + void CN64System::CloseSystem() { if (g_BaseSystem) diff --git a/Source/Project64-core/N64System/N64Class.h b/Source/Project64-core/N64System/N64Class.h index df41ba593..efe0e7403 100644 --- a/Source/Project64-core/N64System/N64Class.h +++ b/Source/Project64-core/N64System/N64Class.h @@ -56,6 +56,8 @@ public: //Methods static bool RunFileImage(const char * FileLoc); + static bool RunFileImageIPL(const char * FileLoc); + static bool RunDiskImage(const char * FileLoc); static void CloseSystem(void); void CloseCpu(); diff --git a/Source/Project64-core/N64System/N64RomClass.cpp b/Source/Project64-core/N64System/N64RomClass.cpp index 33cbd81c6..bcf5c8a53 100644 --- a/Source/Project64-core/N64System/N64RomClass.cpp +++ b/Source/Project64-core/N64System/N64RomClass.cpp @@ -579,6 +579,183 @@ bool CN64Rom::LoadN64Image(const char * FileLoc, bool LoadBootCodeOnly) return true; } +bool CN64Rom::LoadN64ImageIPL(const char * FileLoc, bool LoadBootCodeOnly) +{ + UnallocateRomImage(); + m_ErrorMsg = EMPTY_STRING; + + stdstr ext = CPath(FileLoc).GetExtension(); + bool Loaded7zFile = false; + + if (strstr(FileLoc, "?") != NULL || _stricmp(ext.c_str(), "7z") == 0) + { + stdstr FullPath = FileLoc; + + //this should be a 7zip file + char * SubFile = strstr(const_cast(FullPath.c_str()), "?"); + if (SubFile == NULL) + { + //Pop up a dialog and select file + //allocate memory for sub name and copy selected file name to var + return false; //remove once dialog is done + } + else + { + *SubFile = '\0'; + SubFile += 1; + } + + C7zip ZipFile(FullPath.c_str()); + ZipFile.SetNotificationCallback((C7zip::LP7ZNOTIFICATION)NotificationCB, this); + for (int i = 0; i < ZipFile.NumFiles(); i++) + { + CSzFileItem * f = ZipFile.FileItem(i); + if (f->IsDir) + { + continue; + } + + stdstr ZipFileName; + ZipFileName.FromUTF16(ZipFile.FileNameIndex(i).c_str()); + if (SubFile != NULL) + { + if (_stricmp(ZipFileName.c_str(), SubFile) != 0) + { + continue; + } + } + + //Get the size of the rom and try to allocate the memory needed. + uint32_t RomFileSize = (uint32_t)f->Size; + //if loading boot code then just load the first 0x1000 bytes + if (LoadBootCodeOnly) { RomFileSize = 0x1000; } + + if (!AllocateRomImage(RomFileSize)) + { + return false; + } + + //Load the n64 rom to the allocated memory + g_Notify->DisplayMessage(5, MSG_LOADING); + if (!ZipFile.GetFile(i, m_ROMImage, RomFileSize)) + { + SetError(MSG_FAIL_IMAGE); + return false; + } + + if (!IsValidRomImage(m_ROMImage)) + { + SetError(MSG_FAIL_IMAGE); + return false; + } + g_Notify->DisplayMessage(5, MSG_BYTESWAP); + ByteSwapRom(); + + //Protect the memory so that it can not be written to. + ProtectMemory(m_ROMImage, m_RomFileSize, MEM_READONLY); + Loaded7zFile = true; + break; + } + if (!Loaded7zFile) + { + SetError(MSG_7Z_FILE_NOT_FOUND); + return false; + } + } + + //Try to open the file as a zip file + if (!Loaded7zFile) + { + if (!AllocateAndLoadZipImage(FileLoc, LoadBootCodeOnly)) + { + if (m_ErrorMsg != EMPTY_STRING) + { + return false; + } + if (!AllocateAndLoadN64Image(FileLoc, LoadBootCodeOnly)) + { + return false; + } + } + } + + char RomName[260]; + int count; + //Get the header from the rom image + memcpy(&RomName[0], (void *)(m_ROMImage + 0x20), 20); + for (count = 0; count < 20; count += 4) + { + RomName[count] ^= RomName[count + 3]; + RomName[count + 3] ^= RomName[count]; + RomName[count] ^= RomName[count + 3]; + RomName[count + 1] ^= RomName[count + 2]; + RomName[count + 2] ^= RomName[count + 1]; + RomName[count + 1] ^= RomName[count + 2]; + } + + //truncate all the spaces at the end of the string + for (count = 19; count >= 0; count--) + { + if (RomName[count] == ' ') + { + RomName[count] = '\0'; + } + else if (RomName[count] == '\0') + { + } + else + { + count = -1; + } + } + RomName[20] = '\0'; + if (strlen(RomName) == 0) + { + strcpy(RomName, CPath(FileLoc).GetName().c_str()); + } + + //remove all /,\,: from the string + for (count = 0; count < (int)strlen(RomName); count++) + { + switch (RomName[count]) + { + case '/': case '\\': RomName[count] = '-'; break; + case ':': RomName[count] = ';'; break; + } + } + WriteTrace(TraceN64System, TraceDebug, "RomName %s", RomName); + + m_RomName = RomName; + m_FileName = FileLoc; + m_MD5 = ""; + + if (!LoadBootCodeOnly) + { + //Calculate files MD5 + m_MD5 = MD5((const unsigned char *)m_ROMImage, m_RomFileSize).hex_digest(); + WriteTrace(TraceN64System, TraceDebug, "MD5: %s", m_MD5.c_str()); + } + + m_Country = (Country)m_ROMImage[0x3D]; + m_RomIdent.Format("%08X-%08X-C:%X", *(uint32_t *)(&m_ROMImage[0x10]), *(uint32_t *)(&m_ROMImage[0x14]), m_ROMImage[0x3D]); + WriteTrace(TraceN64System, TraceDebug, "Ident: %s", m_RomIdent.c_str()); + CalculateCicChip(); + + if (!LoadBootCodeOnly && g_DDRom == this) + { + g_Settings->SaveBool(GameRunning_LoadingInProgress, false); + SaveRomSettingID(false); + } + + if (g_Settings->LoadBool(Game_CRC_Recalc)) + { + //Calculate ROM Header CRC + CalculateRomCrc(); + } + + return true; +} + //Save the settings of the loaded rom, so all loaded settings about rom will be identified with //this rom void CN64Rom::SaveRomSettingID(bool temp) diff --git a/Source/Project64-core/N64System/N64RomClass.h b/Source/Project64-core/N64System/N64RomClass.h index 6e10a0709..fef95da55 100644 --- a/Source/Project64-core/N64System/N64RomClass.h +++ b/Source/Project64-core/N64System/N64RomClass.h @@ -21,6 +21,7 @@ public: ~CN64Rom(); bool LoadN64Image(const char * FileLoc, bool LoadBootCodeOnly = false); + bool LoadN64ImageIPL(const char * FileLoc, bool LoadBootCodeOnly = false); static bool IsValidRomImage(uint8_t Test[4]); void SaveRomSettingID(bool temp); void ClearRomSettingID(); diff --git a/Source/Project64-core/Settings/Settings.h b/Source/Project64-core/Settings/Settings.h index 869aa9d0d..010f4cc1d 100644 --- a/Source/Project64-core/Settings/Settings.h +++ b/Source/Project64-core/Settings/Settings.h @@ -48,8 +48,6 @@ enum SettingID SupportFile_RomListCacheDefault, SupportFile_7zipCache, SupportFile_7zipCacheDefault, - //64DD TEST - SupportFile_DiskTest, //Settings Setting_ApplicationName, @@ -226,6 +224,7 @@ enum SettingID //File Info File_RecentGameFileCount, File_RecentGameFileIndex, + File_DiskIPLPath, //Debugger Debugger_Enabled, diff --git a/Source/Project64-core/Settings/SettingsClass.cpp b/Source/Project64-core/Settings/SettingsClass.cpp index bd9aa60fc..eff641bb6 100644 --- a/Source/Project64-core/Settings/SettingsClass.cpp +++ b/Source/Project64-core/Settings/SettingsClass.cpp @@ -114,8 +114,6 @@ void CSettings::AddHowToHandleSetting() AddHandler(SupportFile_7zipCache, new CSettingTypeApplicationPath("", "7zipCache", SupportFile_7zipCacheDefault)); AddHandler(SupportFile_7zipCacheDefault, new CSettingTypeRelativePath("Config", "Project64.zcache")); - AddHandler(SupportFile_DiskTest, new CSettingTypeRelativePath("Config", "DMPJ.ndd")); - //AddHandler(SyncPluginDir, new CSettingTypeRelativePath("SyncPlugin","")); //Settings location @@ -311,6 +309,7 @@ void CSettings::AddHowToHandleSetting() AddHandler(File_RecentGameFileCount, new CSettingTypeApplication("", "Remembered Rom Files", (uint32_t)10)); AddHandler(File_RecentGameFileIndex, new CSettingTypeApplicationIndex("Recent File", "Recent Rom", Default_None)); + AddHandler(File_DiskIPLPath, new CSettingTypeApplicationPath("", "Disk IPL ROM Path", Default_None)); AddHandler(Debugger_Enabled, new CSettingTypeApplication("Debugger", "Debugger", false)); AddHandler(Debugger_ShowTLBMisses, new CSettingTypeApplication("Debugger", "Show TLB Misses", false)); diff --git a/Source/Project64/UserInterface/GuiClass.cpp b/Source/Project64/UserInterface/GuiClass.cpp index d81e3d28a..4f6de4a8a 100644 --- a/Source/Project64/UserInterface/GuiClass.cpp +++ b/Source/Project64/UserInterface/GuiClass.cpp @@ -979,6 +979,64 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO switch (LOWORD(wParam)) { case ID_POPUPMENU_PLAYGAME: g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); break; + case ID_POPUPMENU_PLAYGAMEWITHDISK: + if (!g_BaseSystem->RunFileImageIPL(g_Settings->LoadStringVal(File_DiskIPLPath).c_str())) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunFileImageIPL(FileName); + // Open Disk + openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunDiskImage(FileName); + g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); + } + } + } + else + { + // Open Disk + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunDiskImage(FileName); + g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); + } + } + break; case ID_POPUPMENU_ROMDIRECTORY: _this->SelectRomDir(); break; case ID_POPUPMENU_REFRESHROMLIST: _this->RefreshRomBrowser(); break; case ID_POPUPMENU_ROMINFORMATION: diff --git a/Source/Project64/UserInterface/RomBrowserClass.cpp b/Source/Project64/UserInterface/RomBrowserClass.cpp index 97f444470..d01abf1d5 100644 --- a/Source/Project64/UserInterface/RomBrowserClass.cpp +++ b/Source/Project64/UserInterface/RomBrowserClass.cpp @@ -1502,21 +1502,23 @@ void CRomBrowser::RomList_PopupMenu(uint32_t /*pnmh*/) //Fix up menu MenuSetText(hPopupMenu, 0, wGS(POPUP_PLAY).c_str(), NULL); - MenuSetText(hPopupMenu, 2, wGS(MENU_REFRESH).c_str(), NULL); - MenuSetText(hPopupMenu, 3, wGS(MENU_CHOOSE_ROM).c_str(), NULL); - MenuSetText(hPopupMenu, 5, wGS(POPUP_INFO).c_str(), NULL); - MenuSetText(hPopupMenu, 6, wGS(POPUP_GFX_PLUGIN).c_str(), NULL); - MenuSetText(hPopupMenu, 8, wGS(POPUP_SETTINGS).c_str(), NULL); - MenuSetText(hPopupMenu, 9, wGS(POPUP_CHEATS).c_str(), NULL); + MenuSetText(hPopupMenu, 1, wGS(POPUP_PLAYDISK).c_str(), NULL); + MenuSetText(hPopupMenu, 3, wGS(MENU_REFRESH).c_str(), NULL); + MenuSetText(hPopupMenu, 4, wGS(MENU_CHOOSE_ROM).c_str(), NULL); + MenuSetText(hPopupMenu, 6, wGS(POPUP_INFO).c_str(), NULL); + MenuSetText(hPopupMenu, 7, wGS(POPUP_GFX_PLUGIN).c_str(), NULL); + MenuSetText(hPopupMenu, 9, wGS(POPUP_SETTINGS).c_str(), NULL); + MenuSetText(hPopupMenu, 10, wGS(POPUP_CHEATS).c_str(), NULL); if (m_SelectedRom.size() == 0) { + DeleteMenu(hPopupMenu, 10, MF_BYPOSITION); DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); DeleteMenu(hPopupMenu, 6, MF_BYPOSITION); DeleteMenu(hPopupMenu, 5, MF_BYPOSITION); - DeleteMenu(hPopupMenu, 4, MF_BYPOSITION); + DeleteMenu(hPopupMenu, 2, MF_BYPOSITION); DeleteMenu(hPopupMenu, 1, MF_BYPOSITION); DeleteMenu(hPopupMenu, 0, MF_BYPOSITION); } @@ -1524,17 +1526,17 @@ void CRomBrowser::RomList_PopupMenu(uint32_t /*pnmh*/) { bool inBasicMode = g_Settings->LoadDword(UserInterface_BasicMode) != 0; bool CheatsRemembered = g_Settings->LoadDword(Setting_RememberCheats) != 0; - if (!CheatsRemembered) { DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); } - if (inBasicMode) { DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); } - if (inBasicMode && !CheatsRemembered) { DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); } - DeleteMenu(hPopupMenu, 6, MF_BYPOSITION); + if (!CheatsRemembered) { DeleteMenu(hPopupMenu, 10, MF_BYPOSITION); } + if (inBasicMode) { DeleteMenu(hPopupMenu, 9, MF_BYPOSITION); } + if (inBasicMode && !CheatsRemembered) { DeleteMenu(hPopupMenu, 8, MF_BYPOSITION); } + DeleteMenu(hPopupMenu, 7, MF_BYPOSITION); if (!inBasicMode && g_Plugins && g_Plugins->Gfx() && g_Plugins->Gfx()->GetRomBrowserMenu != NULL) { HMENU GfxMenu = (HMENU)g_Plugins->Gfx()->GetRomBrowserMenu(); if (GfxMenu) { MENUITEMINFO lpmii; - InsertMenuW(hPopupMenu, 6, MF_POPUP | MF_BYPOSITION, (uint32_t)GfxMenu, wGS(POPUP_GFX_PLUGIN).c_str()); + InsertMenuW(hPopupMenu, 7, MF_POPUP | MF_BYPOSITION, (uint32_t)GfxMenu, wGS(POPUP_GFX_PLUGIN).c_str()); lpmii.cbSize = sizeof(MENUITEMINFO); lpmii.fMask = MIIM_STATE; lpmii.fState = 0; diff --git a/Source/Project64/UserInterface/UIResources.rc b/Source/Project64/UserInterface/UIResources.rc index 372c7f353..ffc6138e6 100644 --- a/Source/Project64/UserInterface/UIResources.rc +++ b/Source/Project64/UserInterface/UIResources.rc @@ -895,6 +895,7 @@ BEGIN POPUP "PopupMenu" BEGIN MENUITEM "Play Game", ID_POPUPMENU_PLAYGAME + MENUITEM "Play Game with Disk", ID_POPUPMENU_PLAYGAMEWITHDISK MENUITEM SEPARATOR MENUITEM "Refresh Rom List", ID_POPUPMENU_REFRESHROMLIST MENUITEM "Choose Rom Directory...", ID_POPUPMENU_ROMDIRECTORY diff --git a/Source/Project64/UserInterface/resource.h b/Source/Project64/UserInterface/resource.h index 18799098c..04b70981d 100644 --- a/Source/Project64/UserInterface/resource.h +++ b/Source/Project64/UserInterface/resource.h @@ -329,6 +329,7 @@ #define IDC_NOTES_TEXT 1208 #define IDC_LANG_SEL 1219 #define ID_POPUP_SHOWINMEMORYVIEWER 40005 +#define ID_POPUPMENU_PLAYGAMEWITHDISK 40008 #define ID_POPUPMENU_ROMDIRECTORY 40137 #define ID_POPUPMENU_REFRESHROMLIST 40138 #define ID_POPUPMENU_PLAYGAME 40152 @@ -344,7 +345,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 150 -#define _APS_NEXT_COMMAND_VALUE 40008 +#define _APS_NEXT_COMMAND_VALUE 40009 #define _APS_NEXT_CONTROL_VALUE 1100 #define _APS_NEXT_SYMED_VALUE 101 #endif From f0b81bbfc00bb1f5efbb053d6848b8cf5bae9d5a Mon Sep 17 00:00:00 2001 From: luigiblood Date: Mon, 25 Jan 2016 22:39:26 +0100 Subject: [PATCH 08/12] Added "Open Disk" to File menu. --- Source/Project64-core/Multilanguage.h | 3 +- .../Multilanguage/LanguageClass.cpp | 1 + Source/Project64/UserInterface/GuiClass.cpp | 15 +++-- .../Project64/UserInterface/MainMenuClass.cpp | 63 +++++++++++++++++++ .../Project64/UserInterface/MainMenuClass.h | 2 +- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Source/Project64-core/Multilanguage.h b/Source/Project64-core/Multilanguage.h index 6795c07cd..f3d8ab7f7 100644 --- a/Source/Project64-core/Multilanguage.h +++ b/Source/Project64-core/Multilanguage.h @@ -63,6 +63,7 @@ enum LanguageStringID{ MENU_RECENT_ROM = 107, MENU_RECENT_DIR = 108, MENU_EXIT = 109, + MENU_DISK = 110, //System Menu MENU_SYSTEM = 120, @@ -125,7 +126,7 @@ enum LanguageStringID{ POPUP_SETTINGS = 212, POPUP_CHEATS = 213, POPUP_GFX_PLUGIN = 214, - POPUP_PLAYDISK = 215, + POPUP_PLAYDISK = 215, //selecting save slot SAVE_SLOT_DEFAULT = 220, diff --git a/Source/Project64-core/Multilanguage/LanguageClass.cpp b/Source/Project64-core/Multilanguage/LanguageClass.cpp index 861c1f186..50a4b34c1 100644 --- a/Source/Project64-core/Multilanguage/LanguageClass.cpp +++ b/Source/Project64-core/Multilanguage/LanguageClass.cpp @@ -71,6 +71,7 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(MENU_RECENT_ROM, "Recent ROM"); DEF_STR(MENU_RECENT_DIR, "Recent ROM Directories"); DEF_STR(MENU_EXIT, "E&xit"); + DEF_STR(MENU_DISK, "Open Disk"); //System Menu DEF_STR(MENU_SYSTEM, "&System"); diff --git a/Source/Project64/UserInterface/GuiClass.cpp b/Source/Project64/UserInterface/GuiClass.cpp index 4f6de4a8a..0239207d9 100644 --- a/Source/Project64/UserInterface/GuiClass.cpp +++ b/Source/Project64/UserInterface/GuiClass.cpp @@ -980,7 +980,9 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO switch (LOWORD(wParam)) { case ID_POPUPMENU_PLAYGAME: g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); break; case ID_POPUPMENU_PLAYGAMEWITHDISK: - if (!g_BaseSystem->RunFileImageIPL(g_Settings->LoadStringVal(File_DiskIPLPath).c_str())) + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImageIPL(IPLROM.c_str()))) { // Open DDROM OPENFILENAME openfilename; @@ -1006,8 +1008,8 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; if (GetOpenFileName(&openfilename)) { - g_BaseSystem->RunDiskImage(FileName); - g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); + if (g_BaseSystem->RunDiskImage(FileName)) + g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); } } } @@ -1032,11 +1034,12 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO if (GetOpenFileName(&openfilename)) { - g_BaseSystem->RunDiskImage(FileName); - g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); + if (g_BaseSystem->RunDiskImage(FileName)) + g_BaseSystem->RunFileImage(_this->CurrentedSelectedRom()); } } - break; + } + break; case ID_POPUPMENU_ROMDIRECTORY: _this->SelectRomDir(); break; case ID_POPUPMENU_REFRESHROMLIST: _this->RefreshRomBrowser(); break; case ID_POPUPMENU_ROMINFORMATION: diff --git a/Source/Project64/UserInterface/MainMenuClass.cpp b/Source/Project64/UserInterface/MainMenuClass.cpp index 32473b38c..0ad307fa5 100644 --- a/Source/Project64/UserInterface/MainMenuClass.cpp +++ b/Source/Project64/UserInterface/MainMenuClass.cpp @@ -123,6 +123,67 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI } } break; + case ID_FILE_DISK: + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImageIPL(IPLROM.c_str()))) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunFileImageIPL(FileName); + // Open Disk + openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; + if (GetOpenFileName(&openfilename)) + { + if (g_BaseSystem->RunDiskImage(FileName)) + g_BaseSystem->RunFileImage(g_Settings->LoadStringVal(File_DiskIPLPath).c_str()); + } + } + } + else + { + // Open Disk + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + if (g_BaseSystem->RunDiskImage(FileName)) + g_BaseSystem->RunFileImage(g_Settings->LoadStringVal(File_DiskIPLPath).c_str()); + } + } + } + break; case ID_FILE_ROM_INFO: { if (g_Rom) @@ -691,6 +752,8 @@ void CMainMenu::FillOutMenu(HMENU hMenu) MenuItemList FileMenu; Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, m_ShortCuts.ShortCutString(ID_FILE_OPEN_ROM, AccessLevel)); FileMenu.push_back(Item); + Item.Reset(ID_FILE_DISK, MENU_DISK, m_ShortCuts.ShortCutString(ID_FILE_DISK, AccessLevel)); + FileMenu.push_back(Item); if (!inBasicMode) { Item.Reset(ID_FILE_ROM_INFO, MENU_ROM_INFO, m_ShortCuts.ShortCutString(ID_FILE_ROM_INFO, AccessLevel)); diff --git a/Source/Project64/UserInterface/MainMenuClass.h b/Source/Project64/UserInterface/MainMenuClass.h index dafda79c5..32540c725 100644 --- a/Source/Project64/UserInterface/MainMenuClass.h +++ b/Source/Project64/UserInterface/MainMenuClass.h @@ -4,7 +4,7 @@ enum MainMenuID { //File Menu ID_FILE_OPEN_ROM = 4000, ID_FILE_ROM_INFO, ID_FILE_STARTEMULATION, ID_FILE_ENDEMULATION, - ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, + ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, ID_FILE_DISK, //language ID_LANG_START, ID_LANG_END = ID_LANG_START + 100, From 96a6862c80dc8f2cfc987b809b97c539dc578edd Mon Sep 17 00:00:00 2001 From: luigiblood Date: Tue, 26 Jan 2016 03:04:48 +0100 Subject: [PATCH 09/12] Use Open ROM to open Disk instead It's a much better idea anyway. --- Source/Project64-core/Multilanguage.h | 1 - .../Multilanguage/LanguageClass.cpp | 1 - .../Project64/UserInterface/MainMenuClass.cpp | 100 +++++++----------- .../Project64/UserInterface/MainMenuClass.h | 2 +- 4 files changed, 40 insertions(+), 64 deletions(-) diff --git a/Source/Project64-core/Multilanguage.h b/Source/Project64-core/Multilanguage.h index f3d8ab7f7..64bf79658 100644 --- a/Source/Project64-core/Multilanguage.h +++ b/Source/Project64-core/Multilanguage.h @@ -63,7 +63,6 @@ enum LanguageStringID{ MENU_RECENT_ROM = 107, MENU_RECENT_DIR = 108, MENU_EXIT = 109, - MENU_DISK = 110, //System Menu MENU_SYSTEM = 120, diff --git a/Source/Project64-core/Multilanguage/LanguageClass.cpp b/Source/Project64-core/Multilanguage/LanguageClass.cpp index 50a4b34c1..861c1f186 100644 --- a/Source/Project64-core/Multilanguage/LanguageClass.cpp +++ b/Source/Project64-core/Multilanguage/LanguageClass.cpp @@ -71,7 +71,6 @@ void CLanguage::LoadDefaultStrings(void) DEF_STR(MENU_RECENT_ROM, "Recent ROM"); DEF_STR(MENU_RECENT_DIR, "Recent ROM Directories"); DEF_STR(MENU_EXIT, "E&xit"); - DEF_STR(MENU_DISK, "Open Disk"); //System Menu DEF_STR(MENU_SYSTEM, "&System"); diff --git a/Source/Project64/UserInterface/MainMenuClass.cpp b/Source/Project64/UserInterface/MainMenuClass.cpp index 0ad307fa5..cefc90b03 100644 --- a/Source/Project64/UserInterface/MainMenuClass.cpp +++ b/Source/Project64/UserInterface/MainMenuClass.cpp @@ -92,7 +92,7 @@ stdstr CMainMenu::ChooseFileToOpen(HWND hParent) openfilename.lStructSize = sizeof(openfilename); openfilename.hwndOwner = (HWND)hParent; - openfilename.lpstrFilter = "N64 ROMs (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFilter = "N64 ROMs (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin, *.ndd)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal;*.ndd\0All files (*.*)\0*.*\0"; openfilename.lpstrFile = FileName; openfilename.lpstrInitialDir = Directory; openfilename.nMaxFile = MAX_PATH; @@ -119,67 +119,47 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI stdstr File = ChooseFileToOpen(hWnd); if (File.length() > 0) { - g_BaseSystem->RunFileImage(File.c_str()); - } - } - break; - case ID_FILE_DISK: - { - stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); - if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImageIPL(IPLROM.c_str()))) - { - // Open DDROM - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) + stdstr Test = File.substr(File.length() - 3, 4); + Test.ToLower(); + if (!Test.compare(".ndd")) { - g_BaseSystem->RunFileImageIPL(FileName); - // Open Disk - openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; - if (GetOpenFileName(&openfilename)) - { - if (g_BaseSystem->RunDiskImage(FileName)) - g_BaseSystem->RunFileImage(g_Settings->LoadStringVal(File_DiskIPLPath).c_str()); - } + g_BaseSystem->RunFileImage(File.c_str()); } - } - else - { - // Open Disk - OPENFILENAME openfilename; - char FileName[_MAX_PATH], Directory[_MAX_PATH]; - - memset(&FileName, 0, sizeof(FileName)); - memset(&openfilename, 0, sizeof(openfilename)); - - strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - - openfilename.lStructSize = sizeof(openfilename); - openfilename.hwndOwner = (HWND)hWnd; - openfilename.lpstrFilter = "N64DD Disk Image (*.ndd)\0*.ndd\0All files (*.*)\0*.*\0"; - openfilename.lpstrFile = FileName; - openfilename.lpstrInitialDir = Directory; - openfilename.nMaxFile = MAX_PATH; - openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - - if (GetOpenFileName(&openfilename)) + else { - if (g_BaseSystem->RunDiskImage(FileName)) - g_BaseSystem->RunFileImage(g_Settings->LoadStringVal(File_DiskIPLPath).c_str()); + // Open Disk + if (g_BaseSystem->RunDiskImage(File.c_str())) + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!g_BaseSystem->RunFileImage(IPLROM.c_str()))) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + g_BaseSystem->RunFileImage(FileName); + } + } + else + { + g_BaseSystem->RunFileImage(IPLROM.c_str()); + } + } } } } @@ -752,8 +732,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu) MenuItemList FileMenu; Item.Reset(ID_FILE_OPEN_ROM, MENU_OPEN, m_ShortCuts.ShortCutString(ID_FILE_OPEN_ROM, AccessLevel)); FileMenu.push_back(Item); - Item.Reset(ID_FILE_DISK, MENU_DISK, m_ShortCuts.ShortCutString(ID_FILE_DISK, AccessLevel)); - FileMenu.push_back(Item); if (!inBasicMode) { Item.Reset(ID_FILE_ROM_INFO, MENU_ROM_INFO, m_ShortCuts.ShortCutString(ID_FILE_ROM_INFO, AccessLevel)); diff --git a/Source/Project64/UserInterface/MainMenuClass.h b/Source/Project64/UserInterface/MainMenuClass.h index 32540c725..dafda79c5 100644 --- a/Source/Project64/UserInterface/MainMenuClass.h +++ b/Source/Project64/UserInterface/MainMenuClass.h @@ -4,7 +4,7 @@ enum MainMenuID { //File Menu ID_FILE_OPEN_ROM = 4000, ID_FILE_ROM_INFO, ID_FILE_STARTEMULATION, ID_FILE_ENDEMULATION, - ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, ID_FILE_DISK, + ID_FILE_ROMDIRECTORY, ID_FILE_REFRESHROMLIST, ID_FILE_EXIT, //language ID_LANG_START, ID_LANG_END = ID_LANG_START + 100, From 226c29d5c7dd54f31477103d83a2bbccf8501a9e Mon Sep 17 00:00:00 2001 From: luigiblood Date: Tue, 26 Jan 2016 15:31:24 +0100 Subject: [PATCH 10/12] Disk Conversion support, AppCleanup() update There's still a problem with Open ROM but other than that it's fully functional. --- Source/Project64-core/AppInit.cpp | 29 +-- Source/Project64-core/N64System/N64Class.cpp | 6 + .../Project64-core/N64System/N64DiskClass.cpp | 218 ++++++++++++++++-- .../Project64-core/N64System/N64DiskClass.h | 12 +- .../Project64/UserInterface/MainMenuClass.cpp | 15 +- 5 files changed, 231 insertions(+), 49 deletions(-) diff --git a/Source/Project64-core/AppInit.cpp b/Source/Project64-core/AppInit.cpp index 0b62fdfac..ae9c63e9e 100644 --- a/Source/Project64-core/AppInit.cpp +++ b/Source/Project64-core/AppInit.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "Settings/SettingType/SettingsType-Application.h" static void FixDirectories(void); @@ -152,8 +153,8 @@ void TraceDone(void) const char * AppName ( void ) { - static stdstr_f ApplicationName("Project64 %s", VER_FILE_VERSION_STR); - return ApplicationName.c_str(); + static stdstr_f ApplicationName("Project64 %s", VER_FILE_VERSION_STR); + return ApplicationName.c_str(); } static bool ParseCommand(int32_t argc, char **argv) @@ -168,8 +169,8 @@ static bool ParseCommand(int32_t argc, char **argv) if (strcmp(argv[i], "--basedir") == 0 && ArgsLeft >= 1) { g_Settings->SaveString(Cmd_BaseDirectory, argv[i + 1]); - CSettingTypeApplication::Initialize(AppName()); - i++; + CSettingTypeApplication::Initialize(AppName()); + i++; } else if (strcmp(argv[i], "--help") == 0) { @@ -195,11 +196,11 @@ bool AppInit(CNotification * Notify, int argc, char **argv) { g_Notify = Notify; InitializeLog(); - if (Notify == NULL) - { - WriteTrace(TraceAppInit, TraceError, "No Notification class passed"); - return false; - } + if (Notify == NULL) + { + WriteTrace(TraceAppInit, TraceError, "No Notification class passed"); + return false; + } g_Settings = new CSettings; g_Settings->Initialize(AppName()); @@ -232,14 +233,14 @@ bool AppInit(CNotification * Notify, int argc, char **argv) g_Lang = new CLanguage(); g_Lang->LoadCurrentStrings(); g_Notify->AppInitDone(); - WriteTrace(TraceAppInit, TraceDebug, "Initialized Successfully"); - return true; + WriteTrace(TraceAppInit, TraceDebug, "Initialized Successfully"); + return true; } catch (...) { g_Notify->DisplayError(stdstr_f("Exception caught\nFile: %s\nLine: %d", __FILE__, __LINE__).c_str()); - WriteTrace(TraceAppInit, TraceError, "Exception caught, Init was not successfull"); - return false; + WriteTrace(TraceAppInit, TraceError, "Exception caught, Init was not successfull"); + return false; } } @@ -249,6 +250,8 @@ void AppCleanup(void) CleanupTrace(); if (g_Rom) { delete g_Rom; g_Rom = NULL; } + if (g_DDRom) { delete g_DDRom; g_DDRom = NULL; } + if (g_Disk) { delete g_Disk; g_Disk = NULL; } if (g_Plugins) { delete g_Plugins; g_Plugins = NULL; } if (g_Settings) { delete g_Settings; g_Settings = NULL; } if (g_Lang) { delete g_Lang; g_Lang = NULL; } diff --git a/Source/Project64-core/N64System/N64Class.cpp b/Source/Project64-core/N64System/N64Class.cpp index c8196ac77..152d54ad2 100644 --- a/Source/Project64-core/N64System/N64Class.cpp +++ b/Source/Project64-core/N64System/N64Class.cpp @@ -189,6 +189,7 @@ void CN64System::ExternalEvent(SystemEvent action) bool CN64System::RunFileImage(const char * FileLoc) { CloseSystem(); + g_Settings->SaveBool(Setting_EnableDisk, false); if (g_Settings->LoadBool(GameRunning_LoadingInProgress)) { return false; @@ -220,6 +221,11 @@ bool CN64System::RunFileImage(const char * FileLoc) g_Settings->SaveString(File_DiskIPLPath, FileLoc); } + if (g_DDRom != NULL) + { + g_Settings->SaveBool(Setting_EnableDisk, true); + } + g_System->RefreshGameSettings(); g_Settings->SaveString(Game_File, FileLoc); diff --git a/Source/Project64-core/N64System/N64DiskClass.cpp b/Source/Project64-core/N64System/N64DiskClass.cpp index 2a25ceca8..321d75929 100644 --- a/Source/Project64-core/N64System/N64DiskClass.cpp +++ b/Source/Project64-core/N64System/N64DiskClass.cpp @@ -97,40 +97,69 @@ bool CN64Disk::AllocateAndLoadDiskImage(const char * FileLoc) uint32_t DiskFileSize = m_DiskFile.GetLength(); WriteTrace(TraceN64System, TraceDebug, "Successfully Opened, size: 0x%X", DiskFileSize); - if (!AllocateDiskImage(DiskFileSize)) + //Check Disk File Format + if (DiskFileSize == MameFormatSize) { - m_DiskFile.Close(); - return false; - } + //If Disk is MAME Format (size is constant, it should be the same for every file), then continue + WriteTrace(TraceN64System, TraceDebug, "Disk File is MAME Format", ); - //Load the n64 disk to the allocated memory - g_Notify->DisplayMessage(5, MSG_LOADING); - m_DiskFile.SeekToBegin(); + if (!AllocateDiskImage(DiskFileSize)) + { + m_DiskFile.Close(); + return false; + } - uint32_t count, TotalRead = 0; - for (count = 0; count < (int)DiskFileSize; count += ReadFromRomSection) - { - uint32_t dwToRead = DiskFileSize - count; - if (dwToRead > ReadFromRomSection) { dwToRead = ReadFromRomSection; } + //Load the n64 disk to the allocated memory + g_Notify->DisplayMessage(5, MSG_LOADING); + m_DiskFile.SeekToBegin(); - if (m_DiskFile.Read(&m_DiskImage[count], dwToRead) != dwToRead) + 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, "Failed to read file (TotalRead: 0x%X)", TotalRead); + WriteTrace(TraceN64System, TraceError, "Expected to read: 0x%X, read: 0x%X", TotalRead, DiskFileSize); 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) + else if (DiskFileSize == SDKFormatSize) { + //If Disk is SDK format (made with SDK based dumpers like LuigiBlood's, or Nintendo's, size is also constant) + //We need to convert it. + g_Notify->DisplayMessage(5, MSG_LOADING); + + //Allocate supported size + if (!AllocateDiskImage(MameFormatSize)) + { + m_DiskFile.Close(); + return false; + } + + ConvertDiskFormat(); + } + else + { + //Else the disk file is invalid m_DiskFile.Close(); - SetError(MSG_FAIL_IMAGE); - WriteTrace(TraceN64System, TraceError, "Expected to read: 0x%X, read: 0x%X", TotalRead, DiskFileSize); + WriteTrace(TraceN64System, TraceError, "Disk File is invalid, unexpected size"); return false; } @@ -180,4 +209,149 @@ void CN64Disk::UnallocateDiskImage() m_DiskImageBase = NULL; } m_DiskImage = NULL; +} + +void CN64Disk::ConvertDiskFormat() +{ + //Original code by Happy_ + m_DiskFile.SeekToBegin(); + + const uint32_t ZoneSecSize[16] = { 232, 216, 208, 192, 176, 160, 144, 128, + 216, 208, 192, 176, 160, 144, 128, 112 }; + const uint32_t ZoneTracks[16] = { 158, 158, 149, 149, 149, 149, 149, 114, + 158, 158, 149, 149, 149, 149, 149, 114 }; + const uint32_t DiskTypeZones[7][16] = { + { 0, 1, 2, 9, 8, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10 }, + { 0, 1, 2, 3, 10, 9, 8, 4, 5, 6, 7, 15, 14, 13, 12, 11 }, + { 0, 1, 2, 3, 4, 11, 10, 9, 8, 5, 6, 7, 15, 14, 13, 12 }, + { 0, 1, 2, 3, 4, 5, 12, 11, 10, 9, 8, 6, 7, 15, 14, 13 }, + { 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 } + }; + const uint32_t RevDiskTypeZones[7][16] = { + { 0, 1, 2, 5, 6, 7, 8, 9, 4, 3, 15, 14, 13, 12, 11, 10 }, + { 0, 1, 2, 3, 7, 8, 9, 10, 6, 5, 4, 15, 14, 13, 12, 11 }, + { 0, 1, 2, 3, 4, 9, 10, 11, 8, 7, 6, 5, 15, 14, 13, 12 }, + { 0, 1, 2, 3, 4, 5, 11, 12, 10, 9, 8, 7, 6, 15, 14, 13 }, + { 0, 1, 2, 3, 4, 5, 6, 13, 12, 11, 10, 9, 8, 7, 15, 14 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8 } + }; + const uint32_t StartBlock[7][16] = { + { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1 }, + { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 }, + { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1 }, + { 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0 }, + { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 }, + { 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, + { 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 } + }; + + uint32_t disktype = 0; + uint32_t zone, track = 0; + int32_t atrack = 0; + int32_t block = 0; + uint8_t SystemData[0xE8]; + uint8_t BlockData0[0x100 * SECTORS_PER_BLOCK]; + uint8_t BlockData1[0x100 * SECTORS_PER_BLOCK]; + uint32_t InOffset, OutOffset = 0; + uint32_t InStart[16]; + uint32_t OutStart[16]; + + InStart[0] = 0; + OutStart[0] = 0; + + //Read System Area + m_DiskFile.Read(&SystemData, 0xE8); + + disktype = SystemData[5] & 0xF; + + //Prepare Input Offsets + for (zone = 1; zone < 16; zone++) + { + InStart[zone] = InStart[zone - 1] + + VZONESIZE(DiskTypeZones[disktype][zone - 1]); + } + + //Prepare Output Offsets + for (zone = 1; zone < 16; zone++) + { + OutStart[zone] = OutStart[zone - 1] + ZONESIZE(zone - 1); + } + + //Copy Head 0 + for (zone = 0; zone < 8; zone++) + { + OutOffset = OutStart[zone]; + InOffset = InStart[RevDiskTypeZones[disktype][zone]]; + m_DiskFile.Seek(InOffset, CFileBase::SeekPosition::begin); + block = StartBlock[disktype][zone]; + atrack = 0; + for (track = 0; track < ZoneTracks[zone]; track++) + { + if (track == SystemData[0x20 + zone * 0xC + atrack]) + { + memset((void *)(&BlockData0), 0, BLOCKSIZE(zone)); + memset((void *)(&BlockData1), 0, BLOCKSIZE(zone)); + atrack += 1; + } + else + { + if ((block % 2) == 1) + { + m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); + m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); + } + else + { + m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); + m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); + } + block = 1 - block; + } + memcpy(m_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone)); + OutOffset += BLOCKSIZE(zone); + memcpy(m_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone)); + OutOffset += BLOCKSIZE(zone); + } + } + + //Copy Head 1 + for (zone = 8; zone < 16; zone++) + { + //OutOffset = OutStart[zone]; + InOffset = InStart[RevDiskTypeZones[disktype][zone]]; + m_DiskFile.Seek(InOffset, CFileBase::SeekPosition::begin); + block = StartBlock[disktype][zone]; + atrack = 0xB; + for (track = 1; track < ZoneTracks[zone] + 1; track++) + { + if ((ZoneTracks[zone] - track) == SystemData[0x20 + (zone)* 0xC + atrack]) + { + memset((void *)(&BlockData0), 0, BLOCKSIZE(zone)); + memset((void *)(&BlockData1), 0, BLOCKSIZE(zone)); + atrack -= 1; + } + else + { + if ((block % 2) == 1) + { + m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); + m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); + } + else + { + m_DiskFile.Read(&BlockData0, BLOCKSIZE(zone)); + m_DiskFile.Read(&BlockData1, BLOCKSIZE(zone)); + } + block = 1 - block; + } + OutOffset = OutStart[zone] + (ZoneTracks[zone] - track) * TRACKSIZE(zone); + memcpy(m_DiskImage + OutOffset, &BlockData0, BLOCKSIZE(zone)); + OutOffset += BLOCKSIZE(zone); + memcpy(m_DiskImage + OutOffset, &BlockData1, BLOCKSIZE(zone)); + OutOffset += BLOCKSIZE(zone); + } + } } \ No newline at end of file diff --git a/Source/Project64-core/N64System/N64DiskClass.h b/Source/Project64-core/N64System/N64DiskClass.h index 36a440e74..2b3938966 100644 --- a/Source/Project64-core/N64System/N64DiskClass.h +++ b/Source/Project64-core/N64System/N64DiskClass.h @@ -31,9 +31,10 @@ private: bool AllocateAndLoadDiskImage(const char * FileLoc); void ByteSwapDisk(); void SetError(LanguageStringID ErrorMsg); + void ConvertDiskFormat(); //constant values - enum { ReadFromRomSection = 0x400000 }; + enum { ReadFromRomSection = 0x400000, MameFormatSize = 0x0435B0C0, SDKFormatSize = 0x03DEC800 }; //class variables CFile m_DiskFile; @@ -43,4 +44,13 @@ private: uint32_t m_DiskBufAddress; LanguageStringID m_ErrorMsg; stdstr m_FileName, m_DiskIdent; + + //disk convert + #define SECTORS_PER_BLOCK 85 + #define BLOCKS_PER_TRACK 2 + + #define BLOCKSIZE(_zone) ZoneSecSize[_zone] * SECTORS_PER_BLOCK + #define TRACKSIZE(_zone) BLOCKSIZE(_zone) * BLOCKS_PER_TRACK + #define ZONESIZE(_zone) TRACKSIZE(_zone) * ZoneTracks[_zone] + #define VZONESIZE(_zone) TRACKSIZE(_zone) * (ZoneTracks[_zone] - 0xC) }; \ No newline at end of file diff --git a/Source/Project64/UserInterface/MainMenuClass.cpp b/Source/Project64/UserInterface/MainMenuClass.cpp index cefc90b03..f4321443d 100644 --- a/Source/Project64/UserInterface/MainMenuClass.cpp +++ b/Source/Project64/UserInterface/MainMenuClass.cpp @@ -119,13 +119,7 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI stdstr File = ChooseFileToOpen(hWnd); if (File.length() > 0) { - stdstr Test = File.substr(File.length() - 3, 4); - Test.ToLower(); - if (!Test.compare(".ndd")) - { - g_BaseSystem->RunFileImage(File.c_str()); - } - else + if (!g_BaseSystem->RunFileImage(File.c_str())) { // Open Disk if (g_BaseSystem->RunDiskImage(File.c_str())) @@ -136,12 +130,10 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI // Open DDROM OPENFILENAME openfilename; char FileName[_MAX_PATH], Directory[_MAX_PATH]; - memset(&FileName, 0, sizeof(FileName)); memset(&openfilename, 0, sizeof(openfilename)); strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); - openfilename.lStructSize = sizeof(openfilename); openfilename.hwndOwner = (HWND)hWnd; openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; @@ -155,12 +147,9 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI g_BaseSystem->RunFileImage(FileName); } } - else - { - g_BaseSystem->RunFileImage(IPLROM.c_str()); - } } } + } } break; From 7c468bd624ad9e98a7e3e36c21fad77b9021eae7 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Tue, 26 Jan 2016 15:55:30 +0100 Subject: [PATCH 11/12] Drag & Drop 64DD Disk support --- Source/Project64/UserInterface/GuiClass.cpp | 31 ++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Source/Project64/UserInterface/GuiClass.cpp b/Source/Project64/UserInterface/GuiClass.cpp index 0239207d9..288e03147 100644 --- a/Source/Project64/UserInterface/GuiClass.cpp +++ b/Source/Project64/UserInterface/GuiClass.cpp @@ -1142,7 +1142,36 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO DragQueryFile(hDrop, 0, filename, sizeof(filename)); DragFinish(hDrop); - CN64System::RunFileImage(filename); + if (!CN64System::RunFileImage(filename)) + { + // Open Disk + if (CN64System::RunDiskImage(filename)) + { + stdstr IPLROM = g_Settings->LoadStringVal(File_DiskIPLPath); + if ((IPLROM.length() <= 0) || (!CN64System::RunFileImage(IPLROM.c_str()))) + { + // Open DDROM + OPENFILENAME openfilename; + char FileName[_MAX_PATH], Directory[_MAX_PATH]; + memset(&FileName, 0, sizeof(FileName)); + memset(&openfilename, 0, sizeof(openfilename)); + + strcpy(Directory, g_Settings->LoadStringVal(Directory_Game).c_str()); + openfilename.lStructSize = sizeof(openfilename); + openfilename.hwndOwner = (HWND)hWnd; + openfilename.lpstrFilter = "64DD IPL ROM Image (*.zip, *.7z, *.?64, *.rom, *.usa, *.jap, *.pal, *.bin)\0*.?64;*.zip;*.7z;*.bin;*.rom;*.usa;*.jap;*.pal\0All files (*.*)\0*.*\0"; + openfilename.lpstrFile = FileName; + openfilename.lpstrInitialDir = Directory; + openfilename.nMaxFile = MAX_PATH; + openfilename.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + + if (GetOpenFileName(&openfilename)) + { + CN64System::RunFileImage(FileName); + } + } + } + } } break; case WM_DESTROY: From 4bf95e61f1af92b351323ac2e5ea1321a5a7b9f8 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Tue, 26 Jan 2016 16:43:44 +0100 Subject: [PATCH 12/12] Open ROM/Drag&Drop Error fixed, delete g_DDRom if normal N64 ROM play --- Source/Project64/UserInterface/GuiClass.cpp | 9 ++++++++- Source/Project64/UserInterface/MainMenuClass.cpp | 9 ++++++++- Source/Project64/UserInterface/RomBrowserClass.cpp | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Source/Project64/UserInterface/GuiClass.cpp b/Source/Project64/UserInterface/GuiClass.cpp index 288e03147..018d4d1c4 100644 --- a/Source/Project64/UserInterface/GuiClass.cpp +++ b/Source/Project64/UserInterface/GuiClass.cpp @@ -1142,7 +1142,14 @@ LRESULT CALLBACK CMainGui::MainGui_Proc(HWND hWnd, DWORD uMsg, DWORD wParam, DWO DragQueryFile(hDrop, 0, filename, sizeof(filename)); DragFinish(hDrop); - if (!CN64System::RunFileImage(filename)) + stdstr ext = CPath(filename).GetExtension(); + if (!(_stricmp(ext.c_str(), "ndd") == 0)) + { + delete g_DDRom; + g_DDRom = NULL; + CN64System::RunFileImage(filename); + } + else { // Open Disk if (CN64System::RunDiskImage(filename)) diff --git a/Source/Project64/UserInterface/MainMenuClass.cpp b/Source/Project64/UserInterface/MainMenuClass.cpp index f4321443d..9cd63e182 100644 --- a/Source/Project64/UserInterface/MainMenuClass.cpp +++ b/Source/Project64/UserInterface/MainMenuClass.cpp @@ -119,7 +119,14 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI stdstr File = ChooseFileToOpen(hWnd); if (File.length() > 0) { - if (!g_BaseSystem->RunFileImage(File.c_str())) + stdstr ext = CPath(File).GetExtension(); + if (!(_stricmp(ext.c_str(), "ndd") == 0)) + { + delete g_DDRom; + g_DDRom = NULL; + g_BaseSystem->RunFileImage(File.c_str()); + } + else { // Open Disk if (g_BaseSystem->RunDiskImage(File.c_str())) diff --git a/Source/Project64/UserInterface/RomBrowserClass.cpp b/Source/Project64/UserInterface/RomBrowserClass.cpp index d01abf1d5..735072bdb 100644 --- a/Source/Project64/UserInterface/RomBrowserClass.cpp +++ b/Source/Project64/UserInterface/RomBrowserClass.cpp @@ -1472,6 +1472,10 @@ void CRomBrowser::RomList_OpenRom(uint32_t /*pnmh*/) if (!pRomInfo) { return; } m_StopRefresh = true; + + delete g_DDRom; + g_DDRom = NULL; + CN64System::RunFileImage(pRomInfo->szFullFileName); }