mirror of https://github.com/mgba-emu/mgba.git
GB SIO: Fix lockstep failing games aren't reloaded
This commit is contained in:
parent
918caf87c4
commit
a9e96c7d00
1
CHANGES
1
CHANGES
|
@ -31,6 +31,7 @@ Other fixes:
|
|||
- Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421)
|
||||
- Core: Fix crashes if core directories aren't set
|
||||
- Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317)
|
||||
- GB SIO: Fix lockstep failing games aren't reloaded
|
||||
Misc:
|
||||
- GBA Savedata: EEPROM performance fixes
|
||||
- GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
|
||||
|
|
|
@ -31,6 +31,7 @@ void GBSIOInit(struct GBSIO* sio) {
|
|||
void GBSIOReset(struct GBSIO* sio) {
|
||||
sio->nextEvent = INT_MAX;
|
||||
sio->remainingBits = 0;
|
||||
GBSIOSetDriver(sio, sio->driver);
|
||||
}
|
||||
|
||||
void GBSIODeinit(struct GBSIO* sio) {
|
||||
|
|
|
@ -103,9 +103,12 @@ static void _finishTransfer(struct GBSIOLockstepNode* node) {
|
|||
|
||||
|
||||
static int32_t _masterUpdate(struct GBSIOLockstepNode* node) {
|
||||
enum mLockstepPhase transferActive;
|
||||
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
||||
|
||||
bool needsToWait = false;
|
||||
int i;
|
||||
switch (node->p->d.transferActive) {
|
||||
switch (transferActive) {
|
||||
case TRANSFER_IDLE:
|
||||
// If the master hasn't initiated a transfer, it can keep going.
|
||||
node->nextEvent += LOCKSTEP_INCREMENT;
|
||||
|
@ -165,8 +168,12 @@ static int32_t _masterUpdate(struct GBSIOLockstepNode* node) {
|
|||
}
|
||||
|
||||
static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) {
|
||||
enum mLockstepPhase transferActive;
|
||||
|
||||
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
||||
|
||||
bool signal = false;
|
||||
switch (node->p->d.transferActive) {
|
||||
switch (transferActive) {
|
||||
case TRANSFER_IDLE:
|
||||
node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT);
|
||||
break;
|
||||
|
@ -174,10 +181,16 @@ static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) {
|
|||
case TRANSFER_FINISHING:
|
||||
break;
|
||||
case TRANSFER_STARTED:
|
||||
if (node->p->d.unusedCycles(&node->p->d, node->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) {
|
||||
break;
|
||||
}
|
||||
_finishTransfer(node);
|
||||
signal = true;
|
||||
break;
|
||||
|
@ -193,7 +206,10 @@ static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) {
|
|||
|
||||
static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
||||
struct GBSIOLockstepNode* node = user;
|
||||
mLockstepLock(&node->p->d);
|
||||
if (node->p->d.attached < 2) {
|
||||
mTimingSchedule(timing, &node->event, (GBSIOCyclesPerTransfer[0] >> 1) - cyclesLate);
|
||||
mLockstepUnlock(&node->p->d);
|
||||
return;
|
||||
}
|
||||
int32_t cycles = 0;
|
||||
|
@ -209,6 +225,8 @@ static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* user,
|
|||
} else {
|
||||
cycles = node->nextEvent;
|
||||
}
|
||||
mLockstepUnlock(&node->p->d);
|
||||
|
||||
if (cycles > 0) {
|
||||
node->nextEvent = 0;
|
||||
node->eventDiff += cycles;
|
||||
|
@ -227,17 +245,22 @@ static void GBSIOLockstepNodeWriteSB(struct GBSIODriver* driver, uint8_t value)
|
|||
|
||||
static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t value) {
|
||||
struct GBSIOLockstepNode* node = (struct GBSIOLockstepNode*) driver;
|
||||
if ((value & 0x81) == 0x81 && node->p->d.attached > 1) {
|
||||
int attached;
|
||||
ATOMIC_LOAD(attached, node->p->d.attached);
|
||||
|
||||
if ((value & 0x81) == 0x81 && attached > 1) {
|
||||
mLockstepLock(&node->p->d);
|
||||
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];
|
||||
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
||||
ATOMIC_STORE(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);
|
||||
} else {
|
||||
mLOG(GB_SIO, FATAL, "GBSIOLockstepNodeWriteSC() failed to write to masterClaimed\n");
|
||||
mLOG(GB_SIO, DEBUG, "GBSIOLockstepNodeWriteSC() failed to write to masterClaimed\n");
|
||||
}
|
||||
mLockstepUnlock(&node->p->d);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue