mirror of
https://github.com/liuk7071/ChonkyStation.git
synced 2024-05-20 12:57:52 -04:00
[DMA] GPU LinkedList
This commit is contained in:
parent
34923221d3
commit
f40ade4b33
3
external/Panda3DS/logger.hpp
vendored
3
external/Panda3DS/logger.hpp
vendored
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
};
|
Loading…
Reference in a new issue