CDROM: Fix intermediate seek->read status transition

This commit is contained in:
Connor McLaughlin 2021-06-29 19:29:58 +10:00
parent 911e9a37f1
commit 37e50c62f0
2 changed files with 19 additions and 12 deletions

View file

@ -1749,8 +1749,6 @@ void CDROM::BeginReading(TickCount ticks_late /* = 0 */, bool after_seek /* = fa
const TickCount ticks = GetTicksForRead(); const TickCount ticks = GetTicksForRead();
const TickCount first_sector_ticks = ticks + (after_seek ? 0 : GetTicksForSeek(m_current_lba)) - ticks_late; const TickCount first_sector_ticks = ticks + (after_seek ? 0 : GetTicksForSeek(m_current_lba)) - ticks_late;
m_secondary_status.ClearActiveBits();
m_secondary_status.motor_on = true;
ResetAudioDecoder(); ResetAudioDecoder();
m_drive_state = DriveState::Reading; m_drive_state = DriveState::Reading;
@ -1792,9 +1790,6 @@ void CDROM::BeginPlaying(u8 track, TickCount ticks_late /* = 0 */, bool after_se
const TickCount ticks = GetTicksForRead(); const TickCount ticks = GetTicksForRead();
const TickCount first_sector_ticks = ticks + (after_seek ? 0 : GetTicksForSeek(m_current_lba, true)) - ticks_late; const TickCount first_sector_ticks = ticks + (after_seek ? 0 : GetTicksForSeek(m_current_lba, true)) - ticks_late;
m_secondary_status.ClearActiveBits();
m_secondary_status.motor_on = true;
m_secondary_status.playing_cdda = true;
ClearSectorBuffers(); ClearSectorBuffers();
ResetAudioDecoder(); ResetAudioDecoder();
@ -1824,9 +1819,7 @@ void CDROM::BeginSeeking(bool logical, bool read_after_seek, bool play_after_see
const CDImage::LBA seek_lba = m_setloc_position.ToLBA(); const CDImage::LBA seek_lba = m_setloc_position.ToLBA();
const TickCount seek_time = GetTicksForSeek(seek_lba, play_after_seek); const TickCount seek_time = GetTicksForSeek(seek_lba, play_after_seek);
m_secondary_status.ClearActiveBits(); m_secondary_status.SetSeeking();
m_secondary_status.motor_on = true;
m_secondary_status.seeking = true;
m_last_sector_header_valid = false; m_last_sector_header_valid = false;
ResetAudioDecoder(); ResetAudioDecoder();
@ -1983,7 +1976,6 @@ bool CDROM::CompleteSeek()
{ {
const bool logical = (m_drive_state == DriveState::SeekingLogical); const bool logical = (m_drive_state == DriveState::SeekingLogical);
ClearDriveState(); ClearDriveState();
m_secondary_status.ClearActiveBits();
bool seek_okay = m_reader.WaitForReadToComplete(); bool seek_okay = m_reader.WaitForReadToComplete();
if (seek_okay) if (seek_okay)
@ -2057,6 +2049,7 @@ void CDROM::DoSeekComplete(TickCount ticks_late)
} }
else else
{ {
m_secondary_status.ClearActiveBits();
m_async_response_fifo.Push(m_secondary_status.bits); m_async_response_fifo.Push(m_secondary_status.bits);
SetAsyncInterrupt(Interrupt::Complete); SetAsyncInterrupt(Interrupt::Complete);
} }
@ -2066,6 +2059,8 @@ void CDROM::DoSeekComplete(TickCount ticks_late)
CDImage::Position pos(CDImage::Position::FromLBA(m_reader.GetLastReadSector())); CDImage::Position pos(CDImage::Position::FromLBA(m_reader.GetLastReadSector()));
Log_WarningPrintf("%s seek to [%02u:%02u:%02u] failed", logical ? "Logical" : "Physical", pos.minute, pos.second, Log_WarningPrintf("%s seek to [%02u:%02u:%02u] failed", logical ? "Logical" : "Physical", pos.minute, pos.second,
pos.frame); pos.frame);
m_secondary_status.ClearActiveBits();
SendAsyncErrorResponse(STAT_SEEK_ERROR, 0x04); SendAsyncErrorResponse(STAT_SEEK_ERROR, 0x04);
m_last_sector_header_valid = false; m_last_sector_header_valid = false;
} }
@ -2212,6 +2207,8 @@ void CDROM::DoSectorRead()
m_physical_lba_update_tick = TimingEvents::GetGlobalTickCounter(); m_physical_lba_update_tick = TimingEvents::GetGlobalTickCounter();
m_physical_lba_update_carry = 0; m_physical_lba_update_carry = 0;
m_secondary_status.SetReadingBits(m_drive_state == DriveState::Playing);
const CDImage::SubChannelQ& subq = m_reader.GetSectorSubQ(); const CDImage::SubChannelQ& subq = m_reader.GetSectorSubQ();
const bool subq_valid = subq.IsCRCValid(); const bool subq_valid = subq.IsCRCValid();
if (subq_valid) if (subq_valid)
@ -2296,9 +2293,6 @@ void CDROM::ProcessDataSector(const u8* raw_sector, const CDImage::SubChannelQ&
ZeroExtend32(m_last_sector_header.sector_mode), ZeroExtend32(m_last_sector_subheader.submode.bits), ZeroExtend32(m_last_sector_header.sector_mode), ZeroExtend32(m_last_sector_subheader.submode.bits),
sb_num); sb_num);
// The reading bit shouldn't be set until the first sector is processed.
m_secondary_status.reading = true;
if (m_mode.xa_enable && m_last_sector_header.sector_mode == 2) if (m_mode.xa_enable && m_last_sector_header.sector_mode == 2)
{ {
if (m_last_sector_subheader.submode.realtime && m_last_sector_subheader.submode.audio) if (m_last_sector_subheader.submode.realtime && m_last_sector_subheader.submode.audio)

View file

@ -200,6 +200,19 @@ private:
/// Clears the CDDA/seeking bits. /// Clears the CDDA/seeking bits.
ALWAYS_INLINE void ClearActiveBits() { bits &= ~(STAT_SEEKING | STAT_READING | STAT_PLAYING_CDDA); } ALWAYS_INLINE void ClearActiveBits() { bits &= ~(STAT_SEEKING | STAT_READING | STAT_PLAYING_CDDA); }
/// Sets the bits for seeking.
ALWAYS_INLINE void SetSeeking()
{
bits = (bits & ~(STAT_READING | STAT_PLAYING_CDDA)) | (STAT_MOTOR_ON | STAT_SEEKING);
}
/// Sets the bits for reading/playing.
ALWAYS_INLINE void SetReadingBits(bool audio)
{
bits = (bits & ~(STAT_SEEKING | STAT_READING | STAT_PLAYING_CDDA)) |
((audio) ? (STAT_MOTOR_ON | STAT_PLAYING_CDDA) : (STAT_MOTOR_ON | STAT_READING));
}
}; };
union ModeRegister union ModeRegister