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:
parent
286240894a
commit
3bd25ae58f
4 changed files with 50 additions and 13 deletions
17
src/ARM.cpp
17
src/ARM.cpp
|
@ -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
|
||||
|
|
|
@ -255,6 +255,8 @@ public:
|
|||
u8 abt;
|
||||
u64 iter;
|
||||
|
||||
u64 IRQTimestamp;
|
||||
|
||||
u8 FuncQueueFill;
|
||||
u8 FuncQueueEnd;
|
||||
u8 FuncQueueProg;
|
||||
|
|
|
@ -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;
|
||||
|
|
42
src/NDS.cpp
42
src/NDS.cpp
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue