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.
// Normally, this would happen some time after the DMA actually completes, so we need to put it on a delay.
// 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.
SectorBuffer& next_sb = s_sector_buffers[s_current_write_sector_buffer]; SectorBuffer& next_sb = s_sector_buffers[s_current_write_sector_buffer];
if (next_sb.position == 0 && next_sb.size > 0) if (next_sb.position == 0 && next_sb.size > 0 && !HasPendingAsyncInterrupt())
{ {
DEV_LOG("Sending additional INT1 for missed sector in buffer {}", s_current_write_sector_buffer); DEV_LOG("Sending additional INT1 for missed sector in buffer {}", s_current_write_sector_buffer);
s_current_read_sector_buffer = s_current_write_sector_buffer;
s_async_response_fifo.Push(s_secondary_status.bits); s_async_response_fifo.Push(s_secondary_status.bits);
SetAsyncInterrupt(Interrupt::DataReady); s_pending_async_interrupt = static_cast<u8>(Interrupt::DataReady);
} s_async_interrupt_event->Schedule(INTERRUPT_DELAY_CYCLES);
} }
} }