Skip to content

Commit

Permalink
CDROM: Improve accuracy of sector redelivery on DMA complete
Browse files Browse the repository at this point in the history
Fixes hang in loading in Syphon Filter 2/3.
  • Loading branch information
stenzek committed Jun 9, 2024
1 parent 3486107 commit 8595175
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions src/core/cdrom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3381,17 +3381,20 @@ void CDROM::CheckForSectorBufferReadComplete()
{
sb.position = 0;
sb.size = 0;
}

// Redeliver missed sector on DMA/read complete.
// I'm still not sure if this is correct behavior.
SectorBuffer& next_sb = s_sector_buffers[s_current_write_sector_buffer];
if (next_sb.position == 0 && next_sb.size > 0)
{
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);
SetAsyncInterrupt(Interrupt::DataReady);
}
// Redeliver missed sector on DMA/read complete.
// 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];
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);
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);
}
}

Expand Down

0 comments on commit 8595175

Please sign in to comment.