CDROM: Improve timings

This commit is contained in:
Connor McLaughlin 2019-10-05 16:07:15 +10:00
parent ebe44ccc0b
commit 20a011a074
2 changed files with 27 additions and 23 deletions

View File

@ -19,6 +19,14 @@ bool CDROM::Initialize(System* system, DMA* dma, InterruptController* interrupt_
} }
void CDROM::Reset() void CDROM::Reset()
{
if (m_media)
m_media->Seek(0);
SoftReset();
}
void CDROM::SoftReset()
{ {
m_command_state = CommandState::Idle; m_command_state = CommandState::Idle;
m_command = Command::Sync; m_command = Command::Sync;
@ -36,6 +44,7 @@ void CDROM::Reset()
m_param_fifo.Clear(); m_param_fifo.Clear();
m_response_fifo.Clear(); m_response_fifo.Clear();
m_data_fifo.Clear(); m_data_fifo.Clear();
m_sector_buffer.clear();
UpdateStatusRegister(); UpdateStatusRegister();
} }
@ -379,23 +388,13 @@ void CDROM::UpdateStatusRegister()
m_status.BUSYSTS = m_command_state == CommandState::WaitForExecute; m_status.BUSYSTS = m_command_state == CommandState::WaitForExecute;
} }
u32 CDROM::GetTicksForCommand() const u32 CDROM::GetAckDelayForCommand() const
{ {
switch (m_command) const u32 default_ack_delay = 20000;
{ if (m_command == Command::Init)
case Command::ReadN: return 60000;
case Command::ReadS: else
{ return default_ack_delay;
// more if seeking..
return 1000;
}
case Command::Pause:
return 1000;
default:
return 1000;
}
} }
u32 CDROM::GetTicksForRead() const u32 CDROM::GetTicksForRead() const
@ -443,7 +442,7 @@ void CDROM::BeginCommand(Command command)
m_command = command; m_command = command;
m_command_stage = 0; m_command_stage = 0;
m_command_remaining_ticks = GetTicksForCommand(); m_command_remaining_ticks = GetAckDelayForCommand();
if (m_command_remaining_ticks == 0) if (m_command_remaining_ticks == 0)
{ {
ExecuteCommand(); ExecuteCommand();
@ -524,7 +523,7 @@ void CDROM::ExecuteCommand()
// INT3(stat), ... // INT3(stat), ...
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::ACK); SetInterrupt(Interrupt::ACK);
NextCommandStage(true, GetTicksForCommand()); NextCommandStage(true, 18000);
} }
} }
else else
@ -574,7 +573,7 @@ void CDROM::ExecuteCommand()
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);
SetInterrupt(Interrupt::ACK); SetInterrupt(Interrupt::ACK);
NextCommandStage(false, 100); NextCommandStage(false, 20000);
} }
else else
{ {
@ -640,7 +639,7 @@ void CDROM::ExecuteCommand()
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::ACK); SetInterrupt(Interrupt::ACK);
StopReading(); StopReading();
NextCommandStage(true, was_reading ? (m_mode.double_speed ? 2000000 : 1000000) : 1000); NextCommandStage(true, was_reading ? (m_mode.double_speed ? 2000000 : 1000000) : 7000);
} }
else else
{ {
@ -660,10 +659,13 @@ void CDROM::ExecuteCommand()
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::ACK); SetInterrupt(Interrupt::ACK);
StopReading(); StopReading();
NextCommandStage(true, 1000); NextCommandStage(true, 8000);
} }
else else
{ {
m_mode.bits = 0;
m_secondary_status.bits = 0;
m_secondary_status.motor_on = true;
m_response_fifo.Push(m_secondary_status.bits); m_response_fifo.Push(m_secondary_status.bits);
SetInterrupt(Interrupt::INT2); SetInterrupt(Interrupt::INT2);
EndCommand(); EndCommand();

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "common/bitfield.h" #include "common/bitfield.h"
#include "common/fifo_queue.h"
#include "common/cd_image.h" #include "common/cd_image.h"
#include "common/fifo_queue.h"
#include "types.h" #include "types.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -154,12 +154,14 @@ private:
BitField<u8, bool, 7, 1> BFRD; BitField<u8, bool, 7, 1> BFRD;
}; };
void SoftReset();
bool HasPendingInterrupt() const { return m_interrupt_flag_register != 0; } bool HasPendingInterrupt() const { return m_interrupt_flag_register != 0; }
void SetInterrupt(Interrupt interrupt); void SetInterrupt(Interrupt interrupt);
void PushStatResponse(Interrupt interrupt = Interrupt::ACK); void PushStatResponse(Interrupt interrupt = Interrupt::ACK);
void UpdateStatusRegister(); void UpdateStatusRegister();
u32 GetTicksForCommand() const; u32 GetAckDelayForCommand() const;
u32 GetTicksForRead() 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);