From 00c24c2501af90c4e2b35476640bd32b190764ab Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 31 Mar 2020 22:28:48 +1000 Subject: [PATCH] CDROM: Adjust ACK timings to be closer to hardware test results Fixes Shrek Treasure Hunt. --- src/core/cdrom.cpp | 37 +++++++++++++++++++++++++++---------- src/core/cdrom.h | 3 ++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index a69376cad..7ffa00cb5 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -226,7 +226,7 @@ u8 CDROM::ReadRegister(u32 offset) switch (offset) { case 0: // status register - Log_TracePrintf("CDROM read status register <- 0x%08X", m_status.bits); + Log_TracePrintf("CDROM read status register -> 0x%08X", m_status.bits); return m_status.bits; case 1: // always response FIFO @@ -239,7 +239,7 @@ u8 CDROM::ReadRegister(u32 offset) const u8 value = m_response_fifo.Pop(); UpdateStatusRegister(); - Log_DebugPrintf("CDROM read response FIFO <- 0x%08X", ZeroExtend32(value)); + Log_DebugPrintf("CDROM read response FIFO -> 0x%08X", ZeroExtend32(value)); return value; } @@ -247,7 +247,7 @@ u8 CDROM::ReadRegister(u32 offset) { const u8 value = m_data_fifo.Pop(); UpdateStatusRegister(); - Log_DebugPrintf("CDROM read data FIFO <- 0x%08X", ZeroExtend32(value)); + Log_DebugPrintf("CDROM read data FIFO -> 0x%08X", ZeroExtend32(value)); return value; } @@ -256,13 +256,13 @@ u8 CDROM::ReadRegister(u32 offset) if (m_status.index & 1) { const u8 value = m_interrupt_flag_register | ~INTERRUPT_REGISTER_MASK; - Log_DebugPrintf("CDROM read interrupt flag register <- 0x%02X", ZeroExtend32(value)); + Log_DebugPrintf("CDROM read interrupt flag register -> 0x%02X", ZeroExtend32(value)); return value; } else { const u8 value = m_interrupt_enable_register | ~INTERRUPT_REGISTER_MASK; - Log_DebugPrintf("CDROM read interrupt enable register <- 0x%02X", ZeroExtend32(value)); + Log_DebugPrintf("CDROM read interrupt enable register -> 0x%02X", ZeroExtend32(value)); return value; } } @@ -293,7 +293,7 @@ void CDROM::WriteRegister(u32 offset, u8 value) if (HasPendingCommand()) { Log_WarningPrintf("Cancelling pending command 0x%02X", static_cast(m_command)); - m_command = Command::None; + AbortCommand(); } BeginCommand(static_cast(value)); @@ -516,10 +516,19 @@ void CDROM::UpdateInterruptRequest() m_interrupt_controller->InterruptRequest(InterruptController::IRQ::CDROM); } -TickCount CDROM::GetAckDelayForCommand() const +TickCount CDROM::GetAckDelayForCommand(Command command) const { - const u32 default_ack_delay = 10000; - return default_ack_delay; + if (command == Command::Init) + { + // Init takes longer. + return 120000; + } + + // Tests show that the average time to acknowledge a command is significantly higher when a disc is in the drive, + // presumably because the controller is busy doing discy-things. + constexpr u32 default_ack_delay_no_disc = 20000; + constexpr u32 default_ack_delay_with_disc = 30000; + return HasMedia() ? default_ack_delay_with_disc : default_ack_delay_no_disc; } TickCount CDROM::GetTicksForRead() const @@ -551,7 +560,7 @@ TickCount CDROM::GetTicksForSeek() const void CDROM::BeginCommand(Command command) { m_command = command; - m_command_event->Schedule(GetAckDelayForCommand()); + m_command_event->Schedule(GetAckDelayForCommand(command)); UpdateCommandEvent(); UpdateStatusRegister(); } @@ -565,6 +574,13 @@ void CDROM::EndCommand() UpdateStatusRegister(); } +void CDROM::AbortCommand() +{ + m_command = Command::None; + m_command_event->Deactivate(); + UpdateStatusRegister(); +} + void CDROM::ExecuteCommand() { Log_DevPrintf("CDROM executing command 0x%02X", ZeroExtend32(static_cast(m_command))); @@ -751,6 +767,7 @@ void CDROM::ExecuteCommand() case Command::Pause: { + // TODO: Should return an error if seeking. const bool was_reading = (m_drive_state == DriveState::Reading || m_drive_state == DriveState::Playing); const TickCount pause_time = was_reading ? (m_mode.double_speed ? 2000000 : 1000000) : 7000; Log_DebugPrintf("CDROM pause command"); diff --git a/src/core/cdrom.h b/src/core/cdrom.h index 1dc1940ad..5e94bb893 100644 --- a/src/core/cdrom.h +++ b/src/core/cdrom.h @@ -201,11 +201,12 @@ private: void UpdateStatusRegister(); void UpdateInterruptRequest(); - TickCount GetAckDelayForCommand() const; + TickCount GetAckDelayForCommand(Command command) const; TickCount GetTicksForRead() const; TickCount GetTicksForSeek() const; void BeginCommand(Command command); // also update status register void EndCommand(); // also updates status register + void AbortCommand(); void ExecuteCommand(); void ExecuteTestCommand(u8 subcommand); void UpdateCommandEvent();