diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index 8e2c6ab1f..35ae863a1 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -276,7 +276,10 @@ void CDROM::InsertMedia(std::unique_ptr media) // motor automatically spins up if (m_drive_state != DriveState::ShellOpening) - m_secondary_status.motor_on = true; + { + m_drive_state = DriveState::SpinningUp; + m_drive_event->Schedule(System::GetTicksPerSecond()); + } // reading TOC? interestingly this doesn't work for GetlocL though... CDImage::SubChannelQ subq; @@ -698,8 +701,18 @@ TickCount CDROM::GetTicksForSeek(CDImage::LBA new_lba) u32 ticks = std::max( 20000, static_cast( ((static_cast(lba_diff) * static_cast(tps) * static_cast(1000)) / (72 * 60 * 75)) / 1000)); + + // Motor spin-up time. if (!m_secondary_status.motor_on) - ticks += tps; + { + ticks += (m_drive_state == DriveState::SpinningUp) ? m_drive_event->GetTicksUntilNextExecution() : tps; + if (m_drive_state == DriveState::ShellOpening || m_drive_state == DriveState::SpinningUp) + { + m_drive_state = DriveState::Idle; + m_drive_event->Deactivate(); + } + } + if (lba_diff >= 2550) ticks += static_cast((u64(tps) * 300) / 1000); else @@ -1471,6 +1484,10 @@ void CDROM::ExecuteDrive(TickCount ticks_late) DoChangeSessionComplete(); break; + case DriveState::SpinningUp: + DoSpinUpComplete(); + break; + case DriveState::Idle: default: break; @@ -1691,7 +1708,10 @@ void CDROM::DoShellOpenComplete(TickCount ticks_late) m_drive_event->Deactivate(); if (m_reader.HasMedia()) - m_secondary_status.motor_on = true; + { + m_drive_state = DriveState::SpinningUp; + m_drive_event->Schedule(System::GetTicksPerSecond()); + } } void CDROM::DoResetComplete(TickCount ticks_late) @@ -1870,6 +1890,15 @@ void CDROM::DoChangeSessionComplete() } } +void CDROM::DoSpinUpComplete() +{ + Log_DebugPrintf("Spinup complete"); + m_drive_state = DriveState::Idle; + m_drive_event->Deactivate(); + m_secondary_status.ClearActiveBits(); + m_secondary_status.motor_on = true; +} + void CDROM::DoIDRead() { Log_DebugPrintf("ID read complete"); @@ -2477,9 +2506,9 @@ void CDROM::DrawDebugWindow() if (ImGui::CollapsingHeader("Status/Mode", ImGuiTreeNodeFlags_DefaultOpen)) { - static constexpr std::array drive_state_names = { + static constexpr std::array drive_state_names = { {"Idle", "Opening Shell", "Resetting", "Seeking (Physical)", "Seeking (Logical)", "Reading ID", "Reading TOC", - "Reading", "Playing", "Pausing", "Stopping", "Changing Session"}}; + "Reading", "Playing", "Pausing", "Stopping", "Changing Session", "Spinning Up"}}; ImGui::Columns(3); diff --git a/src/core/cdrom.h b/src/core/cdrom.h index 40d4f226e..399232c05 100644 --- a/src/core/cdrom.h +++ b/src/core/cdrom.h @@ -146,7 +146,8 @@ private: Playing, Pausing, Stopping, - ChangingSession + ChangingSession, + SpinningUp }; union StatusRegister @@ -281,6 +282,7 @@ private: void DoPauseComplete(); void DoStopComplete(); void DoChangeSessionComplete(); + void DoSpinUpComplete(); void DoIDRead(); void DoTOCRead(); void DoSectorRead();