mirror of https://github.com/mgba-emu/mgba.git
GBA SIO: Convert to mTiming
This commit is contained in:
parent
86571c8496
commit
82a0088e1e
|
@ -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) {
|
||||
|
|
|
@ -106,6 +106,7 @@ struct GBA {
|
|||
uint32_t lastJump;
|
||||
bool haltPending;
|
||||
bool cpuBlocked;
|
||||
bool earlyExit;
|
||||
int idleDetectionStep;
|
||||
int idleDetectionFailures;
|
||||
int32_t cachedRegisters[16];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue