CDROM: Fix double-reads hitting incorrect sector again

Fixes Bedlem / Rise 2 without breaking Vigilante 8 - 2nd Offense.
This commit is contained in:
Connor McLaughlin 2020-06-02 00:59:11 +10:00
parent 5e7fd5aa71
commit dcfb929de5
2 changed files with 17 additions and 4 deletions

View file

@ -853,6 +853,15 @@ TickCount CDROM::GetTicksForStop(bool motor_was_on)
return motor_was_on ? (m_mode.double_speed ? 25000000 : 13000000) : 7000; return motor_was_on ? (m_mode.double_speed ? 25000000 : 13000000) : 7000;
} }
CDImage::LBA CDROM::GetNextSectorToBeRead()
{
if (!IsReadingOrPlaying())
return m_current_lba;
m_reader.WaitForReadToComplete();
return m_reader.GetLastReadSector();
}
void CDROM::BeginCommand(Command command) void CDROM::BeginCommand(Command command)
{ {
TickCount ack_delay = GetAckDelayForCommand(command); TickCount ack_delay = GetAckDelayForCommand(command);
@ -1077,7 +1086,7 @@ void CDROM::ExecuteCommand()
{ {
SendACKAndStat(); SendACKAndStat();
if ((!m_setloc_pending || m_setloc_position.ToLBA() == m_current_lba) && if ((!m_setloc_pending || m_setloc_position.ToLBA() == GetNextSectorToBeRead()) &&
(m_drive_state == DriveState::Reading || (IsSeeking() && m_read_after_seek))) (m_drive_state == DriveState::Reading || (IsSeeking() && m_read_after_seek)))
{ {
Log_DevPrintf("Ignoring read command with no/same setloc, already reading/reading after seek"); Log_DevPrintf("Ignoring read command with no/same setloc, already reading/reading after seek");
@ -1108,7 +1117,7 @@ void CDROM::ExecuteCommand()
{ {
SendACKAndStat(); SendACKAndStat();
if (track == 0 && (!m_setloc_pending || m_setloc_position.ToLBA() == m_current_lba) && if (track == 0 && (!m_setloc_pending || m_setloc_position.ToLBA() == GetNextSectorToBeRead()) &&
(m_drive_state == DriveState::Playing || (IsSeeking() && m_play_after_seek))) (m_drive_state == DriveState::Playing || (IsSeeking() && m_play_after_seek)))
{ {
Log_DevPrintf("Ignoring play command with no/same setloc, already playing/playing after seek"); Log_DevPrintf("Ignoring play command with no/same setloc, already playing/playing after seek");
@ -1924,8 +1933,7 @@ void CDROM::DoSectorRead()
is_data_sector ? "data" : "audio", is_data_sector ? "reading" : "playing"); is_data_sector ? "data" : "audio", is_data_sector ? "reading" : "playing");
} }
m_current_lba++; m_reader.QueueReadSector(m_current_lba + 1u);
m_reader.QueueReadSector(m_current_lba);
} }
void CDROM::ProcessDataSectorHeader(const u8* raw_sector) void CDROM::ProcessDataSectorHeader(const u8* raw_sector)

View file

@ -202,6 +202,10 @@ private:
{ {
return (m_drive_state == DriveState::SeekingLogical || m_drive_state == DriveState::SeekingPhysical); return (m_drive_state == DriveState::SeekingLogical || m_drive_state == DriveState::SeekingPhysical);
} }
bool IsReadingOrPlaying() const
{
return (m_drive_state == DriveState::Reading || m_drive_state == DriveState::Playing);
}
bool CanReadMedia() const { return (m_drive_state != DriveState::ShellOpening && m_reader.HasMedia()); } bool CanReadMedia() const { return (m_drive_state != DriveState::ShellOpening && m_reader.HasMedia()); }
bool HasPendingCommand() const { return m_command != Command::None; } bool HasPendingCommand() const { return m_command != Command::None; }
bool HasPendingInterrupt() const { return m_interrupt_flag_register != 0; } bool HasPendingInterrupt() const { return m_interrupt_flag_register != 0; }
@ -220,6 +224,7 @@ private:
TickCount GetTicksForRead(); TickCount GetTicksForRead();
TickCount GetTicksForSeek(CDImage::LBA new_lba); TickCount GetTicksForSeek(CDImage::LBA new_lba);
TickCount GetTicksForStop(bool motor_was_on); TickCount GetTicksForStop(bool motor_was_on);
CDImage::LBA GetNextSectorToBeRead();
void BeginCommand(Command command); // also update status register void BeginCommand(Command command); // also update status register
void EndCommand(); // also updates status register void EndCommand(); // also updates status register
void AbortCommand(); void AbortCommand();