所以我一直在使用 6502 Klaus Dormann 测试来测试我的 6510 模拟器。除了中断测试之外,一切似乎都正确。我环顾四周并做了一些研究,发现我需要创建一个中断处理程序。但无论出于何种原因,NMI 每次都会被触发。一位不和谐的用户提到了这一点(当我正在寻找解决方案时):
消息 1:“请记住 IRQ 是电平敏感的,而不是边缘敏感的。”
消息 2:“如果我正确地遵循了您的代码,那么看起来您在从低到高的转换时触发了 IRQ,这是不正确的。”
以下是更好参考的代码:
static inline bool
changed(int ov, int nv, int bit) {
return ((ov & bit) == 0 && (nv & bit) != 0);
}
中断处理程序:
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;
}
}
执行循环:
c->irq_status = rb(c, 0xBFFC);
while(true)
{
interrupt_handler(c);
mnemonics(c);
...
}
这是我的 IRQ 和 NMI 实现:
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;
}
我想我已经发布了所有必要的信息,如果我需要编辑帖子,请告诉我!
提前谢谢您!