1
0
Fork 0
mirror of https://github.com/melonDS-emu/melonDS.git synced 2025-03-06 21:00:31 +01:00

use timestamps for irq handling

Also add a (probably not fully correct) 4 cycle delay across the board.
Should improve the timing of when IRQs are noticed by the CPU a fair bit?
This commit is contained in:
Jaklyy 2024-12-26 12:44:39 -05:00
parent 286240894a
commit 3bd25ae58f
4 changed files with 50 additions and 13 deletions

View file

@ -161,6 +161,7 @@ void ARM::Reset()
DataCycles = 0;
IRQ = 0;
IRQTimestamp = -1;
for (int i = 0; i < 16; i++)
R[i] = 0;
@ -705,7 +706,7 @@ void ARMv5::StartExecTHUMB()
else NullFetch = false;
PC = R[15];
if (IRQ && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
if ((NDS.ARM9Timestamp >= IRQTimestamp) && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
else if (CurInstr > 0xFFFFFFFF) [[unlikely]] // handle aborted instructions
{
PrefetchAbort();
@ -728,7 +729,7 @@ void ARMv5::StartExecARM()
NullFetch = false;
PC = R[15];
if (IRQ && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
if ((NDS.ARM9Timestamp >= IRQTimestamp) && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
else if (CurInstr & ((u64)1<<63)) [[unlikely]] // handle aborted instructions
{
PrefetchAbort();
@ -775,9 +776,9 @@ void ARMv5::Execute()
{
#ifdef JIT_ENABLED
if constexpr (mode == CPUExecuteMode::JIT) TriggerIRQ<mode>();
else
//else
#endif
IRQ = 1;
//IRQ = 1;
}
}
else
@ -921,7 +922,7 @@ void ARMv4::StartExecTHUMB()
CodeRead16(R[15]);
QueueFunction(&ARMv4::UpdateNextInstr1);
if (IRQ && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
if ((NDS.ARM7Timestamp >= IRQTimestamp) && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
else
{
// actually execute
@ -939,7 +940,7 @@ void ARMv4::StartExecARM()
CodeRead32(R[15]);
QueueFunction(&ARMv4::UpdateNextInstr1);
if (IRQ && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
if ((NDS.ARM7Timestamp >= IRQTimestamp) && !(CPSR & 0x80)) TriggerIRQ<CPUExecuteMode::Interpreter>();
else if (CheckCondition(CurInstr >> 28)) // actually execute
{
u32 icode = ((CurInstr >> 4) & 0xF) | ((CurInstr >> 16) & 0xFF0);
@ -968,9 +969,9 @@ void ARMv4::Execute()
{
#ifdef JIT_ENABLED
if constexpr (mode == CPUExecuteMode::JIT) TriggerIRQ<mode>();
else
//else
#endif
IRQ = 1;
//IRQ = 1;
}
}
else

View file

@ -255,6 +255,8 @@ public:
u8 abt;
u64 iter;
u64 IRQTimestamp;
u8 FuncQueueFill;
u8 FuncQueueEnd;
u8 FuncQueueProg;

View file

@ -1288,6 +1288,7 @@ void DSi::Set_SCFG_Clock9(u16 val)
}
ARM9.TimestampMemory >>= ARM9ClockShift;
ARM9.ITCMTimestamp >>= ARM9ClockShift;
ARM9.IRQTimestamp >>= ARM9ClockShift;
ARM9.WBTimestamp >>= ARM9ClockShift;
ARM9.WBDelay >>= ARM9ClockShift;
ARM9.WBReleaseTS >>= ARM9ClockShift;
@ -1311,6 +1312,7 @@ void DSi::Set_SCFG_Clock9(u16 val)
}
ARM9.TimestampMemory <<= ARM9ClockShift;
ARM9.ITCMTimestamp <<= ARM9ClockShift;
ARM9.IRQTimestamp <<= ARM9ClockShift;
ARM9.WBTimestamp <<= ARM9ClockShift;
ARM9.WBDelay <<= ARM9ClockShift;
ARM9.WBReleaseTS <<= ARM9ClockShift;

View file

@ -1851,6 +1851,7 @@ u32 NDS::RunFrame()
}
}
CurCPU = 2;
RunSystem(ARM7Target);
if (CPUStop & CPUStop_Sleep)
@ -2170,17 +2171,48 @@ void NDS::SetGBASlotTimings()
void NDS::UpdateIRQ(u32 cpu)
{
ARM& arm = cpu ? (ARM&)ARM7 : (ARM&)ARM9;
u64 time;
if (IME[cpu] & 0x1)
if (CurCPU == 0)
{
arm.IRQ = !!(IE[cpu] & IF[cpu]);
if ((ConsoleType == 1) && cpu)
arm.IRQ |= !!(IE2 & IF2);
time = (std::max(ARM9Timestamp, DMA9Timestamp) >> ARM9ClockShift) + 4;
}
else if (CurCPU == 1)
{
time = ARM7Timestamp + 4;
}
else
{
arm.IRQ = 0;
time = SysTimestamp + 4;
}
if (IME[cpu] & 0x1)
{
/*arm.IRQ = !!(IE[cpu] & IF[cpu]);
if ((ConsoleType == 1) && cpu)
arm.IRQ |= !!(IE2 & IF2);*/
{
if ((IE[cpu] & IF[cpu]))
{
if (time < arm.IRQTimestamp) arm.IRQTimestamp = time;
}
else if (((ConsoleType == 1) && cpu) && (IE2 & IF2))
{
if (time < arm.IRQTimestamp) arm.IRQTimestamp = time;
}
else
{
arm.IRQTimestamp = UINT64_MAX;
}
}
}
else
{
arm.IRQTimestamp = UINT64_MAX;
}
if (cpu == 0) arm.IRQTimestamp <<= ARM9ClockShift;
}
void NDS::SetIRQ(u32 cpu, u32 irq)