mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Fix Normal mode transfer start timing (fixes #425)
This commit is contained in:
parent
e12ca74d1e
commit
7a3f2b12b5
1
CHANGES
1
CHANGES
|
@ -51,6 +51,7 @@ Emulation fixes:
|
|||
- GBA SIO: Fix Normal mode being totally broken (fixes mgba.io/i/1800)
|
||||
- GBA SIO: Fix deseralizing SIO registers
|
||||
- GBA SIO: Fix hanging on starting a second multiplayer window (fixes mgba.io/i/854)
|
||||
- GBA SIO: Fix Normal mode transfer start timing (fixes mgba.io/i/425)
|
||||
- GBA Timers: Fix toggling timer cascading while timer is active (fixes mgba.io/i/2043)
|
||||
- GBA Video: Latch scanline at end of Hblank (fixes mgba.io/i/1319)
|
||||
- GBA Video: Fix Hblank timing
|
||||
|
|
|
@ -367,17 +367,22 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) {
|
|||
|
||||
static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) {
|
||||
enum mLockstepPhase transferActive;
|
||||
int attachedMulti, attached;
|
||||
int attached;
|
||||
int attachedMode;
|
||||
|
||||
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
||||
ATOMIC_LOAD(attachedMulti, node->p->attachedMulti);
|
||||
ATOMIC_LOAD(attached, node->p->d.attached);
|
||||
|
||||
node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached);
|
||||
if (node->mode == SIO_MULTI) {
|
||||
ATOMIC_LOAD(attachedMode, node->p->attachedMulti);
|
||||
node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMode == attached);
|
||||
} else {
|
||||
ATOMIC_LOAD(attachedMode, node->p->attachedNormal);
|
||||
}
|
||||
bool signal = false;
|
||||
switch (transferActive) {
|
||||
case TRANSFER_IDLE:
|
||||
if (!GBASIOMultiplayerIsReady(node->d.p->siocnt)) {
|
||||
if (attachedMode != attached) {
|
||||
node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT);
|
||||
}
|
||||
break;
|
||||
|
@ -479,15 +484,32 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive
|
|||
}
|
||||
if (value & 0x0080) {
|
||||
if (!node->id) {
|
||||
// Internal shift clock
|
||||
if (value & 1) {
|
||||
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
||||
}
|
||||
// Frequency
|
||||
int32_t cycles;
|
||||
if (value & 2) {
|
||||
node->p->d.transferCycles = GBA_ARM7TDMI_FREQUENCY / 1024;
|
||||
cycles = 8 * 8;
|
||||
} else {
|
||||
node->p->d.transferCycles = GBA_ARM7TDMI_FREQUENCY / 8192;
|
||||
cycles = 64 * 8;
|
||||
}
|
||||
if (value & 0x1000) {
|
||||
cycles *= 4;
|
||||
}
|
||||
|
||||
enum mLockstepPhase transferActive;
|
||||
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
||||
|
||||
if (transferActive == TRANSFER_IDLE) {
|
||||
mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id);
|
||||
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
||||
ATOMIC_STORE(node->p->d.transferCycles, cycles);
|
||||
|
||||
if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) {
|
||||
node->eventDiff -= node->event.when - mTimingCurrentTime(&driver->p->p->timing);
|
||||
mTimingDeschedule(&driver->p->p->timing, &node->event);
|
||||
}
|
||||
mTimingSchedule(&driver->p->p->timing, &node->event, 0);
|
||||
} else {
|
||||
value &= ~0x0080;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
|
Loading…
Reference in New Issue