GBA SIO: Convert to mTiming

This commit is contained in:
Jeffrey Pfau 2016-11-11 14:59:11 -08:00
parent 86571c8496
commit 82a0088e1e
6 changed files with 28 additions and 29 deletions

View File

@ -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) {

View File

@ -106,6 +106,7 @@ struct GBA {
uint32_t lastJump;
bool haltPending;
bool cpuBlocked;
bool earlyExit;
int idleDetectionStep;
int idleDetectionFailures;
int32_t cachedRegisters[16];

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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;