diff --git a/Core/DmaController.cpp b/Core/DmaController.cpp index f5e2811..8402efa 100644 --- a/Core/DmaController.cpp +++ b/Core/DmaController.cpp @@ -271,7 +271,7 @@ bool DmaController::ProcessHdmaChannels() //"b. If Addressing Mode is Indirect, read two bytes from Address into Indirect Address(and increment Address by two bytes)." if(ch.HdmaIndirectAddressing) { - if(ch.HdmaLineCounterAndRepeat == 0) { + if(ch.HdmaLineCounterAndRepeat == 0 && IsLastActiveHdmaChannel(i)) { //"One oddity: if $43xA is 0 and this is the last active HDMA channel for this scanline, only load one byte for Address, //and use the $00 for the low byte.So Address ends up incremented one less than otherwise expected, and one less CPU Cycle is used." uint8_t msb = _memoryManager->ReadDma((ch.SrcBank << 16) | ch.HdmaTableAddress++, true); @@ -310,6 +310,16 @@ bool DmaController::ProcessHdmaChannels() return true; } +bool DmaController::IsLastActiveHdmaChannel(uint8_t channel) +{ + for(int i = channel + 1; i < 8; i++) { + if((_hdmaChannels & (1 << i)) && !_channel[i].HdmaFinished) { + return false; + } + } + return true; +} + void DmaController::UpdateNeedToProcessFlag() { //Slightly faster execution time by doing this rather than processing all 4 flags on each cycle diff --git a/Core/DmaController.h b/Core/DmaController.h index bfd5a94..89ee10a 100644 --- a/Core/DmaController.h +++ b/Core/DmaController.h @@ -30,6 +30,7 @@ private: void RunHdmaTransfer(DmaChannelConfig &channel); bool ProcessHdmaChannels(); + bool IsLastActiveHdmaChannel(uint8_t channel); bool InitHdmaChannels(); void SyncStartDma();