From 79fa4200b7d426cc8373bbef3bbe8d03e4a766a1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 31 Aug 2021 01:40:23 +0200 Subject: [PATCH] see, Arisotura, was it that hard? blarg. --- src/DMA.cpp | 402 +++++++++++++++++++++------------------------------- src/DMA.h | 4 +- 2 files changed, 160 insertions(+), 246 deletions(-) diff --git a/src/DMA.cpp b/src/DMA.cpp index 4cf60419..e6018719 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -78,6 +78,7 @@ void DMA::Reset() Running = false; InProgress = false; + MRAMBurstCount = 0; } void DMA::DoSavestate(Savestate* file) @@ -101,6 +102,7 @@ void DMA::DoSavestate(Savestate* file) file->Var32(&Running); file->Bool32(&InProgress); file->Bool32(&IsGXFIFODMA); + file->Var32(&MRAMBurstCount); } void DMA::WriteCnt(u32 val) @@ -178,10 +180,7 @@ void DMA::Start() // TODO eventually: not stop if we're running code in ITCM - /*if (NDS::DMAsRunning(CPU)) - Running = 1; - else*/ - Running = 2; + Running = 2; // safety measure MRAMBurstTable = DMATiming::MRAMDummy; @@ -190,72 +189,6 @@ void DMA::Start() NDS::StopCPU(CPU, 1<> 14; - u32 dst_id = CurDstAddr >> 14; - - if (Cnt & (1<<26)) // 32-bit - { - src_n = NDS::ARM9MemTimings[src_id][6]; - src_s = NDS::ARM9MemTimings[src_id][7]; - dst_n = NDS::ARM9MemTimings[dst_id][6]; - dst_s = NDS::ARM9MemTimings[dst_id][7]; - } - else // 16-bit - { - src_n = NDS::ARM9MemTimings[src_id][4]; - src_s = NDS::ARM9MemTimings[src_id][5]; - dst_n = NDS::ARM9MemTimings[dst_id][4]; - dst_s = NDS::ARM9MemTimings[dst_id][5]; - } - - u32 src_rgn = NDS::ARM9Regions[src_id]; - u32 dst_rgn = NDS::ARM9Regions[dst_id]; - - src_mainram = (src_rgn == NDS::Mem9_MainRAM); - sameregion = ((src_rgn & dst_rgn) != 0); - } - else - { - u32 src_id = CurSrcAddr >> 15; - u32 dst_id = CurDstAddr >> 15; - - if (Cnt & (1<<26)) // 32-bit - { - src_n = NDS::ARM7MemTimings[src_id][2]; - src_s = NDS::ARM7MemTimings[src_id][3]; - dst_n = NDS::ARM7MemTimings[dst_id][2]; - dst_s = NDS::ARM7MemTimings[dst_id][3]; - } - else // 16-bit - { - src_n = NDS::ARM7MemTimings[src_id][0]; - src_s = NDS::ARM7MemTimings[src_id][1]; - dst_n = NDS::ARM7MemTimings[dst_id][0]; - dst_s = NDS::ARM7MemTimings[dst_id][1]; - } - - u32 src_rgn = NDS::ARM7Regions[src_id]; - u32 dst_rgn = NDS::ARM7Regions[dst_id]; - - src_mainram = (src_rgn == NDS::Mem7_MainRAM); - sameregion = ((src_rgn & dst_rgn) != 0); - } - - // -} - u32 DMA::UnitTimings9_16(bool burststart) { u32 src_id = CurSrcAddr >> 14; @@ -430,87 +363,184 @@ u32 DMA::UnitTimings9_32(bool burststart) else return src_s + dst_s; } +} -#if 0 - if (src_rgn & dst_rgn) +// TODO: the ARM7 ones don't take into account that the two wifi regions have different timings + +u32 DMA::UnitTimings7_16(bool burststart) +{ + u32 src_id = CurSrcAddr >> 15; + u32 dst_id = CurDstAddr >> 15; + + u32 src_rgn = NDS::ARM7Regions[src_id]; + u32 dst_rgn = NDS::ARM7Regions[dst_id]; + + u32 src_n, src_s, dst_n, dst_s; + src_n = NDS::ARM7MemTimings[src_id][0]; + src_s = NDS::ARM7MemTimings[src_id][1]; + dst_n = NDS::ARM7MemTimings[dst_id][0]; + dst_s = NDS::ARM7MemTimings[dst_id][1]; + + if (src_rgn == NDS::Mem7_MainRAM) { - return src_n + dst_n; - } - - u32 ret = 0; - ret=1; - - if (src_rgn == NDS::Mem9_MainRAM) - { - // for main RAM: sequential timings only work with incrementing addresses - // read bursts have a maximum length of 118 words + if (dst_rgn == NDS::Mem7_MainRAM) + return 16; if (SrcAddrInc > 0) { - if (burststart || BurstCount >= 118) - BurstCount = 0; + if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + { + MRAMBurstCount = 0; - ret += (BurstCount == 0) ? src_n : src_s; + if (dst_rgn == NDS::Mem7_GBAROM || dst_rgn == NDS::Mem7_Wifi0 || dst_rgn == NDS::Mem7_Wifi1) + { + if (dst_s == 4) + MRAMBurstTable = DMATiming::MRAMRead16Bursts[1]; + else + MRAMBurstTable = DMATiming::MRAMRead16Bursts[2]; + } + else + MRAMBurstTable = DMATiming::MRAMRead16Bursts[0]; + } - BurstCount++; + u32 ret = MRAMBurstTable[MRAMBurstCount++]; + return ret; } else { - ret += src_n; - if ((CurSrcAddr & 0x1F) == 0x1C) ret--; + // TODO: not quite right for GBA slot + return (((CurSrcAddr & 0x1F) == 0x1E) ? 7 : 8) + + (burststart ? dst_n : dst_s); } - - // main RAM reads can parallelize with writes to another region - ret--; } - else if (src_rgn == NDS::Mem9_GBAROM) + else if (dst_rgn == NDS::Mem7_MainRAM) { - // for GBA ROM: sequential timings always work, except for the last halfword - // of every 0x20000 byte block - - ret += (burststart || ((CurSrcAddr & 0x1FFFF) == 0x1FFFC)) ? src_n : src_s; - } - else - { - // for other regions: nonseq/sequential timings are the same - - ret += src_s; - } - - if (dst_rgn == NDS::Mem9_MainRAM) - { - // for main RAM: sequential timings only work with incrementing addresses - // write bursts have a maximum length of 80 words - if (DstAddrInc > 0) { - if (burststart || BurstCount >= 80) - BurstCount = 0; + if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + { + MRAMBurstCount = 0; - ret += (BurstCount == 0) ? dst_n : dst_s; + if (src_rgn == NDS::Mem7_GBAROM || src_rgn == NDS::Mem7_Wifi0 || src_rgn == NDS::Mem7_Wifi1) + { + if (src_s == 4) + MRAMBurstTable = DMATiming::MRAMWrite16Bursts[1]; + else + MRAMBurstTable = DMATiming::MRAMWrite16Bursts[2]; + } + else + MRAMBurstTable = DMATiming::MRAMWrite16Bursts[0]; + } - BurstCount++; + u32 ret = MRAMBurstTable[MRAMBurstCount++]; + return ret; } else { - ret += dst_n; + return (burststart ? src_n : src_s) + 7; } } - else if (dst_rgn == NDS::Mem9_GBAROM) + else if (src_rgn & dst_rgn) { - // for GBA ROM: sequential timings always work, except for the last halfword - // of every 0x20000 byte block - - ret += (burststart || ((CurDstAddr & 0x1FFFF) == 0x1FFFC)) ? dst_n : dst_s; + return src_n + dst_n + 1; } else { - // for other regions: nonseq/sequential timings are the same - - ret += dst_s; + if (burststart) + return src_n + dst_n; + else + return src_s + dst_s; + } +} + +u32 DMA::UnitTimings7_32(bool burststart) +{ + u32 src_id = CurSrcAddr >> 15; + u32 dst_id = CurDstAddr >> 15; + + u32 src_rgn = NDS::ARM7Regions[src_id]; + u32 dst_rgn = NDS::ARM7Regions[dst_id]; + + u32 src_n, src_s, dst_n, dst_s; + src_n = NDS::ARM7MemTimings[src_id][2]; + src_s = NDS::ARM7MemTimings[src_id][3]; + dst_n = NDS::ARM7MemTimings[dst_id][2]; + dst_s = NDS::ARM7MemTimings[dst_id][3]; + + if (src_rgn == NDS::Mem7_MainRAM) + { + if (dst_rgn == NDS::Mem7_MainRAM) + return 18; + + if (SrcAddrInc > 0) + { + if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + { + MRAMBurstCount = 0; + + if (dst_rgn == NDS::Mem7_GBAROM || dst_rgn == NDS::Mem7_Wifi0 || dst_rgn == NDS::Mem7_Wifi1) + { + if (dst_s == 8) + MRAMBurstTable = DMATiming::MRAMRead32Bursts[2]; + else + MRAMBurstTable = DMATiming::MRAMRead32Bursts[3]; + } + else if (dst_n == 2) + MRAMBurstTable = DMATiming::MRAMRead32Bursts[0]; + else + MRAMBurstTable = DMATiming::MRAMRead32Bursts[1]; + } + + u32 ret = MRAMBurstTable[MRAMBurstCount++]; + return ret; + } + else + { + // TODO: not quite right for GBA slot + return (((CurSrcAddr & 0x1F) == 0x1C) ? (dst_n==2 ? 7:8) : 9) + + (burststart ? dst_n : dst_s); + } + } + else if (dst_rgn == NDS::Mem7_MainRAM) + { + if (DstAddrInc > 0) + { + if (burststart || MRAMBurstTable[MRAMBurstCount] == 0) + { + MRAMBurstCount = 0; + + if (src_rgn == NDS::Mem7_GBAROM || src_rgn == NDS::Mem7_Wifi0 || src_rgn == NDS::Mem7_Wifi1) + { + if (src_s == 8) + MRAMBurstTable = DMATiming::MRAMWrite32Bursts[2]; + else + MRAMBurstTable = DMATiming::MRAMWrite32Bursts[3]; + } + else if (src_n == 2) + MRAMBurstTable = DMATiming::MRAMWrite32Bursts[0]; + else + MRAMBurstTable = DMATiming::MRAMWrite32Bursts[1]; + } + + u32 ret = MRAMBurstTable[MRAMBurstCount++]; + return ret; + } + else + { + return (burststart ? src_n : src_s) + 8; + } + } + else if (src_rgn & dst_rgn) + { + return src_n + dst_n + 1; + } + else + { + if (burststart) + return src_n + dst_n; + else + return src_s + dst_s; } -#endif -// return ret; } template @@ -524,34 +554,10 @@ void DMA::Run9() bool burststart = (Running == 2); Running = 1; - s32 unitcycles; - //s32 lastcycles = cycles; - if (!(Cnt & (1<<26))) { - #if 1 - if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02) - { - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][0] + NDS::ARM9MemTimings[CurDstAddr >> 14][0]; - } - else - { - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][1] + NDS::ARM9MemTimings[CurDstAddr >> 14][1]; - if ((CurSrcAddr >> 24) == (CurDstAddr >> 24)) - unitcycles++; - - /*if (burststart) - { - cycles -= 2; - cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 14][0] + NDS::ARM9MemTimings[CurDstAddr >> 14][0]); - cycles += unitcycles; - }*/ - } - #endif - while (IterCount > 0 && !Stall) { - //NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift); NDS::ARM9Timestamp += (UnitTimings9_16(burststart) << NDS::ARM9ClockShift); burststart = false; @@ -570,50 +576,8 @@ void DMA::Run9() } else { - #if 0 - if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02) - { - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][2] + NDS::ARM9MemTimings[CurDstAddr >> 14][2]; - } - else - { - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][3] + NDS::ARM9MemTimings[CurDstAddr >> 14][3]; - if ((CurSrcAddr >> 24) == (CurDstAddr >> 24)) - unitcycles++; - else if ((CurSrcAddr >> 24) == 0x02) - unitcycles--; - - /*if (burststart) - { - cycles -= 2; - cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 14][2] + NDS::ARM9MemTimings[CurDstAddr >> 14][2]); - cycles += unitcycles; - }*/ - } - #endif - /*bool forcedNS = false; - if (((Cnt >> 21) & 0xF) != 0x0) forcedNS = true; - if (NDS::ARM9Regions[CurSrcAddr >> 14] & NDS::ARM9Regions[CurDstAddr >> 14]) forcedNS = true; - if (burststart || forcedNS) - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][6] + NDS::ARM9MemTimings[CurDstAddr >> 14][6]; - else - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][7] + NDS::ARM9MemTimings[CurDstAddr >> 14][7];*/ - bool sameregion = (NDS::ARM9Regions[CurSrcAddr >> 14] & NDS::ARM9Regions[CurDstAddr >> 14]) != 0; - if (burststart || sameregion || ((Cnt >> 23) & 0x3) != 0) - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][6]; - else - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][7]; - if (burststart || sameregion || ((Cnt >> 21) & 0x3) != 0) - unitcycles += NDS::ARM9MemTimings[CurDstAddr >> 14][6]; - else - unitcycles += NDS::ARM9MemTimings[CurDstAddr >> 14][7]; - if (!sameregion) unitcycles--; // ??? - // 6 not good?? (all 10, not 9) - // src-fixed is slower?? - while (IterCount > 0 && !Stall) { - //NDS::ARM9Timestamp += (unitcycles << NDS::ARM9ClockShift); NDS::ARM9Timestamp += (UnitTimings9_32(burststart) << NDS::ARM9ClockShift); burststart = false; @@ -628,17 +592,6 @@ void DMA::Run9() RemCount--; if (NDS::ARM9Timestamp >= NDS::ARM9Target) break; - - //bool sameregion = (NDS::ARM9Regions[CurSrcAddr >> 14] & NDS::ARM9Regions[CurDstAddr >> 14]) != 0; - if (sameregion || ((Cnt >> 23) & 0x3) != 0) - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][6]; - else - unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 14][7]; - if (sameregion || ((Cnt >> 21) & 0x3) != 0) - unitcycles += NDS::ARM9MemTimings[CurDstAddr >> 14][6]; - else - unitcycles += NDS::ARM9MemTimings[CurDstAddr >> 14][7]; - if (!sameregion) unitcycles--; // ??? } } @@ -681,32 +634,12 @@ void DMA::Run7() bool burststart = (Running == 2); Running = 1; - s32 unitcycles; - //s32 lastcycles = cycles; - if (!(Cnt & (1<<26))) { - if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02) - { - unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][0] + NDS::ARM7MemTimings[CurDstAddr >> 15][0]; - } - else - { - unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][1] + NDS::ARM7MemTimings[CurDstAddr >> 15][1]; - if ((CurSrcAddr >> 23) == (CurDstAddr >> 23)) - unitcycles++; - - /*if (burststart) - { - cycles -= 2; - cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 15][0] + NDS::ARM7MemTimings[CurDstAddr >> 15][0]); - cycles += unitcycles; - }*/ - } - while (IterCount > 0 && !Stall) { - NDS::ARM7Timestamp += unitcycles; + NDS::ARM7Timestamp += UnitTimings7_16(burststart); + burststart = false; if (ConsoleType == 1) DSi::ARM7Write16(CurDstAddr, DSi::ARM7Read16(CurSrcAddr)); @@ -723,29 +656,10 @@ void DMA::Run7() } else { - if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02) - { - unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][2] + NDS::ARM7MemTimings[CurDstAddr >> 15][2]; - } - else - { - unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 15][3] + NDS::ARM7MemTimings[CurDstAddr >> 15][3]; - if ((CurSrcAddr >> 23) == (CurDstAddr >> 23)) - unitcycles++; - else if ((CurSrcAddr >> 24) == 0x02) - unitcycles--; - - /*if (burststart) - { - cycles -= 2; - cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 15][2] + NDS::ARM7MemTimings[CurDstAddr >> 15][2]); - cycles += unitcycles; - }*/ - } - while (IterCount > 0 && !Stall) { - NDS::ARM7Timestamp += unitcycles; + NDS::ARM7Timestamp += UnitTimings7_32(burststart); + burststart = false; if (ConsoleType == 1) DSi::ARM7Write32(CurDstAddr, DSi::ARM7Read32(CurSrcAddr)); diff --git a/src/DMA.h b/src/DMA.h index 2853d122..17cb6181 100644 --- a/src/DMA.h +++ b/src/DMA.h @@ -34,10 +34,10 @@ public: void WriteCnt(u32 val); void Start(); - void CalculateTimings(u32& burststart, u32& unit); - u32 UnitTimings9_16(bool burststart); u32 UnitTimings9_32(bool burststart); + u32 UnitTimings7_16(bool burststart); + u32 UnitTimings7_32(bool burststart); template void Run();