GBA SIO: Move NORMAL finishing logic out of drivers

This commit is contained in:
Vicki Pfau 2024-05-21 23:39:15 -07:00
parent 1b0b540de6
commit 54c9e9d411
5 changed files with 25 additions and 30 deletions

View File

@ -86,6 +86,8 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu
int32_t GBASIOTransferCycles(struct GBASIO* sio); int32_t GBASIOTransferCycles(struct GBASIO* sio);
void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint32_t cyclesLate); 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); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data);

View File

@ -115,12 +115,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
struct GBASIOBattlechipGate* gate = user; struct GBASIOBattlechipGate* gate = user;
if (gate->d.p->mode == GBA_SIO_NORMAL_32) { if (gate->d.p->mode == GBA_SIO_NORMAL_32) {
gate->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0; GBASIONormal32FinishTransfer(gate->d.p, 0, cyclesLate);
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);
}
return; return;
} }

View File

@ -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) { int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data) {
switch (command) { switch (command) {
case JOY_RESET: case JOY_RESET:

View File

@ -143,7 +143,6 @@ static int _gbpSioConnectedDevices(struct GBASIODriver* driver) {
void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
UNUSED(timing); UNUSED(timing);
UNUSED(cyclesLate);
struct GBASIOPlayer* gbp = user; struct GBASIOPlayer* gbp = user;
uint32_t tx = 0; uint32_t tx = 0;
int txPosition = gbp->txPosition; int txPosition = gbp->txPosition;
@ -155,11 +154,5 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat
} }
tx = _gbpTxData[txPosition]; tx = _gbpTxData[txPosition];
++gbp->txPosition; ++gbp->txPosition;
gbp->p->memory.io[GBA_REG(SIODATA32_LO)] = tx; GBASIONormal32FinishTransfer(gbp->d.p, tx, cyclesLate);
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;
} }

View File

@ -283,31 +283,19 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) {
GBASIOMultiplayerFinishTransfer(sio, node->p->multiRecv, 0); GBASIOMultiplayerFinishTransfer(sio, node->p->multiRecv, 0);
break; break;
case GBA_SIO_NORMAL_8: case GBA_SIO_NORMAL_8:
// TODO
sio->siocnt = GBASIONormalClearStart(sio->siocnt);
if (node->id) { if (node->id) {
sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); 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 { } else {
node->d.p->p->memory.io[GBA_REG(SIODATA8)] = 0xFFFF; GBASIONormal8FinishTransfer(sio, 0xFF, 0);
}
if (GBASIONormalIsIrq(sio->siocnt)) {
GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0);
} }
break; break;
case GBA_SIO_NORMAL_32: case GBA_SIO_NORMAL_32:
// TODO
sio->siocnt = GBASIONormalClearStart(sio->siocnt);
if (node->id) { if (node->id) {
sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); 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]; GBASIONormal32FinishTransfer(sio, node->p->normalRecv[node->id - 1], 0);
node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = node->p->normalRecv[node->id - 1] >> 16;
} else { } else {
node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0xFFFF; GBASIONormal32FinishTransfer(sio, 0xFFFFFFFF, 0);
node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0xFFFF;
}
if (GBASIONormalIsIrq(sio->siocnt)) {
GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0);
} }
break; break;
default: default: