【问题标题】:Why is the initial state of the interrupt flag of the 6502 a 1?为什么6502的中断标志初始状态为1?
【发布时间】:2013-06-04 08:47:57
【问题描述】:

我正在模拟 6502 处理器,我快完成了(现在处于测试阶段),我正在使用 nesdev 站点上的一些 NES 测试,它告诉我中断标志和未使用第 5 个标志最初应该设置为 1(即禁用中断),但为什么呢?我可以理解未使用的标志部分,因为它......嗯......未使用,但我不理解中断标志。我试过在谷歌上搜索,一些网站确认它应该设置为 1,但没有人解释这背后的原因。为什么中断应该从程序开始就被阻止?

【问题讨论】:

    标签: emulation interrupt flags cpu-registers 6502


    【解决方案1】:

    上电时,状态寄存器中的“未使用”位由 CPU 的内部电路硬连线为逻辑“1”。它只能是“1”,因为它不受任何内部标志或寄存器控制,而是由与“高”信号线的物理连接决定。

    状态寄存器中的“I”标志由 CPU 复位逻辑初始化为“1”,当然可以通过“SEI”和“CLI”程序指令以及 CPU 本身修改(例如例如在 IRQ 处理期间)。默认状态为“1”(因此设置中断禁用标志)的原因是主机系统可以执行启动/重置代码,而无需考虑和安排 IRQ 断言的服务。

    许多 6502 主机系统依赖于某些外部触发源来进行 IRQ 和 NMI 断言 - 这通常是 VIA 或 CIA 配套芯片,由 MOS Technology 专门设计为具有可配置定时器和其他事件响应器的接口适配器,可无缝工作使用 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 做同样的事情并不需要付出太多努力——这意味着可以从 CPU 初始化电路中删除默认的“I”标志为“1”,或者,NMI 应该被硬连线以在 RESET 期间被忽略。但是,当然,它们不会在所有情况下都是不可屏蔽的,并且您需要在状态寄存器中设置一个特殊的“RESET”标志,您可以清除它来告诉 CPU RESET 处理已完成并且现在可以进行 NMI正常服务。但我离题了。 ;)

    【讨论】:

    • 这个答案...哇。非常感谢。这只给我留下了一个简单的问题。你从哪里得到所有这些信息?大多数 6502(和变体)文档几乎没有为我提供足够的正确信息来模拟系统,更不用说了解它的内部运作了。
    • 嘿。 30 多年来之不易的经验往往会导致对一个主题相当深入的理解——我在 1982 年开始编写 6502 代码。:) 除此之外,还有很多关于 6502 的信息,但它往往是分散在多个来源中,通常特定于芯片的特定方面(例如,关于 IRQ 处理、BRK 指令、未记录的操作码等的讨论)。不过,作为一个长期存在的社区,6502.org 是一个显而易见的起点。 Visual6502.org 是最近才出现的,但有一些有用的信息。当然还有我的博客。 ;)
    • 据我了解,硬件只是保持复位几毫秒,直到电路稳定下来,以避免上电 NMI。
    【解决方案2】:

    通常,机器需要设置其全局状态才能安全地接收中断。如果最初启用了中断,那么您将永远不会知道在您的中断例程中初始化了什么以及没有初始化什么。

    所以它是关于允许在事件开始之前强加一个已知状态。

    特别是在 NES 上,它可能没什么区别——内置硬件会生成不可屏蔽的中断,并且在被告知开始之前不会这样做。大多数带有标准中断生成硬件的磁带也需要提前被告知开始生成中断,而不仅仅是在开机时这样做。

    但是,这种 6502 行为对于部件来说是通用的。他们可能试图避免的一个示例问题可能是具有两秒启动时间的系统和产生中断的键盘。中断例程可能会缓冲击键。但是如果它在系统设置之前尝试这样做,那么它最终可能会将字节写入内存中的随机位置。

    【讨论】:

      猜你喜欢
      • 2019-05-08
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 2016-05-27
      • 2021-09-30
      • 1970-01-01
      • 2021-12-02
      相关资源
      最近更新 更多