mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Move NORMAL finishing logic out of drivers
This commit is contained in:
parent
1b0b540de6
commit
54c9e9d411
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue