From cd45dcea94746aecf195c1aadb6c6386c1238ec1 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 14 Nov 2025 23:01:46 -0600 Subject: [PATCH] HW/SI: Fix CMD_STATUS response lengths. They are supposed to be 3, not 4. --- Source/Core/Core/HW/SI/SI_Device.cpp | 10 ++++++++++ Source/Core/Core/HW/SI/SI_Device.h | 8 ++++++++ Source/Core/Core/HW/SI/SI_DeviceDanceMat.cpp | 8 ++------ Source/Core/Core/HW/SI/SI_DeviceGBAEmu.cpp | 1 - Source/Core/Core/HW/SI/SI_DeviceGCController.cpp | 4 +--- Source/Core/Core/HW/SI/SI_DeviceGCSteeringWheel.cpp | 4 +--- Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp | 5 +---- 7 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Source/Core/Core/HW/SI/SI_Device.cpp b/Source/Core/Core/HW/SI/SI_Device.cpp index 8ea3e75d024..451523624b1 100644 --- a/Source/Core/Core/HW/SI/SI_Device.cpp +++ b/Source/Core/Core/HW/SI/SI_Device.cpp @@ -11,6 +11,7 @@ #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" +#include "Common/Swap.h" #include "Core/HW/SI/SI_DeviceDanceMat.h" #include "Core/HW/SI/SI_DeviceGBA.h" #ifdef HAS_LIBMGBA @@ -87,6 +88,15 @@ void ISIDevice::OnEvent(u64 userdata, s64 cycles_late) { } +int ISIDevice::CreateStatusResponse(u32 si_device_id, u8* buffer) +{ + constexpr int RESPONSE_LENGTH = 3; + + Common::BigEndianValue id(si_device_id); + std::memcpy(buffer, &id, RESPONSE_LENGTH); + return RESPONSE_LENGTH; +} + int SIDevice_GetGBATransferTime(const SystemTimers::SystemTimersManager& timers, EBufferCommands cmd) { diff --git a/Source/Core/Core/HW/SI/SI_Device.h b/Source/Core/Core/HW/SI/SI_Device.h index ebab7e32357..234c475e5f3 100644 --- a/Source/Core/Core/HW/SI/SI_Device.h +++ b/Source/Core/Core/HW/SI/SI_Device.h @@ -123,7 +123,12 @@ public: SIDevices GetDeviceType() const; // Run the SI Buffer + // Return value: + // positive: The response length. + // 0: Response not ready, we will try again `TransferInterval()` cycles later. + // -1: No response. virtual int RunBuffer(u8* buffer, int request_length); + virtual int TransferInterval(); virtual DataResponse GetData(u32& hi, u32& low) = 0; @@ -138,6 +143,9 @@ public: virtual void OnEvent(u64 userdata, s64 cycles_late); protected: + // Only the three high bytes of `si_device_id` are used. + static int CreateStatusResponse(u32 si_device_id, u8* buffer); + Core::System& m_system; int m_device_number; diff --git a/Source/Core/Core/HW/SI/SI_DeviceDanceMat.cpp b/Source/Core/Core/HW/SI/SI_DeviceDanceMat.cpp index d7ca1c8a3a2..10cf79c0eca 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceDanceMat.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceDanceMat.cpp @@ -3,10 +3,7 @@ #include "Core/HW/SI/SI_DeviceDanceMat.h" -#include - #include "Common/CommonTypes.h" -#include "Common/Swap.h" #include "InputCommon/GCPadStatus.h" namespace SerialInterface @@ -22,11 +19,10 @@ int CSIDevice_DanceMat::RunBuffer(u8* buffer, int request_length) const auto command = static_cast(buffer[0]); if (command == EBufferCommands::CMD_STATUS) { + // Only used for logging. ISIDevice::RunBuffer(buffer, request_length); - const u32 id = Common::swap32(SI_DANCEMAT); - std::memcpy(buffer, &id, sizeof(id)); - return sizeof(id); + return CreateStatusResponse(SI_DANCEMAT, buffer); } return CSIDevice_GCController::RunBuffer(buffer, request_length); } diff --git a/Source/Core/Core/HW/SI/SI_DeviceGBAEmu.cpp b/Source/Core/Core/HW/SI/SI_DeviceGBAEmu.cpp index b9c22f1d585..eb7c06343dd 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGBAEmu.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceGBAEmu.cpp @@ -10,7 +10,6 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Common/Swap.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/HW/GBACore.h" diff --git a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp index beb633f4992..270e75f56ad 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp @@ -57,9 +57,7 @@ int CSIDevice_GCController::RunBuffer(u8* buffer, int request_length) case EBufferCommands::CMD_STATUS: case EBufferCommands::CMD_RESET: { - const u32 id = Common::swap32(SI_GC_CONTROLLER); - std::memcpy(buffer, &id, sizeof(id)); - return sizeof(id); + return CreateStatusResponse(SI_GC_CONTROLLER, buffer); } case EBufferCommands::CMD_DIRECT: diff --git a/Source/Core/Core/HW/SI/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/HW/SI/SI_DeviceGCSteeringWheel.cpp index cb639f415e2..a3ca7e9ebef 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGCSteeringWheel.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceGCSteeringWheel.cpp @@ -34,9 +34,7 @@ int CSIDevice_GCSteeringWheel::RunBuffer(u8* buffer, int request_length) case EBufferCommands::CMD_STATUS: case EBufferCommands::CMD_RESET: { - const u32 id = Common::swap32(SI_GC_STEERING); - std::memcpy(buffer, &id, sizeof(id)); - return sizeof(id); + return CreateStatusResponse(SI_GC_STEERING, buffer); } default: return CSIDevice_GCController::RunBuffer(buffer, request_length); diff --git a/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp b/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp index 28ffc13f611..e3655bc904e 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceKeyboard.cpp @@ -9,7 +9,6 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Common/Swap.h" #include "Core/HW/GCKeyboard.h" #include "InputCommon/KeyboardStatus.h" @@ -35,9 +34,7 @@ int CSIDevice_Keyboard::RunBuffer(u8* buffer, int request_length) case EBufferCommands::CMD_STATUS: case EBufferCommands::CMD_RESET: { - const u32 id = Common::swap32(SI_GC_KEYBOARD); - std::memcpy(buffer, &id, sizeof(id)); - return sizeof(id); + return CreateStatusResponse(SI_GC_KEYBOARD, buffer); } case EBufferCommands::CMD_DIRECT_KB: