内存映射表和相关背景知识

  • 内存映射表和相关背景知识
    ---汉化《铳钢战记》前的最后准备
    文/神奇误差


    Gameboy的CPU有16根地址线(A0~A15),因此它的寻址空间是64KB(2的16次方),即0x0000~0xFFFF。无论是外设还是每一个存储器中的字节,都分配了相应的地址。一般将这样的资源分配称为内存映射表(Memory Map)。
    Gameboy掌机的内存映射表(以DMG型掌机为例)如下:



    图1


    知晓Gameboy对内存空间的映射能够帮助调试人员了解程序。黄色高亮部分是尤其重要的内存区域。表中亦表明用户程序区只有32KB。这样的用户程序区是如何容纳2MB大小的《铳钢战记》?现一一说明如下:


    显存区(0x8000~0x9FFF)
    Gameboy的计算能力有限,因此采用图案映射表的方式显示图片。具体做法是,以画片为最小单元设计游戏画面,一个画片的尺寸是8x8像素(精灵画片的尺寸有8x8像素和8x16像素两种)。精灵画片一般用来表示动态的物品如主角,子弹,特效等。以8x8像素的画片为例,每一个画片都有一个编号,每个画片占用16个字节的空间。


    为什么占用了16个字节,还有其它疑问??请参考硬件区的这篇帖子“Gameboy的显存和地址


    图案映射表储存了所有需要显示的画片编号,每个编号占用一个字节(整个游戏最多可以同时显示384个不同画片)。一幅图案映射表对应一张游戏中的背景图案。显示图案时,液晶屏控制器通过映射表里的编号调用对应的画片,将画片组合起来形成对应的图案。实际上每个图案映射表的大小是400H字节,包含了400H个画片编号,即能够显示20Hx20H尺寸大小的屏幕。以10进制表示:每个图案映射表的显示能力是32x32画片。然而Gameboy屏幕的显示能力是166x144像素,即20x18画片。因此,在实际显示时,gameboy只显示了背景图案的一部分。具体位置由特殊寄存器控制。


    用BGB打开《铳钢战记》,用Vram Viewer查看画片(Tiles)信息。画片数据区的地址范围是0x8000~0x97FF。可以从图片中看到画片区有3个较明显的分区。每个分区可容纳128个画片。第一个分区以精灵画片为主(人物角色的图案),第二个分区以背景画片为主(道路,房屋),第三个分区有较大的空白(这实际上是本游戏的文本画片储存区)


    图2


    图案映射表不能通过Vram Viewer查看到,一般作为图像数据储存在程序中。


    特殊寄存器(0xFF00~0xFF7F)
    寄存器是一个表示存储空间的术语。这里指的特殊寄存器用来和硬件打交道,可以认为是一个能保存状态数据的接口电路。每个寄存器都是1个字节大小,通过向指定地址的寄存器写控制码(对应的字节),和读入寄存器上的数据,实现和硬件的交互。包括打开声音电路,调整声音大小,读入串口数据,打开液晶显示屏,滚动屏幕等等。


    想要一个直观快速的了解,可以参考硬件区的这篇“Gameboy的特殊寄存器


    这里涉及到的控制字繁多,我们可以在汉化过程中一一熟络。幸运地是,BGB在反汇编时会注明相关特殊寄存器。只需要记住,一旦程序要操作0xFF00~0xFF7F之间的数据,就表明这是和硬件相关的。



    图3
    具体信息可参考GBCPUman.pdf 35页起的介绍(英文)
    http://marc.rawer.de/Gameboy/Docs/GBCPUman.pdf


    32KB的用户程序空间
    gameboy只能认知64KB空间的数据,用户程序空间只有32KB,而《铳钢战记》有2MB大小。卡带里的游戏程序是如何成功的运行在一次只能处理32KB用户程序的Gameboy中的呢?
    秘密就是卡带里的内存Bank控制器(Memory Bank Controller)。


    MBC值得另撰文细说,现仅就《铳钢战记》使用的MBC5加以说明。
    通过MBC5,2MB的程序被顺序分割成80H个ROM段,每段ROM的大小是4000H(16KB)。与Gameboy的地址映射表匹配时,0x0000~0x3FFF 永远对应的是ROM00,而0x4000~0x7FFF可以指向ROM00~ROM7FH的任一段ROM,术语称为映射。


    换句话说,在Gameboy运行时的任意时刻,0x0000~0x3FFF永远是游戏程序的ROM00段,而地址0x4000~0x7FFF是2MB游戏程序的任一个的ROM段(包括ROM00)。 :cry:


    ROM段的选择通过向0x2000~0x3FFF 任一地址写入ROM段编号即可。举例,寄存器A的数据为1DH,则下面的指令将使地址0x4000~0x7FFF指向ROM1D,程序将跳转到ROM1D的第一行(0x4000)

    Code
    1. 机器码;汇编指令
    2. EA 00 20;LD (2000),A
    3. C3 00 40; JP 4000


    需要提一句,如图3所示,BGB 程序是以“ROM段编号:内存映射表地址”的形式标明每一条汇编指令的地址。

Join us

Have your own thoughts on this discussion? Wanna help others, avoid the mistakes you met before? Wanna contribute more to this or other topic? Just join us! Registration is free. Join us!