GB: Convert memory events to mTiming
Jeffrey Pfau jeffrey@endrift.com
Sat, 17 Sep 2016 18:56:46 -0700
4 files changed,
25 insertions(+),
46 deletions(-)
M
src/gb/gb.c
→
src/gb/gb.c
@@ -570,11 +570,6 @@ if (testEvent < nextEvent) {
nextEvent = testEvent; } - testEvent = GBMemoryProcessEvents(gb, cycles); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } - cpu->cycles -= cycles; cpu->nextEvent = nextEvent;
M
src/gb/memory.c
→
src/gb/memory.c
@@ -53,8 +53,8 @@ break;
} } -static void _GBMemoryDMAService(struct GB* gb); -static void _GBMemoryHDMAService(struct GB* gb); +static void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate); +static void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate); void GBMemoryInit(struct GB* gb) { struct LR35902Core* cpu = gb->cpu;@@ -111,15 +111,21 @@
gb->memory.ime = false; gb->memory.ie = 0; - gb->memory.dmaNext = INT_MAX; gb->memory.dmaRemaining = 0; gb->memory.dmaSource = 0; gb->memory.dmaDest = 0; - gb->memory.hdmaNext = INT_MAX; gb->memory.hdmaRemaining = 0; gb->memory.hdmaSource = 0; gb->memory.hdmaDest = 0; gb->memory.isHdma = false; + + + gb->memory.dmaEvent.context = gb; + gb->memory.dmaEvent.name = "GB DMA"; + gb->memory.dmaEvent.callback = _GBMemoryDMAService; + gb->memory.hdmaEvent.context = gb; + gb->memory.hdmaEvent.name = "GB HDMA"; + gb->memory.hdmaEvent.callback = _GBMemoryHDMAService; gb->memory.sramAccess = false; gb->memory.rtcAccess = false;@@ -343,27 +349,6 @@ return GBIORead(gb, REG_IE);
} } -int32_t GBMemoryProcessEvents(struct GB* gb, int32_t cycles) { - int nextEvent = INT_MAX; - if (gb->memory.dmaRemaining) { - gb->memory.dmaNext -= cycles; - if (gb->memory.dmaNext <= 0) { - _GBMemoryDMAService(gb); - } - nextEvent = gb->memory.dmaNext; - } - if (gb->memory.hdmaRemaining) { - gb->memory.hdmaNext -= cycles; - if (gb->memory.hdmaNext <= 0) { - _GBMemoryHDMAService(gb); - } - if (gb->memory.hdmaNext < nextEvent) { - nextEvent = gb->memory.hdmaNext; - } - } - return nextEvent; -} - void GBMemoryDMA(struct GB* gb, uint16_t base) { if (base > 0xF100) { return;@@ -371,9 +356,9 @@ }
gb->cpu->memory.store8 = GBDMAStore8; gb->cpu->memory.load8 = GBDMALoad8; gb->cpu->memory.cpuLoad8 = GBDMALoad8; - gb->memory.dmaNext = gb->cpu->cycles + 8; - if (gb->memory.dmaNext < gb->cpu->nextEvent) { - gb->cpu->nextEvent = gb->memory.dmaNext; + mTimingSchedule(&gb->timing, &gb->memory.dmaEvent, 8); + if (gb->cpu->cycles + 8 < gb->cpu->nextEvent) { + gb->cpu->nextEvent = gb->cpu->cycles + 8; } gb->memory.dmaSource = base; gb->memory.dmaDest = 0;@@ -396,12 +381,13 @@ bool wasHdma = gb->memory.isHdma;
gb->memory.isHdma = value & 0x80; if ((!wasHdma && !gb->memory.isHdma) || gb->video.mode == 0) { gb->memory.hdmaRemaining = ((value & 0x7F) + 1) * 0x10; - gb->memory.hdmaNext = gb->cpu->cycles; + mTimingSchedule(&gb->timing, &gb->memory.hdmaEvent, 0); gb->cpu->nextEvent = gb->cpu->cycles; } } -void _GBMemoryDMAService(struct GB* gb) { +void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) { + struct GB* gb = context; uint8_t b = GBLoad8(gb->cpu, gb->memory.dmaSource); // TODO: Can DMA write OAM during modes 2-3? gb->video.oam.raw[gb->memory.dmaDest] = b;@@ -409,15 +395,15 @@ ++gb->memory.dmaSource;
++gb->memory.dmaDest; --gb->memory.dmaRemaining; if (gb->memory.dmaRemaining) { - gb->memory.dmaNext += 4; + mTimingSchedule(timing, &gb->memory.dmaEvent, 4 - cyclesLate); } else { - gb->memory.dmaNext = INT_MAX; gb->cpu->memory.store8 = GBStore8; gb->cpu->memory.load8 = GBLoad8; } } -void _GBMemoryHDMAService(struct GB* gb) { +void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) { + struct GB* gb = context; uint8_t b = gb->cpu->memory.load8(gb->cpu, gb->memory.hdmaSource); gb->cpu->memory.store8(gb->cpu, gb->memory.hdmaDest, b); ++gb->memory.hdmaSource;@@ -425,7 +411,7 @@ ++gb->memory.hdmaDest;
--gb->memory.hdmaRemaining; gb->cpu->cycles += 2; if (gb->memory.hdmaRemaining) { - gb->memory.hdmaNext += 2; + mTimingSchedule(timing, &gb->memory.hdmaEvent, 2 - cyclesLate); } else { gb->memory.io[REG_HDMA1] = gb->memory.hdmaSource >> 8; gb->memory.io[REG_HDMA2] = gb->memory.hdmaSource;@@ -591,11 +577,9 @@ STORE_16LE(memory->currentBank, 0, &state->memory.currentBank);
state->memory.wramCurrentBank = memory->wramCurrentBank; state->memory.sramCurrentBank = memory->sramCurrentBank; - STORE_32LE(memory->dmaNext, 0, &state->memory.dmaNext); STORE_16LE(memory->dmaSource, 0, &state->memory.dmaSource); STORE_16LE(memory->dmaDest, 0, &state->memory.dmaDest); - STORE_32LE(memory->hdmaNext, 0, &state->memory.hdmaNext); STORE_16LE(memory->hdmaSource, 0, &state->memory.hdmaSource); STORE_16LE(memory->hdmaDest, 0, &state->memory.hdmaDest);@@ -625,11 +609,9 @@ GBMBCSwitchBank(memory, memory->currentBank);
GBMemorySwitchWramBank(memory, memory->wramCurrentBank); GBMBCSwitchSramBank(gb, memory->sramCurrentBank); - LOAD_32LE(memory->dmaNext, 0, &state->memory.dmaNext); LOAD_16LE(memory->dmaSource, 0, &state->memory.dmaSource); LOAD_16LE(memory->dmaDest, 0, &state->memory.dmaDest); - LOAD_32LE(memory->hdmaNext, 0, &state->memory.hdmaNext); LOAD_16LE(memory->hdmaSource, 0, &state->memory.hdmaSource); LOAD_16LE(memory->hdmaDest, 0, &state->memory.hdmaDest);
M
src/gb/memory.h
→
src/gb/memory.h
@@ -9,6 +9,7 @@
#include "util/common.h" #include "core/log.h" +#include "core/timing.h" #include "gb/interface.h" #include "lr35902/lr35902.h"@@ -127,16 +128,17 @@ uint8_t ie;
uint8_t hram[GB_SIZE_HRAM]; - int32_t dmaNext; uint16_t dmaSource; uint16_t dmaDest; int dmaRemaining; - int32_t hdmaNext; uint16_t hdmaSource; uint16_t hdmaDest; int hdmaRemaining; bool isHdma; + + struct mTimingEvent dmaEvent; + struct mTimingEvent hdmaEvent; size_t romSize;
M
src/gb/video.c
→
src/gb/video.c
@@ -196,7 +196,7 @@ GBUpdateIRQs(video->p);
} if (video->ly < GB_VIDEO_VERTICAL_PIXELS && video->p->memory.isHdma && video->p->memory.io[REG_HDMA5] != 0xFF) { video->p->memory.hdmaRemaining = 0x10; - video->p->memory.hdmaNext = video->p->cpu->cycles; + mTimingSchedule(&video->p->timing, &video->p->memory.hdmaEvent, 0); } break; }