add support for 1 reg ldm/stm a9 timings and fix a bug
This commit is contained in:
parent
8ff0946b8a
commit
9ed4c66592
|
@ -617,6 +617,12 @@ void A_LDM(ARM* cpu)
|
|||
|
||||
cpu->AddCycles_CDI();
|
||||
|
||||
if (__builtin_popcount(cpu->CurInstr & 0xFFFF) == 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?
|
||||
}
|
||||
|
||||
// handle data aborts
|
||||
if (dabort) [[unlikely]]
|
||||
{
|
||||
|
@ -735,6 +741,12 @@ void A_STM(ARM* cpu)
|
|||
|
||||
cpu->AddCycles_CD();
|
||||
|
||||
if (__builtin_popcount(cpu->CurInstr & 0xFFFF) == 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?
|
||||
}
|
||||
|
||||
// handle data aborts
|
||||
if (dabort) [[unlikely]]
|
||||
{
|
||||
|
@ -909,6 +921,12 @@ void T_PUSH(ARM* cpu)
|
|||
|
||||
cpu->AddCycles_CD();
|
||||
|
||||
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 (dabort) [[unlikely]]
|
||||
{
|
||||
((ARMv5*)cpu)->DataAbort();
|
||||
|
@ -952,33 +970,47 @@ void T_POP(ARM* cpu)
|
|||
dabort |= !(first ? cpu->DataRead32 (base, &pc)
|
||||
: cpu->DataRead32S(base, &pc));
|
||||
|
||||
if (dabort) [[unlikely]] goto dataabort;
|
||||
if (!dabort) [[likely]]
|
||||
{
|
||||
cpu->AddCycles_CDI();
|
||||
|
||||
cpu->AddCycles_CDI();
|
||||
if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) pc |= 0x1;
|
||||
cpu->JumpTo(pc);
|
||||
base += 4;
|
||||
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
|
||||
{
|
||||
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 == 0)
|
||||
{
|
||||
u8 lastreg = 31 - __builtin_clz(cpu->CurInstr & 0xFF);
|
||||
((ARMv5*)cpu)->ILCurrReg = lastreg;
|
||||
((ARMv5*)cpu)->ILCurrTime = ((ARMv5*)cpu)->TimestampActual;
|
||||
if (dabort) [[unlikely]]
|
||||
{
|
||||
((ARMv5*)cpu)->DataAbort();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 lastreg = 31 - __builtin_clz(cpu->CurInstr & 0xFF);
|
||||
((ARMv5*)cpu)->ILCurrReg = lastreg;
|
||||
((ARMv5*)cpu)->ILCurrTime = ((ARMv5*)cpu)->TimestampActual;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dabort) [[unlikely]]
|
||||
{
|
||||
dataabort:
|
||||
cpu->AddCycles_CDI();
|
||||
((ARMv5*)cpu)->DataAbort();
|
||||
return;
|
||||
}
|
||||
|
||||
cpu->R[13] = base;
|
||||
}
|
||||
|
||||
|
@ -1015,6 +1047,12 @@ void T_STMIA(ARM* cpu)
|
|||
|
||||
cpu->AddCycles_CD();
|
||||
|
||||
if (__builtin_popcount(cpu->CurInstr & 0xFF) == 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 (dabort) [[unlikely]]
|
||||
{
|
||||
((ARMv5*)cpu)->DataAbort();
|
||||
|
@ -1054,12 +1092,18 @@ void T_LDMIA(ARM* cpu)
|
|||
|
||||
cpu->AddCycles_CDI();
|
||||
|
||||
if (__builtin_popcount(cpu->CurInstr & 0xFF) == 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 (dabort) [[unlikely]]
|
||||
{
|
||||
((ARMv5*)cpu)->DataAbort();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (cpu->Num == 0)
|
||||
{
|
||||
u8 lastreg = 31 - __builtin_clz(cpu->CurInstr & 0xFF);
|
||||
|
|
|
@ -321,7 +321,7 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend)
|
|||
{
|
||||
MemTimings[i][1] = ((bustimings[0] - 1) << NDS.ARM9ClockShift) + 1;
|
||||
MemTimings[i][2] = ((bustimings[2] - 1) << NDS.ARM9ClockShift) + 1;
|
||||
MemTimings[i][3] = bustimings[3] << NDS.ARM9ClockShift; // inaccurate but ehgh
|
||||
MemTimings[i][3] = ((bustimings[3] - 1) << NDS.ARM9ClockShift) + 1;; // inaccurate but ehgh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1367,7 +1367,7 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val)
|
|||
|
||||
if ((addr >> 24) == 0x02)
|
||||
{
|
||||
if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) NDS.ARM9Timestamp = MainRAMTimestamp - DataCycles;
|
||||
if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) DataCycles += MainRAMTimestamp - NDS.ARM9Timestamp;
|
||||
MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles;
|
||||
DataRegion = Mem9_MainRAM;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue