Add: GPU DMA chunk management.

This commit is contained in:
Blue 2019-06-19 18:14:54 +02:00
parent 5911b1f8b9
commit b01ffeb18b

View file

@ -2,6 +2,11 @@
using static ProjectPSX.Width; using static ProjectPSX.Width;
namespace ProjectPSX.Devices { namespace ProjectPSX.Devices {
//TODO
//This class was one of the first to be write and needs to be rewrited to not use "Device" and to address all those load and writes
//and use variables for the channels maybe something like the timers a Channel inner class...
//Also I think CD reads are overkill word per word so DMA chunks should be handled as a whole but this causes issues on the cd itseld
//as it can read random values can be handled with a little pointer variable like the GPU transfers (doable but low priority)
public class DMA : Device { public class DMA : Device {
private DMA_Transfer dma_transfer; private DMA_Transfer dma_transfer;
@ -16,11 +21,11 @@ namespace ProjectPSX.Devices {
memOffset = 0x1F801080; memOffset = 0x1F801080;
//CONTROL = 0x07654321; //CONTROL = 0x07654321;
write(WORD, 0x1F8010F0, 0x07654321); write(0x1F8010F0, 0x07654321);
} }
public new void write(Width w, uint addr, uint value) { public void write(uint addr, uint value) {
if (addr == 0x1F8010F4) { if (addr == 0x1F8010F4) {
//Console.WriteLine("Write to interrupt handler " + addr.ToString("x8") + " " + value.ToString("x8")); //Console.WriteLine("Write to interrupt handler " + addr.ToString("x8") + " " + value.ToString("x8"));
value &= 0x7FFF_FFFF; value &= 0x7FFF_FFFF;
@ -33,7 +38,7 @@ namespace ProjectPSX.Devices {
value |= irqFlag << 24; value |= irqFlag << 24;
//Console.WriteLine("Write to interrupt handler 2" + addr.ToString("x8") + " " + value.ToString("x8")); //Console.WriteLine("Write to interrupt handler 2" + addr.ToString("x8") + " " + value.ToString("x8"));
} }
base.write(w, addr, value); base.write32(addr, value);
//Console.WriteLine("[DMA] Write: {0} Value: {1}", addr.ToString("x8"), value.ToString("x8")); //Console.WriteLine("[DMA] Write: {0} Value: {1}", addr.ToString("x8"), value.ToString("x8"));
@ -42,7 +47,7 @@ namespace ProjectPSX.Devices {
uint register = addr & 0xF; uint register = addr & 0xF;
switch (channel) { switch (channel) {
case uint CHANNELS when channel >= 0 && channel <= 6: case uint channels when channel <= 6:
if (register == 8 && isActive(value)) { if (register == 8 && isActive(value)) {
//Console.WriteLine("[DMA] [CHANNEL] " + channel + " " + addr.ToString("x8")); //Console.WriteLine("[DMA] [CHANNEL] " + channel + " " + addr.ToString("x8"));
handleDMA(addr, value); handleDMA(addr, value);
@ -115,7 +120,7 @@ namespace ProjectPSX.Devices {
private void disable(uint addr, uint value) { private void disable(uint addr, uint value) {
uint disabled = (uint)(value & ~0x11000000); uint disabled = (uint)(value & ~0x11000000);
write(WORD, addr, disabled); write32(addr, disabled);
} }
private void handleDMA(uint addr, uint control) { private void handleDMA(uint addr, uint control) {
@ -123,34 +128,34 @@ namespace ProjectPSX.Devices {
//Console.WriteLine("[DMA] SyncMode: " + syncMode); //Console.WriteLine("[DMA] SyncMode: " + syncMode);
switch (syncMode) { switch (syncMode) {
case 2: case 2:
linkedList(addr, control); linkedList(addr);
break; break;
default: default:
blockCopy(syncMode, addr, control); blockCopy(syncMode, addr, control);
break; break;
} }
} }
private void linkedList(uint addr, uint control) { private void linkedList(uint addr) {
uint header = 0; uint header = 0;
uint dmaAddress = getStartAdress(addr); uint dmaAddress = getStartAdress(addr);
while ((header & 0x800000) == 0) { while ((header & 0x800000) == 0) {
header = dma_transfer.fromRAM(WORD, dmaAddress); header = dma_transfer.fromRAM(dmaAddress);
// Console.WriteLine("HEADER addr " + dmaAddress.ToString("x8") + " value: " + header.ToString("x8")); //Console.WriteLine("HEADER addr " + dmaAddress.ToString("x8") + " value: " + header.ToString("x8"));
uint size = header >> 24; uint size = header >> 24;
while (size > 0) { if (size > 0) {
dmaAddress = (dmaAddress + 4) & 0x1ffffc; dmaAddress = (dmaAddress + 4) & 0x1ffffc;
uint load = dma_transfer.fromRAM(WORD, dmaAddress); //uint load = dma_transfer.fromRAM(dmaAddress);
// Console.WriteLine("GPU SEND addr " + dmaAddress.ToString("x8") + " value: " + load.ToString("x8")); // Console.WriteLine("GPU SEND addr " + dmaAddress.ToString("x8") + " value: " + load.ToString("x8"));
dma_transfer.toGPU(load); //dma_transfer.toGPU(load);
size--; uint[] bufferTest = dma_transfer.fromRAM(dmaAddress, size);
dma_transfer.toGPU(bufferTest);
} }
dmaAddress = header & 0x1ffffc; dmaAddress = header & 0x1ffffc;
} }
} }
private void blockCopy(uint syncMode, uint addr, uint control) { private void blockCopy(uint syncMode, uint addr, uint control) {
@ -165,6 +170,7 @@ namespace ProjectPSX.Devices {
switch (direction) { switch (direction) {
case 0: //To Ram case 0: //To Ram
uint data = 0; uint data = 0;
//byte[] cdTest = null;
switch (channel) { switch (channel) {
@ -174,7 +180,17 @@ namespace ProjectPSX.Devices {
break; break;
case 3: //CD case 3: //CD
data = dma_transfer.fromCD(); data = dma_transfer.fromCD();
// Console.WriteLine("[DMA] [C3 CD] TORAM Address: {0} Data: {1} Size {2}", (dmaAddress & 0x1F_FFFC).ToString("x8"), data.ToString("x8"), size); //if(step == -4) {
// Console.WriteLine("WARNING !!! UNHANDLED REVERSE ON BUFFER CD TRANSFER");
// Console.ReadLine();
//}
//cdTest = dma_transfer.fromCD(size);
//for (int i = 0; i < cdTest.Length; i++) {
// Console.WriteLine(cdTest[i].ToString("x2"));
//}
//dma_transfer.toRAM(dmaAddress & 0x1F_FFFC, cdTest, size);
//return;
//Console.WriteLine("[DMA] [C3 CD] TORAM Address: {0} Data: {1} Size {2}", (dmaAddress & 0x1F_FFFC).ToString("x8"), data.ToString("x8"), size);
break; break;
case 6: //OTC case 6: //OTC
if (size == 1) { if (size == 1) {
@ -189,26 +205,21 @@ namespace ProjectPSX.Devices {
//Console.WriteLine("[DMA] [BLOCK COPY] Unsupported Channel (to Ram) " + channel); //Console.WriteLine("[DMA] [BLOCK COPY] Unsupported Channel (to Ram) " + channel);
break; break;
} }
dma_transfer.toRAM(WORD, dmaAddress & 0x1F_FFFC, data); dma_transfer.toRAM(dmaAddress & 0x1F_FFFC, data);
break; break;
case 1: //From Ram case 1: //From Ram
uint load = 0; //Console.WriteLine("Size " + size);
try { uint[] load = dma_transfer.fromRAM(dmaAddress & 0x1F_FFFC, size);
load = dma_transfer.fromRAM(WORD, dmaAddress & 0x1F_FFFC);
}catch(Exception e) {
Console.WriteLine(dmaAddress.ToString("x8")); //00253af4
}
switch (channel) { switch (channel) {
case 2: //GPU case 2: //GPU
dma_transfer.toGPU(load); dma_transfer.toGPU(load);
break; return;
default: //MDECin and SPU default: //MDECin and SPU
//Console.WriteLine("[DMA] [BLOCK COPY] Unsupported Channel (from Ram) " + channel); Console.WriteLine("[DMA] [BLOCK COPY] Unsupported Channel (from Ram) " + channel);
break; return;
} }
break;
} }
dmaAddress += (uint)step; dmaAddress += (uint)step;
@ -255,9 +266,9 @@ namespace ProjectPSX.Devices {
} }
} }
public new uint load(Width w, uint addr) { public uint load(uint addr) {
//Console.WriteLine("[DMA] Load: {0} Value: {1}", addr.ToString("x8"), base.load(w, addr).ToString("x8")); //Console.WriteLine("[DMA] Load: {0} Value: {1}", addr.ToString("x8"), base.load(w, addr).ToString("x8"));
return base.load(w, addr); return base.load(Width.WORD, addr);
} }
public void setDMA_Transfer(DMA_Transfer dma_transfer) { public void setDMA_Transfer(DMA_Transfer dma_transfer) {