tweak dmas to be more accurate (actually less?)
This commit is contained in:
parent
d341260e5a
commit
73be2f3e01
33
src/CP15.cpp
33
src/CP15.cpp
|
@ -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);
|
||||
}
|
||||
|
|
17
src/DMA.cpp
17
src/DMA.cpp
|
@ -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;
|
||||
|
|
20
src/NDS.cpp
20
src/NDS.cpp
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue