From 304f69e350afea6b701d93787f5b8d3fb1fc406e Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 18 Aug 2024 19:04:31 +1000 Subject: [PATCH] CDROM: Fix rare interrupt race when cancelling commands Fixes hang during loading in Street Fighter Alpha 3. --- src/core/cdrom.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index dadc0c14c..8732c687a 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -1567,6 +1567,17 @@ void CDROM::BeginCommand(Command command) const TickCount elapsed_ticks = s_command_event.GetInterval() - s_command_event.GetTicksUntilNextExecution(); ack_delay = std::max(ack_delay - elapsed_ticks, 1); s_command_event.Deactivate(); + + // If there's a pending async interrupt, we need to deliver it now, since we've deactivated the command that was + // blocking it from being delivered. Not doing so will cause lockups in Street Fighter Alpha 3, where it spams + // multiple pause commands while an INT1 is scheduled, and there isn't much that can stop an INT1 once it's been + // queued on real hardware. + if (HasPendingAsyncInterrupt()) + { + WARNING_LOG("Delivering pending interrupt after command {} cancellation for {}.", + s_command_info[static_cast(s_command)].name, s_command_info[static_cast(command)].name); + QueueDeliverAsyncInterrupt(); + } } }