dma rewrite 1
This commit is contained in:
parent
feb1cd562d
commit
d341260e5a
|
@ -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,
|
||||
|
|
34
src/DMA.cpp
34
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<<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;
|
||||
|
|
18
src/DMA.h
18
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 {};
|
||||
|
|
216
src/NDS.cpp
216
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<<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);
|
||||
|
|
|
@ -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.)
|
||||
|
|
Loading…
Reference in New Issue