GBA SIO: Fix copying Normal mode transfer values

This commit is contained in:
Vicki Pfau 2020-02-24 20:00:34 -08:00
parent 85f663fccc
commit 77a67f8904
2 changed files with 31 additions and 10 deletions

View File

@ -11,6 +11,7 @@ Emulation fixes:
- GBA Memory: Improve gamepak prefetch timing - GBA Memory: Improve gamepak prefetch timing
- GBA SIO: Fix Multiplayer busy bit - GBA SIO: Fix Multiplayer busy bit
- GBA SIO: Fix double-unloading active driver - GBA SIO: Fix double-unloading active driver
- GBA SIO: Fix copying Normal mode transfer values
- 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
Other fixes: Other fixes:

View File

@ -279,11 +279,15 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) {
case TRANSFER_IDLE: case TRANSFER_IDLE:
// If the master hasn't initiated a transfer, it can keep going. // If the master hasn't initiated a transfer, it can keep going.
node->nextEvent += LOCKSTEP_INCREMENT; node->nextEvent += LOCKSTEP_INCREMENT;
if (node->mode == SIO_MULTI) {
node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached); node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached);
}
break; break;
case TRANSFER_STARTING: case TRANSFER_STARTING:
// Start the transfer, but wait for the other GBAs to catch up // Start the transfer, but wait for the other GBAs to catch up
node->transferFinished = false; node->transferFinished = false;
switch (node->mode) {
case SIO_MULTI:
node->p->multiRecv[0] = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1]; node->p->multiRecv[0] = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1];
node->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = 0xFFFF; node->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = 0xFFFF;
node->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = 0xFFFF; node->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = 0xFFFF;
@ -292,6 +296,22 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) {
node->p->multiRecv[1] = 0xFFFF; node->p->multiRecv[1] = 0xFFFF;
node->p->multiRecv[2] = 0xFFFF; node->p->multiRecv[2] = 0xFFFF;
node->p->multiRecv[3] = 0xFFFF; node->p->multiRecv[3] = 0xFFFF;
break;
case SIO_NORMAL_8:
node->p->multiRecv[0] = 0xFFFF;
node->p->normalRecv[0] = node->d.p->p->memory.io[REG_SIODATA8 >> 1] & 0xFF;
break;
case SIO_NORMAL_32:
node->p->multiRecv[0] = 0xFFFF;
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04x", node->id, node->d.p->p->memory.io[REG_SIODATA32_LO >> 1]);
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04x", node->id, node->d.p->p->memory.io[REG_SIODATA32_HI >> 1]);
node->p->normalRecv[0] = node->d.p->p->memory.io[REG_SIODATA32_LO >> 1];
node->p->normalRecv[0] |= node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] << 16;
break;
default:
node->p->multiRecv[0] = 0xFFFF;
break;
}
needsToWait = true; needsToWait = true;
ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTED); ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTED);
node->nextEvent += LOCKSTEP_TRANSFER; node->nextEvent += LOCKSTEP_TRANSFER;
@ -456,7 +476,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive
mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04x", node->id, value); mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04x", node->id, value);
value &= 0xFF8B; value &= 0xFF8B;
if (!node->id) { if (!node->id) {
driver->p->siocnt = GBASIONormalFillSi(driver->p->siocnt); value = GBASIONormalFillSi(value);
} }
if (value & 0x0080 && !node->id) { if (value & 0x0080 && !node->id) {
// Internal shift clock // Internal shift clock