fix a few misc things?

This commit is contained in:
Jaklyy 2024-10-18 21:08:56 -04:00
parent 9ed4c66592
commit e33d19cf14
3 changed files with 115 additions and 48 deletions

View File

@ -1184,14 +1184,24 @@ void ARMv5::HandleInterlocksExecute(u16 ilmask)
{
if ((bitfield && (ilmask & (1<<ILCurrReg))) || (!bitfield && (ilmask == ILCurrReg)))
{
if (NDS.ARM9Timestamp < ILCurrTime) NDS.ARM9Timestamp = ILCurrTime;
if (NDS.ARM9Timestamp < ILCurrTime)
{
u64 diff = ILCurrTime - NDS.ARM9Timestamp;
NDS.ARM9Timestamp = ILCurrTime;
ITCMTimestamp += diff;
}
ILCurrReg = 16;
ILPrevReg = 16;
return;
}
else if ((bitfield && (ilmask & (1<<ILPrevReg))) || (!bitfield && (ilmask == ILCurrReg)))
{
if (NDS.ARM9Timestamp < ILPrevTime) NDS.ARM9Timestamp = ILPrevTime;
if (NDS.ARM9Timestamp < ILPrevTime)
{
u64 diff = ILPrevTime - NDS.ARM9Timestamp; // should always be 1?
NDS.ARM9Timestamp = ILPrevTime;
ITCMTimestamp += diff;
}
}
ILPrevReg = ILCurrReg;
@ -1204,8 +1214,11 @@ template void ARMv5::HandleInterlocksExecute<false>(u16 ilmask);
void ARMv5::HandleInterlocksMemory(u8 reg)
{
if ((reg != ILPrevReg) || (NDS.ARM9Timestamp >= ILPrevTime)) return;
u64 diff = ILPrevTime - NDS.ARM9Timestamp; // should always be 1?
NDS.ARM9Timestamp = ILPrevTime;
MainRAMTimestamp += diff;
ITCMTimestamp += diff;
ILPrevTime = 16;
}

View File

@ -157,7 +157,11 @@ void StoreSingle(ARM* cpu, u8 rd, u8 rn, s32 offset, u16 ilmask)
((ARMv5*)cpu)->PU_Map = ((ARMv5*)cpu)->PU_UserMap;
}
if (cpu->Num == 0) ((ARMv5*)cpu)->HandleInterlocksMemory(rd);
if (cpu->Num == 0)
{
((ARMv5*)cpu)->HandleInterlocksMemory(rd);
((ARMv5*)cpu)->Store = true;
}
bool dabort;
if constexpr (size == 8) dabort = !cpu->DataWrite8 (addr, storeval);
@ -614,14 +618,20 @@ void A_LDM(ARM* cpu)
// switch back to previous regs
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true);
cpu->AddCycles_CDI();
if (__builtin_popcount(cpu->CurInstr & 0xFFFF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CDI();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CDI();
}
// handle data aborts
if (dabort) [[unlikely]]
@ -739,13 +749,18 @@ void A_STM(ARM* cpu)
if (cpu->CurInstr & (1<<22))
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true);
cpu->AddCycles_CD();
if (__builtin_popcount(cpu->CurInstr & 0xFFFF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CD();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CD();
}
// handle data aborts
if (dabort) [[unlikely]]
@ -919,13 +934,18 @@ void T_PUSH(ARM* cpu)
: cpu->DataWrite32S(base, cpu->R[14]));
}
cpu->AddCycles_CD();
if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CD();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CD();
}
if (dabort) [[unlikely]]
{
@ -970,30 +990,47 @@ void T_POP(ARM* cpu)
dabort |= !(first ? cpu->DataRead32 (base, &pc)
: cpu->DataRead32S(base, &pc));
if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CDI();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CDI();
}
if (!dabort) [[likely]]
{
cpu->AddCycles_CDI();
if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) pc |= 0x1;
cpu->JumpTo(pc);
base += 4;
}
else [[unlikely]]
{
((ARMv5*)cpu)->DataAbort();
return;
}
}
else
{
cpu->AddCycles_CDI();
if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CDI();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CDI();
}
if (cpu->Num == 0)
{
@ -1045,13 +1082,19 @@ void T_STMIA(ARM* cpu)
}
}
cpu->AddCycles_CD();
if (__builtin_popcount(cpu->CurInstr & 0xFF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CD();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CD();
}
if (dabort) [[unlikely]]
{
@ -1090,13 +1133,18 @@ void T_LDMIA(ARM* cpu)
}
}
cpu->AddCycles_CDI();
if (__builtin_popcount(cpu->CurInstr & 0xFF) == 1) [[unlikely]] // single reg
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
cpu->AddCycles_CDI();
if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
else; // CHECKME: ARM7 timing behavior?
}
else
{
if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2;
cpu->AddCycles_CDI();
}
if (dabort) [[unlikely]]
{

View File

@ -926,7 +926,8 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
}
else if (NDS.ARM9Regions[addr>>14] == DataRegion && Store) NDS.ARM9Timestamp += (1<<NDS.ARM9ClockShift);
Store = false;
NDS.ARM9Timestamp += CodeCycles;
if (NDS.ARM9Timestamp < TimestampActual) NDS.ARM9Timestamp = TimestampActual;
@ -938,7 +939,6 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch)
bool ARMv5::DataRead8(u32 addr, u32* val)
{
Store = false;
// Data Aborts
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
@ -984,7 +984,6 @@ bool ARMv5::DataRead8(u32 addr, u32* val)
bool ARMv5::DataRead16(u32 addr, u32* val)
{
Store = false;
// Data Aborts
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
@ -1032,7 +1031,6 @@ bool ARMv5::DataRead16(u32 addr, u32* val)
bool ARMv5::DataRead32(u32 addr, u32* val)
{
Store = false;
// Data Aborts
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
@ -1084,7 +1082,8 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]]
{
DataCycles += 1;
NDS.ARM9Timestamp += DataCycles;
DataCycles = 1;
return false;
}
@ -1092,15 +1091,17 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
if (addr < ITCMSize)
{
DataCycles += 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
NDS.ARM9Timestamp += DataCycles;
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)];
return true;
}
if ((addr & DTCMMask) == DTCMBase)
{
DataCycles += 1;
NDS.ARM9Timestamp += DataCycles;
DataCycles = 1;
DataRegion = Mem9_DTCM;
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
return true;
@ -1111,9 +1112,9 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
NDS.ARM9Timestamp += DataCycles;
if (!(addr & 0x3FF)) return DataRead32(addr, val); // bursts cannot cross a 1kb boundary
DataCycles = MemTimings[addr >> 12][3];
// bursts cannot cross a 1kb boundary
if (addr & 0x3FF) DataCycles = MemTimings[addr >> 12][3]; //s
else DataCycles = MemTimings[addr >> 12][2]; // ns
NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1);
@ -1131,7 +1132,6 @@ bool ARMv5::DataRead32S(u32 addr, u32* val)
bool ARMv5::DataWrite8(u32 addr, u8 val)
{
Store = true;
// Data Aborts
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
@ -1143,7 +1143,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
// does not stall (for some reason?)
DataRegion = Mem9_ITCM;
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
@ -1170,7 +1170,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
DataCycles -= (3<<NDS.ARM9ClockShift);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
@ -1196,7 +1196,6 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
bool ARMv5::DataWrite16(u32 addr, u16 val)
{
Store = true;
// Data Aborts
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
@ -1210,7 +1209,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
// does not stall (for some reason?)
DataRegion = Mem9_ITCM;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
@ -1237,7 +1236,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
DataCycles -= (3<<NDS.ARM9ClockShift);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
@ -1263,7 +1262,6 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
bool ARMv5::DataWrite32(u32 addr, u32 val)
{
Store = true;
// Data Aborts
// Exception is handled in the actual instruction implementation
if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]]
@ -1277,7 +1275,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
if (addr < ITCMSize)
{
DataCycles = 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
// does not stall (for some reason?)
DataRegion = Mem9_ITCM;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
#ifdef JIT_ENABLED
@ -1304,7 +1302,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp;
DataRegion = Mem9_MainRAM;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
DataCycles -= (2<<NDS.ARM9ClockShift);
DataCycles -= (3<<NDS.ARM9ClockShift);
}
else DataRegion = NDS.ARM9Regions[addr>>14];
@ -1343,7 +1341,7 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val)
if (addr < ITCMSize)
{
DataCycles += 1;
ITCMTimestamp = NDS.ARM9Timestamp + DataCycles;
// 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;
#ifdef JIT_ENABLED
@ -1362,13 +1360,16 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val)
if (!(PU_Map[addr>>12] & 0x30))
{
DataCycles += (((NDS.ARM9Timestamp + DataCycles) + ((1<<NDS.ARM9ClockShift)-1) & ~((1<<NDS.ARM9ClockShift)-1))) - (NDS.ARM9Timestamp + DataCycles);
if (!(addr & 0x3FF)) return DataWrite32(addr, val); // bursts cannot cross a 1kb boundary
// bursts cannot cross a 1kb boundary
// CHECKME: should this cause a "barrier" for how early a code fetch can occur?
if (addr & 0x3FF) DataCycles += MemTimings[addr >> 12][3]; //s
else DataCycles += MemTimings[addr >> 12][2]; // ns
if ((addr >> 24) == 0x02)
{
if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) DataCycles += MainRAMTimestamp - NDS.ARM9Timestamp;
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
//if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) DataCycles += MainRAMTimestamp - NDS.ARM9Timestamp; // what the hell was i smoking here?
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles + (2 << NDS.ARM9ClockShift);
DataRegion = Mem9_MainRAM;
}
else DataRegion = NDS.ARM9Regions[addr>>14];
@ -1378,7 +1379,12 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val)
}
else
{
u8 cycles = NDS.ARM9MemTimings[addr>>14][3];
u8 cycles;
// bursts cannot cross a 1kb boundary
// CHECKME: does this actually apply to the write buffer too? it should
if (addr & 0x3FF) cycles = NDS.ARM9MemTimings[addr>>14][3]; //s
else cycles = NDS.ARM9MemTimings[addr>>14][2]; // ns
if ((addr >> 24) == 0x02)
{
cycles = (cycles - 2) | 0x80;