From 54c9e9d411bbc03a27ab9ae418227162c3855aef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:39:15 -0700 Subject: [PATCH] GBA SIO: Move NORMAL finishing logic out of drivers --- include/mgba/internal/gba/sio.h | 2 ++ src/gba/extra/battlechip.c | 7 +------ src/gba/sio.c | 17 +++++++++++++++++ src/gba/sio/gbp.c | 9 +-------- src/gba/sio/lockstep.c | 20 ++++---------------- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index 2576dfffe..43acaa7b8 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -86,6 +86,8 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu int32_t GBASIOTransferCycles(struct GBASIO* sio); void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); +void GBASIONormal8FinishTransfer(struct GBASIO* sio, uint8_t data, uint32_t cyclesLate); +void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, 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 3314ff02c..040ec80b8 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -115,12 +115,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle struct GBASIOBattlechipGate* gate = user; if (gate->d.p->mode == GBA_SIO_NORMAL_32) { - gate->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0; - gate->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0; - gate->d.p->siocnt = GBASIONormalClearStart(gate->d.p->siocnt); - if (GBASIONormalIsIrq(gate->d.p->siocnt)) { - GBARaiseIRQ(gate->d.p->p, GBA_IRQ_SIO, cyclesLate); - } + GBASIONormal32FinishTransfer(gate->d.p, 0, cyclesLate); return; } diff --git a/src/gba/sio.c b/src/gba/sio.c index 76d2ea144..56dc55a9f 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -360,6 +360,23 @@ void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint3 } } +void GBASIONormal8FinishTransfer(struct GBASIO* sio, uint8_t data, uint32_t cyclesLate) { + sio->siocnt = GBASIONormalClearStart(sio->siocnt); + sio->p->memory.io[GBA_REG(SIODATA8)] = data; + if (GBASIONormalIsIrq(sio->siocnt)) { + GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); + } +} + +void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, uint32_t cyclesLate) { + sio->siocnt = GBASIONormalClearStart(sio->siocnt); + sio->p->memory.io[GBA_REG(SIODATA32_LO)] = data; + sio->p->memory.io[GBA_REG(SIODATA32_HI)] = data >> 16; + if (GBASIONormalIsIrq(sio->siocnt)) { + GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); + } +} + int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) { switch (command) { case JOY_RESET: diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index e1f008274..37944d596 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -143,7 +143,6 @@ static int _gbpSioConnectedDevices(struct GBASIODriver* driver) { void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { UNUSED(timing); - UNUSED(cyclesLate); struct GBASIOPlayer* gbp = user; uint32_t tx = 0; int txPosition = gbp->txPosition; @@ -155,11 +154,5 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat } tx = _gbpTxData[txPosition]; ++gbp->txPosition; - gbp->p->memory.io[GBA_REG(SIODATA32_LO)] = tx; - gbp->p->memory.io[GBA_REG(SIODATA32_HI)] = tx >> 16; - if (GBASIONormalIsIrq(gbp->d.p->siocnt)) { - GBARaiseIRQ(gbp->p, GBA_IRQ_SIO, cyclesLate); - } - gbp->d.p->siocnt = GBASIONormalClearStart(gbp->d.p->siocnt); - gbp->p->memory.io[GBA_REG(SIOCNT)] = gbp->d.p->siocnt & ~0x0080; + GBASIONormal32FinishTransfer(gbp->d.p, tx, cyclesLate); } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 08c586ae5..67b359234 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -283,31 +283,19 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { GBASIOMultiplayerFinishTransfer(sio, node->p->multiRecv, 0); break; case GBA_SIO_NORMAL_8: - // TODO - sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - node->d.p->p->memory.io[GBA_REG(SIODATA8)] = node->p->normalRecv[node->id - 1] & 0xFF; + GBASIONormal8FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0); } else { - node->d.p->p->memory.io[GBA_REG(SIODATA8)] = 0xFFFF; - } - if (GBASIONormalIsIrq(sio->siocnt)) { - GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); + GBASIONormal8FinishTransfer(sio, 0xFF, 0); } break; case GBA_SIO_NORMAL_32: - // TODO - sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); - node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = node->p->normalRecv[node->id - 1]; - node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = node->p->normalRecv[node->id - 1] >> 16; + GBASIONormal32FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0); } else { - node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0xFFFF; - node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0xFFFF; - } - if (GBASIONormalIsIrq(sio->siocnt)) { - GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); + GBASIONormal32FinishTransfer(sio, 0xFFFFFFFF, 0); } break; default: