diff --git a/Source/Project64-core/N64System/Mips/Disk.cpp b/Source/Project64-core/N64System/Mips/Disk.cpp index b4354c2a6..5ac125965 100644 --- a/Source/Project64-core/N64System/Mips/Disk.cpp +++ b/Source/Project64-core/N64System/Mips/Disk.cpp @@ -62,23 +62,28 @@ void DiskCommand() uint8_t second = (uint8_t)(((result.tm_sec / 10) << 4) | (result.tm_sec % 10)); #endif + //Used for seek times + bool isSeek = false; + switch (cmd & 0xFFFF0000) { case 0x00010000: //Seek Read g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; dd_write = false; + isSeek = true; break; case 0x00020000: //Seek Write g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000; dd_write = true; + isSeek = true; break; case 0x00080000: //Unset Disk Changed Bit g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; break; case 0x00090000: - //Unset Reset Bit + //Unset Reset & Disk Changed bit Bit g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE; g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; //F-Zero X + Expansion Kit fix so it doesn't enable "swapping" at boot @@ -99,6 +104,19 @@ void DiskCommand() //Disk Inquiry g_Reg->ASIC_DATA = 0x00000000; break; } + + if (isSeek) + { + //Emulate Seek Times, send interrupt later + g_SystemTimer->SetTimer(g_SystemTimer->DDSeekTimer, 0x400000, false); + } + else + { + //Other commands are basically instant + g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT; + g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3; + g_Reg->CheckInterrupts(); + } } void DiskReset(void) @@ -157,6 +175,9 @@ void DiskBMControl(void) void DiskGapSectorCheck() { + //On 64DD Status Register Read + + //Buffer Manager Interrupt, Gap Sector Check if (g_Reg->ASIC_STATUS & DD_STATUS_BM_INT) { if (SECTORS_PER_BLOCK < dd_current) @@ -168,6 +189,7 @@ void DiskGapSectorCheck() } } + //Delay Disk Swapping by removing the disk for a certain amount of time, then insert the newly loaded disk (after 50 Status Register reads, here). if (!(g_Reg->ASIC_STATUS & DD_STATUS_DISK_PRES) && g_Disk != NULL && g_Settings->LoadBool(GameRunning_LoadingInProgress) == false) { dd_swapdelay++; @@ -190,12 +212,14 @@ void DiskBMUpdate() //Write Data if (dd_current < SECTORS_PER_BLOCK) { + //User Sector if (!DiskBMReadWrite(true)) g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; dd_current += 1; } else if (dd_current < SECTORS_PER_BLOCK + 1) { + //C2 Sector if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) { dd_start_block = 1 - dd_start_block; @@ -222,25 +246,27 @@ void DiskBMUpdate() //Read Data if (((g_Reg->ASIC_CUR_TK >> 16) & 0x1FFF) == 6 && g_Reg->ASIC_CUR_SECTOR == 0 && g_Disk->GetCountry() != Country::UnknownCountry) { - //Copy Protection + //Copy Protection if Retail Disk g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ; g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO; } else if (dd_current < SECTORS_PER_BLOCK) { + //User Sector if (!DiskBMReadWrite(false)) g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ; dd_current += 1; } else if (dd_current < SECTORS_PER_BLOCK + 4) { - //READ C2 (00!) + //C2 sectors (All 00s) dd_current += 1; if (dd_current == SECTORS_PER_BLOCK + 4) g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER; } else if (dd_current == SECTORS_PER_BLOCK + 4) { + //Gap Sector if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK) { dd_start_block = 1 - dd_start_block; diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index 9a713fd53..455444f4f 100755 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -2157,9 +2157,6 @@ void CMipsMemoryVM::Write32CartridgeDomain2Address1(void) case 0x05000508: g_Reg->ASIC_CMD = m_MemLookupValue.UW[0]; DiskCommand(); - g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT; - g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3; - g_Reg->CheckInterrupts(); break; case 0x05000510: //ASIC_BM_STATUS_CTL diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.cpp b/Source/Project64-core/N64System/Mips/SystemTiming.cpp index 9af409bd4..4602e16a5 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.cpp +++ b/Source/Project64-core/N64System/Mips/SystemTiming.cpp @@ -221,6 +221,16 @@ void CSystemTimer::TimerDone() m_Reg.MI_INTR_REG |= MI_INTR_PI; m_Reg.CheckInterrupts(); break; + case CSystemTimer::DDSeekTimer: + g_SystemTimer->StopTimer(CSystemTimer::DDSeekTimer); + g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT; + g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3; + g_Reg->CheckInterrupts(); + break; + case CSystemTimer::DDMotorTimer: + g_SystemTimer->StopTimer(CSystemTimer::DDMotorTimer); + g_Reg->ASIC_STATUS &= ~DD_STATUS_MTR_N_SPIN; + break; case CSystemTimer::ViTimer: try { diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.h b/Source/Project64-core/N64System/Mips/SystemTiming.h index d75c487d8..053a74534 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.h +++ b/Source/Project64-core/N64System/Mips/SystemTiming.h @@ -32,6 +32,8 @@ public: RspTimer, RSPTimerDlist, DDPiTimer, + DDSeekTimer, + DDMotorTimer, MaxTimer }; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 9e99a9d15..9f9220b22 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -11783,18 +11783,6 @@ void CX86RecompilerOps::SW_Register(x86Reg Reg, uint32_t VAddr) MoveX86regToVariable(Reg, &g_Reg->ASIC_CMD, "ASIC_CMD"); m_RegWorkingSet.BeforeCallDirect(); Call_Direct(AddressOf(&DiskCommand), "DiskCommand"); - m_RegWorkingSet.AfterCallDirect(); - OrConstToVariable((uint32_t)DD_STATUS_MECHA_INT, &g_Reg->ASIC_STATUS, "ASIC_STATUS"); - OrConstToVariable((uint32_t)CAUSE_IP3, &g_Reg->FAKE_CAUSE_REGISTER, "FAKE_CAUSE_REGISTER"); - m_RegWorkingSet.BeforeCallDirect(); -#ifdef _MSC_VER - MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); - Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); -#else - PushImm32((uint32_t)g_Reg); - Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); - AddConstToX86Reg(x86_ESP, 4); -#endif m_RegWorkingSet.AfterCallDirect(); break; }