mirror of
https://github.com/libretro/mgba.git
synced 2024-11-23 16:10:01 +00:00
Core: Implement deterministic event ordering
This commit is contained in:
parent
327c3e78c6
commit
ad85acab75
@ -28,9 +28,10 @@ void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t
|
||||
}
|
||||
struct mTimingEvent** previous = &timing->root;
|
||||
struct mTimingEvent* next = timing->root;
|
||||
unsigned priority = event->priority;
|
||||
while (next) {
|
||||
int32_t nextWhen = next->when - timing->masterCycles;
|
||||
if (nextWhen > when) {
|
||||
if (nextWhen > when || (nextWhen == when && next->priority > priority)) {
|
||||
break;
|
||||
}
|
||||
previous = &next->next;
|
||||
|
@ -14,6 +14,7 @@ struct mTimingEvent {
|
||||
void (*callback)(struct mTiming*, void* context, uint32_t);
|
||||
const char* name;
|
||||
uint32_t when;
|
||||
unsigned priority;
|
||||
|
||||
struct mTimingEvent* next;
|
||||
};
|
||||
|
@ -68,24 +68,31 @@ void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAu
|
||||
audio->frameEvent.context = audio;
|
||||
audio->frameEvent.name = "GB Audio Frame Sequencer";
|
||||
audio->frameEvent.callback = _updateFrame;
|
||||
audio->frameEvent.priority = 0x10;
|
||||
audio->ch1Event.context = audio;
|
||||
audio->ch1Event.name = "GB Audio Channel 1";
|
||||
audio->ch1Event.callback = _updateChannel1;
|
||||
audio->ch1Event.priority = 0x11;
|
||||
audio->ch2Event.context = audio;
|
||||
audio->ch2Event.name = "GB Audio Channel 2";
|
||||
audio->ch2Event.callback = _updateChannel2;
|
||||
audio->ch2Event.priority = 0x12;
|
||||
audio->ch3Event.context = audio;
|
||||
audio->ch3Event.name = "GB Audio Channel 3";
|
||||
audio->ch3Event.callback = _updateChannel3;
|
||||
audio->ch3Event.priority = 0x13;
|
||||
audio->ch3Fade.context = audio;
|
||||
audio->ch3Fade.name = "GB Audio Channel 3 Memory";
|
||||
audio->ch3Fade.callback = _fadeChannel3;
|
||||
audio->ch3Fade.priority = 0x14;
|
||||
audio->ch4Event.context = audio;
|
||||
audio->ch4Event.name = "GB Audio Channel 4";
|
||||
audio->ch4Event.callback = _updateChannel4;
|
||||
audio->ch4Event.priority = 0x15;
|
||||
audio->sampleEvent.context = audio;
|
||||
audio->sampleEvent.name = "GB Audio Sample";
|
||||
audio->sampleEvent.callback = _sample;
|
||||
audio->ch1Event.priority = 0x18;
|
||||
}
|
||||
|
||||
void GBAudioDeinit(struct GBAudio* audio) {
|
||||
|
@ -91,6 +91,7 @@ static void GBInit(void* cpu, struct mCPUComponent* component) {
|
||||
gb->eiPending.name = "GB EI";
|
||||
gb->eiPending.callback = _enableInterrupts;
|
||||
gb->eiPending.context = gb;
|
||||
gb->eiPending.priority = 0;
|
||||
}
|
||||
|
||||
static void GBDeinit(struct mCPUComponent* component) {
|
||||
|
@ -123,9 +123,11 @@ void GBMemoryReset(struct GB* gb) {
|
||||
gb->memory.dmaEvent.context = gb;
|
||||
gb->memory.dmaEvent.name = "GB DMA";
|
||||
gb->memory.dmaEvent.callback = _GBMemoryDMAService;
|
||||
gb->memory.dmaEvent.priority = 0x40;
|
||||
gb->memory.hdmaEvent.context = gb;
|
||||
gb->memory.hdmaEvent.name = "GB HDMA";
|
||||
gb->memory.hdmaEvent.callback = _GBMemoryHDMAService;
|
||||
gb->memory.hdmaEvent.priority = 0x41;
|
||||
|
||||
gb->memory.sramAccess = false;
|
||||
gb->memory.rtcAccess = false;
|
||||
|
@ -16,6 +16,7 @@ void GBSIOInit(struct GBSIO* sio) {
|
||||
sio->event.context = sio;
|
||||
sio->event.name = "GB SIO";
|
||||
sio->event.callback = _GBSIOProcessEvents;
|
||||
sio->event.priority = 0x30;
|
||||
}
|
||||
|
||||
void GBSIOReset(struct GBSIO* sio) {
|
||||
|
@ -51,9 +51,11 @@ void GBTimerReset(struct GBTimer* timer) {
|
||||
timer->event.context = timer;
|
||||
timer->event.name = "GB Timer";
|
||||
timer->event.callback = _GBTimerIncrement;
|
||||
timer->event.priority = 0x20;
|
||||
timer->irq.context = timer;
|
||||
timer->irq.name = "GB Timer IRQ";
|
||||
timer->irq.callback = _GBTimerIRQ;
|
||||
timer->event.priority = 0x21;
|
||||
|
||||
timer->nextDiv = GB_DMG_DIV_PERIOD; // TODO: GBC differences
|
||||
timer->timaPeriod = 1024 >> 4;
|
||||
|
@ -55,9 +55,11 @@ void GBVideoInit(struct GBVideo* video) {
|
||||
video->modeEvent.context = video;
|
||||
video->modeEvent.name = "GB Video Mode";
|
||||
video->modeEvent.callback = NULL;
|
||||
video->modeEvent.priority = 8;
|
||||
video->frameEvent.context = video;
|
||||
video->frameEvent.name = "GB Video Frame";
|
||||
video->frameEvent.callback = _updateFrameCount;
|
||||
video->frameEvent.priority = 9;
|
||||
}
|
||||
|
||||
void GBVideoReset(struct GBVideo* video) {
|
||||
|
@ -31,6 +31,7 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
|
||||
audio->sampleEvent.context = audio;
|
||||
audio->sampleEvent.name = "GBA Audio Sample";
|
||||
audio->sampleEvent.callback = _sample;
|
||||
audio->sampleEvent.priority = 0x18;
|
||||
audio->psg.p = NULL;
|
||||
uint8_t* nr52 = (uint8_t*) &audio->p->memory.io[REG_SOUNDCNT_X >> 1];
|
||||
#ifdef __BIG_ENDIAN__
|
||||
|
@ -18,6 +18,7 @@ void GBADMAInit(struct GBA* gba) {
|
||||
gba->memory.dmaEvent.name = "GBA DMA";
|
||||
gba->memory.dmaEvent.callback = _dmaEvent;
|
||||
gba->memory.dmaEvent.context = gba;
|
||||
gba->memory.dmaEvent.priority = 0x40;
|
||||
}
|
||||
|
||||
void GBADMAReset(struct GBA* gba) {
|
||||
|
@ -84,6 +84,7 @@ bool GBASIOLockstepNodeInit(struct GBASIODriver* driver) {
|
||||
node->event.context = node;
|
||||
node->event.name = "GBA SIO Lockstep";
|
||||
node->event.callback = _GBASIOLockstepNodeProcessEvents;
|
||||
node->event.priority = 0x80;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -65,15 +65,19 @@ void GBATimerInit(struct GBA* gba) {
|
||||
gba->timers[0].event.name = "GBA Timer 0";
|
||||
gba->timers[0].event.callback = GBATimerUpdate0;
|
||||
gba->timers[0].event.context = gba;
|
||||
gba->timers[0].event.priority = 0x20;
|
||||
gba->timers[1].event.name = "GBA Timer 1";
|
||||
gba->timers[1].event.callback = GBATimerUpdate1;
|
||||
gba->timers[1].event.context = gba;
|
||||
gba->timers[1].event.priority = 0x21;
|
||||
gba->timers[2].event.name = "GBA Timer 2";
|
||||
gba->timers[2].event.callback = GBATimerUpdate2;
|
||||
gba->timers[2].event.context = gba;
|
||||
gba->timers[2].event.priority = 0x22;
|
||||
gba->timers[3].event.name = "GBA Timer 3";
|
||||
gba->timers[3].event.callback = GBATimerUpdate3;
|
||||
gba->timers[3].event.context = gba;
|
||||
gba->timers[3].event.priority = 0x23;
|
||||
}
|
||||
|
||||
void GBATimerUpdateRegister(struct GBA* gba, int timer) {
|
||||
|
@ -74,6 +74,7 @@ void GBAVideoInit(struct GBAVideo* video) {
|
||||
video->event.name = "GBA Video";
|
||||
video->event.callback = NULL;
|
||||
video->event.context = video;
|
||||
video->event.priority = 8;
|
||||
}
|
||||
|
||||
void GBAVideoReset(struct GBAVideo* video) {
|
||||
|
Loading…
Reference in New Issue
Block a user