mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Move starting/end timing logic out of drivers
This commit is contained in:
parent
435c4aa243
commit
621eb4d425
|
@ -119,6 +119,10 @@ struct GBASIODriver {
|
|||
int (*deviceId)(struct GBASIODriver* driver);
|
||||
uint16_t (*writeSIOCNT)(struct GBASIODriver* driver, uint16_t value);
|
||||
uint16_t (*writeRCNT)(struct GBASIODriver* driver, uint16_t value);
|
||||
bool (*start)(struct GBASIODriver* driver);
|
||||
void (*finishMultiplayer)(struct GBASIODriver* driver, uint16_t data[4]);
|
||||
uint8_t (*finishNormal8)(struct GBASIODriver* driver);
|
||||
uint32_t (*finishNormal32)(struct GBASIODriver* driver);
|
||||
};
|
||||
|
||||
enum GBASIOBattleChipGateFlavor {
|
||||
|
@ -130,7 +134,6 @@ enum GBASIOBattleChipGateFlavor {
|
|||
|
||||
struct GBASIOBattlechipGate {
|
||||
struct GBASIODriver d;
|
||||
struct mTimingEvent event;
|
||||
uint16_t chipId;
|
||||
uint16_t data[2];
|
||||
int state;
|
||||
|
|
|
@ -191,7 +191,7 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
|
|||
* | bits 2 - 3: GB Player inputs posted
|
||||
* | bits 4 - 8: GB Player transmit position
|
||||
* | bits 9 - 23: Reserved
|
||||
* 0x002C4 - 0x002C7: Game Boy Player next event
|
||||
* 0x002C4 - 0x002C7: SIO next event
|
||||
* 0x002C8 - 0x002CB: Current DMA transfer word
|
||||
* 0x002CC - 0x002CF: Last DMA transfer PC
|
||||
* 0x002D0 - 0x002DF: Matrix memory command buffer
|
||||
|
@ -370,7 +370,7 @@ struct GBASerializedState {
|
|||
uint8_t lightSample;
|
||||
GBASerializedHWFlags2 flags2;
|
||||
GBASerializedHWFlags3 flags3;
|
||||
uint32_t gbpNextEvent;
|
||||
uint32_t sioNextEvent;
|
||||
} hw;
|
||||
|
||||
uint32_t dmaTransferRegister;
|
||||
|
|
|
@ -21,7 +21,6 @@ struct GBASIOPlayer {
|
|||
struct GBA* p;
|
||||
unsigned inputsPosted;
|
||||
int txPosition;
|
||||
struct mTimingEvent event;
|
||||
struct GBASIOPlayerKeyCallback callback;
|
||||
bool oldOpposingDirections;
|
||||
struct mKeyCallback* oldCallback;
|
||||
|
|
|
@ -486,10 +486,10 @@ void GBAHardwareSerialize(const struct GBACartridgeHardware* hw, struct GBASeria
|
|||
flags2 = GBASerializedHWFlags2SetTiltState(flags2, hw->tiltState);
|
||||
flags2 = GBASerializedHWFlags1SetLightCounter(flags2, hw->lightCounter);
|
||||
|
||||
// GBP stuff is only here for legacy reasons
|
||||
// GBP/SIO stuff is only here for legacy reasons
|
||||
flags2 = GBASerializedHWFlags2SetGbpInputsPosted(flags2, hw->p->sio.gbp.inputsPosted);
|
||||
flags2 = GBASerializedHWFlags2SetGbpTxPosition(flags2, hw->p->sio.gbp.txPosition);
|
||||
STORE_32(hw->p->sio.gbp.event.when - mTimingCurrentTime(&hw->p->timing), 0, &state->hw.gbpNextEvent);
|
||||
STORE_32(hw->p->sio.completeEvent.when - mTimingCurrentTime(&hw->p->timing), 0, &state->hw.sioNextEvent);
|
||||
|
||||
state->hw.flags2 = flags2;
|
||||
}
|
||||
|
@ -520,16 +520,16 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer
|
|||
hw->lightSample = state->hw.lightSample;
|
||||
hw->lightEdge = GBASerializedHWFlags1GetLightEdge(flags1);
|
||||
|
||||
// GBP stuff is only here for legacy reasons
|
||||
// GBP/SIO stuff is only here for legacy reasons
|
||||
hw->p->sio.gbp.inputsPosted = GBASerializedHWFlags2GetGbpInputsPosted(state->hw.flags2);
|
||||
hw->p->sio.gbp.txPosition = GBASerializedHWFlags2GetGbpTxPosition(state->hw.flags2);
|
||||
|
||||
uint32_t when;
|
||||
LOAD_32(when, 0, &state->hw.gbpNextEvent);
|
||||
LOAD_32(when, 0, &state->hw.sioNextEvent);
|
||||
if (hw->devices & HW_GB_PLAYER) {
|
||||
GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32);
|
||||
if (hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) {
|
||||
mTimingSchedule(&hw->p->timing, &hw->p->sio.gbp.event, when);
|
||||
}
|
||||
}
|
||||
if ((hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) && when < 0x20000) {
|
||||
mTimingSchedule(&hw->p->timing, &hw->p->sio.completeEvent, when);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,25 +37,15 @@ static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver);
|
|||
static uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value);
|
||||
static bool GBASIOBattlechipGateHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver);
|
||||
|
||||
static void _battlechipTransfer(struct GBASIOBattlechipGate* gate);
|
||||
static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate);
|
||||
static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, uint16_t data[4]);
|
||||
|
||||
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
|
||||
gate->d.init = NULL;
|
||||
gate->d.deinit = NULL;
|
||||
memset(&gate->d, 0, sizeof(gate->d));
|
||||
gate->d.load = GBASIOBattlechipGateLoad;
|
||||
gate->d.unload = NULL;
|
||||
gate->d.writeSIOCNT = GBASIOBattlechipGateWriteSIOCNT;
|
||||
gate->d.setMode = NULL;
|
||||
gate->d.handlesMode = GBASIOBattlechipGateHandlesMode;
|
||||
gate->d.connectedDevices = GBASIOBattlechipGateConnectedDevices;
|
||||
gate->d.deviceId = NULL;
|
||||
gate->d.writeRCNT = NULL;
|
||||
|
||||
gate->event.context = gate;
|
||||
gate->event.callback = _battlechipTransferEvent;
|
||||
gate->event.priority = 0x80;
|
||||
gate->d.finishMultiplayer = GBASIOBattlechipGateFinishMultiplayer;
|
||||
|
||||
gate->chipId = 0;
|
||||
gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE;
|
||||
|
@ -70,12 +60,9 @@ bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) {
|
|||
}
|
||||
|
||||
uint16_t GBASIOBattlechipGateWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) {
|
||||
struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver;
|
||||
UNUSED(driver);
|
||||
value &= ~0xC;
|
||||
value |= 0x8;
|
||||
if (value & 0x80) {
|
||||
_battlechipTransfer(gate);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -95,20 +82,8 @@ static int GBASIOBattlechipGateConnectedDevices(struct GBASIODriver* driver) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void _battlechipTransfer(struct GBASIOBattlechipGate* gate) {
|
||||
int32_t cycles = GBASIOTransferCycles(gate->d.p);
|
||||
mTimingDeschedule(&gate->d.p->p->timing, &gate->event);
|
||||
mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles);
|
||||
}
|
||||
|
||||
void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
||||
UNUSED(timing);
|
||||
struct GBASIOBattlechipGate* gate = user;
|
||||
|
||||
if (gate->d.p->mode == GBA_SIO_NORMAL_32) {
|
||||
GBASIONormal32FinishTransfer(gate->d.p, 0, cyclesLate);
|
||||
return;
|
||||
}
|
||||
static void GBASIOBattlechipGateFinishMultiplayer(struct GBASIODriver* driver, uint16_t data[4]) {
|
||||
struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver;
|
||||
|
||||
uint16_t cmd = gate->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)];
|
||||
uint16_t reply = 0xFFFF;
|
||||
|
@ -189,8 +164,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
|
|||
mLOG(GBA_BATTLECHIP, DEBUG, "Gate: %04X (%i)", reply, gate->state);
|
||||
++gate->state;
|
||||
|
||||
uint16_t data[4] = {
|
||||
cmd, reply, 0xFFFF, 0xFFFF
|
||||
};
|
||||
GBASIOMultiplayerFinishTransfer(gate->d.p, data, cyclesLate);
|
||||
data[0] = cmd;
|
||||
data[1] = reply;
|
||||
data[2] = 0xFFFF;
|
||||
data[3] = 0xFFFF;
|
||||
}
|
||||
|
|
|
@ -221,6 +221,17 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
|
|||
}
|
||||
}
|
||||
|
||||
static void _startTransfer(struct GBASIO* sio) {
|
||||
if (sio->activeDriver && sio->activeDriver->start) {
|
||||
if (!sio->activeDriver->start(sio->activeDriver)) {
|
||||
// Transfer completion is handled internally to the driver
|
||||
return;
|
||||
}
|
||||
}
|
||||
mTimingDeschedule(&sio->p->timing, &sio->completeEvent);
|
||||
mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio));
|
||||
}
|
||||
|
||||
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
||||
if ((value ^ sio->siocnt) & 0x3000) {
|
||||
sio->siocnt = value & 0x3000;
|
||||
|
@ -256,6 +267,18 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
// investigation than I managed, apparently.
|
||||
sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt);
|
||||
|
||||
if (GBASIOMultiplayerIsBusy(value) && !GBASIOMultiplayerIsBusy(sio->siocnt)) {
|
||||
if (!id) {
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF;
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF;
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF;
|
||||
sio->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF;
|
||||
sio->rcnt = GBASIORegisterRCNTClearSc(sio->rcnt);
|
||||
_startTransfer(sio);
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GBA_SIO_NORMAL_8:
|
||||
case GBA_SIO_NORMAL_32:
|
||||
|
@ -264,6 +287,13 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
if (GBASIONormalGetSc(value)) {
|
||||
sio->rcnt = GBASIORegisterRCNTFillSc(sio->rcnt);
|
||||
}
|
||||
if (GBASIONormalIsStart(value) && !GBASIONormalIsStart(sio->siocnt)) {
|
||||
if (GBASIONormalIsSc(value)) {
|
||||
_startTransfer(sio);
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// TODO
|
||||
|
@ -277,15 +307,6 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
|||
case GBA_SIO_NORMAL_8:
|
||||
case GBA_SIO_NORMAL_32:
|
||||
value = GBASIONormalFillSi(value);
|
||||
if ((value & 0x0081) == 0x0081) {
|
||||
if (GBASIONormalIsIrq(value)) {
|
||||
mTimingDeschedule(&sio->p->timing, &sio->completeEvent);
|
||||
mTimingSchedule(&sio->p->timing, &sio->completeEvent, GBASIOTransferCycles(sio));
|
||||
} else {
|
||||
// TODO: Test this on hardware to see if this is correct
|
||||
value = GBASIONormalClearStart(value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GBA_SIO_MULTI:
|
||||
value = GBASIOMultiplayerFillReady(value);
|
||||
|
@ -473,16 +494,29 @@ void GBASIONormal32FinishTransfer(struct GBASIO* sio, uint32_t data, uint32_t cy
|
|||
static void _sioFinish(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
||||
UNUSED(timing);
|
||||
struct GBASIO* sio = user;
|
||||
uint16_t data[4] = {0, 0, 0, 0};
|
||||
union {
|
||||
uint16_t multi[4];
|
||||
uint8_t normal8;
|
||||
uint32_t normal32;
|
||||
} data = {0};
|
||||
switch (sio->mode) {
|
||||
case GBA_SIO_MULTI:
|
||||
GBASIOMultiplayerFinishTransfer(sio, data, cyclesLate);
|
||||
if (sio->activeDriver && sio->activeDriver->finishMultiplayer) {
|
||||
sio->activeDriver->finishMultiplayer(sio->activeDriver, data.multi);
|
||||
}
|
||||
GBASIOMultiplayerFinishTransfer(sio, data.multi, cyclesLate);
|
||||
break;
|
||||
case GBA_SIO_NORMAL_8:
|
||||
GBASIONormal8FinishTransfer(sio, 0, cyclesLate);
|
||||
if (sio->activeDriver && sio->activeDriver->finishNormal8) {
|
||||
data.normal8 = sio->activeDriver->finishNormal8(sio->activeDriver);
|
||||
}
|
||||
GBASIONormal8FinishTransfer(sio, data.normal8, cyclesLate);
|
||||
break;
|
||||
case GBA_SIO_NORMAL_32:
|
||||
GBASIONormal32FinishTransfer(sio, 0, cyclesLate);
|
||||
if (sio->activeDriver && sio->activeDriver->finishNormal32) {
|
||||
data.normal32 = sio->activeDriver->finishNormal32(sio->activeDriver);
|
||||
}
|
||||
GBASIONormal32FinishTransfer(sio, data.normal32, cyclesLate);
|
||||
break;
|
||||
default:
|
||||
// TODO
|
||||
|
|
|
@ -33,15 +33,12 @@ static int32_t _processCommand(struct GBASIODolphin* dol, uint32_t cyclesLate);
|
|||
static void _flush(struct GBASIODolphin* dol);
|
||||
|
||||
void GBASIODolphinCreate(struct GBASIODolphin* dol) {
|
||||
memset(&dol->d, 0, sizeof(dol->d));
|
||||
dol->d.init = GBASIODolphinInit;
|
||||
dol->d.load = GBASIODolphinLoad;
|
||||
dol->d.unload = GBASIODolphinUnload;
|
||||
dol->d.writeSIOCNT = NULL;
|
||||
dol->d.setMode = NULL;
|
||||
dol->d.handlesMode = GBASIODolphinHandlesMode;
|
||||
dol->d.connectedDevices = GBASIODolphinConnectedDevices;
|
||||
dol->d.deviceId = NULL;
|
||||
dol->d.writeSIOCNT = NULL;
|
||||
dol->event.context = dol;
|
||||
dol->event.name = "GB SIO Lockstep";
|
||||
dol->event.callback = GBASIODolphinProcessEvents;
|
||||
|
|
|
@ -16,7 +16,8 @@ static uint16_t _gbpRead(struct mKeyCallback*);
|
|||
static uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value);
|
||||
static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
static int _gbpSioConnectedDevices(struct GBASIODriver* driver);
|
||||
static void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate);
|
||||
static bool _gbpSioStart(struct GBASIODriver* driver);
|
||||
static uint32_t _gbpSioFinishNormal32(struct GBASIODriver* driver);
|
||||
|
||||
static const uint8_t _logoPalette[] = {
|
||||
0xDF, 0xFF, 0x0C, 0x64, 0x0C, 0xE4, 0x2D, 0xE4, 0x4E, 0x64, 0x4E, 0xE4, 0x6E, 0xE4, 0xAF, 0x68,
|
||||
|
@ -45,20 +46,12 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) {
|
|||
gbp->callback.d.readKeys = _gbpRead;
|
||||
gbp->callback.d.requireOpposingDirections = true;
|
||||
gbp->callback.p = gbp;
|
||||
gbp->d.init = NULL;
|
||||
gbp->d.deinit = NULL;
|
||||
gbp->d.load = NULL;
|
||||
gbp->d.unload = NULL;
|
||||
memset(&gbp->d, 0, sizeof(gbp->d));
|
||||
gbp->d.writeSIOCNT = _gbpSioWriteSIOCNT;
|
||||
gbp->d.setMode = NULL;
|
||||
gbp->d.handlesMode = _gbpSioHandlesMode;
|
||||
gbp->d.connectedDevices = _gbpSioConnectedDevices;
|
||||
gbp->d.deviceId = NULL;
|
||||
gbp->d.writeRCNT = NULL;
|
||||
gbp->event.context = gbp;
|
||||
gbp->event.name = "GBA SIO Game Boy Player";
|
||||
gbp->event.callback = _gbpSioProcessEvents;
|
||||
gbp->event.priority = 0x80;
|
||||
gbp->d.start = _gbpSioStart;
|
||||
gbp->d.finishNormal32 = _gbpSioFinishNormal32;
|
||||
}
|
||||
|
||||
void GBASIOPlayerReset(struct GBASIOPlayer* gbp) {
|
||||
|
@ -108,13 +101,16 @@ uint16_t _gbpRead(struct mKeyCallback* callback) {
|
|||
}
|
||||
|
||||
uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) {
|
||||
UNUSED(driver);
|
||||
return value & 0x78FB;
|
||||
}
|
||||
|
||||
bool _gbpSioStart(struct GBASIODriver* driver) {
|
||||
struct GBASIOPlayer* gbp = (struct GBASIOPlayer*) driver;
|
||||
if (value & 0x0080) {
|
||||
uint32_t rx = gbp->p->memory.io[GBA_REG(SIODATA32_LO)] | (gbp->p->memory.io[GBA_REG(SIODATA32_HI)] << 16);
|
||||
if (gbp->txPosition < 12 && gbp->txPosition > 0) {
|
||||
// TODO: Check expected
|
||||
} else if (gbp->txPosition >= 12) {
|
||||
uint32_t mask = 0x33;
|
||||
// 0x00 = Stop
|
||||
// 0x11 = Hard Stop
|
||||
// 0x22 = Start
|
||||
|
@ -124,11 +120,7 @@ uint16_t _gbpSioWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) {
|
|||
gbp->p->lastRumble = currentTime;
|
||||
}
|
||||
}
|
||||
mTimingDeschedule(&gbp->p->timing, &gbp->event);
|
||||
mTimingSchedule(&gbp->p->timing, &gbp->event, 2048);
|
||||
}
|
||||
value &= 0x78FB;
|
||||
return value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _gbpSioHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode) {
|
||||
|
@ -141,9 +133,8 @@ static int _gbpSioConnectedDevices(struct GBASIODriver* driver) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
||||
UNUSED(timing);
|
||||
struct GBASIOPlayer* gbp = user;
|
||||
uint32_t _gbpSioFinishNormal32(struct GBASIODriver* driver) {
|
||||
struct GBASIOPlayer* gbp = (struct GBASIOPlayer*) driver;
|
||||
uint32_t tx = 0;
|
||||
int txPosition = gbp->txPosition;
|
||||
if (txPosition > 16) {
|
||||
|
@ -154,5 +145,5 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat
|
|||
}
|
||||
tx = _gbpTxData[txPosition];
|
||||
++gbp->txPosition;
|
||||
GBASIONormal32FinishTransfer(gbp->d.p, tx, cyclesLate);
|
||||
return tx;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver);
|
|||
static bool GBASIOLockstepNodeHandlesMode(struct GBASIODriver* driver, enum GBASIOMode mode);
|
||||
static int GBASIOLockstepNodeConnectedDevices(struct GBASIODriver* driver);
|
||||
static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver);
|
||||
static bool GBASIOLockstepNodeStart(struct GBASIODriver* driver);
|
||||
static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value);
|
||||
static uint16_t GBASIOLockstepNodeNormalWriteSIOCNT(struct GBASIODriver* driver, uint16_t value);
|
||||
static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate);
|
||||
|
@ -37,16 +38,16 @@ void GBASIOLockstepInit(struct GBASIOLockstep* lockstep) {
|
|||
}
|
||||
|
||||
void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) {
|
||||
memset(&node->d, 0, sizeof(node->d));
|
||||
node->d.init = GBASIOLockstepNodeInit;
|
||||
node->d.deinit = GBASIOLockstepNodeDeinit;
|
||||
node->d.load = GBASIOLockstepNodeLoad;
|
||||
node->d.unload = GBASIOLockstepNodeUnload;
|
||||
node->d.setMode = NULL;
|
||||
node->d.handlesMode = GBASIOLockstepNodeHandlesMode;
|
||||
node->d.connectedDevices = GBASIOLockstepNodeConnectedDevices;
|
||||
node->d.deviceId = GBASIOLockstepNodeDeviceId;
|
||||
node->d.start = GBASIOLockstepNodeStart;
|
||||
node->d.writeSIOCNT = NULL;
|
||||
node->d.writeRCNT = NULL;
|
||||
}
|
||||
|
||||
bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) {
|
||||
|
@ -224,6 +225,11 @@ static int GBASIOLockstepNodeDeviceId(struct GBASIODriver* driver) {
|
|||
return node->id;
|
||||
}
|
||||
|
||||
static bool GBASIOLockstepNodeStart(struct GBASIODriver* driver) {
|
||||
UNUSED(driver);
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint16_t GBASIOLockstepNodeMultiWriteSIOCNT(struct GBASIODriver* driver, uint16_t value) {
|
||||
struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;
|
||||
|
||||
|
@ -319,10 +325,6 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) {
|
|||
switch (node->mode) {
|
||||
case GBA_SIO_MULTI:
|
||||
node->p->multiRecv[0] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)];
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI2)] = 0xFFFF;
|
||||
node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF;
|
||||
node->p->multiRecv[1] = 0xFFFF;
|
||||
node->p->multiRecv[2] = 0xFFFF;
|
||||
node->p->multiRecv[3] = 0xFFFF;
|
||||
|
|
Loading…
Reference in New Issue