emulation - 为什么6502的中断标志的初始状态为1?

标签 emulation interrupt flags cpu-registers 6502

我正在模拟6502处理器,并且快要完成了(现在处于测试阶段),并且正在使用nesdev网站上的一些NES测试,它告诉我中断标志和未使用的第5个标志都是应该最初设置为1(即禁用中断),但是为什么呢?我可以理解未使用的标志部分,因为它是...很好...未使用,但是我不理解中断标志。我曾尝试在Google上进行搜索,但有些网站确认应将其设置为1,但没有人解释其背后的原因。为什么应该从程序开始阻止中断?

最佳答案

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

CPU复位逻辑将状态寄存器中的“I”标志初始化为“1”,并且当然可以通过“SEI”和“CLI”程序指令以及CPU自身进行修改(例如,在IRQ期间)加工)。默认状态为“1”(因此设置了“中断禁用”标志)的原因是,主机系统可以执行启动/重置代码,而不必考虑IRQ声明并为其进行服务。

许多6502主机系统依赖于一些外部触发源来进行IRQ和NMI声明-通常这是VIA或CIA配套芯片,由MOS Technology专门设计为具有可配置计时器和其他事件响应器的接口(interface)适配器,旨在与6502无缝协作响应预定的硬件条件而引发中断。这些配套芯片本身需要一些程序驱动的配置,以便将它们设置为已知状态,以便开始监视硬件事件并相应地引发中断。

由于这些芯片可能被硬件初始化为可能不确定的状态,因此6502不想立即开始处理来自它们的中断,因为这些中断可能是完全虚假的。通过将“I”标志默认设置为“on”,CPU知道软件可以初始化主机系统的其余部分(包括VIA和CIA等支持芯片)就可以开始其“RESET”程序执行,而不会出现虚假的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服务可以开始了。

现在,说了这么多,是什么才能阻止NMI在RESET处理期间的任何时候被断言? CPU会努力地挂起RESET程序,并跳过NMI ROM向量-并且'I'标志无效(正如您所期望的-NMI是不可屏蔽的,不能忽略)。因此,具有讽刺意味的是,尽管为了保护RESET代码不受伪造或过早的IRQ的影响,“I”标志默认为“1”,但仍然存在伪造NMI的可能性,该伪造NMI无法被阻止,因此可能导致同样的情况如果向量指向RAM(直接或间接),则会出现问题。

程序员的任务是找到一种方法来管理这种不合时宜的NMI,以使这些NMI如果发生,则不会起作用,或者至少不会干扰RESET处理。因此,可以说,如果软件必须适应这种情况,那么对IRQ进行相同的操作就不会花费太多的精力-这意味着可能已从CPU初始化电路中删除了“I”标志的默认设置为“1”,或者在复位期间应忽略NMI的硬连线。但是,然后,当然,它们并非在所有情况下都是不可屏蔽的,并且您需要在状态寄存器中添加一个特殊的“RESET”标志,您可以清除该标志以告知CPU RESET处理已完成,并且现在可以将NMI正常维修。但是我离题了。 ;)

关于emulation - 为什么6502的中断标志的初始状态为1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16913423/

相关文章:

linux - 完全消除现代 Linux >=5.0 中的计时器滴答

Android Studio 1.x AVD 未运行?

emulation - 对于 6502 Cpu,当 X 和 Y 为 0 时递减(DEX/DEY 操作码)

java-me - 如何避免 WTK 中的 API 访问警报

android - Titanium 3.1.0 - 模拟器进程退出,代码为 1 - 无法编译 APK

C# 枚举 - 根据掩码检查标志

c - 为什么 Linux 内核不会在返回 IRQ_HANDLED 的共享 IRQ 的第一个处理程序处停止?

timer - sw4stm32中如何使能中断功能

java - Java 应用程序中的 SameSite cookie

xcode - xcode 可以将编译标志从依赖目标传递到依赖目标吗?