From 1b0b540de6743d306e1e53583b1ed24215a25334 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:24:06 -0700 Subject: [PATCH] GBA SIO: Move cycle estimation values into core --- include/mgba/internal/gba/sio.h | 4 ++-- src/gba/extra/battlechip.c | 7 +------ src/gba/sio.c | 27 ++++++++++++++++++++++++++- src/gba/sio/lockstep.c | 14 +++----------- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index a546017dc..2576dfffe 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -16,8 +16,6 @@ CXX_GUARD_START #define MAX_GBAS 4 -extern const int GBASIOCyclesPerTransfer[4][MAX_GBAS]; - mLOG_DECLARE_CATEGORY(GBA_SIO); enum { @@ -85,6 +83,8 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value); void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value); uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value); +int32_t GBASIOTransferCycles(struct GBASIO* sio); + void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 12750f67b..3314ff02c 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -105,12 +105,7 @@ static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) { } void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { - int32_t cycles; - if (gate->d.p->mode == GBA_SIO_NORMAL_32) { - cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000; - } else { - cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(gate->d.p->siocnt)][1]; - } + int32_t cycles = GBASIOTransferCycles(gate->d.p); mTimingDeschedule(&gate->d.p->p->timing, &gate->event); mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles); } diff --git a/src/gba/sio.c b/src/gba/sio.c index cdccf1ea3..76d2ea144 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -11,7 +11,7 @@ mLOG_DEFINE_CATEGORY(GBA_SIO, "GBA Serial I/O", "gba.sio"); -const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { +static const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { { 31976, 63427, 94884, 125829 }, { 8378, 16241, 24104, 31457 }, { 5750, 10998, 16241, 20972 }, @@ -318,6 +318,31 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu return value; } +int32_t GBASIOTransferCycles(struct GBASIO* sio) { + int connected = 0; + if (sio->activeDriver) { + connected = sio->activeDriver->connectedDevices(sio->activeDriver); + } + + if (connected < 0 || connected >= MAX_GBAS) { + mLOG(GBA_SIO, ERROR, "SIO driver returned invalid device count %i", connected); + return 0; + } + + switch (sio->mode) { + case GBA_SIO_MULTI: + return GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(sio->siocnt)][connected]; + case GBA_SIO_NORMAL_8: + return 8 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024); + case GBA_SIO_NORMAL_32: + return 32 * GBA_ARM7TDMI_FREQUENCY / ((GBASIONormalIsInternalSc(sio->siocnt) ? 2048 : 256) * 1024); + default: + mLOG(GBA_SIO, STUB, "No cycle count implemented for mode %s", _modeName(sio->mode)); + break; + } + return 0; +} + void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate) { int id = 0; if (sio->activeDriver && sio->activeDriver->deviceId) { diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index b7f5752b4..08c586ae5 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -250,7 +250,7 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver if (!node->id && attached > 1 && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][node->p->d.attached - 1]); + ATOMIC_STORE(node->p->d.transferCycles, GBASIOTransferCycles(node->d.p)); if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing); @@ -502,7 +502,7 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, if (node->p->d.attached < 2) { switch (node->mode) { case GBA_SIO_MULTI: - cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][0]; + cycles = GBASIOTransferCycles(node->d.p); break; case GBA_SIO_NORMAL_8: case GBA_SIO_NORMAL_32: @@ -568,15 +568,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive if ((value & 0x0081) == 0x0081) { if (!node->id) { // Frequency - int32_t cycles; - if (value & 2) { - cycles = 8 * 8; - } else { - cycles = 64 * 8; - } - if (value & 0x1000) { - cycles *= 4; - } + int32_t cycles = GBASIOTransferCycles(node->d.p); if (transferActive == TRANSFER_IDLE) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id);