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 7f9c7706bc
commit 9248dcb07a
4 changed files with 8 additions and 5 deletions

View File

@ -6,6 +6,7 @@ Bugfixes:
- GBA Cheats: Fix PARv3 slide codes (fixes mgba.io/i/919) - GBA Cheats: Fix PARv3 slide codes (fixes mgba.io/i/919)
- GBA Video: OBJWIN can change blend params after OBJ is drawn (fixes mgba.io/i/921) - GBA Video: OBJWIN can change blend params after OBJ is drawn (fixes mgba.io/i/921)
- GBA Savedata: Fix crash when resizing flash - GBA Savedata: Fix crash when resizing flash
- GB Memory: HDMAs should not start when LCD is off (fixes mgba.io/i/310)
Misc: Misc:
- GBA: Improve multiboot image detection - GBA: Improve multiboot image detection
- GB MBC: Remove erroneous bank 0 wrapping - GB MBC: Remove erroneous bank 0 wrapping

View File

@ -177,7 +177,7 @@ int GBCurrentSegment(struct LR35902Core* cpu, uint16_t address);
uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment); uint8_t GBView8(struct LR35902Core* cpu, uint16_t address, int segment);
void GBMemoryDMA(struct GB* gb, uint16_t base); 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); void GBPatch8(struct LR35902Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment);

View File

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

View File

@ -449,7 +449,7 @@ void GBMemoryDMA(struct GB* gb, uint16_t base) {
gb->memory.dmaRemaining = 0xA0; 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_HDMA1] << 8;
gb->memory.hdmaSource |= gb->memory.io[REG_HDMA2]; gb->memory.hdmaSource |= gb->memory.io[REG_HDMA2];
gb->memory.hdmaDest = gb->memory.io[REG_HDMA3] << 8; gb->memory.hdmaDest = gb->memory.io[REG_HDMA3] << 8;
@ -457,7 +457,7 @@ void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
gb->memory.hdmaSource &= 0xFFF0; gb->memory.hdmaSource &= 0xFFF0;
if (gb->memory.hdmaSource >= 0x8000 && gb->memory.hdmaSource < 0xA000) { if (gb->memory.hdmaSource >= 0x8000 && gb->memory.hdmaSource < 0xA000) {
mLOG(GB_MEM, GAME_ERROR, "Invalid HDMA source: %04X", gb->memory.hdmaSource); mLOG(GB_MEM, GAME_ERROR, "Invalid HDMA source: %04X", gb->memory.hdmaSource);
return; return value | 0x80;
} }
gb->memory.hdmaDest &= 0x1FF0; gb->memory.hdmaDest &= 0x1FF0;
gb->memory.hdmaDest |= 0x8000; gb->memory.hdmaDest |= 0x8000;
@ -471,7 +471,10 @@ void GBMemoryWriteHDMA5(struct GB* gb, uint8_t value) {
} }
gb->cpuBlocked = true; gb->cpuBlocked = true;
mTimingSchedule(&gb->timing, &gb->memory.hdmaEvent, 0); 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) { void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) {