GB Memory: Fix HDMAs

This commit is contained in:
Jeffrey Pfau 2016-11-10 20:05:33 -08:00
parent 84844232ec
commit e429d726dc
4 changed files with 12 additions and 2 deletions

View File

@ -425,6 +425,7 @@ void GBReset(struct LR35902Core* cpu) {
cpu->pc = 0x100; cpu->pc = 0x100;
} }
gb->cpuBlocked = false;
gb->eiPending = INT_MAX; gb->eiPending = INT_MAX;
gb->doubleSpeed = 0; gb->doubleSpeed = 0;
@ -546,7 +547,11 @@ void GBProcessEvents(struct LR35902Core* cpu) {
} }
} }
cpu->nextEvent = mTimingTick(&gb->timing, cycles); nextEvent = cycles;
do {
nextEvent = mTimingTick(&gb->timing, nextEvent);
} while (gb->cpuBlocked);
cpu->nextEvent = nextEvent;
if (cpu->halted) { if (cpu->halted) {
cpu->cycles = cpu->nextEvent; cpu->cycles = cpu->nextEvent;

View File

@ -78,6 +78,7 @@ struct GB {
struct mCoreCallbacks* coreCallbacks; struct mCoreCallbacks* coreCallbacks;
struct mAVStream* stream; struct mAVStream* stream;
bool cpuBlocked;
int32_t eiPending; int32_t eiPending;
unsigned doubleSpeed; unsigned doubleSpeed;
}; };

View File

@ -381,6 +381,7 @@ void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
gb->memory.isHdma = value & 0x80; gb->memory.isHdma = value & 0x80;
if ((!wasHdma && !gb->memory.isHdma) || gb->video.mode == 0) { if ((!wasHdma && !gb->memory.isHdma) || gb->video.mode == 0) {
gb->memory.hdmaRemaining = ((value & 0x7F) + 1) * 0x10; gb->memory.hdmaRemaining = ((value & 0x7F) + 1) * 0x10;
gb->cpuBlocked = true;
mTimingSchedule(&gb->timing, &gb->memory.hdmaEvent, 0); mTimingSchedule(&gb->timing, &gb->memory.hdmaEvent, 0);
gb->cpu->nextEvent = gb->cpu->cycles; gb->cpu->nextEvent = gb->cpu->cycles;
} }
@ -404,14 +405,17 @@ void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesL
void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) { void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) {
struct GB* gb = context; struct GB* gb = context;
gb->cpuBlocked = true;
uint8_t b = gb->cpu->memory.load8(gb->cpu, gb->memory.hdmaSource); uint8_t b = gb->cpu->memory.load8(gb->cpu, gb->memory.hdmaSource);
gb->cpu->memory.store8(gb->cpu, gb->memory.hdmaDest, b); gb->cpu->memory.store8(gb->cpu, gb->memory.hdmaDest, b);
++gb->memory.hdmaSource; ++gb->memory.hdmaSource;
++gb->memory.hdmaDest; ++gb->memory.hdmaDest;
--gb->memory.hdmaRemaining; --gb->memory.hdmaRemaining;
if (gb->memory.hdmaRemaining) { if (gb->memory.hdmaRemaining) {
mTimingDeschedule(timing, &gb->memory.hdmaEvent);
mTimingSchedule(timing, &gb->memory.hdmaEvent, 2 - cyclesLate); mTimingSchedule(timing, &gb->memory.hdmaEvent, 2 - cyclesLate);
} else { } else {
gb->cpuBlocked = false;
gb->memory.io[REG_HDMA1] = gb->memory.hdmaSource >> 8; gb->memory.io[REG_HDMA1] = gb->memory.hdmaSource >> 8;
gb->memory.io[REG_HDMA2] = gb->memory.hdmaSource; gb->memory.io[REG_HDMA2] = gb->memory.hdmaSource;
gb->memory.io[REG_HDMA3] = gb->memory.hdmaDest >> 8; gb->memory.io[REG_HDMA3] = gb->memory.hdmaDest >> 8;
@ -425,7 +429,6 @@ void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cycles
gb->memory.io[REG_HDMA5] = 0xFF; gb->memory.io[REG_HDMA5] = 0xFF;
} }
} }
gb->cpu->cycles += 2;
} }
struct OAMBlock { struct OAMBlock {

View File

@ -206,6 +206,7 @@ void _endMode3(struct mTiming* timing, void* context, uint32_t cyclesLate) {
} }
if (video->ly < GB_VIDEO_VERTICAL_PIXELS && video->p->memory.isHdma && video->p->memory.io[REG_HDMA5] != 0xFF) { 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.hdmaRemaining = 0x10;
mTimingDeschedule(timing, &video->p->memory.hdmaEvent);
mTimingSchedule(timing, &video->p->memory.hdmaEvent, 0); mTimingSchedule(timing, &video->p->memory.hdmaEvent, 0);
} }
video->mode = 0; video->mode = 0;