6510 用于 6502 Klaus Dormman 中断测试的中断处理程序

问题描述 投票:0回答:0

所以我一直在使用 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;
}

我想我已经发布了所有必要的信息,如果我需要编辑帖子,请告诉我!

提前谢谢您!

c emulation 6502 commodore 6510
© www.soinside.com 2019 - 2024. All rights reserved.