From d341260e5a39b926aa2b688edd68d07a0cd366d6 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:23:02 -0500 Subject: [PATCH] dma rewrite 1 --- src/ARM.h | 6 +- src/DMA.cpp | 34 +++++++-- src/DMA.h | 18 ++--- src/NDS.cpp | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/NDS.h | 2 + 5 files changed, 252 insertions(+), 24 deletions(-) diff --git a/src/ARM.h b/src/ARM.h index 04020540..413510f8 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -69,7 +69,11 @@ enum class MainRAMType : u8 Fetch, ICacheStream, DCacheStream, - WriteBufferCmds, // all write buffer commands must be above this one; wb cmds not strictly used for main ram + DMA16, + DMA32, + + WriteBufferCmds, // all write buffer commands must be below this one; wb cmds are not strictly used for main ram + WBDrain, WBWrite, WBCheck, diff --git a/src/DMA.cpp b/src/DMA.cpp index 56ec1564..5269a974 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -21,6 +21,7 @@ #include "DSi.h" #include "DMA.h" #include "GPU.h" +#include "ARM.h" #include "GPU3D.h" #include "DMA_Timings.h" #include "Platform.h" @@ -213,8 +214,8 @@ u32 DMA::UnitTimings9_16(u8 burststart) src_s = NDS.ARM9MemTimings[src_id][5]; dst_n = NDS.ARM9MemTimings[dst_id][4]; dst_s = NDS.ARM9MemTimings[dst_id][5]; - - if (src_rgn == Mem9_MainRAM) + + /*if (src_rgn == Mem9_MainRAM) { if (dst_rgn == Mem9_MainRAM) { @@ -275,7 +276,7 @@ u32 DMA::UnitTimings9_16(u8 burststart) return ((burststart == 2) ? src_n : src_s) + 7; } } - else if (src_rgn & dst_rgn) + else*/ if (src_rgn & dst_rgn) { if (burststart != 1) return src_n + dst_n + (src_n == 1 || burststart <= 0); @@ -305,7 +306,7 @@ u32 DMA::UnitTimings9_32(u8 burststart) dst_n = NDS.ARM9MemTimings[dst_id][6]; dst_s = NDS.ARM9MemTimings[dst_id][7]; - if (src_rgn == Mem9_MainRAM) + /*if (src_rgn == Mem9_MainRAM) { if (dst_rgn == Mem9_MainRAM) return (burststart == 2) ? 13 : 18; @@ -368,7 +369,7 @@ u32 DMA::UnitTimings9_32(u8 burststart) return ((burststart == 2) ? src_n : src_s) + 8; } } - else if (src_rgn & dst_rgn) + else*/ if (src_rgn & dst_rgn) { if (burststart != 1) return src_n + dst_n + (src_n == 1 || burststart <= 0); @@ -570,14 +571,22 @@ void DMA::Run9() // add NS penalty for first accesses in burst int burststart = Running-1; - Running = 2; NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1< 0 && !Stall) { + u32 rgn = NDS.ARM9Regions[CurSrcAddr>>14] | NDS.ARM9Regions[CurDstAddr>>14]; + if (rgn & Mem9_MainRAM) + { + NDS.ARM9.MRTrack.Type = MainRAMType::DMA16; + NDS.ARM9.MRTrack.Var = Num; + return; + } + Running = 2; + NDS.ARM9Timestamp += (UnitTimings9_16(burststart) << NDS.ARM9ClockShift); burststart -= 1; @@ -595,6 +604,15 @@ void DMA::Run9() { while (IterCount > 0 && !Stall) { + u32 rgn = NDS.ARM9Regions[CurSrcAddr>>14] | NDS.ARM9Regions[CurDstAddr>>14]; + if (rgn & Mem9_MainRAM) + { + NDS.ARM9.MRTrack.Type = MainRAMType::DMA32; + NDS.ARM9.MRTrack.Var = Num; + return; + } + Running = 2; + NDS.ARM9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift); burststart -= 1; @@ -609,7 +627,7 @@ void DMA::Run9() } } - if (burststart == 1) Running = 1; + if (burststart == 0) Running = 1; Executing = false; Stall = false; diff --git a/src/DMA.h b/src/DMA.h index 64d5647f..65aaff82 100644 --- a/src/DMA.h +++ b/src/DMA.h @@ -81,23 +81,23 @@ public: u32 SrcAddr {}; u32 DstAddr {}; u32 Cnt {}; - -private: - melonDS::NDS& NDS; - u32 CPU {}; - u32 Num {}; - - u32 StartMode {}; u32 CurSrcAddr {}; u32 CurDstAddr {}; u32 RemCount {}; u32 IterCount {}; s32 SrcAddrInc {}; s32 DstAddrInc {}; - u32 CountMask {}; - u32 Running {}; bool InProgress {}; + u32 Num {}; + u32 StartMode {}; + +private: + melonDS::NDS& NDS; + u32 CPU {}; + + u32 CountMask {}; + bool Executing {}; bool Stall {}; diff --git a/src/NDS.cpp b/src/NDS.cpp index 3e124663..2f97a9db 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -1055,6 +1055,210 @@ void NDS::MainRAMHandleARM9() break; } + case MainRAMType::DMA32: + { + DMA* dma = &DMAs[ARM9.MRTrack.Var]; + int burststart = dma->Running - 1; + + u32 srcaddr = dma->CurSrcAddr; + u32 srcrgn = ARM9Regions[srcaddr>>14]; + u32 dstaddr = dma->CurDstAddr; + u32 dstrgn = ARM9Regions[dstaddr>>14]; + if (!ARM9.MRTrack.Progress) + { + if (srcrgn == Mem9_MainRAM) + { + if (burststart == 2 || A7WENTLAST || DMALastWasMainRAM || dma->SrcAddrInc <= 0) + { + if (A9ContentionTS < MainRAMTimestamp) { A9ContentionTS = MainRAMTimestamp; if (A7PRIORITY) return; } + MainRAMTimestamp = A9ContentionTS + 9; + A9ContentionTS += 6; + MainRAMLastAccess = A9LAST; + } + else + { + A9ContentionTS += 2; + MainRAMTimestamp += 2; + } + DMALastWasMainRAM = true; + } + else + { + if (burststart == 2 || dma->SrcAddrInc <= 0) A9ContentionTS += ARM9MemTimings[srcaddr>>14][6] + (ARM9MemTimings[srcaddr>>14][6] == 1); + else A9ContentionTS += ARM9MemTimings[srcaddr>>14][7]; + DMALastWasMainRAM = false; + } + + DMAReadHold = ARM9Read32(srcaddr); + + ARM9.MRTrack.Progress = 1; + } + else + { + if (dstrgn == Mem9_MainRAM) + { + if (burststart == 2 || A7WENTLAST || DMALastWasMainRAM || dma->DstAddrInc <= 0) + { + if (A9ContentionTS < MainRAMTimestamp) { A9ContentionTS = MainRAMTimestamp; if (A7PRIORITY) return; } + MainRAMTimestamp = A9ContentionTS + 9; + A9ContentionTS += 4; + MainRAMLastAccess = A9LAST; + } + else + { + A9ContentionTS += 2; + MainRAMTimestamp += 2; + } + DMALastWasMainRAM = true; + } + else + { + if (burststart == 2 || dma->DstAddrInc <= 0) A9ContentionTS += ARM9MemTimings[dstaddr>>14][6]; + else A9ContentionTS += ARM9MemTimings[dstaddr>>14][7] - (burststart <= 0); + DMALastWasMainRAM = false; + } + + ARM9Write32(dstaddr, DMAReadHold); + + dma->CurSrcAddr += dma->SrcAddrInc<<2; + dma->CurDstAddr += dma->DstAddrInc<<2; + dma->IterCount--; + dma->RemCount--; + burststart -= 1; + if (burststart <= 0) dma->Running = 1; + else dma->Running = 2; + ARM9Timestamp = A9ContentionTS << ARM9ClockShift; + memset(&ARM9.MRTrack, 0, sizeof(ARM9.MRTrack)); + ConTSLock = false; + if (dma->RemCount) + { + if (dma->IterCount == 0) + { + dma->Running = 0; + ResumeCPU(0, 1<Num); + + if (dma->StartMode == 0x07) + GPU.GPU3D.CheckFIFODMA(); + } + + break; + } + + if (!(dma->Cnt & (1<<25))) + dma->Cnt &= ~(1<<31); + + if (dma->Cnt & (1<<30)) + SetIRQ(0, IRQ_DMA0 + dma->Num); + + dma->Running = 0; + dma->InProgress = false; + ResumeCPU(0, 1<Num); + } + break; + } + + case MainRAMType::DMA16: + { + DMA* dma = &DMAs[ARM9.MRTrack.Var]; + int burststart = dma->Running - 1; + + u32 srcaddr = dma->CurSrcAddr; + u32 srcrgn = ARM9Regions[srcaddr>>14]; + u32 dstaddr = dma->CurDstAddr; + u32 dstrgn = ARM9Regions[dstaddr>>14]; + if (!ARM9.MRTrack.Progress) + { + if (srcrgn == Mem9_MainRAM) + { + if (burststart == 2 || A7WENTLAST || DMALastWasMainRAM || dma->SrcAddrInc <= 0) + { + if (A9ContentionTS < MainRAMTimestamp) { A9ContentionTS = MainRAMTimestamp; if (A7PRIORITY) return; } + MainRAMTimestamp = A9ContentionTS + 8; + A9ContentionTS += 5; + MainRAMLastAccess = A9LAST; + } + else + { + A9ContentionTS += 1; + MainRAMTimestamp += 1; + } + DMALastWasMainRAM = true; + } + else + { + if (burststart == 2 || dma->SrcAddrInc <= 0) A9ContentionTS += ARM9MemTimings[srcaddr>>14][4] + (ARM9MemTimings[srcaddr>>14][4] == 1); + else A9ContentionTS += ARM9MemTimings[srcaddr>>14][5]; + DMALastWasMainRAM = false; + } + + DMAReadHold = ARM9Read16(srcaddr); + + ARM9.MRTrack.Progress = 1; + } + else + { + if (dstrgn == Mem9_MainRAM) + { + if (burststart == 2 || A7WENTLAST || DMALastWasMainRAM || dma->DstAddrInc <= 0) + { + if (A9ContentionTS < MainRAMTimestamp) { A9ContentionTS = MainRAMTimestamp; if (A7PRIORITY) return; } + MainRAMTimestamp = A9ContentionTS + 8; + A9ContentionTS += 3; + MainRAMLastAccess = A9LAST; + } + else + { + A9ContentionTS += 1; + MainRAMTimestamp += 1; + } + DMALastWasMainRAM = true; + } + else + { + if (burststart == 2 || dma->DstAddrInc <= 0) A9ContentionTS += ARM9MemTimings[dstaddr>>14][4]; + else A9ContentionTS += ARM9MemTimings[dstaddr>>14][5] - (burststart <= 0); + DMALastWasMainRAM = false; + } + + ARM9Write16(dstaddr, DMAReadHold); + + dma->CurSrcAddr += dma->SrcAddrInc<<1; + dma->CurDstAddr += dma->DstAddrInc<<1; + dma->IterCount--; + dma->RemCount--; + burststart -= 1; + if (burststart <= 0) Running = 1; + else dma->Running = 2; + ARM9Timestamp = A9ContentionTS << ARM9ClockShift; + memset(&ARM9.MRTrack, 0, sizeof(ARM9.MRTrack)); + ConTSLock = false; + if (dma->RemCount) + { + if (dma->IterCount == 0) + { + dma->Running = 0; + ResumeCPU(0, 1<Num); + + if (dma->StartMode == 0x07) + GPU.GPU3D.CheckFIFODMA(); + } + + break; + } + + if (!(dma->Cnt & (1<<25))) + dma->Cnt &= ~(1<<31); + + if (dma->Cnt & (1<<30)) + SetIRQ(0, IRQ_DMA0 + dma->Num); + + dma->Running = 0; + dma->InProgress = false; + ResumeCPU(0, 1<Num); + } + break; + } + case MainRAMType::WBDrain: { if (!ARM9.WriteBufferHandle()) return; @@ -1334,9 +1538,9 @@ u32 NDS::RunFrame() { u64 ts = ARM9Timestamp; DMAs[0].Run(); - if (!(CPUStop & CPUStop_GXStall)) DMAs[1].Run(); - if (!(CPUStop & CPUStop_GXStall)) DMAs[2].Run(); - if (!(CPUStop & CPUStop_GXStall)) DMAs[3].Run(); + if (!(CPUStop & CPUStop_GXStall) && (ARM9.MRTrack.Type == MainRAMType::Null)) DMAs[1].Run(); + if (!(CPUStop & CPUStop_GXStall) && (ARM9.MRTrack.Type == MainRAMType::Null)) DMAs[2].Run(); + if (!(CPUStop & CPUStop_GXStall) && (ARM9.MRTrack.Type == MainRAMType::Null)) DMAs[3].Run(); if (ConsoleType == 1) { auto& dsi = dynamic_cast(*this); @@ -1378,9 +1582,9 @@ u32 NDS::RunFrame() if (CPUStop & CPUStop_DMA7) { DMAs[4].Run(); - DMAs[5].Run(); - DMAs[6].Run(); - DMAs[7].Run(); + if (ARM7.MRTrack.Type == MainRAMType::Null) DMAs[5].Run(); + if (ARM7.MRTrack.Type == MainRAMType::Null) DMAs[6].Run(); + if (ARM7.MRTrack.Type == MainRAMType::Null) DMAs[7].Run(); if (ConsoleType == 1) { auto& dsi = dynamic_cast(*this); diff --git a/src/NDS.h b/src/NDS.h index 6c430aa5..b0b5a911 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -276,7 +276,9 @@ public: // TODO: Encapsulate the rest of these members alignas(u32) u8 ROMSeed0[2*8]; alignas(u32) u8 ROMSeed1[2*8]; + u32 DMAReadHold; bool MainRAMLastAccess; // 0 == ARM9 | 1 == ARM7 + bool DMALastWasMainRAM; protected: // These BIOS arrays should be declared *before* the component objects (JIT, SPI, etc.)