diff --git a/Source/Core/Core/HW/SI/SI_Device.cpp b/Source/Core/Core/HW/SI/SI_Device.cpp index 5717fe10a9..401b1178a7 100644 --- a/Source/Core/Core/HW/SI/SI_Device.cpp +++ b/Source/Core/Core/HW/SI/SI_Device.cpp @@ -20,9 +20,15 @@ #include "Core/HW/SI/SI_DeviceGCSteeringWheel.h" #include "Core/HW/SI/SI_DeviceKeyboard.h" #include "Core/HW/SI/SI_DeviceNull.h" +#include "Core/HW/SystemTimers.h" namespace SerialInterface { +constexpr u64 GC_BITS_PER_SECOND = 200000; +constexpr u64 GBA_BITS_PER_SECOND = 250000; +constexpr u64 GC_STOP_BIT_NS = 6500; +constexpr u64 GBA_STOP_BIT_NS = 14000; + std::ostream& operator<<(std::ostream& stream, SIDevices device) { stream << static_cast>(device); @@ -101,6 +107,44 @@ void ISIDevice::OnEvent(u64 userdata, s64 cycles_late) { } +int SIDevice_GetGBATransferTime(EBufferCommands cmd) +{ + u64 gc_bytes_transferred = 1; + u64 gba_bytes_transferred = 1; + u64 stop_bits_ns = GC_STOP_BIT_NS + GBA_STOP_BIT_NS; + + switch (cmd) + { + case EBufferCommands::CMD_RESET: + case EBufferCommands::CMD_STATUS: + { + gba_bytes_transferred = 3; + break; + } + case EBufferCommands::CMD_READ_GBA: + { + gba_bytes_transferred = 5; + break; + } + case EBufferCommands::CMD_WRITE_GBA: + { + gc_bytes_transferred = 5; + break; + } + default: + { + gba_bytes_transferred = 0; + break; + } + } + + u64 cycles = + (gba_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GBA_BITS_PER_SECOND) + + (gc_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GC_BITS_PER_SECOND) + + (stop_bits_ns * SystemTimers::GetTicksPerSecond() / 1000000000LL); + return static_cast(cycles); +} + // Check if a device class is inheriting from CSIDevice_GCController // The goal of this function is to avoid special casing a long list of // device types when there is no "real" input device, e.g. when playing diff --git a/Source/Core/Core/HW/SI/SI_Device.h b/Source/Core/Core/HW/SI/SI_Device.h index 14bd83201c..c2ae9bef87 100644 --- a/Source/Core/Core/HW/SI/SI_Device.h +++ b/Source/Core/Core/HW/SI/SI_Device.h @@ -130,6 +130,7 @@ protected: SIDevices m_device_type; }; +int SIDevice_GetGBATransferTime(EBufferCommands cmd); bool SIDevice_IsGCController(SIDevices type); std::unique_ptr SIDevice_Create(SIDevices device, int port_number); diff --git a/Source/Core/Core/HW/SI/SI_DeviceGBA.cpp b/Source/Core/Core/HW/SI/SI_DeviceGBA.cpp index 57679bbe50..95ab599a8f 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGBA.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceGBA.cpp @@ -34,52 +34,10 @@ int s_num_connected; Common::Flag s_server_running; } // namespace -constexpr auto GC_BITS_PER_SECOND = 200000; -constexpr auto GBA_BITS_PER_SECOND = 250000; -constexpr auto GC_STOP_BIT_NS = 6500; -constexpr auto GBA_STOP_BIT_NS = 14000; constexpr auto SEND_MAX_SIZE = 5, RECV_MAX_SIZE = 5; // --- GameBoy Advance "Link Cable" --- -static int GetTransferTime(EBufferCommands cmd) -{ - u64 gc_bytes_transferred = 1; - u64 gba_bytes_transferred = 1; - u64 stop_bits_ns = GC_STOP_BIT_NS + GBA_STOP_BIT_NS; - - switch (cmd) - { - case EBufferCommands::CMD_RESET: - case EBufferCommands::CMD_STATUS: - { - gba_bytes_transferred = 3; - break; - } - case EBufferCommands::CMD_READ_GBA: - { - gba_bytes_transferred = 5; - break; - } - case EBufferCommands::CMD_WRITE_GBA: - { - gc_bytes_transferred = 5; - break; - } - default: - { - gba_bytes_transferred = 0; - break; - } - } - - u64 cycles = - (gba_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GBA_BITS_PER_SECOND) + - (gc_bytes_transferred * 8 * SystemTimers::GetTicksPerSecond() / GC_BITS_PER_SECOND) + - (stop_bits_ns * SystemTimers::GetTicksPerSecond() / 1000000000LL); - return static_cast(cycles); -} - static void GBAConnectionWaiter() { s_server_running.Set(); @@ -336,7 +294,7 @@ int CSIDevice_GBA::RunBuffer(u8* buffer, int request_length) { int elapsed_time = static_cast(CoreTiming::GetTicks() - m_timestamp_sent); // Tell SI to ask again after TransferInterval() cycles - if (GetTransferTime(m_last_cmd) > elapsed_time) + if (SIDevice_GetGBATransferTime(m_last_cmd) > elapsed_time) return 0; m_next_action = NextAction::ReceiveResponse; [[fallthrough]]; @@ -383,7 +341,7 @@ int CSIDevice_GBA::RunBuffer(u8* buffer, int request_length) int CSIDevice_GBA::TransferInterval() { - return GetTransferTime(m_last_cmd); + return SIDevice_GetGBATransferTime(m_last_cmd); } bool CSIDevice_GBA::GetData(u32& hi, u32& low)