From 7dd0fd5f79acb9ea88603abfe91e95b22f27dcc1 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Sun, 31 May 2020 21:37:15 +0200 Subject: [PATCH] more accurate dcache timing? --- src/ARM.h | 5 ++++ src/CP15.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/ARM.h b/src/ARM.h index b9f5d892..1e8ba303 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -223,6 +223,11 @@ public: void CP15Write(u32 id, u32 val); u32 CP15Read(u32 id); + void CalcDCacheCycles(u32 addr); + + u32 DCacheCurIndex = 0; + u32 DCacheHistory[32] = {0}; + u64 DCacheHistorySum = 0; u32 CP15Control; u32 RNGSeed; diff --git a/src/CP15.cpp b/src/CP15.cpp index c1f46bcd..8471b7e4 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -27,12 +27,19 @@ // this was measured to be close to hardware average // a value of 1 would represent a perfect cache, but that causes // games to run too fast, causing a number of issues -const int kDataCacheTiming = 3;//2; +const int kDataCacheTiming = 1;//2; +const int kDataCacheTimingSlow = 17; const int kCodeCacheTiming = 3;//5; +u64 sumDataCacheCycles = 0; +u64 dataCacheInstrsCount = 0; void ARMv5::CP15Reset() { + printf("avg. %f\n", (float)sumDataCacheCycles/(float)dataCacheInstrsCount); + sumDataCacheCycles = 0; + dataCacheInstrsCount = 0; + CP15Control = 0x2078; // dunno RNGSeed = 44203; @@ -277,8 +284,8 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend) if (pu & 0x10) { - MemTimings[i][1] = kDataCacheTiming; - MemTimings[i][2] = kDataCacheTiming; + MemTimings[i][1] = 0xFF; + MemTimings[i][2] = 0xFF; MemTimings[i][3] = 1; } else @@ -291,6 +298,28 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend) } +void ARMv5::CalcDCacheCycles(u32 addr) +{ + u64 prevAvg = DCacheHistorySum / 32; + + DCacheHistorySum -= DCacheHistory[DCacheCurIndex]; + DCacheHistory[DCacheCurIndex] = addr & ~0x1F; + DCacheHistorySum += DCacheHistory[DCacheCurIndex]; + + u64 curAvg = DCacheHistorySum / 32; + + u64 diff = abs((s64)curAvg - (s64)prevAvg); + if (diff > 3) + DataCycles = kDataCacheTimingSlow; + else + DataCycles = kDataCacheTiming; + dataCacheInstrsCount++; + sumDataCacheCycles += DataCycles; + + DCacheCurIndex++; + DCacheCurIndex &= 0x1F; +} + u32 ARMv5::RandomLineIndex() { // lame RNG, but good enough for this purpose @@ -740,6 +769,11 @@ void ARMv5::DataRead8(u32 addr, u32* val) *val = NDS::ARM9Read8(addr); DataCycles = MemTimings[addr >> 12][1]; + + if (DataCycles == 0xFF) + { + CalcDCacheCycles(addr); + } } void ARMv5::DataRead16(u32 addr, u32* val) @@ -761,6 +795,11 @@ void ARMv5::DataRead16(u32 addr, u32* val) *val = NDS::ARM9Read16(addr); DataCycles = MemTimings[addr >> 12][1]; + + if (DataCycles == 0xFF) + { + CalcDCacheCycles(addr); + } } void ARMv5::DataRead32(u32 addr, u32* val) @@ -782,6 +821,11 @@ void ARMv5::DataRead32(u32 addr, u32* val) *val = NDS::ARM9Read32(addr); DataCycles = MemTimings[addr >> 12][2]; + + if (DataCycles == 0xFF) + { + CalcDCacheCycles(addr); + } } void ARMv5::DataRead32S(u32 addr, u32* val) @@ -822,6 +866,11 @@ void ARMv5::DataWrite8(u32 addr, u8 val) NDS::ARM9Write8(addr, val); DataCycles = MemTimings[addr >> 12][1]; + + if (DataCycles == 0xFF) + { + CalcDCacheCycles(addr); + } } void ARMv5::DataWrite16(u32 addr, u16 val) @@ -843,6 +892,11 @@ void ARMv5::DataWrite16(u32 addr, u16 val) NDS::ARM9Write16(addr, val); DataCycles = MemTimings[addr >> 12][1]; + + if (DataCycles == 0xFF) + { + CalcDCacheCycles(addr); + } } void ARMv5::DataWrite32(u32 addr, u32 val) @@ -864,6 +918,11 @@ void ARMv5::DataWrite32(u32 addr, u32 val) NDS::ARM9Write32(addr, val); DataCycles = MemTimings[addr >> 12][2]; + + if (DataCycles == 0xFF) + { + CalcDCacheCycles(addr); + } } void ARMv5::DataWrite32S(u32 addr, u32 val)