all repos — mgba @ c662b59e9942bfffd69ed6754cc334de86f89e63

mGBA Game Boy Advance Emulator

GB: Allow player 2 to act as shift clock
Jeffrey Pfau jeffrey@endrift.com
Mon, 26 Dec 2016 17:13:53 -0800
commit

c662b59e9942bfffd69ed6754cc334de86f89e63

parent

269b18d8aab439ebb08ff4b02d744a41bf79fb78

2 files changed, 12 insertions(+), 5 deletions(-)

jump to
M src/gb/sio/lockstep.csrc/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.hsrc/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 {