为了模拟 Gameboy,为什么将内存分成不同的区域很重要?

For emulating the Gameboy, why does it matter that the memory is broken up into different areas?

所以我正在编写一个 gameboy 模拟器,我不是 100% 确定为什么其他项目花时间将内存分解为适当的类别。我不知道我是否遗漏了一个重大的技术难题(也许在指令中处理非法参数?),但似乎唯一重要的是写指令给出的地址可以通过正确的读取来检索操作说明。因此,对于一个子问题,如果我在假设程序集完全合法的情况下工作(意味着没有任何东西试图 read/write 它不能),我可以做一个大数组并读写是吗?

请注意,这是一个概念性问题,我知道一个大数组会占用大量内存,我不一定要寻找最好的方法,只是想了解它是如何工作的以及为什么其他模拟器开发人员按照他们的方式来做。

您将拥有只读内存、read/write 内存和映射内存 I/O(外围设备等)。因此,您需要在某种程度上对地址进行解码以将其分解为主要类别,然后对于外围设备,您必须模拟所有这些,因此您必须在地址解码中非常详细。

对于外围设备,您需要检测某个地址的 read/write ,您不能通过简单地将写入写入数组来做到这一点(例如,两次相同值的写入会有所不同,您不能只扫描一些数组以查找必须在读写时触发的更改并执行硬件操作)。

如果您希望周期准确,您还需要知道 ram 和 rom 的时序以便模仿它们,具体取决于每个库的数量或者时序取决于您需要解码的时间地址进一步。

硬件将这些地址解码到同一级别,因此如果您正在模拟硬件,那么您需要...模拟硬件...并执行相同数量的地址解码。

我将在这里专门针对 gameboy。查看gameboy的地址space地图。地址space本身就是分的,不是模拟器做的。硬件本身就是这样运行的。

以下是一些不能仅作为数组实现的区域:

  1. 0x0000-0x3FFF。 ROM 的第一行。它是只读的,但不完全是。阅读下一篇
  2. 0x4000-0x7FFF。可切换的 ROM 库,它也不是只读的。不适合 gameboy 地址 space 的墨盒包含内存库控制器。 ROM 将写入一些特定的只读 ROM 区域,实际上 select 哪个 ROM bank 被映射到 0x4000-0x7FFF 地址范围。因此,您必须检测这些写入,然后将读取重定向到 selected ROM 库。
  3. 0xA000-0xBFFF。可切换的 RAM 库。与可切换 ROM 库相同,但现在用于 RAM。墨盒可能包含额外的 RAM,这些 RAM 被映射到 gameboy 的地址 space。同样,通过写入特定的只读区域来控制映射的 RAM 存储区。
  4. 0xFF00-0xFF4B。 IO端口。这里有硬件寄存器映射到地址 space。 Gameboy 有几个硬件组件,每个组件都有自己的寄存器甚至内存(显示控制器、声音处理器、计时器等)。控制硬件ROM读写IO口。您显然必须检测这些写入,以便您可以模拟它们对应的硬件。您不仅需要模拟 CPU 和内存。我什至会说它的最少部分和简单的部分。例如,要正确设置显示控制器和声道要困难得多。它们具有复杂的逻辑、错误和非常棘手的行为,这些行为没有得到很好的记录,但对于实现准确的模拟至关重要。尤其是wave频道让我很为难。