diff --git a/src/ARM.h b/src/ARM.h index efdf9eba..c714035e 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -690,6 +690,7 @@ public: //u64 WBMainRAMDelay; // timestamp used to emulate the delay before the next main ram write can begin u64 WBDelay; // timestamp in bus cycles use for the delay before next write to the write buffer can occur (seems to be a 1 cycle delay after a write to it) u32 WBLastRegion; // the last region written to by the write buffer + u64 WBReleaseTS; // the timestamp on which the write buffer relinquished control of the bus back #ifdef GDBSTUB_ENABLED u32 ReadMem(u32 addr, int size) override; diff --git a/src/CP15.cpp b/src/CP15.cpp index fb130745..d650a6cc 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -554,6 +554,11 @@ u32 ARMv5::ICacheLookup(const u32 addr) u32 cycles = ns + (seq * linepos); NDS.ARM9Timestamp = cycles += NDS.ARM9Timestamp; + + if (((NDS.ARM9Timestamp <= WBReleaseTS) && (NDS.ARM9Regions[addr>>14] == WBLastRegion)) // check write buffer + || (Store && (NDS.ARM9Regions[addr>>14] == DataRegion))) //check the actual store + NDS.ARM9Timestamp += 1<> 24) == 0x02) MainRAMTimestamp = ICacheFillTimes[6]; } @@ -771,14 +777,25 @@ u32 ARMv5::DCacheLookup(const u32 addr) MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_MainRAM; } - else DataRegion = NDS.ARM9Regions[addr>>14]; + else + { + DataRegion = NDS.ARM9Regions[addr>>14]; + if ((NDS.ARM9Timestamp <= WBTimestamp-1) && (DataRegion == WBLastRegion)) // check write buffer + NDS.ARM9Timestamp += 1<>14]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; } + else + { + if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer + NDS.ARM9Timestamp += 1<> 24) == 0x02) MainRAMTimestamp = DCacheFillTimes[6]; - - DataRegion = NDS.ARM9Regions[addr>>14]; } return ptr[(addr & (DCACHE_LINELENGTH-1)) >> 2]; } @@ -1217,9 +1232,17 @@ inline bool ARMv5::WriteBufferHandle() NDS.ARM9Timestamp = ts; } - WBTimestamp = (ts + ((1<>14] == Mem9_MainRAM) MainRAMTimestamp = ts + ((((WBCurVal >> 61) == 0) ? 4 : 5) << NDS.ARM9ClockShift); - else WBTimestamp += 2; // todo: twl timings + if ((WBCurVal >> 61) != 3) + { + WBReleaseTS = WBTimestamp = (ts + ((1<>14] == Mem9_MainRAM) MainRAMTimestamp = ts + ((((WBCurVal >> 61) == 0) ? 4 : 5) << NDS.ARM9ClockShift); + else WBTimestamp += 2; // todo: twl timings + } + else + { + WBReleaseTS = WBTimestamp = ts; + if (NDS.ARM9Regions[WBCurAddr>>14] == Mem9_MainRAM) MainRAMTimestamp = ts; + } switch (WBCurVal >> 61) { @@ -1288,6 +1311,7 @@ void ARMv5::WriteBufferCheck() } else if constexpr (next == 2) { + if (WBWriting) while(!WriteBufferHandle<2>()); } } @@ -2095,7 +2119,7 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) } else { - if (((NDS.ARM9Timestamp <= WBTimestamp-1) && (NDS.ARM9Regions[addr>>14] == WBLastRegion)) // check write buffer + if (((NDS.ARM9Timestamp <= WBReleaseTS) && (NDS.ARM9Regions[addr>>14] == WBLastRegion)) // check write buffer || (Store && (NDS.ARM9Regions[addr>>14] == DataRegion))) //check the actual store NDS.ARM9Timestamp += 1<>14]; - if ((NDS.ARM9Timestamp <= WBTimestamp-1) && (DataRegion == WBLastRegion)) // check write buffer + if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<>14]; - if ((NDS.ARM9Timestamp <= WBTimestamp-1) && (DataRegion == WBLastRegion)) // check write buffer + if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<>14]; - if ((NDS.ARM9Timestamp <= WBTimestamp-1) && (DataRegion == WBLastRegion)) // check write buffer + if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<>14]; - if ((NDS.ARM9Timestamp <= WBTimestamp-1) && (DataRegion == WBLastRegion)) // check write buffer + if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<>14]; - if ((NDS.ARM9Timestamp <= WBTimestamp-1) && (DataRegion == WBLastRegion)) // check write buffer + if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<