CDROM: Various fixes

This commit is contained in:
Connor McLaughlin 2019-09-24 01:33:18 +10:00
parent 1f13c4ad2c
commit db777fdabb
3 changed files with 56 additions and 13 deletions

View file

@ -82,8 +82,8 @@ static int Run(int argc, char* argv[])
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
// set log flags // set log flags
// g_pLog->SetConsoleOutputParams(true, nullptr, LOGLEVEL_DEBUG); g_pLog->SetConsoleOutputParams(true, nullptr, LOGLEVEL_DEBUG);
g_pLog->SetConsoleOutputParams(true, "GPU GPU_HW_OpenGL DMA Pad DigitalController", LOGLEVEL_DEBUG); // g_pLog->SetConsoleOutputParams(true, "GPU GPU_HW_OpenGL DMA Pad DigitalController", LOGLEVEL_DEBUG);
#ifdef Y_BUILD_CONFIG_RELEASE #ifdef Y_BUILD_CONFIG_RELEASE
g_pLog->SetFilterLevel(LOGLEVEL_INFO); g_pLog->SetFilterLevel(LOGLEVEL_INFO);

View file

@ -21,6 +21,14 @@ bool CDROM::Initialize(System* system, DMA* dma, InterruptController* interrupt_
void CDROM::Reset() void CDROM::Reset()
{ {
m_command_state = CommandState::Idle; m_command_state = CommandState::Idle;
m_command = Command::Sync;
m_command_stage = 0;
m_command_remaining_ticks = 0;
m_sector_read_remaining_ticks = 0;
m_reading = false;
m_muted = false;
m_setloc = {};
m_setloc_dirty = false;
m_status.bits = 0; m_status.bits = 0;
m_secondary_status.bits = 0; m_secondary_status.bits = 0;
m_interrupt_enable_register = INTERRUPT_REGISTER_MASK; m_interrupt_enable_register = INTERRUPT_REGISTER_MASK;
@ -33,6 +41,16 @@ void CDROM::Reset()
bool CDROM::DoState(StateWrapper& sw) bool CDROM::DoState(StateWrapper& sw)
{ {
sw.Do(&m_command);
sw.Do(&m_command_stage);
sw.Do(&m_command_remaining_ticks);
sw.Do(&m_sector_read_remaining_ticks);
sw.Do(&m_reading);
sw.Do(&m_muted);
sw.Do(&m_setloc.minute);
sw.Do(&m_setloc.second);
sw.Do(&m_setloc.frame);
sw.Do(&m_setloc_dirty);
sw.Do(&m_command_state); sw.Do(&m_command_state);
sw.Do(&m_status.bits); sw.Do(&m_status.bits);
sw.Do(&m_secondary_status.bits); sw.Do(&m_secondary_status.bits);
@ -41,6 +59,15 @@ bool CDROM::DoState(StateWrapper& sw)
sw.Do(&m_param_fifo); sw.Do(&m_param_fifo);
sw.Do(&m_response_fifo); sw.Do(&m_response_fifo);
sw.Do(&m_data_fifo); sw.Do(&m_data_fifo);
if (sw.IsReading())
{
if (m_command_state == CommandState::WaitForExecute)
m_system->SetDowncount(m_command_remaining_ticks);
if (m_reading)
m_system->SetDowncount(m_sector_read_remaining_ticks);
}
return !sw.HasError(); return !sw.HasError();
} }
@ -214,6 +241,7 @@ void CDROM::WriteRegister(u32 offset, u8 value)
{ {
case 0: case 0:
{ {
// TODO: sector buffer is not the data fifo
Log_DebugPrintf("Request register <- 0x%02X", value); Log_DebugPrintf("Request register <- 0x%02X", value);
const RequestRegister rr{value}; const RequestRegister rr{value};
// if (!rr.BFRD) // if (!rr.BFRD)
@ -296,12 +324,25 @@ void CDROM::UpdateStatusRegister()
m_status.PRMWRDY = !m_param_fifo.IsFull(); m_status.PRMWRDY = !m_param_fifo.IsFull();
m_status.RSLRRDY = !m_response_fifo.IsEmpty(); m_status.RSLRRDY = !m_response_fifo.IsEmpty();
m_status.DRQSTS = !m_data_fifo.IsEmpty(); m_status.DRQSTS = !m_data_fifo.IsEmpty();
m_status.BUSYSTS = m_command_state != CommandState::Idle; m_status.BUSYSTS = m_command_state == CommandState::WaitForExecute;
} }
u32 CDROM::GetTicksForCommand() const u32 CDROM::GetTicksForCommand() const
{ {
return 100; switch (m_command)
{
case Command::ReadN:
{
// more if seeking..
return 50000;
}
case Command::Pause:
return 50000;
default:
return 50000;
}
} }
u32 CDROM::GetTicksForRead() const u32 CDROM::GetTicksForRead() const
@ -361,6 +402,7 @@ void CDROM::NextCommandStage(bool wait_for_irq, u32 time)
m_command_state = CommandState::WaitForIRQClear; m_command_state = CommandState::WaitForIRQClear;
m_command_remaining_ticks = time; m_command_remaining_ticks = time;
m_command_stage++; m_command_stage++;
UpdateStatusRegister();
if (wait_for_irq) if (wait_for_irq)
return; return;
@ -442,7 +484,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; m_setloc_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);
@ -459,7 +501,7 @@ void CDROM::ExecuteCommand()
if (m_command_stage == 0) if (m_command_stage == 0)
{ {
Assert(m_location_dirty); Assert(m_setloc_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))
{ {
@ -467,7 +509,7 @@ void CDROM::ExecuteCommand()
return; return;
} }
m_location_dirty = false; m_setloc_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);
@ -504,13 +546,13 @@ void CDROM::ExecuteCommand()
StopReading(); StopReading();
// TODO: Seek timing and clean up... // TODO: Seek timing and clean up...
if (m_location_dirty) if (m_setloc_dirty)
{ {
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))
{ {
Panic("Seek error"); Panic("Seek error");
} }
m_location_dirty = false; m_setloc_dirty = false;
} }
EndCommand(); EndCommand();
@ -524,11 +566,12 @@ void CDROM::ExecuteCommand()
{ {
if (m_command_stage == 0) if (m_command_stage == 0)
{ {
const bool was_reading = m_reading;
Log_DebugPrintf("CDROM pause command"); Log_DebugPrintf("CDROM pause command");
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::INT3); SetInterrupt(Interrupt::INT3);
StopReading(); StopReading();
NextCommandStage(true, 1000); NextCommandStage(true, was_reading ? (m_mode.double_speed ? 2000000 : 1000000) : 1000);
} }
else else
{ {

View file

@ -172,6 +172,9 @@ private:
bool m_reading = false; bool m_reading = false;
bool m_muted = false; bool m_muted = false;
Loc m_setloc = {};
bool m_setloc_dirty = false;
StatusRegister m_status = {}; StatusRegister m_status = {};
SecondaryStatusRegister m_secondary_status = {}; SecondaryStatusRegister m_secondary_status = {};
ModeRegister m_mode = {}; ModeRegister m_mode = {};
@ -182,7 +185,4 @@ private:
InlineFIFOQueue<u8, PARAM_FIFO_SIZE> m_param_fifo; InlineFIFOQueue<u8, PARAM_FIFO_SIZE> m_param_fifo;
InlineFIFOQueue<u8, RESPONSE_FIFO_SIZE> m_response_fifo; InlineFIFOQueue<u8, RESPONSE_FIFO_SIZE> m_response_fifo;
HeapFIFOQueue<u8, DATA_FIFO_SIZE> m_data_fifo; HeapFIFOQueue<u8, DATA_FIFO_SIZE> m_data_fifo;
Loc m_setloc = {};
bool m_location_dirty = false;
}; };