diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index 85d24be96..480f461ca 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -524,6 +524,10 @@ void CDROM::Execute(TickCount ticks) DoPauseComplete(); break; + case DriveState::Stopping: + DoStopComplete(); + break; + case DriveState::ReadingID: DoIDRead(); break; @@ -727,6 +731,20 @@ void CDROM::ExecuteCommand() return; } + case Command::Stop: + { + const bool was_motor_on = m_secondary_status.motor_on; + Log_DebugPrintf("CDROM stop command"); + SendACKAndStat(); + + m_drive_state = DriveState::Stopping; + m_drive_remaining_ticks = was_motor_on ? (m_mode.double_speed ? 25000000 : 13000000) : 7000; + m_system->SetDowncount(m_drive_remaining_ticks); + + EndCommand(); + return; + } + case Command::Init: { Log_DebugPrintf("CDROM init command"); @@ -981,6 +999,19 @@ void CDROM::DoPauseComplete() SetAsyncInterrupt(Interrupt::INT2); } +void CDROM::DoStopComplete() +{ + Log_DebugPrintf("Stop complete"); + m_drive_state = DriveState::Idle; + m_secondary_status.ClearActiveBits(); + m_secondary_status.motor_on = false; + m_sector_buffer.clear(); + + m_async_response_fifo.Clear(); + m_async_response_fifo.Push(m_secondary_status.bits); + SetAsyncInterrupt(Interrupt::INT2); +} + void CDROM::DoIDRead() { // TODO: This should depend on the disc type/region... @@ -1294,8 +1325,8 @@ void CDROM::DrawDebugWindow() if (ImGui::CollapsingHeader("Status/Mode", ImGuiTreeNodeFlags_DefaultOpen)) { - static constexpr std::array drive_state_names = { - {"Idle", "Initializing", "Seeking", "Reading ID", "Reading", "Playing", "Pausing"}}; + static constexpr std::array drive_state_names = { + {"Idle", "Initializing", "Seeking", "Reading ID", "Reading", "Playing", "Pausing", "Stopping"}}; ImGui::Columns(3); diff --git a/src/core/cdrom.h b/src/core/cdrom.h index 145747a31..f2ca20483 100644 --- a/src/core/cdrom.h +++ b/src/core/cdrom.h @@ -114,7 +114,8 @@ private: ReadingID, Reading, Playing, - Pausing + Pausing, + Stopping, }; union StatusRegister @@ -197,6 +198,7 @@ private: void DoInitComplete(); void DoSeekComplete(); void DoPauseComplete(); + void DoStopComplete(); void DoIDRead(); void DoSectorRead(); void ProcessDataSector(const u8* raw_sector);