So I have been testing my 6510 emulator using the 6502 Klaus Dormann tests. Everything seems to be right except the interrupt testing. I have looked around and did some research and found out that I need to create an interrupt handler. But for whatever reason NMI is being triggered every time. One fellow discord user mentioned this (while I was looking for a solution):
Message 1: "keep in mind that IRQ is level sensitive, not edge sensitive."
Message 2: "if I am following your code correctly it looks like you are triggering the IRQ when there is a low to high transition which would not be correct."
Here is the code for better reference:
static inline bool
changed(int ov, int nv, int bit) {
return ((ov & bit) == 0 && (nv & bit) != 0);
}
Interrupt handler:
void
interrupt_handler(MOS_6510* const c)
{
if(changed(c->old_status, c->irq_status, 0x2))
{
NMI(c);
c->old_status |= 0x2;
}
else if(changed(c->old_status, c->irq_status, 0x1))
{
if(IRQ(c)) c->old_status |= 0x1;
}
else if(changed(c->irq_status, c->old_status, 0x2))
{
c->old_status &= ~0x2;
}
else if(changed(c->irq_status, c->old_status, 0x1))
{
c->old_status &= ~0x1;
}
}
Execution loop:
c->irq_status = rb(c, 0xBFFC);
while(true)
{
interrupt_handler(c);
mnemonics(c);
...
}
Here are my IRQ and NMI implementations:
bool
IRQ(MOS_6510* const c)
{
if((c->p >> IRQ_DISABLE_FLAG) & 1) return false;
push_word(c, c->pc);
push_byte(c, c->p);
change_bit(c->p, IRQ_DISABLE_FLAG, 1);
c->pc = rw(c, 0xFFFE);
c->cyc += 7;
return true;
}
void
NMI(MOS_6510* const c)
{
change_bit(c->p, BREAK_COMMAND_FLAG, 1);
push_word(c, c->pc);
push_byte(c, c->p);
change_bit(c->p, IRQ_DISABLE_FLAG, 1);
c->pc = rw(c, 0xFFFA);
c->cyc += 7;
}
I think I have posted all the necessary information, if I need to edit the post please let me know!
Thank you in advance!