CDROM: Improve accuracy of sector redelivery on DMA complete

Fixes hang in loading in Syphon Filter 2/3.
This commit is contained in:
Stenzek 2024-06-09 19:42:17 +10:00
parent 34861074c1
commit 8595175267
No known key found for this signature in database

View file

@ -3381,17 +3381,20 @@ void CDROM::CheckForSectorBufferReadComplete()
{ {
sb.position = 0; sb.position = 0;
sb.size = 0; sb.size = 0;
}
// Redeliver missed sector on DMA/read complete. // Redeliver missed sector on DMA/read complete.
// I'm still not sure if this is correct behavior. // This would be the main loop checking when the DMA is complete, if there's another sector pending.
SectorBuffer& next_sb = s_sector_buffers[s_current_write_sector_buffer]; // Normally, this would happen some time after the DMA actually completes, so we need to put it on a delay.
if (next_sb.position == 0 && next_sb.size > 0) // Otherwise, if games read the header then data out as two separate transfers (which is typical), they'll
{ // get the header for one sector, and the header for the next in the second transfer.
DEV_LOG("Sending additional INT1 for missed sector in buffer {}", s_current_write_sector_buffer); SectorBuffer& next_sb = s_sector_buffers[s_current_write_sector_buffer];
s_current_read_sector_buffer = s_current_write_sector_buffer; if (next_sb.position == 0 && next_sb.size > 0 && !HasPendingAsyncInterrupt())
s_async_response_fifo.Push(s_secondary_status.bits); {
SetAsyncInterrupt(Interrupt::DataReady); DEV_LOG("Sending additional INT1 for missed sector in buffer {}", s_current_write_sector_buffer);
} s_async_response_fifo.Push(s_secondary_status.bits);
s_pending_async_interrupt = static_cast<u8>(Interrupt::DataReady);
s_async_interrupt_event->Schedule(INTERRUPT_DELAY_CYCLES);
} }
} }