From b0c492fd436e7af693e04330ada146e1d9317dfe Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 26 Oct 2019 22:33:23 +1000 Subject: [PATCH] DigitalController: Fix broken input due to 0x01 handling Fixes THPS among others. --- src/core/digital_controller.cpp | 81 +++++++++++++++------------------ src/core/digital_controller.h | 11 +++-- src/core/pad.cpp | 2 + 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/core/digital_controller.cpp b/src/core/digital_controller.cpp index 9c145d6b6..f5b5b29c8 100644 --- a/src/core/digital_controller.cpp +++ b/src/core/digital_controller.cpp @@ -16,68 +16,59 @@ void DigitalController::SetButtonState(Button button, bool pressed) void DigitalController::ResetTransferState() { - m_transfer_fifo.Clear(); + m_transfer_state = TransferState::Idle; } bool DigitalController::Transfer(const u8 data_in, u8* data_out) { - bool ack; + static constexpr u16 ID = 0x5A41; - switch (data_in) + switch (m_transfer_state) { - case 0x01: // tests if the controller is present + case TransferState::Idle: { - Log_DebugPrintf("Access"); - - // response is hi-z - *data_out = 0xFF; - ack = true; - } - break; - - case 0x42: // query state - { - Log_DebugPrintf("Query state"); - QueryState(); - [[fallthrough]]; - } - - default: // sending response - { - if (m_transfer_fifo.IsEmpty()) + // ack when sent 0x01, send ID for 0x42 + if (data_in == 0x42) { - Log_WarningPrint("FIFO empty on read"); - *data_out = 0xFF; - ack = false; + *data_out = Truncate8(ID); + m_transfer_state = TransferState::IDMSB; + return true; } else { - *data_out = m_transfer_fifo.Pop(); - ack = !m_transfer_fifo.IsEmpty(); + *data_out = 0xFF; + return (data_in == 0x01); } } - break; + + case TransferState::IDMSB: + { + *data_out = Truncate8(ID >> 8); + m_transfer_state = TransferState::ButtonsLSB; + return true; + } + + case TransferState::ButtonsLSB: + { + *data_out = Truncate8(m_button_state); + m_transfer_state = TransferState::ButtonsMSB; + return true; + } + + case TransferState::ButtonsMSB: + *data_out = Truncate8(m_button_state >> 8); + m_transfer_state = TransferState::Idle; + return false; + + default: + { + UnreachableCode(); + return false; + } } - - Log_DebugPrintf("Transfer, data_in=0x%02X, data_out=0x%02X, ack=%s", data_in, *data_out, ack ? "true" : "false"); - return ack; -} - -void DigitalController::QueryState() -{ - constexpr u16 ID = 0x5A41; - - m_transfer_fifo.Clear(); - - m_transfer_fifo.Push(Truncate8(ID)); - m_transfer_fifo.Push(Truncate8(ID >> 8)); - - m_transfer_fifo.Push(Truncate8(m_button_state)); // Digital switches low - m_transfer_fifo.Push(Truncate8(m_button_state >> 8)); // Digital switches high } std::shared_ptr DigitalController::Create() { return std::make_shared(); } - diff --git a/src/core/digital_controller.h b/src/core/digital_controller.h index 7f28a7e82..510bf544a 100644 --- a/src/core/digital_controller.h +++ b/src/core/digital_controller.h @@ -1,5 +1,4 @@ #pragma once -#include "common/fifo_queue.h" #include "pad_device.h" #include @@ -37,10 +36,16 @@ public: bool Transfer(const u8 data_in, u8* data_out) override; private: - void QueryState(); + enum class TransferState : u8 + { + Idle, + IDMSB, + ButtonsLSB, + ButtonsMSB + }; // buttons are active low u16 m_button_state = UINT16_C(0xFFFF); - InlineFIFOQueue m_transfer_fifo; + TransferState m_transfer_state = TransferState::Idle; }; diff --git a/src/core/pad.cpp b/src/core/pad.cpp index 5d60fed2c..8d121bb24 100644 --- a/src/core/pad.cpp +++ b/src/core/pad.cpp @@ -278,12 +278,14 @@ void Pad::DoTransfer() else { // memory card responded, make it the active device until non-ack + Log_DebugPrintf("Transfer to memory card, data_out=0x%02X, data_in=0x%02X", data_in, data_out); m_active_device = ActiveDevice::MemoryCard; } } else { // controller responded, make it the active device until non-ack + Log_DebugPrintf("Transfer to controller, data_out=0x%02X, data_in=0x%02X", data_in, data_out); m_active_device = ActiveDevice::Controller; } }