diff --git a/Core/DmaController.cpp b/Core/DmaController.cpp index e01890d..1e445f3 100644 --- a/Core/DmaController.cpp +++ b/Core/DmaController.cpp @@ -30,17 +30,21 @@ void DmaController::RunSingleTransfer(DmaChannelConfig &channel) channel.TransferSize--; transferByteCount--; i++; - } while(channel.TransferSize > 0 && transferByteCount > 0); + } while(channel.TransferSize > 0 && transferByteCount > 0 && !channel.InterruptedByHdma); } void DmaController::RunDma(DmaChannelConfig &channel) { + if(channel.InterruptedByHdma) { + return; + } + do { //Manual DMA transfers run to the end of the transfer when started RunSingleTransfer(channel); //TODO : Run HDMA when needed, between 2 DMA transfers - } while(channel.TransferSize > 0); + } while(channel.TransferSize > 0 && !channel.InterruptedByHdma); } void DmaController::InitHdmaChannels() @@ -57,6 +61,7 @@ void DmaController::InitHdmaChannels() if(_hdmaChannels & (1 << i)) { //"1. Copy AAddress into Address." ch.HdmaTableAddress = ch.SrcAddress; + ch.InterruptedByHdma = true; //"2. Load $43xA (Line Counter and Repeat) from the table. I believe $00 will terminate this channel immediately." ch.HdmaLineCounterAndRepeat = _memoryManager->ReadDma((ch.SrcBank << 16) | ch.HdmaTableAddress); @@ -89,6 +94,8 @@ void DmaController::RunHdmaTransfer(DmaChannelConfig &channel) const uint8_t *transferOffsets = _transferOffset[channel.TransferMode]; uint8_t transferByteCount = _transferByteCount[channel.TransferMode]; + channel.InterruptedByHdma = true; + uint32_t srcAddress; if(channel.HdmaIndirectAddressing) { srcAddress = (channel.HdmaBank << 16) | channel.TransferSize; @@ -125,6 +132,12 @@ void DmaController::ProcessHdmaChannels() if(_hdmaChannels) { _hdmaPending = true; + for(int i = 0; i < 8; i++) { + if(_hdmaChannels & (1 << i)) { + _channel[i].InterruptedByHdma = true; + } + } + for(int i = 0; i < 8; i++) { DmaChannelConfig &ch = _channel[i]; if((_hdmaChannels & (1 << i)) == 0 || ch.HdmaFinished) { @@ -198,6 +211,10 @@ void DmaController::Write(uint16_t addr, uint8_t value) //"and an extra 8 master cycles overhead for the whole thing" _memoryManager->IncrementMasterClockValue<8>(); + for(int i = 0; i < 8; i++) { + _channel[i].InterruptedByHdma = false; + } + for(int i = 0; i < 8; i++) { if(value & (1 << i)) { //"Then perform the DMA: 8 master cycles overhead and 8 master cycles per byte per channel" diff --git a/Core/DmaController.h b/Core/DmaController.h index 81d5251..2a3f30c 100644 --- a/Core/DmaController.h +++ b/Core/DmaController.h @@ -24,6 +24,7 @@ struct DmaChannelConfig bool DoTransfer; bool HdmaFinished; + bool InterruptedByHdma; bool UnusedFlag; };