[DMA] GPU LinkedList

This commit is contained in:
liuk7071 2023-07-29 15:43:11 +02:00
parent 34923221d3
commit f40ade4b33
5 changed files with 57 additions and 2 deletions

View file

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

View file

@ -5,6 +5,7 @@
MAKE_LOG_FUNCTION(log, dmaLogger)
DMA::DMA() {
channels[2].doDMA = &gpuDMA;
channels[6].doDMA = &otcDMA;
}
@ -20,14 +21,57 @@ void DMA::doDMA(int channel, Memory* memory) {
channels[channel].doDMA(memory);
}
void DMA::gpuDMA(Memory* memory) {
const auto& dma = memory->dma;
auto& ch = dma->channels[2];
log("Start GPU DMA\n");
switch (ch.chcr.syncMode) {
case (u32)SyncMode::LinkedList: {
Helpers::assert(ch.chcr.dir == (u32)Direction::ToDevice, "[FATAL] GPU LinkedList with direction ToRam");
u32 header = 0;
u32 words = 0;
u32 data = 0;
u32 addr = ch.madr & 0x1ffffc;
while (true) {
header = memory->read<u32>(addr);
words = header >> 24;
while (words-- > 0) {
addr += 4;
data = memory->read<u32>(addr);
memory->gpu->writeGp0(data);
}
if (header & 0x800000)
break;
addr = header & 0x1ffffc;
}
// In SyncMode 2 (LinkedList), MADR is updated to hold the end marker
ch.madr = header;
break;
}
default:
Helpers::panic("[DMA] Unimplemented GPU DMA sync mode %d\n", ch.chcr.syncMode.Value());
}
ch.chcr.enable = 0;
ch.chcr.trigger = 0;
// TODO: Update DICR
log("GPU DMA done\n");
}
void DMA::otcDMA(Memory* memory) {
const auto& dma = memory->dma;
auto& ch = dma->channels[6];
log("Start OTC DMA\n");
// 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

View file

@ -43,6 +43,10 @@ public:
u32 dpcr = 0;
u32 dicr = 0;
enum class Direction {
ToRam,
ToDevice
};
enum class SyncMode {
Block,
Sync,
@ -50,5 +54,6 @@ public:
};
void doDMA(int channel, Memory* memory);
static void gpuDMA(Memory* memory);
static void otcDMA(Memory* memory);
};

View file

@ -56,10 +56,12 @@ void Gpu::startCommand(u32 rawCommand) {
const auto cmd = (rawCommand >> 24) & 0xff;
switch (cmd) {
case (u32)GP0Command::NOP: {
log("NOP\n");
// NOP
break;
}
case (u32)GP0Command::DrawModeSetting: {
log("DrawModeSetting\n");
// Bits 0-10 are copied into GPUSTAT
stat &= ~0x7ff;
stat |= rawCommand & 0x7ff;

View file

@ -1,6 +1,7 @@
#pragma once
#include <helpers.hpp>
#include <logger.hpp>
class Gpu {
@ -31,4 +32,6 @@ public:
private:
u32 stat = 0x14802000;
MAKE_LOG_FUNCTION(log, gpuLogger)
};