Can someone advice me if I am handling interupts correctly here?
I have an Interupt Handler class in my CPU that monitors a flag for NMI and a flag for IRQ once per CPU cycle, if either flag is set, it executes the interupt and then clears the flag:
DoInterupts() is called at the end of each CPU cycle.
Is this the correct way to implement NMI and IRQ?
I have an Interupt Handler class in my CPU that monitors a flag for NMI and a flag for IRQ once per CPU cycle, if either flag is set, it executes the interupt and then clears the flag:
Code:
public class InteruptHandler
{
public bool IRQInterrupt = false;
public bool NMIInterrupt = false;
public void DoInterupts()
{
if (NMIInterrupt)
{
triggerNMI();
NMIInterrupt = false;
}
else if (IRQInterrupt)
{
TriggerIRQ();
IRQInterrupt = false;
}
}
public void TriggerIRQ()
{
// If I is set, the software wants to mask IRQ interupts.
if (!CPU.Registers.P.I)
{
// Push return address onto stack.
CPU.Stack.Push((byte)((CPU.PC >> 8) & 0xff));
CPU.Stack.Push((byte)(CPU.PC & 0xff));
// Push the status register onto the stack
CPU.Stack.Push(CPU.Registers.P.Value);
// Set Interrupt flag
CPU.Registers.P.I = true;
// JMP to interrupt code
CPU.PC = (CPU.Memory[0xFFFe] | (CPU.Memory[0xFFFF] << 8));
}
}
public void triggerNMI()
{
// Push return address onto stack.
CPU.Stack.Push((byte)((CPU.PC >> 8) & 0xff));
CPU.Stack.Push((byte)(CPU.PC & 0xff));
// Push the status register onto the stack
CPU.Stack.Push(CPU.Registers.P.Value);
// JMP to interrupt code
CPU.PC = (CPU.Memory[0xFFFA] | (CPU.Memory[0xFFFB] << 8));
}
}
{
public bool IRQInterrupt = false;
public bool NMIInterrupt = false;
public void DoInterupts()
{
if (NMIInterrupt)
{
triggerNMI();
NMIInterrupt = false;
}
else if (IRQInterrupt)
{
TriggerIRQ();
IRQInterrupt = false;
}
}
public void TriggerIRQ()
{
// If I is set, the software wants to mask IRQ interupts.
if (!CPU.Registers.P.I)
{
// Push return address onto stack.
CPU.Stack.Push((byte)((CPU.PC >> 8) & 0xff));
CPU.Stack.Push((byte)(CPU.PC & 0xff));
// Push the status register onto the stack
CPU.Stack.Push(CPU.Registers.P.Value);
// Set Interrupt flag
CPU.Registers.P.I = true;
// JMP to interrupt code
CPU.PC = (CPU.Memory[0xFFFe] | (CPU.Memory[0xFFFF] << 8));
}
}
public void triggerNMI()
{
// Push return address onto stack.
CPU.Stack.Push((byte)((CPU.PC >> 8) & 0xff));
CPU.Stack.Push((byte)(CPU.PC & 0xff));
// Push the status register onto the stack
CPU.Stack.Push(CPU.Registers.P.Value);
// JMP to interrupt code
CPU.PC = (CPU.Memory[0xFFFA] | (CPU.Memory[0xFFFB] << 8));
}
}
DoInterupts() is called at the end of each CPU cycle.
Is this the correct way to implement NMI and IRQ?