all repos — mgba @ 269b18d8aab439ebb08ff4b02d744a41bf79fb78

mGBA Game Boy Advance Emulator

GB SIO: Some fixes
Jeffrey Pfau jeffrey@endrift.com
Mon, 26 Dec 2016 12:03:23 -0800
commit

269b18d8aab439ebb08ff4b02d744a41bf79fb78

parent

ceea51b55ea2f112c49b4ad22e6d70b08ad430e7

2 files changed, 22 insertions(+), 9 deletions(-)

jump to
M src/gb/sio.csrc/gb/sio.c

@@ -61,14 +61,20 @@

void _GBSIOProcessEvents(struct mTiming* timing, void* context, uint32_t cyclesLate) { UNUSED(cyclesLate); struct GBSIO* sio = context; - --sio->remainingBits; - sio->p->memory.io[REG_SB] &= ~(8 >> sio->remainingBits); - sio->p->memory.io[REG_SB] |= sio->pendingSB & ~(8 >> sio->remainingBits); + bool doIRQ = false; + if (sio->remainingBits) { + doIRQ = true; + --sio->remainingBits; + sio->p->memory.io[REG_SB] &= ~(128 >> sio->remainingBits); + sio->p->memory.io[REG_SB] |= sio->pendingSB & (128 >> sio->remainingBits); + } if (!sio->remainingBits) { - sio->p->memory.io[REG_IF] |= (1 << GB_IRQ_SIO); sio->p->memory.io[REG_SC] = GBRegisterSCClearEnable(sio->p->memory.io[REG_SC]); - sio->pendingSB = 0xFF; - GBUpdateIRQs(sio->p); + if (doIRQ) { + sio->p->memory.io[REG_IF] |= (1 << GB_IRQ_SIO); + GBUpdateIRQs(sio->p); + sio->pendingSB = 0xFF; + } } else { mTimingSchedule(timing, &sio->event, sio->period); }

@@ -85,8 +91,10 @@ void GBSIOWriteSC(struct GBSIO* sio, uint8_t sc) {

sio->period = GBSIOCyclesPerTransfer[GBRegisterSCGetClockSpeed(sc)]; // TODO Shift Clock if (GBRegisterSCIsEnable(sc)) { mTimingDeschedule(&sio->p->timing, &sio->event); - mTimingSchedule(&sio->p->timing, &sio->event, sio->period); - sio->remainingBits = 8; + if (GBRegisterSCIsShiftClock(sc)) { + mTimingSchedule(&sio->p->timing, &sio->event, sio->period); + sio->remainingBits = 8; + } } if (sio->driver) { sio->driver->writeSC(sio->driver, sc);
M src/gb/sio/lockstep.csrc/gb/sio/lockstep.c

@@ -8,7 +8,7 @@

#include "gb/gb.h" #include "gb/io.h" -#define LOCKSTEP_INCREMENT 500 +#define LOCKSTEP_INCREMENT 512 static bool GBSIOLockstepNodeInit(struct GBSIODriver* driver); static void GBSIOLockstepNodeDeinit(struct GBSIODriver* driver);

@@ -90,6 +90,11 @@ return;

} struct GBSIO* sio = node->d.p; sio->pendingSB = node->p->pendingSB[!node->id]; + if (GBRegisterSCIsEnable(sio->p->memory.io[REG_SC])) { + sio->remainingBits = 8; + mTimingDeschedule(&sio->p->timing, &sio->event); + mTimingSchedule(&sio->p->timing, &sio->event, 0); + } node->transferFinished = true; #ifndef NDEBUG ++node->transferId;