mirror of https://github.com/mgba-emu/mgba.git
GB Memory: Fix HDMAs
This commit is contained in:
parent
84844232ec
commit
e429d726dc
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue