Pad: Improve ACK timing

Fixes random pauses in Moto Racer.
This commit is contained in:
Connor McLaughlin 2020-07-02 00:43:26 +10:00
parent b471d1043a
commit bff5432879
2 changed files with 14 additions and 6 deletions

View file

@ -152,6 +152,9 @@ u32 Pad::ReadRegister(u32 offset)
{ {
case 0x00: // JOY_DATA case 0x00: // JOY_DATA
{ {
if (IsTransmitting())
m_transfer_event->InvokeEarly();
const u8 value = m_receive_buffer_full ? m_receive_buffer : 0xFF; const u8 value = m_receive_buffer_full ? m_receive_buffer : 0xFF;
Log_DebugPrintf("JOY_DATA (R) -> 0x%02X%s", ZeroExtend32(value), m_receive_buffer_full ? "" : "(EMPTY)"); Log_DebugPrintf("JOY_DATA (R) -> 0x%02X%s", ZeroExtend32(value), m_receive_buffer_full ? "" : "(EMPTY)");
m_receive_buffer_full = false; m_receive_buffer_full = false;
@ -163,6 +166,9 @@ u32 Pad::ReadRegister(u32 offset)
case 0x04: // JOY_STAT case 0x04: // JOY_STAT
{ {
if (IsTransmitting())
m_transfer_event->InvokeEarly();
const u32 bits = m_JOY_STAT.bits; const u32 bits = m_JOY_STAT.bits;
m_JOY_STAT.ACKINPUT = false; m_JOY_STAT.ACKINPUT = false;
return bits; return bits;
@ -388,13 +394,10 @@ void Pad::DoTransfer(TickCount ticks_late)
} }
else else
{ {
const TickCount ack_timer = GetACKTicks(); const TickCount ack_timer = GetACKTicks(m_active_device == ActiveDevice::MemoryCard);
Log_DebugPrintf("Delaying ACK for %d ticks", ack_timer); Log_DebugPrintf("Delaying ACK for %d ticks", ack_timer);
m_state = State::WaitingForACK; m_state = State::WaitingForACK;
if (ticks_late >= ack_timer) m_transfer_event->SetPeriodAndSchedule(ack_timer);
DoACK();
else
m_transfer_event->SetPeriodAndSchedule(ack_timer - ticks_late);
} }
UpdateJoyStat(); UpdateJoyStat();

View file

@ -92,7 +92,12 @@ private:
bool CanTransfer() const { return m_transmit_buffer_full && m_JOY_CTRL.SELECT && m_JOY_CTRL.TXEN; } bool CanTransfer() const { return m_transmit_buffer_full && m_JOY_CTRL.SELECT && m_JOY_CTRL.TXEN; }
TickCount GetTransferTicks() const { return static_cast<TickCount>(ZeroExtend32(m_JOY_BAUD) * 8); } TickCount GetTransferTicks() const { return static_cast<TickCount>(ZeroExtend32(m_JOY_BAUD) * 8); }
TickCount GetACKTicks() const { return 32; }
// From @JaCzekanski
// ACK lasts ~96 ticks or approximately 2.84us at master clock (not implemented).
// ACK delay is between 6.8us-13.7us, or ~338 ticks at master clock for approximately 9.98us.
// Memory card responds faster, approximately 5us or ~170 ticks.
static constexpr TickCount GetACKTicks(bool memory_card) { return memory_card ? 170 : 450; }
void SoftReset(); void SoftReset();
void UpdateJoyStat(); void UpdateJoyStat();