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 Normal mode being totally broken (fixes mgba.io/i/1800)
|
||||||
- GBA SIO: Fix deseralizing SIO registers
|
- GBA SIO: Fix deseralizing SIO registers
|
||||||
- GBA SIO: Fix hanging on starting a second multiplayer window (fixes mgba.io/i/854)
|
- 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 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: Latch scanline at end of Hblank (fixes mgba.io/i/1319)
|
||||||
- GBA Video: Fix Hblank timing
|
- GBA Video: Fix Hblank timing
|
||||||
|
|
|
@ -367,17 +367,22 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) {
|
||||||
|
|
||||||
static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) {
|
static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) {
|
||||||
enum mLockstepPhase transferActive;
|
enum mLockstepPhase transferActive;
|
||||||
int attachedMulti, attached;
|
int attached;
|
||||||
|
int attachedMode;
|
||||||
|
|
||||||
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
ATOMIC_LOAD(transferActive, node->p->d.transferActive);
|
||||||
ATOMIC_LOAD(attachedMulti, node->p->attachedMulti);
|
|
||||||
ATOMIC_LOAD(attached, node->p->d.attached);
|
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;
|
bool signal = false;
|
||||||
switch (transferActive) {
|
switch (transferActive) {
|
||||||
case TRANSFER_IDLE:
|
case TRANSFER_IDLE:
|
||||||
if (!GBASIOMultiplayerIsReady(node->d.p->siocnt)) {
|
if (attachedMode != attached) {
|
||||||
node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT);
|
node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -479,15 +484,32 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive
|
||||||
}
|
}
|
||||||
if (value & 0x0080) {
|
if (value & 0x0080) {
|
||||||
if (!node->id) {
|
if (!node->id) {
|
||||||
// Internal shift clock
|
|
||||||
if (value & 1) {
|
|
||||||
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING);
|
|
||||||
}
|
|
||||||
// Frequency
|
// Frequency
|
||||||
|
int32_t cycles;
|
||||||
if (value & 2) {
|
if (value & 2) {
|
||||||
node->p->d.transferCycles = GBA_ARM7TDMI_FREQUENCY / 1024;
|
cycles = 8 * 8;
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue