rework tracking of overlap

This commit is contained in:
Jaklyy 2024-12-07 00:43:36 -05:00
parent 698d78bc8d
commit 3d6ebc1d2b
7 changed files with 108 additions and 116 deletions

View File

@ -1399,12 +1399,9 @@ void ARMv5::AddCycles_MW(s32 numM)
void ARMv5::AddCycles_MW_2()
{
s32 numM = DataCycles;
TimestampActual = numM + NDS.ARM9Timestamp;
TimestampActual = NDS.ARM9Timestamp;
numM -= 3<<NDS.ARM9ClockShift;
if (numM > 0) NDS.ARM9Timestamp += numM;
NDS.ARM9Timestamp -= DataCycles;
}
template <bool bitfield>

View File

@ -684,7 +684,6 @@ public:
void JumpTo_3C();
void JumpTo_4();
void DAbortHandle();
void DAbortHandleS();
void DCacheFin8();
void DRead8_2();
void DCacheFin16();

View File

@ -37,7 +37,6 @@ namespace melonDS::ARMInterpreter
void A_UNK(ARM* cpu)
{
cpu->AddCycles_C();
cpu->abt=1;
Log(LogLevel::Warn, "undefined ARM%d instruction %08X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-8);
#ifdef GDBSTUB_ENABLED
cpu->GdbStub.Enter(cpu->GdbStub.IsConnected(), Gdb::TgtStatus::FaultInsn, cpu->R[15]-8);
@ -232,7 +231,7 @@ void A_MRS(ARM* cpu)
if (cpu->Num != 1) // arm9
{
cpu->AddCycles_C(); // 1 X
cpu->AddCycles_CI(2); // 1 X
((ARMv5*)cpu)->AddCycles_MW(2); // 2 M
}
else cpu->AddCycles_C(); // arm7
@ -314,7 +313,7 @@ void A_MRC(ARM* cpu)
if (cpu->Num != 1)
{
cpu->AddCycles_C(); // 1 Execute cycle
cpu->AddCycles_CI(2); // 1 Execute cycle
((ARMv5*)cpu)->AddCycles_MW(2); // 2 Memory cycles
((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 12) & 0xF; // only one rd interlocks
((ARMv5*)cpu)->ILCurrTime = ((ARMv5*)cpu)->TimestampActual;

View File

@ -924,7 +924,7 @@ void A_MUL(ARM* cpu)
if (cpu->CurInstr & (1<<20)) cpu->AddCycles_CI(3); // S
else
{
cpu->AddCycles_C(); // 1 X
cpu->AddCycles_CI(2); // 1 X
((ARMv5*)cpu)->AddCycles_MW(2); // 2 M
((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 16) & 0xF;
@ -971,7 +971,7 @@ void A_MLA(ARM* cpu)
if (cpu->CurInstr & (1<<20)) cpu->AddCycles_CI(3);
else
{
cpu->AddCycles_C(); // 1 X
cpu->AddCycles_CI(2); // 1 X
((ARMv5*)cpu)->AddCycles_MW(2); // 2 M
((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 16) & 0xF;
@ -1331,7 +1331,7 @@ void A_SMLALxy(ARM* cpu)
(1 << ((cpu->CurInstr >> 8) & 0xF)) |
(1 << ((cpu->CurInstr >> 12) & 0xF))/* |
(1 << ((cpu->CurInstr >> 16) & 0xF))*/, iltime);
cpu->AddCycles_C(); // 1 X
cpu->AddCycles_CI(2); // 1 X
((ARMv5*)cpu)->AddCycles_MW(2); // 2 M
((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 16) & 0xF; // only one rd interlocks

View File

@ -636,7 +636,7 @@ bool ARMv5::DCacheLookup(const u32 addr)
if (DCacheStreamPtr >= 7)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
}
else
{
@ -644,6 +644,8 @@ bool ARMv5::DCacheLookup(const u32 addr)
//if (NDS.ARM9Timestamp < nextfill) // can this ever really fail?
{
DataCycles = nextfill - NDS.ARM9Timestamp;
if (DataCycles > (3<<NDS.ARM9ClockShift)) DataCycles = 3<<NDS.ARM9ClockShift;
NDS.ARM9Timestamp = nextfill;
}
/*else
{
@ -737,7 +739,7 @@ bool ARMv5::DCacheLookup(const u32 addr)
{
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
NDS.ARM9Timestamp += MemTimings[tag >> 14][1] + (MemTimings[tag >> 14][2] * ((DCACHE_LINELENGTH / 4) - 2));
NDS.ARM9Timestamp += MemTimings[tag >> 14][1] + (MemTimings[tag >> 14][2] * ((DCACHE_LINELENGTH / 4) - 1));
DataCycles = MemTimings[tag>>14][2];
DataRegion = NDS.ARM9Regions[addr>>14];
@ -759,9 +761,9 @@ bool ARMv5::DCacheLookup(const u32 addr)
u8 linepos = (addr & 0x1F) >> 2; // technically this is one too low, but we want that actually
u64 cycles = ns + (seq * linepos);
DataCycles = cycles;
cycles += NDS.ARM9Timestamp;
DataCycles = 3<<NDS.ARM9ClockShift;
NDS.ARM9Timestamp += DataCycles;
cycles = NDS.ARM9Timestamp;
DCacheStreamPtr = linepos;
for (int i = linepos; i < 7; i++)
@ -821,7 +823,7 @@ bool ARMv5::DCacheWrite32(const u32 addr, const u32 val)
{
u32 *cacheLine = (u32 *)&DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
cacheLine[(addr & (DCACHE_LINELENGTH-1)) >> 2] = val;
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DCache;
#if !DISABLE_CACHEWRITEBACK
if (PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_BUFFERABLE)
@ -889,7 +891,7 @@ bool ARMv5::DCacheWrite16(const u32 addr, const u16 val)
{
u16 *cacheLine = (u16 *)&DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
cacheLine[(addr & (DCACHE_LINELENGTH-1)) >> 1] = val;
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DCache;
#if !DISABLE_CACHEWRITEBACK
if (PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_BUFFERABLE)
@ -958,7 +960,7 @@ bool ARMv5::DCacheWrite8(const u32 addr, const u8 val)
{
u8 *cacheLine = &DCache[(id+set) << DCACHE_LINELENGTH_LOG2];
cacheLine[addr & (DCACHE_LINELENGTH-1)] = val;
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DCache;
#if !DISABLE_CACHEWRITEBACK
if (PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_BUFFERABLE)
@ -2113,21 +2115,7 @@ void ARMv5::DAbortHandle()
DCacheStreamPtr = 7;
}
DataCycles = 1;
}
void ARMv5::DAbortHandleS()
{
NDS.ARM9Timestamp += DataCycles;
if (DCacheStreamPtr < 7)
{
u64 fillend = DCacheStreamTimes[6] + 1;
if (NDS.ARM9Timestamp < fillend) NDS.ARM9Timestamp = fillend; // checkme: should this be data cycles?
DCacheStreamPtr = 7;
}
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
}
void ARMv5::DCacheFin8()
@ -2171,15 +2159,15 @@ void ARMv5::DRead8_2()
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
NDS.ARM9Timestamp += DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp;
DataRegion = Mem9_ITCM;
*val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)];
return;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)];
return;
@ -2216,8 +2204,6 @@ void ARMv5::DRead8_2()
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 14][0];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2226,12 +2212,14 @@ void ARMv5::DRead8_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
DataCycles = 3<<NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
*val = BusRead8(addr);
}
}
@ -2279,7 +2267,7 @@ void ARMv5::DRead16_2()
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)];
@ -2287,7 +2275,7 @@ void ARMv5::DRead16_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*val = *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)];
return;
@ -2324,8 +2312,6 @@ void ARMv5::DRead16_2()
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 14][0];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2334,12 +2320,14 @@ void ARMv5::DRead16_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
DataCycles = 3<<NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
*val = BusRead16(addr);
}
}
@ -2386,7 +2374,7 @@ void ARMv5::DRead32_2()
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataRegion = Mem9_ITCM;
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
@ -2395,7 +2383,7 @@ void ARMv5::DRead32_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
LDRRegs &= ~1<<reg;
@ -2433,8 +2421,6 @@ void ARMv5::DRead32_2()
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 14][1];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2443,12 +2429,14 @@ void ARMv5::DRead32_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr >> 14][1];
DataCycles = 3<<NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
*val = BusRead32(addr);
}
LDRRegs &= ~1<<reg;
@ -2460,7 +2448,7 @@ bool ARMv5::DataRead32S(u32 addr, u8 reg)
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & CP15_MAP_READABLE)) [[unlikely]]
{
QueueFunction(&ARMv5::DAbortHandleS);
QueueFunction(&ARMv5::DAbortHandle);
return false;
}
@ -2477,13 +2465,11 @@ void ARMv5::DRead32S_2()
u32 addr = FetchAddr[reg];
u32 dummy; u32* val = (LDRFailedRegs & (1<<reg)) ? &dummy : &R[reg];
NDS.ARM9Timestamp += DataCycles;
addr &= ~3;
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
// we update the timestamp during the actual function, as a sequential itcm access can only occur during instructions with strange itcm wait cycles
DataRegion = Mem9_ITCM;
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
@ -2492,7 +2478,7 @@ void ARMv5::DRead32S_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
LDRRegs &= ~1<<reg;
@ -2531,8 +2517,6 @@ void ARMv5::DRead32S_2()
// bursts cannot cross a 1kb boundary
if (addr & 0x3FF) // s
{
DataCycles = MemTimings[addr>>14][2];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2541,12 +2525,14 @@ void ARMv5::DRead32S_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr>>14][2];
DataCycles = MemTimings[addr>>14][2];
DataRegion = NDS.ARM9Regions[addr>>14];
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
*val = BusRead32(addr);
}
}
@ -2554,8 +2540,6 @@ void ARMv5::DRead32S_2()
{
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr>>14][1];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2564,12 +2548,14 @@ void ARMv5::DRead32S_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr>>14][1];
DataCycles = 3<<NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer
NDS.ARM9Timestamp += 1<<NDS.ARM9ClockShift;
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp - (3<<NDS.ARM9ClockShift) + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
*val = BusRead32(addr);
}
}
@ -2609,7 +2595,7 @@ void ARMv5::DWrite8_2()
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
// does not stall (for some reason?)
DataRegion = Mem9_ITCM;
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
@ -2620,7 +2606,7 @@ void ARMv5::DWrite8_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return;
@ -2653,8 +2639,6 @@ void ARMv5::DWrite8_2()
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 14][0];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2663,10 +2647,12 @@ void ARMv5::DWrite8_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
DataCycles = 3<<NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
BusWrite8(addr, val);
}
}
@ -2677,8 +2663,8 @@ void ARMv5::DWrite8_2()
WriteBufferWrite(addr, 4);
WriteBufferWrite(val, 0, addr);
DataRegion = Mem9_Null;
DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 2;
NDS.ARM9Timestamp += DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 1;
}
}
@ -2717,7 +2703,7 @@ void ARMv5::DWrite16_2()
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
// does not stall (for some reason?)
DataRegion = Mem9_ITCM;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
@ -2728,7 +2714,7 @@ void ARMv5::DWrite16_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return;
@ -2761,8 +2747,6 @@ void ARMv5::DWrite16_2()
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 14][0];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2771,10 +2755,12 @@ void ARMv5::DWrite16_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr >> 14][0];
DataCycles = NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
BusWrite16(addr, val);
}
}
@ -2785,8 +2771,8 @@ void ARMv5::DWrite16_2()
WriteBufferWrite(addr, 4);
WriteBufferWrite(val, 1, addr);
DataRegion = Mem9_Null;
DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 2;
NDS.ARM9Timestamp += DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 1;
}
}
@ -2825,7 +2811,7 @@ void ARMv5::DWrite32_2()
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
// does not stall (for some reason?)
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
@ -2837,7 +2823,7 @@ void ARMv5::DWrite32_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
STRRegs &= ~1<<reg;
@ -2874,8 +2860,6 @@ void ARMv5::DWrite32_2()
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr >> 14][1];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2884,10 +2868,12 @@ void ARMv5::DWrite32_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr >> 14][1];
DataCycles = 3<<NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
BusWrite32(addr, val);
}
}
@ -2898,8 +2884,8 @@ void ARMv5::DWrite32_2()
WriteBufferWrite(addr, 4);
WriteBufferWrite(val, 2, addr);
DataRegion = Mem9_Null;
DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 2;
NDS.ARM9Timestamp += DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 1;
}
STRRegs &= ~1<<reg;
}
@ -2910,7 +2896,7 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val, u8 reg)
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & CP15_MAP_WRITEABLE)) [[unlikely]]
{
QueueFunction(&ARMv5::DAbortHandleS);
QueueFunction(&ARMv5::DAbortHandle);
return false;
}
@ -2928,13 +2914,11 @@ void ARMv5::DWrite32S_2()
u32 addr = FetchAddr[reg];
u32 val = STRVal[reg];
NDS.ARM9Timestamp += DataCycles;
addr &= ~3;
if (addr < ITCMSize)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
// we update the timestamp during the actual function, as a sequential itcm access can only occur during instructions with strange itcm wait cycles
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
@ -2946,7 +2930,7 @@ void ARMv5::DWrite32S_2()
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles = 1;
NDS.ARM9Timestamp += DataCycles = 1;
DataRegion = Mem9_DTCM;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
STRRegs &= ~1<<reg;
@ -2984,8 +2968,6 @@ void ARMv5::DWrite32S_2()
// bursts cannot cross a 1kb boundary
if (addr & 0x3FF) // s
{
DataCycles = MemTimings[addr>>14][2];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -2994,25 +2976,18 @@ void ARMv5::DWrite32S_2()
}
else
{
NDS.ARM9Timestamp += DataCycles = MemTimings[addr>>14][2];
DataRegion = NDS.ARM9Regions[addr>>14];
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
BusWrite32(addr, val);
}
// burst stores seem to process the extra delay cycles at the end of the burst
// this means that we end up *always* able to begin code fetches 3 cycles early when accessing the bus
// this is a weird way of implementing this but it should work fine....?
NDS.ARM9Timestamp -= 3<<NDS.ARM9ClockShift;
DataCycles += 3<<NDS.ARM9ClockShift;
}
else // ns
{
NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
DataCycles = MemTimings[addr>>14][1];
if ((addr >> 24) == 0x02)
{
MRTrack.Type = MainRAMType::Fetch;
@ -3021,10 +2996,12 @@ void ARMv5::DWrite32S_2()
}
else
{
NDS.ARM9Timestamp += MemTimings[addr>>14][1];
DataCycles = 3 << NDS.ARM9ClockShift;
DataRegion = NDS.ARM9Regions[addr>>14];
if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + DataCycles + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
if (WBTimestamp < ((NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1)))
WBTimestamp = (NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1)) & ~((1<<NDS.ARM9ClockShift)-1);
BusWrite32(addr, val);
}
}
@ -3033,8 +3010,8 @@ void ARMv5::DWrite32S_2()
{
WriteBufferWrite(val, 3, addr);
DataRegion = Mem9_Null;
DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 2;
NDS.ARM9Timestamp += DataCycles = 1;
WBDelay = NDS.ARM9Timestamp + 1;
}
STRRegs &= ~1<<reg;
}

View File

@ -1277,6 +1277,15 @@ void DSi::Set_SCFG_Clock9(u16 val)
{
ARM9Timestamp >>= ARM9ClockShift;
ARM9Target >>= ARM9ClockShift;
for (int i = 0; i < 7; i++)
{
ARM9.ICacheStreamTimes[i] >>= ARM9ClockShift;
ARM9.DCacheStreamTimes[i] >>= ARM9ClockShift;
}
ARM9.WBTimestamp >>= ARM9ClockShift;
ARM9.WBDelay >>= ARM9ClockShift;
ARM9.WBReleaseTS >>= ARM9ClockShift;
ARM9.WBInitialTS >>= ARM9ClockShift;
Log(LogLevel::Debug, "CLOCK9=%04X\n", val);
SCFG_Clock9 = val & 0x0187;
@ -1286,6 +1295,16 @@ void DSi::Set_SCFG_Clock9(u16 val)
ARM9Timestamp <<= ARM9ClockShift;
ARM9Target <<= ARM9ClockShift;
for (int i = 0; i < 7; i++)
{
ARM9.ICacheStreamTimes[i] <<= ARM9ClockShift;
ARM9.DCacheStreamTimes[i] <<= ARM9ClockShift;
}
ARM9.WBTimestamp <<= ARM9ClockShift;
ARM9.WBDelay <<= ARM9ClockShift;
ARM9.WBReleaseTS <<= ARM9ClockShift;
ARM9.WBInitialTS <<= ARM9ClockShift;
ARM9.UpdateRegionTimings(0x00000, 0x40000);
}
@ -2562,7 +2581,7 @@ void DSi::ARM9IOWrite32(u32 addr, u32 val)
if (oldvram != newvram)
SetVRAMTimings(newvram);
/*switch ((SCFG_EXT[0] >> 14) & 0x3)
switch ((SCFG_EXT[0] >> 14) & 0x3)
{
case 0:
case 1:
@ -2575,7 +2594,7 @@ void DSi::ARM9IOWrite32(u32 addr, u32 val)
NDS::MainRAMMask = 0xFFFFFF;
printf("RAM: 16MB\n");
break;
}*/
}
// HAX!!
// a change to the RAM size setting is supposed to apply immediately (it does so on hardware)
// however, doing so will cause DS-mode app startup to break, because the change happens while the ARM7

View File

@ -928,7 +928,8 @@ void NDS::MainRAMHandleARM9()
if ((var & MRSequential) && A9WENTLAST)
{
MainRAMTimestamp = A9ContentionTS += 2;
A9ContentionTS += 2;
MainRAMTimestamp += 2;
ARM9.DataCycles = 2 << ARM9ClockShift;
}
else