[DMA] Implement OTC DMA

This commit is contained in:
liuk7071 2023-07-29 00:43:56 +02:00
parent b9988373ba
commit 34923221d3
4 changed files with 34 additions and 9 deletions

View file

@ -24,7 +24,8 @@ public:
};
// Our loggers here. Enable/disable by toggling the template param
static auto cpuTraceLogger = Logger<false>("[CPU TRACE] ");
static auto cpuTraceLogger = Logger<false>("[CPU TRACE] ");
static auto dmaLogger = Logger<true>("[ DMA ] ");
#define MAKE_LOG_FUNCTION(functionName, logger) \

View file

@ -2,6 +2,8 @@
#include <memory.hpp>
MAKE_LOG_FUNCTION(log, dmaLogger)
DMA::DMA() {
channels[6].doDMA = &otcDMA;
}
@ -19,12 +21,30 @@ void DMA::doDMA(int channel, Memory* memory) {
}
void DMA::otcDMA(Memory* memory) {
auto& dma = memory->dma;
constexpr auto ch = 6;
const auto& dma = memory->dma;
auto& ch = dma->channels[6];
// OTC DMA is always sync mode 0 and backwards memory address step
switch (dma->channels[ch].chcr.syncMode) {
default:
Helpers::panic("[DMA] Unimplemented OTC DMA sync mode %d\n", dma->channels[ch].chcr.syncMode.Value());
// OTC DMA is always sync mode 0 and backwards memory address step and no chopping
switch (ch.chcr.syncMode) {
case (u32)SyncMode::Block: {
log("Start OTC DMA\n");
u32 addr = ch.madr & 0x1ffffc; // SyncMode 0 with chopping disabled doesn't update MADR
u32 bc = ch.bcr.bc; // SyncMode 0 with chopping disabled doesn't update BCR
if (!bc) bc = 0x10000; // If bc is 0, we need to transfer 0x10000 words
while (bc-- > 1) {
memory->write<u32>(addr, addr - 4);
addr -= 4; // OTC DMA is always decrementing
}
// Last word is 0xffffff
memory->write<u32>(addr, 0xffffff);
break;
}
default:
Helpers::panic("[DMA] Unimplemented OTC DMA sync mode %d\n", ch.chcr.syncMode.Value());
}
ch.chcr.enable = 0;
ch.chcr.trigger = 0;
// TODO: Update DICR
log("OTC DMA done\n");
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <helpers.hpp>
#include <logger.hpp>
#include <BitField.hpp>
@ -16,8 +17,9 @@ public:
union {
u32 raw = 0;
BitField<0, 16, u32> bs;
BitField<0, 16, u32> ba;
BitField<0, 16, u32> bc;
BitField<0, 16, u32> bs;
BitField<16, 16, u32> ba;
} bcr;
union {

View file

@ -121,6 +121,8 @@ u32 Memory::read(u32 vaddr) {
}
else if (paddr == 0x1f8010f0) return dma->dpcr;
else if (paddr == 0x1f8010f4) return dma->dicr;
// Timers
else if (Helpers::inRangeSized<u32>(paddr, (u32)MemoryBase::Timer, (u32)MemorySize::Timer)) return 0;
else
Helpers::panic("[FATAL] Unhandled read32 0x%08x (virtual 0x%08x)\n", paddr, vaddr);
}