GB: Allow player 2 to act as shift clock
Jeffrey Pfau jeffrey@endrift.com
Mon, 26 Dec 2016 17:13:53 -0800
2 files changed,
12 insertions(+),
5 deletions(-)
M
src/gb/sio/lockstep.c
→
src/gb/sio/lockstep.c
@@ -22,6 +22,7 @@ lockstep->players[0] = NULL;
lockstep->players[1] = NULL; lockstep->pendingSB[0] = 0xFF; lockstep->pendingSB[1] = 0xFF; + lockstep->masterClaimed = false; } void GBSIOLockstepNodeCreate(struct GBSIOLockstepNode* node) {@@ -135,6 +136,7 @@ break;
case TRANSFER_FINISHED: // Everything's settled. We're done. _finishTransfer(node); + ATOMIC_STORE(node->p->masterClaimed, false); node->nextEvent += LOCKSTEP_INCREMENT; ATOMIC_STORE(node->p->d.transferActive, TRANSFER_IDLE); break;@@ -226,11 +228,15 @@ }
static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t value) { struct GBSIOLockstepNode* node = (struct GBSIOLockstepNode*) driver; - if (!node->id && (value & 0x81) == 0x81) { - node->p->d.transferActive = TRANSFER_STARTING; - node->p->d.transferCycles = GBSIOCyclesPerTransfer[(value >> 1) & 1]; - mTimingDeschedule(&driver->p->p->timing, &node->event); - mTimingSchedule(&driver->p->p->timing, &node->event, 0); + if ((value & 0x81) == 0x81 && node->p->d.attached > 1) { + bool claimed = false; + if (ATOMIC_CMPXCHG(node->p->masterClaimed, claimed, true)) { + node->p->d.transferActive = TRANSFER_STARTING; + node->p->d.transferCycles = GBSIOCyclesPerTransfer[(value >> 1) & 1]; + mTimingDeschedule(&driver->p->p->timing, &driver->p->event); + mTimingDeschedule(&driver->p->p->timing, &node->event); + mTimingSchedule(&driver->p->p->timing, &node->event, 0); + } } return value; }
M
src/gb/sio/lockstep.h
→
src/gb/sio/lockstep.h
@@ -17,6 +17,7 @@ struct mLockstep d;
struct GBSIOLockstepNode* players[MAX_GBS]; uint8_t pendingSB[MAX_GBS]; + bool masterClaimed; }; struct GBSIOLockstepNode {