From 002cb7f5ce17ac1ceae3871efe62d581593cd109 Mon Sep 17 00:00:00 2001 From: luigiblood Date: Wed, 20 Jan 2016 14:31:29 +0100 Subject: [PATCH] 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