CDROM: Read timing and demute command, seek on ReadN

This commit is contained in:
Connor McLaughlin 2019-09-23 23:31:51 +10:00
parent 20f14688ca
commit d65c9b3592
2 changed files with 43 additions and 6 deletions

View file

@ -304,6 +304,11 @@ u32 CDROM::GetTicksForCommand() const
return 100; return 100;
} }
u32 CDROM::GetTicksForRead() const
{
return m_mode.double_speed ? (MASTER_CLOCK / 150) : (MASTER_CLOCK / 75);
}
void CDROM::Execute(TickCount ticks) void CDROM::Execute(TickCount ticks)
{ {
switch (m_command_state) switch (m_command_state)
@ -317,6 +322,8 @@ void CDROM::Execute(TickCount ticks)
m_command_remaining_ticks -= ticks; m_command_remaining_ticks -= ticks;
if (m_command_remaining_ticks <= 0) if (m_command_remaining_ticks <= 0)
ExecuteCommand(); ExecuteCommand();
else
m_system->SetDowncount(m_command_remaining_ticks);
} }
break; break;
@ -330,6 +337,8 @@ void CDROM::Execute(TickCount ticks)
m_sector_read_remaining_ticks -= ticks; m_sector_read_remaining_ticks -= ticks;
if (m_sector_read_remaining_ticks <= 0) if (m_sector_read_remaining_ticks <= 0)
DoSectorRead(); DoSectorRead();
else
m_system->SetDowncount(m_sector_read_remaining_ticks);
} }
} }
@ -433,6 +442,7 @@ void CDROM::ExecuteCommand()
m_setloc.minute = BCDToDecimal(m_param_fifo.Peek(0)); m_setloc.minute = BCDToDecimal(m_param_fifo.Peek(0));
m_setloc.second = BCDToDecimal(m_param_fifo.Peek(1)); m_setloc.second = BCDToDecimal(m_param_fifo.Peek(1));
m_setloc.frame = BCDToDecimal(m_param_fifo.Peek(2)); m_setloc.frame = BCDToDecimal(m_param_fifo.Peek(2));
m_location_dirty = true;
Log_DebugPrintf("CDROM setloc command (%u, %u, %u)", ZeroExtend32(m_setloc.minute), ZeroExtend32(m_setloc.second), Log_DebugPrintf("CDROM setloc command (%u, %u, %u)", ZeroExtend32(m_setloc.minute), ZeroExtend32(m_setloc.second),
ZeroExtend32(m_setloc.frame)); ZeroExtend32(m_setloc.frame));
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
@ -449,6 +459,7 @@ void CDROM::ExecuteCommand()
if (m_command_stage == 0) if (m_command_stage == 0)
{ {
Assert(m_location_dirty);
StopReading(); StopReading();
if (!m_media || !m_media->Seek(m_setloc.minute, m_setloc.second - 2 /* pregap */, m_setloc.frame)) if (!m_media || !m_media->Seek(m_setloc.minute, m_setloc.second - 2 /* pregap */, m_setloc.frame))
{ {
@ -456,6 +467,7 @@ void CDROM::ExecuteCommand()
return; return;
} }
m_location_dirty = false;
m_secondary_status.motor_on = true; m_secondary_status.motor_on = true;
m_secondary_status.seeking = true; m_secondary_status.seeking = true;
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
@ -490,6 +502,17 @@ void CDROM::ExecuteCommand()
{ {
Log_DebugPrintf("CDROM read command"); Log_DebugPrintf("CDROM read command");
StopReading(); StopReading();
// TODO: Seek timing and clean up...
if (m_location_dirty)
{
if (!m_media || !m_media->Seek(m_setloc.minute, m_setloc.second - 2 /* pregap */, m_setloc.frame))
{
Panic("Seek error");
}
m_location_dirty = false;
}
EndCommand(); EndCommand();
BeginReading(); BeginReading();
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
@ -538,6 +561,16 @@ void CDROM::ExecuteCommand()
} }
break; break;
case Command::Demute:
{
Log_DebugPrintf("CDROM demute command");
m_muted = false;
m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::INT3);
EndCommand();
}
break;
default: default:
Panic("Unknown command"); Panic("Unknown command");
break; break;
@ -586,7 +619,7 @@ void CDROM::BeginReading()
m_secondary_status.reading = true; m_secondary_status.reading = true;
m_reading = true; m_reading = true;
m_sector_read_remaining_ticks = 4000; m_sector_read_remaining_ticks = GetTicksForRead();
m_system->SetDowncount(m_sector_read_remaining_ticks); m_system->SetDowncount(m_sector_read_remaining_ticks);
UpdateStatusRegister(); UpdateStatusRegister();
} }
@ -597,9 +630,9 @@ void CDROM::DoSectorRead()
{ {
// can't read with a pending interrupt? // can't read with a pending interrupt?
Log_WarningPrintf("Missed sector read..."); Log_WarningPrintf("Missed sector read...");
//m_sector_read_remaining_ticks += 10; // m_sector_read_remaining_ticks += 10;
//m_system->SetDowncount(m_sector_read_remaining_ticks); // m_system->SetDowncount(m_sector_read_remaining_ticks);
//return; // return;
} }
Log_DebugPrintf("Reading sector %llu", m_media->GetCurrentLBA()); Log_DebugPrintf("Reading sector %llu", m_media->GetCurrentLBA());
@ -608,12 +641,13 @@ void CDROM::DoSectorRead()
u8 buffer[CDImage::RAW_SECTOR_SIZE]; u8 buffer[CDImage::RAW_SECTOR_SIZE];
m_media->Read(m_mode.read_raw_sector ? CDImage::ReadMode::RawNoSync : CDImage::ReadMode::DataOnly, 1, buffer); m_media->Read(m_mode.read_raw_sector ? CDImage::ReadMode::RawNoSync : CDImage::ReadMode::DataOnly, 1, buffer);
m_data_fifo.Clear(); m_data_fifo.Clear();
m_data_fifo.PushRange(buffer, m_mode.read_raw_sector ? CDImage::RAW_SECTOR_SIZE : CDImage::DATA_SECTOR_SIZE); m_data_fifo.PushRange(buffer, m_mode.read_raw_sector ? CDImage::RAW_SECTOR_SIZE - CDImage::SECTOR_SYNC_SIZE :
CDImage::DATA_SECTOR_SIZE);
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::INT1); SetInterrupt(Interrupt::INT1);
UpdateStatusRegister(); UpdateStatusRegister();
m_sector_read_remaining_ticks += 4000; m_sector_read_remaining_ticks += GetTicksForRead();
m_system->SetDowncount(m_sector_read_remaining_ticks); m_system->SetDowncount(m_sector_read_remaining_ticks);
} }

View file

@ -148,6 +148,7 @@ private:
void UpdateStatusRegister(); void UpdateStatusRegister();
u32 GetTicksForCommand() const; u32 GetTicksForCommand() const;
u32 GetTicksForRead() const;
void BeginCommand(Command command); // also update status register void BeginCommand(Command command); // also update status register
void NextCommandStage(bool wait_for_irq, u32 time); void NextCommandStage(bool wait_for_irq, u32 time);
void EndCommand(); // also updates status register void EndCommand(); // also updates status register
@ -169,6 +170,7 @@ private:
TickCount m_sector_read_remaining_ticks = 0; TickCount m_sector_read_remaining_ticks = 0;
bool m_reading = false; bool m_reading = false;
bool m_muted = false;
StatusRegister m_status = {}; StatusRegister m_status = {};
SecondaryStatusRegister m_secondary_status = {}; SecondaryStatusRegister m_secondary_status = {};
@ -182,4 +184,5 @@ private:
HeapFIFOQueue<u8, DATA_FIFO_SIZE> m_data_fifo; HeapFIFOQueue<u8, DATA_FIFO_SIZE> m_data_fifo;
Loc m_setloc = {}; Loc m_setloc = {};
bool m_location_dirty = false;
}; };