dma rewrite 1

This commit is contained in:
Jaklyy 2024-12-10 21:23:02 -05:00
parent feb1cd562d
commit d341260e5a
5 changed files with 252 additions and 24 deletions

View File

@ -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,

View File

@ -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<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (!(Cnt & (1<<26)))
{
while (IterCount > 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;

View File

@ -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 {};

View File

@ -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<<dma->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<<dma->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<<dma->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<<dma->Num);
}
break;
}
case MainRAMType::WBDrain:
{
if (!ARM9.WriteBufferHandle<WBMode::Force>()) 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<melonDS::DSi&>(*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<melonDS::DSi&>(*this);

View File

@ -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.)