diff --git a/src/DMA.cpp b/src/DMA.cpp index 80cd592c..56ec1564 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -187,16 +187,20 @@ void DMA::Start() // TODO eventually: not stop if we're running code in ITCM - Running = 2; + Running = 3; // safety measure MRAMBurstTable = DMATiming::MRAMDummy; InProgress = true; NDS.StopCPU(CPU, 1<> 14; u32 dst_id = CurDstAddr >> 14; @@ -213,11 +217,13 @@ u32 DMA::UnitTimings9_16(bool burststart) if (src_rgn == Mem9_MainRAM) { if (dst_rgn == Mem9_MainRAM) - return 16; + { + return (burststart == 2) ? 11 : 16; + } if (SrcAddrInc > 0) { - if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + if ((burststart == 2) || MRAMBurstTable[MRAMBurstCount] == 0) { MRAMBurstCount = 0; @@ -239,14 +245,14 @@ u32 DMA::UnitTimings9_16(bool burststart) { // TODO: not quite right for GBA slot return (((CurSrcAddr & 0x1F) == 0x1E) ? 7 : 8) + - (burststart ? dst_n : dst_s); + ((burststart == 2) ? dst_n : dst_s); } } else if (dst_rgn == Mem9_MainRAM) { if (DstAddrInc > 0) { - if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + if ((burststart == 2) || MRAMBurstTable[MRAMBurstCount] == 0) { MRAMBurstCount = 0; @@ -266,23 +272,26 @@ u32 DMA::UnitTimings9_16(bool burststart) } else { - return (burststart ? src_n : src_s) + 7; + return ((burststart == 2) ? src_n : src_s) + 7; } } else if (src_rgn & dst_rgn) { - return src_n + dst_n + 1; + if (burststart != 1) + return src_n + dst_n + (src_n == 1 || burststart <= 0); + else + return src_n + dst_n + (src_n != 1); } else { - if (burststart) - return src_n + dst_n; + if (burststart == 2) + return src_n + dst_n + (src_n == 1); else return src_s + dst_s; } } -u32 DMA::UnitTimings9_32(bool burststart) +u32 DMA::UnitTimings9_32(u8 burststart) { u32 src_id = CurSrcAddr >> 14; u32 dst_id = CurDstAddr >> 14; @@ -299,11 +308,11 @@ u32 DMA::UnitTimings9_32(bool burststart) if (src_rgn == Mem9_MainRAM) { if (dst_rgn == Mem9_MainRAM) - return 18; + return (burststart == 2) ? 13 : 18; if (SrcAddrInc > 0) { - if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + if ((burststart == 2) || MRAMBurstTable[MRAMBurstCount] == 0) { MRAMBurstCount = 0; @@ -327,14 +336,14 @@ u32 DMA::UnitTimings9_32(bool burststart) { // TODO: not quite right for GBA slot return (((CurSrcAddr & 0x1F) == 0x1C) ? (dst_n==2 ? 7:8) : 9) + - (burststart ? dst_n : dst_s); + ((burststart == 2) ? dst_n : dst_s); } } else if (dst_rgn == Mem9_MainRAM) { if (DstAddrInc > 0) { - if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + if ((burststart == 2) || MRAMBurstTable[MRAMBurstCount] == 0) { MRAMBurstCount = 0; @@ -356,17 +365,20 @@ u32 DMA::UnitTimings9_32(bool burststart) } else { - return (burststart ? src_n : src_s) + 8; + return ((burststart == 2) ? src_n : src_s) + 8; } } else if (src_rgn & dst_rgn) { - return src_n + dst_n + 1; + if (burststart != 1) + return src_n + dst_n + (src_n == 1 || burststart <= 0); + else + return src_n + dst_n + (src_n != 1); } else { - if (burststart) - return src_n + dst_n; + if (burststart == 2) + return src_n + dst_n + (src_n == 1); else return src_s + dst_s; } @@ -557,15 +569,17 @@ void DMA::Run9() Executing = true; // add NS penalty for first accesses in burst - bool burststart = (Running == 2); - Running = 1; + int burststart = Running-1; + Running = 2; + + NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1< 0 && !Stall) { NDS.ARM9Timestamp += (UnitTimings9_16(burststart) << NDS.ARM9ClockShift); - burststart = false; + burststart -= 1; NDS.ARM9Write16(CurDstAddr, NDS.ARM9Read16(CurSrcAddr)); @@ -582,7 +596,7 @@ void DMA::Run9() while (IterCount > 0 && !Stall) { NDS.ARM9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift); - burststart = false; + burststart -= 1; NDS.ARM9Write32(CurDstAddr, NDS.ARM9Read32(CurSrcAddr)); @@ -595,6 +609,8 @@ void DMA::Run9() } } + if (burststart == 1) Running = 1; + Executing = false; Stall = false; diff --git a/src/DMA.h b/src/DMA.h index 354f4495..64d5647f 100644 --- a/src/DMA.h +++ b/src/DMA.h @@ -40,8 +40,8 @@ public: void WriteCnt(u32 val); void Start(); - u32 UnitTimings9_16(bool burststart); - u32 UnitTimings9_32(bool burststart); + u32 UnitTimings9_16(u8 burststart); + u32 UnitTimings9_32(u8 burststart); u32 UnitTimings7_16(bool burststart); u32 UnitTimings7_32(bool burststart); @@ -73,6 +73,11 @@ public: if (Executing) Stall = true; } + void ResetBurst() + { + if (Running > 0) Running = (CPU ? 2 : 3); + } + u32 SrcAddr {}; u32 DstAddr {}; u32 Cnt {}; diff --git a/src/DMA_Timings.cpp b/src/DMA_Timings.cpp index a51fedfb..02539a62 100644 --- a/src/DMA_Timings.cpp +++ b/src/DMA_Timings.cpp @@ -48,7 +48,7 @@ extern const std::array MRAMDummy = {0}; extern const std::array MRAMRead16Bursts[] = { // main RAM to regular 16bit or 32bit bus (similar) - {7, 3, 2, 2, 2, 2, 2, 2, 2, 2, + {6, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -60,7 +60,7 @@ extern const std::array MRAMRead16Bursts[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 6, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -72,7 +72,7 @@ extern const std::array MRAMRead16Bursts[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 3, + 6, 3, 0}, // main RAM to GBA/wifi, seq=4 {8, 6, 5, 5, 5, 5, 5, 5, 5, 5, @@ -181,7 +181,7 @@ extern const std::array MRAMRead32Bursts[] = extern const std::array MRAMWrite16Bursts[] = { // regular 16bit or 32bit bus to main RAM (similar) - {8, 2, 2, 2, 2, 2, 2, 2, 2, 2, + {5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -212,7 +212,7 @@ extern const std::array MRAMWrite16Bursts[] = extern const std::array MRAMWrite32Bursts[4] = { // regular 16bit bus to main RAM - {9, 4, 4, 4, 4, 4, 4, 4, 4, 4, + {6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -220,7 +220,7 @@ extern const std::array MRAMWrite32Bursts[4] = 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0}, // regular 32bit bus to main RAM - {9, 3, 3, 3, 3, 3, 3, 3, 3, 3, + {6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, diff --git a/src/NDS.h b/src/NDS.h index e23b1f27..c1f0ff88 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -309,6 +309,7 @@ public: // TODO: Encapsulate the rest of these members GBACart::GBACartSlot GBACartSlot; melonDS::GPU GPU; melonDS::AREngine AREngine; + DMA DMAs[8]; #ifdef JIT_ENABLED bool IsJITEnabled(){return EnableJIT;}; @@ -494,7 +495,6 @@ private: u16 WifiWaitCnt; u8 TimerCheckMask[2]; u64 TimerTimestamp[2]; - DMA DMAs[8]; u32 DMA9Fill[4]; u16 IPCSync9, IPCSync7; u16 IPCFIFOCnt9, IPCFIFOCnt7;