all repos — mgba @ e2357f0b70ed3eab14883819b41c19d1e9f30b8e

mGBA Game Boy Advance Emulator

GB: Convert memory events to mTiming
Jeffrey Pfau jeffrey@endrift.com
Sat, 17 Sep 2016 18:56:46 -0700
commit

e2357f0b70ed3eab14883819b41c19d1e9f30b8e

parent

d831de205fe45a9458efa4015bc0ef808ae84925

4 files changed, 25 insertions(+), 46 deletions(-)

jump to
M src/gb/gb.csrc/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.csrc/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.hsrc/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.csrc/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; }