Merge branch 'rewrite' of https://github.com/liuk7071/ChonkyStation into rewrite

This commit is contained in:
liuk7071 2023-07-28 01:50:10 +02:00
commit b9988373ba
3 changed files with 61 additions and 9 deletions

View file

@ -1 +1,30 @@
#include "dma.hpp"
#include "dma.hpp"
#include <memory.hpp>
DMA::DMA() {
channels[6].doDMA = &otcDMA;
}
bool DMA::DMAChannel::shouldStartDMA() {
return chcr.enable && ((chcr.syncMode == 0) ? chcr.trigger.Value() : true);
}
void DMA::doDMA(int channel, Memory* memory) {
// If the dma func of the channel is null, it means it hasn't been implemented yet
if (!channels[channel].doDMA)
Helpers::panic("[DMA] Unimplemented DMA channel %d\n", channel);
channels[channel].doDMA(memory);
}
void DMA::otcDMA(Memory* memory) {
auto& dma = memory->dma;
constexpr auto ch = 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());
}
}

View file

@ -4,32 +4,49 @@
#include <BitField.hpp>
// Circular dependency
class Memory;
class DMA {
public:
DMA();
struct DMAChannel {
u32 madr;
u32 madr = 0;
union {
u32 raw;
u32 raw = 0;
BitField<0, 16, u32> bs;
BitField<0, 16, u32> ba;
} bcr;
union {
u32 raw;
u32 raw = 0;
BitField<0, 1, u32> dir;
BitField<1, 1, u32> step;
BitField<8, 1, u32> chopping;
BitField<9, 2, u32> syncMode;
BitField<16, 3, u32> choppingDmaSize;
BitField<20, 3, u32> choppingCpuSize;
BitField<24, 1, u32> busy;
BitField<24, 1, u32> enable;
BitField<28, 1, u32> trigger;
} chcr;
bool shouldStartDMA();
void (*doDMA)(Memory*);
};
DMAChannel channels[7];
u32 dpcr = 0;
u32 dicr = 0;
enum class SyncMode {
Block,
Sync,
LinkedList
};
void doDMA(int channel, Memory* memory);
static void otcDMA(Memory* memory);
};

View file

@ -110,7 +110,7 @@ u32 Memory::read(u32 vaddr) {
// DMA
else if (Helpers::inRange<u32>(paddr, 0x1f801080, 0x1f8010e8)) {
const auto channel = ((paddr >> 4) & 0xf) - 8;
Helpers::assert(channel < 8, "Tried to access %dth DMA channel", channel); // Should not get triggered
Helpers::assert(channel < 7, "Tried to access %dth DMA channel", channel); // Should not get triggered
switch (paddr & 0xf) {
case 0x0: return dma->channels[channel].madr;
@ -187,14 +187,20 @@ void Memory::write(u32 vaddr, u32 data) {
else if (paddr == 0x1f801070) interrupt->writeIstat(data);
else if (paddr == 0x1f801074) interrupt->writeImask(data);
// DMA
else if (Helpers::inRange<u32>(paddr, 0x1f801080, 0x1f8010e8)) {
else if (Helpers::inRange<u32>(paddr, 0x1f801080, 0x1f8010e8)) {
const auto channel = ((paddr >> 4) & 0xf) - 8;
Helpers::assert(channel < 8, "Tried to access %dth DMA channel", channel); // Should not get triggered
Helpers::assert(channel < 7, "Tried to access %dth DMA channel", channel); // Should not get triggered
switch (paddr & 0xf) {
case 0x0: dma->channels[channel].madr = data; break;
case 0x4: dma->channels[channel].bcr.raw = data; break;
case 0x8: dma->channels[channel].chcr.raw = data; break;
case 0x8: {
dma->channels[channel].chcr.raw = data;
if (dma->channels[channel].shouldStartDMA()) {
dma->doDMA(channel, this);
}
break;
}
default: Helpers::panic("[FATAL] Unhandled DMA write32 0x%08x <- 0x%08x\n", paddr, data);
}
}