SI/DeviceGBA: Expose GetTransferTime

This commit is contained in:
Bonta 2021-07-04 13:03:56 +02:00
parent fdcee30a3d
commit d849d56695
3 changed files with 47 additions and 44 deletions

View File

@ -20,9 +20,15 @@
#include "Core/HW/SI/SI_DeviceGCSteeringWheel.h" #include "Core/HW/SI/SI_DeviceGCSteeringWheel.h"
#include "Core/HW/SI/SI_DeviceKeyboard.h" #include "Core/HW/SI/SI_DeviceKeyboard.h"
#include "Core/HW/SI/SI_DeviceNull.h" #include "Core/HW/SI/SI_DeviceNull.h"
#include "Core/HW/SystemTimers.h"
namespace SerialInterface 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) std::ostream& operator<<(std::ostream& stream, SIDevices device)
{ {
stream << static_cast<std::underlying_type_t<SIDevices>>(device); stream << static_cast<std::underlying_type_t<SIDevices>>(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<int>(cycles);
}
// Check if a device class is inheriting from CSIDevice_GCController // Check if a device class is inheriting from CSIDevice_GCController
// The goal of this function is to avoid special casing a long list of // 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 // device types when there is no "real" input device, e.g. when playing

View File

@ -130,6 +130,7 @@ protected:
SIDevices m_device_type; SIDevices m_device_type;
}; };
int SIDevice_GetGBATransferTime(EBufferCommands cmd);
bool SIDevice_IsGCController(SIDevices type); bool SIDevice_IsGCController(SIDevices type);
std::unique_ptr<ISIDevice> SIDevice_Create(SIDevices device, int port_number); std::unique_ptr<ISIDevice> SIDevice_Create(SIDevices device, int port_number);

View File

@ -34,52 +34,10 @@ int s_num_connected;
Common::Flag s_server_running; Common::Flag s_server_running;
} // namespace } // 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; constexpr auto SEND_MAX_SIZE = 5, RECV_MAX_SIZE = 5;
// --- GameBoy Advance "Link Cable" --- // --- 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<int>(cycles);
}
static void GBAConnectionWaiter() static void GBAConnectionWaiter()
{ {
s_server_running.Set(); s_server_running.Set();
@ -336,7 +294,7 @@ int CSIDevice_GBA::RunBuffer(u8* buffer, int request_length)
{ {
int elapsed_time = static_cast<int>(CoreTiming::GetTicks() - m_timestamp_sent); int elapsed_time = static_cast<int>(CoreTiming::GetTicks() - m_timestamp_sent);
// Tell SI to ask again after TransferInterval() cycles // 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; return 0;
m_next_action = NextAction::ReceiveResponse; m_next_action = NextAction::ReceiveResponse;
[[fallthrough]]; [[fallthrough]];
@ -383,7 +341,7 @@ int CSIDevice_GBA::RunBuffer(u8* buffer, int request_length)
int CSIDevice_GBA::TransferInterval() int CSIDevice_GBA::TransferInterval()
{ {
return GetTransferTime(m_last_cmd); return SIDevice_GetGBATransferTime(m_last_cmd);
} }
bool CSIDevice_GBA::GetData(u32& hi, u32& low) bool CSIDevice_GBA::GetData(u32& hi, u32& low)