tweak dmas to be more accurate (actually less?)

This commit is contained in:
Jaklyy 2024-12-13 13:09:42 -05:00
parent d341260e5a
commit 73be2f3e01
4 changed files with 45 additions and 27 deletions

View File

@ -454,7 +454,8 @@ bool ARMv5::ICacheLookup(const u32 addr)
// BIST test State register (See arm946e-s Rev 1 technical manual, 2.3.15 "Register 15, test State Register")
if (CP15BISTTestStateRegister & CP15_BIST_TR_DISABLE_ICACHE_LINEFILL) [[unlikely]]
return false;
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
WriteBufferDrain();
FetchAddr[16] = addr;
QueueFunction(&ARMv5::ICacheLookup_2);
@ -688,6 +689,8 @@ bool ARMv5::DCacheLookup(const u32 addr)
// BIST test State register (See arm946e-s Rev 1 technical manual, 2.3.15 "Register 15, test State Register")
if (CP15BISTTestStateRegister & CP15_BIST_TR_DISABLE_DCACHE_LINEFILL) [[unlikely]]
return false;
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
WriteBufferDrain(); // checkme?
FetchAddr[16] = addr;
@ -2214,10 +2217,12 @@ void ARMv5::CodeRead32(u32 addr)
// bus reads can only overlap with dcache streaming by 6 cycles
if (DCacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = DCacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
if (PU_Map[addr>>12] & 0x30)
WriteBufferDrain();
else
@ -2346,10 +2351,12 @@ void ARMv5::DRead8_2()
// checkme: does dcache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
if (PU_Map[addr>>12] & 0x30)
WriteBufferDrain();
else
@ -2460,10 +2467,12 @@ void ARMv5::DRead16_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
if (PU_Map[addr>>12] & 0x30)
WriteBufferDrain();
else
@ -2575,10 +2584,12 @@ void ARMv5::DRead32_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
if (PU_Map[addr>>12] & 0x30)
WriteBufferDrain();
else
@ -2676,15 +2687,17 @@ void ARMv5::DRead32S_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
if (PU_Map[addr>>12] & 0x30) // checkme
WriteBufferDrain();
else
WriteBufferCheck<1>();
QueueFunction(&ARMv5::DRead32S_3);
}
@ -2809,12 +2822,14 @@ void ARMv5::DWrite8_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (!(PU_Map[addr>>12] & (0x30)))
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
WriteBufferCheck<2>();
QueueFunction(&ARMv5::DWrite8_3);
}
@ -2922,12 +2937,14 @@ void ARMv5::DWrite16_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (!(PU_Map[addr>>12] & 0x30))
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
WriteBufferCheck<2>();
QueueFunction(&ARMv5::DWrite16_3);
}
@ -3040,12 +3057,14 @@ void ARMv5::DWrite32_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (!(PU_Map[addr>>12] & 0x30))
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
WriteBufferCheck<2>();
QueueFunction(&ARMv5::DWrite32_3);
}
@ -3153,12 +3172,14 @@ void ARMv5::DWrite32S_2()
// checkme: does cache trigger this?
if (ICacheStreamPtr < 7)
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6?
if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time;
}
if (!(PU_Map[addr>>12] & 0x30)) // non-bufferable
{
if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp;
WriteBufferCheck<2>();
QueueFunction(&ARMv5::DWrite32S_3);
}

View File

@ -565,14 +565,15 @@ u32 DMA::UnitTimings7_32(bool burststart)
void DMA::Run9()
{
if (NDS.ARM9Timestamp >= NDS.ARM9Target) return;
NDS.DMA9Timestamp = std::max(NDS.DMA9Timestamp, NDS.ARM9Timestamp);
NDS.DMA9Timestamp = (NDS.DMA9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) return;
Executing = true;
// add NS penalty for first accesses in burst
int burststart = Running-1;
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (!(Cnt & (1<<26)))
{
@ -587,7 +588,7 @@ void DMA::Run9()
}
Running = 2;
NDS.ARM9Timestamp += (UnitTimings9_16(burststart) << NDS.ARM9ClockShift);
NDS.DMA9Timestamp += (UnitTimings9_16(burststart) << NDS.ARM9ClockShift);
burststart -= 1;
NDS.ARM9Write16(CurDstAddr, NDS.ARM9Read16(CurSrcAddr));
@ -597,7 +598,7 @@ void DMA::Run9()
IterCount--;
RemCount--;
if (NDS.ARM9Timestamp >= NDS.ARM9Target) break;
if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) break;
}
}
else
@ -613,7 +614,7 @@ void DMA::Run9()
}
Running = 2;
NDS.ARM9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift);
NDS.DMA9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift);
burststart -= 1;
NDS.ARM9Write32(CurDstAddr, NDS.ARM9Read32(CurSrcAddr));
@ -623,10 +624,12 @@ void DMA::Run9()
IterCount--;
RemCount--;
if (NDS.ARM9Timestamp >= NDS.ARM9Target) break;
if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) break;
}
}
NDS.DMA9Timestamp -= 1;
if (burststart == 0) Running = 1;
Executing = false;

View File

@ -470,7 +470,7 @@ void NDS::Reset()
// unitialised on the first run
ARM9.CP15Reset();
ARM9Timestamp = 0; ARM9Target = 0;
ARM9Timestamp = 0; DMA9Timestamp = 0; ARM9Target = 0;
ARM7Timestamp = 0; ARM7Target = 0;
MainRAMTimestamp = 0;
A9ContentionTS = 0; ConTSLock = false;
@ -1127,7 +1127,7 @@ void NDS::MainRAMHandleARM9()
burststart -= 1;
if (burststart <= 0) dma->Running = 1;
else dma->Running = 2;
ARM9Timestamp = A9ContentionTS << ARM9ClockShift;
DMA9Timestamp = (A9ContentionTS << ARM9ClockShift) - 1;
memset(&ARM9.MRTrack, 0, sizeof(ARM9.MRTrack));
ConTSLock = false;
if (dma->RemCount)
@ -1229,7 +1229,7 @@ void NDS::MainRAMHandleARM9()
burststart -= 1;
if (burststart <= 0) Running = 1;
else dma->Running = 2;
ARM9Timestamp = A9ContentionTS << ARM9ClockShift;
DMA9Timestamp = (A9ContentionTS << ARM9ClockShift) - 1;
memset(&ARM9.MRTrack, 0, sizeof(ARM9.MRTrack));
ConTSLock = false;
if (dma->RemCount)
@ -1416,6 +1416,8 @@ bool NDS::MainRAMHandle()
if (ARM9.MRTrack.Type > MainRAMType::WriteBufferCmds)
A9ContentionTS = (ARM9.WBTimestamp + ((1<<ARM9ClockShift)-1)) >> ARM9ClockShift;
else if (ARM9.MRTrack.Type == MainRAMType::DMA16 || ARM9.MRTrack.Type == MainRAMType::DMA32)
A9ContentionTS = (DMA9Timestamp + ((1<<ARM9ClockShift)-1)) >> ARM9ClockShift;
else
A9ContentionTS = (ARM9Timestamp + ((1<<ARM9ClockShift)-1)) >> ARM9ClockShift;
}
@ -1523,7 +1525,7 @@ u32 NDS::RunFrame()
ARM9Target = target << ARM9ClockShift;
CurCPU = 0;
while (ARM9Timestamp < ARM9Target)
while (std::max(ARM9Timestamp, DMA9Timestamp) < ARM9Target)
{
if (ARM9.MRTrack.Type == MainRAMType::Null)
{
@ -1532,11 +1534,10 @@ u32 NDS::RunFrame()
// GXFIFO stall
s32 cycles = GPU.GPU3D.CyclesToRunFor();
ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<<ARM9ClockShift));
DMA9Timestamp = std::min(ARM9Target, std::min(ARM9Timestamp+(cycles<<ARM9ClockShift), DMA9Timestamp+(cycles<<ARM9ClockShift)));
}
else if (CPUStop & CPUStop_DMA9)
{
u64 ts = ARM9Timestamp;
DMAs[0].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();
@ -1546,13 +1547,6 @@ u32 NDS::RunFrame()
auto& dsi = dynamic_cast<melonDS::DSi&>(*this);
dsi.RunNDMAs(0);
}
ts = ARM9Timestamp - ts;
for (int i = 0; i < 7; i++)
{
ARM9.ICacheStreamTimes[i] += ts;
ARM9.DCacheStreamTimes[i] += ts;
}
ARM9.WBTimestamp += ts;
}
else
{

View File

@ -255,7 +255,7 @@ public: // TODO: Encapsulate the rest of these members
bool LagFrameFlag;
// no need to worry about those overflowing, they can keep going for atleast 4350 years
u64 ARM9Timestamp, ARM9Target;
u64 ARM9Timestamp, DMA9Timestamp, ARM9Target;
u64 ARM7Timestamp, ARM7Target;
u64 MainRAMTimestamp;
u64 A9ContentionTS; bool ConTSLock;