我正在模拟6502处理器,我差不多完成了(现在处于测试阶段)并且我正在使用nesdev网站上的一些NES测试,它告诉我中断标志和未使用的最初应该将第5个标志设置为1(即禁用中断),但为什么呢?我可以理解未使用的标志部分,因为它......很好......未使用,但我不明白中断标志。我试过在Google上搜索,有些网站确认它应该设置为1,但没有人解释这背后的原因。为什么中断应该从程序开始被阻止?
答案 0 :(得分:9)
上电时,状态寄存器中的“未使用”位通过CPU的内部电路硬连线到逻辑“1”。它永远不会是“1”以外的任何东西,因为它不受任何内部标志或寄存器控制,而是由与“高”信号线的物理连接决定。
状态寄存器中的“I”标志由CPU复位逻辑初始化为“1”,当然可以通过“SEI”和“CLI”程序指令以及CPU本身进行修改(对于在IRQ处理期间的例子)。默认状态为“1”(因此设置中断禁用标志)的原因是主机系统可以执行启动/重置代码,而不必考虑并安排IRQ断言的服务。
许多6502主机系统依赖于IRQ和NMI断言的一些外部触发源 - 通常这将是一个VIA或CIA配套芯片,由MOS技术专门设计为具有可配置定时器和其他事件响应器的接口适配器,可以无缝工作使用6502来响应预定的硬件条件而产生中断。这些配套芯片本身需要一些程序驱动的配置,以便将它们设置为已知状态,以便开始观察硬件事件并相应地提高中断。
由于这些芯片可能被硬件初始化为潜在的不确定状态,因此6502不希望立即开始为它们提供中断,因为这些中断可能完全是假的。通过将'I'标志默认为'on',CPU开始执行'RESET程序,知道软件可以初始化主机系统的其余部分 - 包括VIA和CIA等支持芯片 - 而不会发生虚假的IRQ在整个系统处于可以处理的状态之前。作为示例,考虑一种情况,其中ROM中的CPU IRQ向量指向RAM中的间接向量,其通过RESET代码初始化为IRQ服务例程地址。如果在RESET代码初始化RAM向量之前发生IRQ,它几乎肯定会指向一个随机地址(可能但不保证是$ 0000)并且完全可能发生系统崩溃。默认情况下设置“I”标志,在程序发出'CLI'之前,IRQ不会发生,这将在RAM向量地址被正确初始化为指向有效的IRQ服务例程之后发生。
如果您研究6502 RESET代码的常见示例,您将看到一系列系统初始化例程的重复主题,以设置主机环境(包括用于IRQ生成的支持芯片定时器寄存器),然后是'CLI '指令作为代码的最后一件事。大多数环境往往基本上是IRQ驱动的,以精确的间隔(例如每个视频帧一次)完成家务和服务程序,因此RESET代码以'CLI'结束,表示初始化 - 包括IRQ生成设置 - 已完成且IRQ服务可以开始。
现在,说完所有这些,在RESET处理期间阻止NMI在任何时候被断言是什么,嗯? CPU将努力暂停RESET程序并跳过NMI ROM向量 - 并且'I'标志无效(正如您所期望的那样 - NMI是不可屏蔽的且不能被忽略)。因此,具有讽刺意味的是,尽管'I'标志默认为'1'以保护RESET代码免受虚假或过早的IRQ的影响,但仍存在并且始终存在无法阻塞的虚假NMI的可能性,因此可能会产生相同的错误。如果向量指向RAM(直接或间接),则会出现问题。
程序员的任务是找到一种方法来管理这些不合时宜的NMI,如果它们发生则它们没有效果,或者至少它们不会干扰RESET处理。因此,可以说,如果软件必须满足这种情况,那么为IRQ做同样的事情就没那么多了 - 这意味着'I'标志默认为'1'可能会从CPU初始化电路中删除,或者,在RESET期间,NMI应该被硬连线忽略。但是,当然,它们在所有情况下都不会是不可屏蔽的,并且您需要在状态寄存器中有一个特殊的“RESET”标志,您可以清除它以告诉CPU RESET处理已完成且NMI现在可以正常服务。但我离题了。 ;)
答案 1 :(得分:4)
通常,机器在安全接收中断之前需要设置其全局状态。如果最初启用了中断,那么您将永远不会知道已初始化的内容以及中断例程中没有的内容。
所以它是关于在事件开始滚动之前允许强制执行已知状态。
在NES上,它可能没什么区别 - 内置硬件产生不可屏蔽的中断,并且在被告知启动之前不会这样做。大多数带有标准中断生成硬件的磁带都需要事先告知开始产生中断,而不是仅仅通电才能这样做。
然而,这个6502行为对于该部分是通用的。他们可能试图避免的示例问题可能是具有两秒启动时间的系统和产生中断的键盘。中断例程可以缓冲击键。但是如果它在设置系统之前尝试这样做,那么最终可能会将字节写入内存中的随机位置。