Zim*_*Zim 4 graphics emulation nintendo
我已经成功地模拟了任天堂娱乐系统的(稍微交替的)6502 核心,现在我在 PPU 模拟上有点卡住了。
在各种文档中,PPU 有 0x4000 (16KB) 字节的可用内存。其中只有 2KB 是内部 RAM,而其余部分在墨盒上(或类似的东西)。我不明白的是,PPU 使用了模式表、名称表、属性表、背景调色板和精灵调色板(在我的脑海中)。所有这些东西都存放在哪里?我知道一个 CHR 内存条的大小是 8KB,所以即使 ROM 有多个图形内存条,PPU 怎么知道在哪条内存条中,要找到这些表/调色板中的哪一个?而且有的游戏甚至没有CHR内存,一切都存储在PRG内存中。我怎样才能找出所有图形的存储位置以进行仿真?
编辑:我已经添加了我自己的解释作为答案,因为我现在对 NES 的内部工作有了更多的经验。
自从我问这个问题后,我学到了很多关于 NES PPU 的新东西,所以我将自己回答这个问题。
首先,PPU 的内存映射如下所示:
$0000 - $0FFF Pattern table 0
$1000 - $1FFF Pattern table 1
$2000 - $23BF Nametable 0
$23C0 - $23FF Attribute table 0
$2400 - $27BF Nametable 1
$27C0 - $27FF Attribute table 1
$2800 - $2BBF Nametable 2
$2BC0 - $2BFF Attribute table 2
$2C00 - $2FBF Nametable 3
$2FC0 - $2FFF Attribute table 3
$3000 - $3EFF [0x2000 - 0x2EFF] mirror
$3F00 - $3F09 Background palette
$3F10 - $3F19 Sprite palette
$3F20 - $3FFF Palette mirror
Run Code Online (Sandbox Code Playgroud)
除此之外,还有一个 $FF (256) 字节区域称为 OAM,还有一个 $20 (32) 字节区域称为辅助 OAM。
他们是怎么写的?
模式表用于在模式中保存 NES 的图形数据,即这里存储的任何内容都显示了所使用的精灵的形状。这些通常存储在卡带上的 CHR ROM 中,但它们也可以由游戏程序员写入 PPU 存储器。下面将解释这种情况发生的方式。
除了模式表之外,除了 OAM 和 Secondary OAM 之外的所有内容都由游戏程序员写入 PPU 内存。这是通过使用寄存器$2006和$2007 发生的。如何?
每当程序员想要写入 PPU 内存中的某个地址时,他可以通过像他一样通过 CPU 两次写入$2006来存储(sta、stx、sty 和其他指令)他想要访问的地址。在正常装配中。一个例子是:
LDA #$20
STA $2006
LDA #$00
STA $2006
Run Code Online (Sandbox Code Playgroud)
用户首先写入地址的高字节,然后是低字节。现在,一个 PPU 内部 15 位锁存器(不确定锁存器是否正确)将 PPU 地址 $2000 存储在其中。每当程序员想要写入这个地址(在这种情况下,它是第一个名称表的起始地址)时,他通常可以通过将他想要存储在该内存区域中的值写入内存地址$2007 来实现。写入此地址时,写入的值将放入 15 位锁存器中的地址,锁存器将递增 1 或 32(由地址$2000 中值的第 2 位决定)。基本上就是这么简单。
当然,事情没那么简单。地址$2000 - $2007被称为 PPU 的内存映射寄存器,之所以这样称呼是因为它们位于 CPU 的内存中。它们位于那里,因为 CPU 和 PPU 不能直接访问彼此的内存,所以 CPU 必须找到一些通往 PPU 内存的网关,这些地址就是它。这些寄存器有很多奇怪的异常和怪癖,这里都有解释。
除此之外,还有前面提到的OAM和Secondary OAM,但它们是完全不同的东西,应该通过阅读实际可行的来源来彻底解释,而不是快速解释。
最好从提到的来源(再次,这里)阅读它以获得完整的理解,但这只是对那些好奇并且实际上对这类东西有基本了解的人的快速解释。