From 82a0088e1ec4a1fe13f9eff96c9c72d22995013e Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Fri, 11 Nov 2016 14:59:11 -0800 Subject: [PATCH] GBA SIO: Convert to mTiming --- src/gba/gba.c | 10 +++------- src/gba/gba.h | 1 + src/gba/sio.c | 7 ------- src/gba/sio.h | 2 -- src/gba/sio/lockstep.c | 35 ++++++++++++++++++++++------------- src/gba/sio/lockstep.h | 2 ++ 6 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/gba/gba.c b/src/gba/gba.c index f476283b0..e1c379fc6 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -184,6 +184,7 @@ void GBAReset(struct ARMCore* cpu) { } gba->cpuBlocked = false; + gba->earlyExit = false; if (gba->yankedRomSize) { gba->memory.romSize = gba->yankedRomSize; gba->memory.romMask = toPow2(gba->memory.romSize) - 1; @@ -238,7 +239,6 @@ static void GBAProcessEvents(struct ARMCore* cpu) { int32_t nextEvent = cpu->nextEvent; while (cpu->cycles >= nextEvent) { int32_t cycles = cpu->cycles; - int32_t testEvent; cpu->cycles = 0; cpu->nextEvent = INT_MAX; @@ -253,14 +253,10 @@ static void GBAProcessEvents(struct ARMCore* cpu) { nextEvent = mTimingTick(&gba->timing, nextEvent); } while (gba->cpuBlocked); - testEvent = GBASIOProcessEvents(&gba->sio, cycles); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } - cpu->nextEvent = nextEvent; - if (nextEvent == 0) { + if (gba->earlyExit) { + gba->earlyExit = false; break; } if (cpu->halted) { diff --git a/src/gba/gba.h b/src/gba/gba.h index 8ff475fab..cfcaa94e3 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -106,6 +106,7 @@ struct GBA { uint32_t lastJump; bool haltPending; bool cpuBlocked; + bool earlyExit; int idleDetectionStep; int idleDetectionFailures; int32_t cachedRegisters[16]; diff --git a/src/gba/sio.c b/src/gba/sio.c index d1ea1ab42..1e191e93c 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -174,10 +174,3 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu } return value; } - -int32_t GBASIOProcessEvents(struct GBASIO* sio, int32_t cycles) { - if (sio->activeDriver && sio->activeDriver->processEvents) { - return sio->activeDriver->processEvents(sio->activeDriver, cycles); - } - return INT_MAX; -} diff --git a/src/gba/sio.h b/src/gba/sio.h index 7110ff7bf..d9cfc83f0 100644 --- a/src/gba/sio.h +++ b/src/gba/sio.h @@ -78,6 +78,4 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value); void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value); uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t value); -int32_t GBASIOProcessEvents(struct GBASIO* sio, int32_t cycles); - #endif diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 601236916..4a233e879 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -17,8 +17,7 @@ static bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver); static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); -static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int32_t cycles); -static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int32_t cycles); +static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); void GBASIOLockstepInit(struct GBASIOLockstep* lockstep) { lockstep->players[0] = 0; @@ -47,7 +46,6 @@ void GBASIOLockstepNodeCreate(struct GBASIOLockstepNode* node) { node->d.load = GBASIOLockstepNodeLoad; node->d.unload = GBASIOLockstepNodeUnload; node->d.writeRegister = 0; - node->d.processEvents = GBASIOLockstepNodeProcessEvents; } bool GBASIOLockstepAttachNode(struct GBASIOLockstep* lockstep, struct GBASIOLockstepNode* node) { @@ -83,6 +81,9 @@ bool GBASIOLockstepNodeInit(struct GBASIODriver* driver) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; node->d.p->multiplayerControl.slave = node->id > 0; mLOG(GBA_SIO, DEBUG, "Lockstep %i: Node init", node->id); + node->event.context = node; + node->event.name = "GBA SIO Lockstep"; + node->event.callback = _GBASIOLockstepNodeProcessEvents; return true; } @@ -94,6 +95,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; node->nextEvent = 0; node->eventDiff = 0; + mTimingSchedule(&driver->p->p->timing, &node->event, 0); node->mode = driver->p->mode; switch (node->mode) { case SIO_MULTI: @@ -130,6 +132,7 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { break; } node->p->unload(node->p, node->id); + mTimingDeschedule(&driver->p->p->timing, &node->event); return true; } @@ -142,7 +145,8 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); node->p->transferActive = TRANSFER_STARTING; node->p->transferCycles = GBASIOCyclesPerTransfer[node->d.p->multiplayerControl.baud][node->p->attached - 1]; - node->nextEvent = 0; + mTimingDeschedule(&driver->p->p->timing, &node->event); + mTimingSchedule(&driver->p->p->timing, &node->event, 0); } else { value &= ~0x0080; } @@ -332,28 +336,33 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { return 0; } -static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int32_t cycles) { - struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; +static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { + struct GBASIOLockstepNode* node = user; if (node->p->attached < 2) { - return INT_MAX; + return; } - node->eventDiff += cycles; - node->nextEvent -= cycles; + int32_t cycles = 0; + node->nextEvent -= cyclesLate; if (node->nextEvent <= 0) { if (!node->id) { cycles = _masterUpdate(node); } else { cycles = _slaveUpdate(node); - node->nextEvent += node->p->useCycles(node->p, node->id, node->eventDiff); + cycles += node->p->useCycles(node->p, node->id, node->eventDiff); } node->eventDiff = 0; } else { cycles = node->nextEvent; } - if (cycles < 0) { - return 0; + if (cycles > 0) { + node->nextEvent = 0; + node->eventDiff += cycles; + mTimingDeschedule(timing, &node->event); + mTimingSchedule(timing, &node->event, cycles); + } else { + node->d.p->p->earlyExit = true; + mTimingSchedule(timing, &node->event, cyclesLate + 1); } - return cycles; } static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { diff --git a/src/gba/sio/lockstep.h b/src/gba/sio/lockstep.h index 797bb5859..6da3d0dc3 100644 --- a/src/gba/sio/lockstep.h +++ b/src/gba/sio/lockstep.h @@ -6,6 +6,7 @@ #ifndef SIO_LOCKSTEP_H #define SIO_LOCKSTEP_H +#include "core/timing.h" #include "gba/sio.h" enum GBASIOLockstepPhase { @@ -41,6 +42,7 @@ struct GBASIOLockstep { struct GBASIOLockstepNode { struct GBASIODriver d; struct GBASIOLockstep* p; + struct mTimingEvent event; volatile int32_t nextEvent; int32_t eventDiff;