From ad85acab75a674ec46850a2381323632dae0a83a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sun, 18 Dec 2016 11:46:45 -0800 Subject: [PATCH] Core: Implement deterministic event ordering --- src/core/timing.c | 3 ++- src/core/timing.h | 1 + src/gb/audio.c | 7 +++++++ src/gb/gb.c | 1 + src/gb/memory.c | 2 ++ src/gb/sio.c | 1 + src/gb/timer.c | 2 ++ src/gb/video.c | 2 ++ src/gba/audio.c | 1 + src/gba/dma.c | 1 + src/gba/sio/lockstep.c | 1 + src/gba/timer.c | 4 ++++ src/gba/video.c | 1 + 13 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/core/timing.c b/src/core/timing.c index 9d240411e..b252ace97 100644 --- a/src/core/timing.c +++ b/src/core/timing.c @@ -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; diff --git a/src/core/timing.h b/src/core/timing.h index 3d9fb4da2..6128255c3 100644 --- a/src/core/timing.h +++ b/src/core/timing.h @@ -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; }; diff --git a/src/gb/audio.c b/src/gb/audio.c index 931aec60d..3fe0a73e5 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -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) { diff --git a/src/gb/gb.c b/src/gb/gb.c index f3c23db59..9a307e23d 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -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) { diff --git a/src/gb/memory.c b/src/gb/memory.c index 1fb24f1cf..c3c079048 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -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; diff --git a/src/gb/sio.c b/src/gb/sio.c index cd9642861..2758cafa4 100644 --- a/src/gb/sio.c +++ b/src/gb/sio.c @@ -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) { diff --git a/src/gb/timer.c b/src/gb/timer.c index 1b560a4fb..4192fee7b 100644 --- a/src/gb/timer.c +++ b/src/gb/timer.c @@ -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; diff --git a/src/gb/video.c b/src/gb/video.c index ef8bb95c5..221cb0349 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -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) { diff --git a/src/gba/audio.c b/src/gba/audio.c index 0034f754b..0901e9ccf 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -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__ diff --git a/src/gba/dma.c b/src/gba/dma.c index 85d2697d4..d49a1f313 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -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) { diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 4a233e879..1fd3d6b6d 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -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; } diff --git a/src/gba/timer.c b/src/gba/timer.c index 9abb06a31..84c3b4aa4 100644 --- a/src/gba/timer.c +++ b/src/gba/timer.c @@ -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) { diff --git a/src/gba/video.c b/src/gba/video.c index 5467d73ff..5a9b4c88b 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -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) {