From 7222c21cd9524e423783ca0ed93a25e87bda2cef Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 31 May 2024 23:59:44 +1000 Subject: [PATCH] CDROM: Further refine interrupt delay --- src/core/cdrom.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index 1ce640b28..abe8c2fc1 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -60,7 +60,7 @@ enum : u32 MAX_FAST_FORWARD_RATE = 12, FAST_FORWARD_RATE_STEP = 4, - MINIMUM_INTERRUPT_DELAY = 5000, + MINIMUM_INTERRUPT_DELAY = 6000, INTERRUPT_DELAY_CYCLES = 2000, }; @@ -1200,12 +1200,14 @@ void CDROM::QueueDeliverAsyncInterrupt() // interrupt, then read the FIFO. If an INT1 comes in during that time, it'll read the INT1 response // instead of the INT3 response, and the game gets confused. So, we just delay INT1s a bit, if there // has been any recent INT3s - give it enough time to read the response out. The real console does - // something similar anyway, the INT1 task won't run immediately after the INT3 is cleared. + // something similar anyway, the INT1 task won't run immediately after the INT3 is cleared. We use + // the response FIFO being empty as a second heuristic, to avoid very late INT1s that cause early + // buffer loads and sector retries in other games, like Lego Racers PAL. DebugAssert(HasPendingAsyncInterrupt()); // underflows here are okay const u32 diff = System::GetGlobalTickCounter() - s_last_interrupt_time; - if (diff >= MINIMUM_INTERRUPT_DELAY) + if (diff >= MINIMUM_INTERRUPT_DELAY || s_response_fifo.IsEmpty()) { DeliverAsyncInterrupt(nullptr, 0, 0); }