DMA: HDMA init/run must interrupt/cancel regular DMA

This commit is contained in:
Sour 2019-03-09 12:01:36 -05:00
parent f0ce0f63af
commit 2cecde26fb
2 changed files with 20 additions and 2 deletions

View file

@ -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"

View file

@ -24,6 +24,7 @@ struct DmaChannelConfig
bool DoTransfer;
bool HdmaFinished;
bool InterruptedByHdma;
bool UnusedFlag;
};