mirror of https://github.com/mgba-emu/mgba.git
GB SIO: Further fix bidirectional transfer starting
This commit is contained in:
parent
9b2d4bc68e
commit
6f08b740f9
1
CHANGES
1
CHANGES
|
@ -4,6 +4,7 @@ Features:
|
|||
- Debugger: Add range watchpoints
|
||||
Emulation fixes:
|
||||
- GB Serialize: Don't write BGP/OBP when loading SCGB state (fixes mgba.io/i/2694)
|
||||
- GB SIO: Further fix bidirectional transfer starting
|
||||
- GBA: Fix resetting key IRQ state (fixes mgba.io/i/2716)
|
||||
- GBA Video: Ignore disabled backgrounds as OBJ blend target (fixes mgba.io/i/2489)
|
||||
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)
|
||||
|
|
|
@ -157,7 +157,7 @@ static int32_t _masterUpdate(struct GBSIOLockstepNode* node) {
|
|||
}
|
||||
}
|
||||
// Tell the other GBs they can continue up to where we were
|
||||
node->p->d.addCycles(&node->p->d, node->id, node->eventDiff);
|
||||
node->p->d.addCycles(&node->p->d, 0, node->eventDiff);
|
||||
#ifndef NDEBUG
|
||||
node->phase = node->p->d.transferActive;
|
||||
#endif
|
||||
|
@ -169,26 +169,28 @@ static int32_t _masterUpdate(struct GBSIOLockstepNode* node) {
|
|||
|
||||
static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) {
|
||||
enum mLockstepPhase transferActive;
|
||||
int id;
|
||||
|
||||
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
||||
ATOMIC_LOAD(id, node->id);
|
||||
|
||||
bool signal = false;
|
||||
switch (transferActive) {
|
||||
case TRANSFER_IDLE:
|
||||
node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT);
|
||||
node->p->d.addCycles(&node->p->d, id, LOCKSTEP_INCREMENT);
|
||||
break;
|
||||
case TRANSFER_STARTING:
|
||||
case TRANSFER_FINISHING:
|
||||
break;
|
||||
case TRANSFER_STARTED:
|
||||
if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) {
|
||||
if (node->p->d.unusedCycles(&node->p->d, id) > node->eventDiff) {
|
||||
break;
|
||||
}
|
||||
node->transferFinished = false;
|
||||
signal = true;
|
||||
break;
|
||||
case TRANSFER_FINISHED:
|
||||
if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) {
|
||||
if (node->p->d.unusedCycles(&node->p->d, id) > node->eventDiff) {
|
||||
break;
|
||||
}
|
||||
_finishTransfer(node);
|
||||
|
@ -199,7 +201,7 @@ static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) {
|
|||
node->phase = node->p->d.transferActive;
|
||||
#endif
|
||||
if (signal) {
|
||||
node->p->d.signal(&node->p->d, 1 << node->id);
|
||||
node->p->d.signal(&node->p->d, 1 << id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -215,11 +217,13 @@ static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* user,
|
|||
int32_t cycles = 0;
|
||||
node->nextEvent -= cyclesLate;
|
||||
if (node->nextEvent <= 0) {
|
||||
if (!node->id) {
|
||||
int id;
|
||||
ATOMIC_LOAD(id, node->id);
|
||||
if (!id) {
|
||||
cycles = _masterUpdate(node);
|
||||
} else {
|
||||
cycles = _slaveUpdate(node);
|
||||
cycles += node->p->d.useCycles(&node->p->d, node->id, node->eventDiff);
|
||||
cycles += node->p->d.useCycles(&node->p->d, id, node->eventDiff);
|
||||
}
|
||||
node->eventDiff = 0;
|
||||
} else {
|
||||
|
@ -240,7 +244,9 @@ static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* user,
|
|||
|
||||
static void GBSIOLockstepNodeWriteSB(struct GBSIODriver* driver, uint8_t value) {
|
||||
struct GBSIOLockstepNode* node = (struct GBSIOLockstepNode*) driver;
|
||||
node->p->pendingSB[node->id] = value;
|
||||
int id;
|
||||
ATOMIC_LOAD(id, node->id);
|
||||
node->p->pendingSB[id] = value;
|
||||
}
|
||||
|
||||
static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t value) {
|
||||
|
@ -252,11 +258,17 @@ static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t valu
|
|||
mLockstepLock(&node->p->d);
|
||||
bool claimed = false;
|
||||
if (ATOMIC_CMPXCHG(node->p->masterClaimed, claimed, true)) {
|
||||
if (node->id != 0) {
|
||||
int id;
|
||||
ATOMIC_LOAD(id, node->id);
|
||||
if (id != 0) {
|
||||
unsigned sb;
|
||||
node->p->players[0]->id = 1;
|
||||
node->p->players[1] = node->p->players[0];
|
||||
node->p->players[0] = node->p->players[1];
|
||||
node->id = 0;
|
||||
node->p->players[1] = node->p->players[0];
|
||||
node->p->players[0] = node;
|
||||
sb = node->p->pendingSB[0];
|
||||
node->p->pendingSB[0] = node->p->pendingSB[1];
|
||||
node->p->pendingSB[1] = sb;
|
||||
}
|
||||
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
||||
ATOMIC_STORE(node->p->d.transferCycles, GBSIOCyclesPerTransfer[(value >> 1) & 1]);
|
||||
|
|
Loading…
Reference in New Issue