64DD Sector Read working

This commit is contained in:
luigiblood 2016-01-20 17:43:23 +01:00
parent 002cb7f5ce
commit 0501eb70da
6 changed files with 75 additions and 62 deletions

View File

@ -18,6 +18,7 @@
bool dd_write; bool dd_write;
bool dd_reset_hold; bool dd_reset_hold;
uint32_t dd_track_offset, dd_zone; uint32_t dd_track_offset, dd_zone;
uint32_t dd_start_block, dd_current;
uint8_t dd_buffer[0x100]; uint8_t dd_buffer[0x100];
@ -61,11 +62,13 @@ void DiskCommand()
case 0x00010000: case 0x00010000:
//Seek Read //Seek Read
g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000;
DiskSetOffset();
dd_write = false; dd_write = false;
break; break;
case 0x00020000: case 0x00020000:
//Seek Write //Seek Write
g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000;
DiskSetOffset();
dd_write = true; dd_write = true;
break; break;
case 0x00080000: case 0x00080000:
@ -98,16 +101,18 @@ void DiskReset(void)
void DiskBMControl(void) void DiskBMControl(void)
{ {
g_Reg->ASIC_CUR_SECTOR = g_Reg->ASIC_BM_CTL & 0x00FF0000; g_Reg->ASIC_CUR_SECTOR = g_Reg->ASIC_BM_CTL & 0x00FF0000;
/*
if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x00) if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x00)
{ {
dd_start_block = 0;
dd_current = 0;
} }
else if ((g_Reg->ASIC_CUR_SECTOR >> 16) == 0x5A) 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) if (g_Reg->ASIC_BM_CTL & DD_BM_CTL_BLK_TRANS)
g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_BLOCK; 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_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_BM_STATUS = 0;
g_Reg->ASIC_CUR_SECTOR = 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)) 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) if (g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)
{ {
uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); if (SECTORS_PER_BLOCK < dd_current)
if (testsector >= 0x5A)
testsector -= 0x5A;
if (SECTORS_PER_BLOCK < testsector)
{ {
g_Reg->ASIC_STATUS &= ~DD_STATUS_BM_INT; g_Reg->ASIC_STATUS &= ~DD_STATUS_BM_INT;
g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3; g_Reg->FAKE_CAUSE_REGISTER &= ~CAUSE_IP3;
@ -156,40 +159,44 @@ void DiskBMUpdate()
{ {
if (!(g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_RUNNING)) if (!(g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_RUNNING))
return; return;
/*
uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16); uint16_t testsector = (uint16_t)(g_Reg->ASIC_CUR_SECTOR >> 16);
if (testsector >= 0x5A) if (testsector >= 0x5A)
testsector -= 0x5A; testsector -= 0x5A;
*/
if (dd_write) if (dd_write)
{ {
//Write Data //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; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
} }
else if (testsector < SECTORS_PER_BLOCK) else if (dd_current < SECTORS_PER_BLOCK)
{ {
DiskBMWrite(); DiskBMWrite();
g_Reg->ASIC_CUR_SECTOR += 0x00010000; dd_current += 1;
//g_Reg->ASIC_CUR_SECTOR += 0x00010000;
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; 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) if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK)
{ {
DiskBMWrite(); DiskBMWrite();
g_Reg->ASIC_CUR_SECTOR += 0x00010000; dd_current += 1;
if (g_Reg->ASIC_CUR_SECTOR >> 16 >= 0xB4) //g_Reg->ASIC_CUR_SECTOR += 0x00010000;
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_BM_STATUS &= ~DD_BM_STATUS_BLOCK;
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
} }
else else
{ {
DiskBMWrite(); 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; 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_STATUS &= ~DD_STATUS_DATA_RQ;
g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO; g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO;
} }
else if (testsector == 0) else if (dd_current == 0)
{ {
DiskBMRead(); DiskBMRead();
g_Reg->ASIC_CUR_SECTOR += 0x00010000; dd_current += 1;
//g_Reg->ASIC_CUR_SECTOR += 0x00010000;
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; 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!) //READ C2 (00!)
g_Reg->ASIC_CUR_SECTOR += 0x00010000; dd_current += 1;
if ((g_Reg->ASIC_CUR_SECTOR >> 16) == SECTORS_PER_BLOCK + 4) //g_Reg->ASIC_CUR_SECTOR += 0x00010000;
if (dd_current == SECTORS_PER_BLOCK + 4)
g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER; 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_BM_STATUS & DD_BM_STATUS_BLOCK)
{ {
if (g_Reg->ASIC_CUR_SECTOR >> 16 >= 0xB4) dd_start_block = 1 - dd_start_block;
g_Reg->ASIC_CUR_SECTOR = 0x00000000; dd_current = 0;
g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK; g_Reg->ASIC_BM_STATUS &= ~DD_BM_STATUS_BLOCK;
} }
else else
@ -242,41 +251,34 @@ void DiskBMUpdate()
void DiskBMRead() void DiskBMRead()
{ {
uint8_t * sector; uint32_t sector = 0;
sector = (uint8_t*)g_Disk->GetDiskAddress(); //sector = (uint8_t*)g_Disk->GetDiskAddress();
sector += dd_track_offset; sector += dd_track_offset;
uint16_t block = 0; sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone];
if (g_Reg->ASIC_CUR_SECTOR >= 0x005A0000) sector += (dd_current) * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1);
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);
g_Disk->SetDiskAddressBuffer(sector);
/*
for (int i = 0; i < ((g_Reg->ASIC_SEC_BYTE >> 16) + 1) / 4; i++) 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 | dd_buffer[i] = sector[(i * 4 + 0)] << 24 | sector[(i * 4 + 1)] << 16 |
sector[(i * 4 + 2)] << 8 | sector[(i * 4 + 3)]; sector[(i * 4 + 2)] << 8 | sector[(i * 4 + 3)];
} }
*/
return; return;
} }
void DiskBMWrite() void DiskBMWrite()
{ {
uint8_t * sector; uint32_t sector = 0;
sector = (uint8_t*)g_Disk->GetDiskAddress(); //sector = (uint8_t*)g_Disk->GetDiskAddress();
sector += dd_track_offset; sector += dd_track_offset;
uint16_t block = 0; sector += dd_start_block * SECTORS_PER_BLOCK * ddZoneSecSize[dd_zone];
if (g_Reg->ASIC_CUR_SECTOR >= 0x005A0000) sector += (dd_current - 1) * ((g_Reg->ASIC_SEC_BYTE >> 16) + 1);
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);
g_Disk->SetDiskAddressBuffer(sector);
/*
for (int i = 0; i < ddZoneSecSize[dd_zone] / 4; i++) for (int i = 0; i < ddZoneSecSize[dd_zone] / 4; i++)
{ {
sector[i * 4 + 0] = (dd_buffer[i] >> 24) & 0xFF; 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 + 2] = (dd_buffer[i] >> 8) & 0xFF;
sector[i * 4 + 3] = (dd_buffer[i] >> 0) & 0xFF; sector[i * 4 + 3] = (dd_buffer[i] >> 0) & 0xFF;
} }
*/
return; return;
} }

View File

@ -24,6 +24,7 @@ void DiskSetOffset(void);
extern bool dd_write; extern bool dd_write;
extern bool dd_reset_hold; extern bool dd_reset_hold;
extern uint32_t dd_track_offset, dd_zone; extern uint32_t dd_track_offset, dd_zone;
extern uint32_t dd_start_block, dd_current;
extern uint8_t dd_buffer[0x100]; extern uint8_t dd_buffer[0x100];

View File

@ -17,6 +17,7 @@
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h> #include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
#include <Project64-core/N64System/Mips/RegisterClass.h> #include <Project64-core/N64System/Mips/RegisterClass.h>
#include <Project64-core/N64System/Mips/Disk.h> #include <Project64-core/N64System/Mips/Disk.h>
#include <Project64-core/N64System/N64DiskClass.h>
#include <Project64-core/N64System/N64Class.h> #include <Project64-core/N64System/N64Class.h>
CDMA::CDMA(CFlashram & FlashRam, CSram & Sram) : CDMA::CDMA(CFlashram & FlashRam, CSram & Sram) :
@ -85,9 +86,10 @@ void CDMA::PI_DMA_READ()
//64DD User Sector //64DD User Sector
uint32_t i; uint32_t i;
uint8_t * RDRAM = g_MMU->Rdram(); uint8_t * RDRAM = g_MMU->Rdram();
uint8_t * DISK = g_Disk->GetDiskAddressBuffer();
for (i = 0; i < PI_RD_LEN_REG; i++) 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->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
g_Reg->MI_INTR_REG |= MI_INTR_PI; g_Reg->MI_INTR_REG |= MI_INTR_PI;
@ -238,9 +240,10 @@ void CDMA::PI_DMA_WRITE()
//64DD User Sector //64DD User Sector
uint32_t i; uint32_t i;
uint8_t * RDRAM = g_MMU->Rdram(); uint8_t * RDRAM = g_MMU->Rdram();
uint8_t * DISK = g_Disk->GetDiskAddressBuffer();
for (i = 0; i < PI_WR_LEN_REG; i++) 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->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
g_Reg->MI_INTR_REG |= MI_INTR_PI; g_Reg->MI_INTR_REG |= MI_INTR_PI;

View File

@ -217,17 +217,18 @@ bool CN64System::RunFileImage(const char * FileLoc)
{ {
//64DD IPL //64DD IPL
g_DDRom = g_Rom; g_DDRom = g_Rom;
}
if (g_Disk == NULL) if (g_Disk == NULL)
{ {
g_Disk = new CN64Disk(); g_Disk = new CN64Disk();
} }
if (!g_Disk->LoadDiskImage(g_Settings->LoadStringVal(SupportFile_DiskTest).c_str())); if (!g_Disk->LoadDiskImage(g_Settings->LoadStringVal(SupportFile_DiskTest).c_str()))
{ {
delete g_Disk; g_Notify->DisplayError(g_Disk->GetError());
g_Disk = NULL; delete g_Disk;
} g_Disk = NULL;
} }
g_System->RefreshGameSettings(); g_System->RefreshGameSettings();

View File

@ -18,7 +18,8 @@
CN64Disk::CN64Disk() : CN64Disk::CN64Disk() :
m_DiskImage(NULL), m_DiskImage(NULL),
m_DiskImageBase(NULL), m_DiskImageBase(NULL),
m_ErrorMsg(EMPTY_STRING) m_ErrorMsg(EMPTY_STRING),
m_DiskBufAddress(0)
{ {
} }

View File

@ -20,8 +20,12 @@ public:
bool LoadDiskImage(const char * FileLoc); bool LoadDiskImage(const char * FileLoc);
static bool IsValidDiskImage(uint8_t Test[4]); static bool IsValidDiskImage(uint8_t Test[4]);
uint8_t * GetDiskAddress() { return m_DiskImage; } uint8_t * GetDiskAddress() { return m_DiskImage; }
uint8_t * GetDiskAddressBuffer() { return m_DiskImage + m_DiskBufAddress; }
void SetDiskAddressBuffer(uint32_t address) { m_DiskBufAddress = address; }
void UnallocateDiskImage(); void UnallocateDiskImage();
LanguageStringID GetError() const { return m_ErrorMsg; }
private: private:
bool AllocateDiskImage(uint32_t DiskFileSize); bool AllocateDiskImage(uint32_t DiskFileSize);
bool AllocateAndLoadDiskImage(const char * FileLoc); bool AllocateAndLoadDiskImage(const char * FileLoc);
@ -36,6 +40,7 @@ private:
uint8_t * m_DiskImage; uint8_t * m_DiskImage;
uint8_t * m_DiskImageBase; uint8_t * m_DiskImageBase;
uint32_t m_DiskFileSize; uint32_t m_DiskFileSize;
uint32_t m_DiskBufAddress;
LanguageStringID m_ErrorMsg; LanguageStringID m_ErrorMsg;
stdstr m_FileName, m_DiskIdent; stdstr m_FileName, m_DiskIdent;
}; };