GB Memory: HDMAs should not start when LCD is off (fixes #310)

This commit is contained in:
Vicki Pfau 2017-11-05 21:46:10 -08:00
parent fb939ab042
commit d054be88c7
5 changed files with 10 additions and 6 deletions

View File

@ -26,6 +26,7 @@ Bugfixes:
- GBA DMA: Fix invalid DMA reads (fixes mgba.io/i/142)
- GBA Savedata: Fix crash when resizing flash
- GBA Video: Add delay when enabling BGs (fixes mgba.io/i/744, mgba.io/i/752)
- GB Memory: HDMAs should not start when LCD is off (fixes mgba.io/i/310)
Misc:
- GBA Timer: Use global cycles for timers
- GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)

View File

@ -1 +1,2 @@
fail: true
config:
gb.model: CGB

View File

@ -207,7 +207,7 @@ int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address);
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment);
void GBMemoryDMA(struct GB* gb, uint16_t base);
void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value);
uint8_t GBMemoryWriteHDMA5(struct GB* gb, uint8_t value);
void GBPatch8(struct LR35902Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment);

View File

@ -450,8 +450,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
// Handled transparently by the registers
break;
case REG_HDMA5:
GBMemoryWriteHDMA5(gb, value);
value &= 0x7F;
value = GBMemoryWriteHDMA5(gb, value);
break;
case REG_BCPS:
gb->video.bcpIndex = value & 0x3F;

View File

@ -454,7 +454,7 @@ void GBMemoryDMA(struct GB* gb, uint16_t base) {
gb->memory.dmaRemaining = 0xA0;
}
void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
uint8_t GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
gb->memory.hdmaSource = gb->memory.io[REG_HDMA1] << 8;
gb->memory.hdmaSource |= gb->memory.io[REG_HDMA2];
gb->memory.hdmaDest = gb->memory.io[REG_HDMA3] << 8;
@ -462,7 +462,7 @@ void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
gb->memory.hdmaSource &= 0xFFF0;
if (gb->memory.hdmaSource >= 0x8000 && gb->memory.hdmaSource < 0xA000) {
mLOG(GB_MEM, GAME_ERROR, "Invalid HDMA source: %04X", gb->memory.hdmaSource);
return;
return value | 0x80;
}
gb->memory.hdmaDest &= 0x1FF0;
gb->memory.hdmaDest |= 0x8000;
@ -476,7 +476,10 @@ void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
}
gb->cpuBlocked = true;
mTimingSchedule(&gb->timing, &gb->memory.hdmaEvent, 0);
} else if (gb->memory.isHdma && !GBRegisterLCDCIsEnable(gb->memory.io[REG_LCDC])) {
return 0x80 | ((value + 1) & 0x7F);
}
return value & 0x7F;
}
void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) {