64DD support tentative

This commit is contained in:
luigiblood 2016-01-20 14:31:29 +01:00
parent 25f56e6887
commit 002cb7f5ce
9 changed files with 559 additions and 194 deletions

View File

@ -10,75 +10,330 @@
****************************************************************************/
#pragma once
#include "stdafx.h"
#include "Disk.h"
#include <Project64-core/N64System/N64DiskClass.h>
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Mips/RegisterClass.h>
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(&ltime);
struct tm result = { 0 };
localtime_r(&ltime, &result);
time_t ltime;
ltime = time(&ltime);
struct tm result = { 0 };
localtime_r(&ltime, &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;
}

View File

@ -10,6 +10,30 @@
****************************************************************************/
#pragma once
#include <Common/stdtypes.h>
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

View File

@ -16,6 +16,7 @@
#include <Project64-core/N64System/N64RomClass.h>
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
#include <Project64-core/N64System/Mips/RegisterClass.h>
#include <Project64-core/N64System/Mips/Disk.h>
#include <Project64-core/N64System/N64Class.h>
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;

View File

@ -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;

View File

@ -16,6 +16,7 @@
#include <Project64-core/N64System/Mips/Mempak.H>
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
#include <Project64-core/N64System/Mips/OpcodeName.h>
#include <Project64-core/N64System/N64DiskClass.h>
#include <Project64-core/ExceptionHandler.h>
#include <Project64-core/Logging.h>
#include <Project64-core/Debugger.h>
@ -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();

View File

@ -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<uint8_t> 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<uint8_t> 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;
}

View File

@ -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;
};

View File

@ -48,6 +48,8 @@ enum SettingID
SupportFile_RomListCacheDefault,
SupportFile_7zipCache,
SupportFile_7zipCacheDefault,
//64DD TEST
SupportFile_DiskTest,
//Settings
Setting_ApplicationName,

View File

@ -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