GBA SIO: Add RCNT bitfield

This commit is contained in:
Vicki Pfau 2024-05-26 00:46:00 -07:00
parent 914d879811
commit 0425dadee9
2 changed files with 19 additions and 6 deletions

View File

@ -52,6 +52,15 @@ DECL_BITS(GBASIOMultiplayer, Id, 4, 2);
DECL_BIT(GBASIOMultiplayer, Error, 6); DECL_BIT(GBASIOMultiplayer, Error, 6);
DECL_BIT(GBASIOMultiplayer, Busy, 7); DECL_BIT(GBASIOMultiplayer, Busy, 7);
DECL_BIT(GBASIOMultiplayer, Irq, 14); DECL_BIT(GBASIOMultiplayer, Irq, 14);
DECL_BITFIELD(GBASIORegisterRCNT, uint16_t);
DECL_BIT(GBASIORegisterRCNT, Sc, 0);
DECL_BIT(GBASIORegisterRCNT, Sd, 1);
DECL_BIT(GBASIORegisterRCNT, Si, 2);
DECL_BIT(GBASIORegisterRCNT, So, 3);
DECL_BIT(GBASIORegisterRCNT, ScDirection, 4);
DECL_BIT(GBASIORegisterRCNT, SdDirection, 5);
DECL_BIT(GBASIORegisterRCNT, SiDirection, 6);
DECL_BIT(GBASIORegisterRCNT, SoDirection, 7);
struct GBASIODriverSet { struct GBASIODriverSet {
struct GBASIODriver* normal; struct GBASIODriver* normal;

View File

@ -86,11 +86,7 @@ static void _switchMode(struct GBASIO* sio) {
if (sio->activeDriver && sio->activeDriver->deviceId) { if (sio->activeDriver && sio->activeDriver->deviceId) {
id = sio->activeDriver->deviceId(sio->activeDriver); id = sio->activeDriver->deviceId(sio->activeDriver);
} }
if (id) { sio->rcnt = GBASIORegisterRCNTSetSi(sio->rcnt, !!id);
sio->rcnt |= 4;
} else {
sio->rcnt &= ~4;
}
break; break;
default: default:
// TODO // TODO
@ -417,9 +413,17 @@ void GBASIOMultiplayerFinishTransfer(struct GBASIO* sio, uint16_t data[4], uint3
sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1]; sio->p->memory.io[GBA_REG(SIOMULTI1)] = data[1];
sio->p->memory.io[GBA_REG(SIOMULTI2)] = data[2]; sio->p->memory.io[GBA_REG(SIOMULTI2)] = data[2];
sio->p->memory.io[GBA_REG(SIOMULTI3)] = data[3]; sio->p->memory.io[GBA_REG(SIOMULTI3)] = data[3];
sio->rcnt |= 1;
sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt); sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt);
sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, id); sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, id);
// This SC level is actually a transient pulse, and probably a hardware glitch.
// Based on analog sampling it seems to just be a spike when the other lines deassert.
// It rapidly falls down to GND but it's high enough that it's read out as a 1 for
// several microseconds, likely around 300-500 cycles. I have not measured if and when
// it returns to 0 afterwards.
sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt);
if (GBASIOMultiplayerIsIrq(sio->siocnt)) { if (GBASIOMultiplayerIsIrq(sio->siocnt)) {
GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate); GBARaiseIRQ(sio->p, GBA_IRQ_SIO, cyclesLate);
} }