Pan Docs

概览
关于 Pan Docs
Game Boy 技术数据
内存映射

输入/输出端口
视频显示
声音控制
手柄输入
串行数据传输 (连接线)
定时与分频寄存器
中断
CGB 寄存器
SGB 功能

CPU 规格
CPU 寄存器与标志位
CPU 指令集
CPU 与 Z80 的比较

卡带
卡带头部
MBC (存储页面控制器)
Gamegenie/Shark 作弊

其他
开机流程
降低功耗
活动块 RAM 的错误
外设连接


 关于 Pan Docs

 =================================================================
               你能在这里知道有关 GAMEBOY 的一切 *
 =================================================================

                       * 这种事情开心就好

        Pan of -ATX- Document Updated by contributions from:
     Marat Fayzullin, Pascal Felber, Paul Robson, Martin Korth
             CPU, SGB, CGB, AUX specs by Martin Korth

                  Last updated 10/2001 by nocash
               Previously updated 4-Mar-98 by kOOPa

Forward
The following was typed up for informational purposes regarding the inner workings on the hand-held game machine known as GameBoy, manufactured and designed by Nintendo Co., LTD. This info is presented to inform a user on how their Game Boy works and what makes it "tick". GameBoy is copyrighted by Nintendo Co., LTD. Any reference to copyrighted material is not presented for monetary gain, but for educational purposes and higher learning.

Available Document Formats
The present version of this document is available in Text and Html format:
  http://www.work.de/nocash/pandocs.txt
  http://www.work.de/nocash/pandocs.htm
Also, a copy of this document is included in the manual of newer versions of the no$gmb debugger, because of recent piracy attacks (many thanks and best wishes go to hell) I have currently no intention to publish any such or further no$gmb updates though.


 Game Boy 技术数据

  CPU          - 8位 (与 Z80 处理器相似)
  时钟主频     - 4.194304 MHz (SGB 是 4.295454 MHz, CGB 最高可达 8.4 MHz)
  工作 RAM     - 8K 字节 (CGB 为 32K 字节)
  显示 RAM     - 8K 字节 (CGB 为 16K 字节)
  屏幕大小     - 2.6 寸
  分辨率       - 160x144 (20x18 图块)
  最大活动块   - 屏幕最多40个, 每行最多10个
  活动块大小   - 8x8 或者 8x16
  调色板       - BG 1x4, OBJ 2x3 (CGB 为 BG 8x4, OBJ 8x3)
  颜色         - 4级灰度 (CGB 为32768色)
  横向同步     - 9198 KHz (SGB 为 9420 KHz)
  纵向同步     - 59.73 Hz (SGB 为 61.17 Hz)
  声音         - 4通道立体声
  电源         - DC6V 0.7W (GB Pocket 为 DC3V 0.7W, CGB 为 DC3V 0.6W)


 内存映射

Gameboy 的地址总线宽度为16位, 用于 ROM 或 RAM 以及 I/O 寄存器的寻址.

内存映射概览
  0000-3FFF   16KB ROM Bank 00           (于卡带内, 固定为 Bank 00)
  4000-7FFF   16KB ROM Bank 01 到 NN     (于卡带内, 可切 Bank)
  8000-9FFF   8KB 显示 RAM        (VRAM) (在 CGB 模式中可以切 Bank 0 或 1)
  A000-BFFF   8KB 外部 RAM   (ERAM/SRAM) (于卡带内, 如果条件允许可切 Bank)
  C000-CFFF   4KB 工作 RAM Bank 0 (WRAM)
  D000-DFFF   4KB 工作 RAM Bank 1 (WRAM) (在 CGB 模式中可以切 Bank 1 到 7)
  E000-FDFF   与 C000-DDFF 一致   (ECHO) (一般不用)
  FE00-FE9F   活动块属性表        (OAM)
  FEA0-FEFF   不可用
  FF00-FF7F   I/O 端口
  FF80-FFFE   高位 RAM            (HRAM)
  FFFF        中断启用寄存器

ROM 首个 Bank 的跳转向量
下面的地址可作为跳转向量:
  0000,0008,0010,0018,0020,0028,0030,0038   通过使用 RST 指令
  0040,0048,0050,0058,0060                  通过中断
然而,在你的程序不使用任何或部分 RST 指令或者中断时, 你可以将这些内存另作他用. RST 是一个1字节的操作码, 除了目标地址是固定的之外, 与 CALL 操作码的工作方式相似.

ROM 首个 Bank 的卡带头部
内存 0100-014F 为卡带头部. 这个区域含有程序的信息, 程序的入口, 校验和, 所用 MBC 芯片的信息, ROM 和 RAM 的大小等等. 这个区域的大部分字节需要正确设定. 更多详情请阅读卡带头部相关章节.

外部存储与硬件
内存 0000-7FFF 和 A000-BFFF 一般用于连接外部硬件. 第一个区域一般用于 ROM 寻址 (当然是只读的), 有着 MBC 的卡带会额外使用这个区域来输出数据 (只写) 到 MBC 芯片. 第二个区域一般用于外部 RAM 的寻址, 或者其他外部硬件的寻址 (实时时钟等). 外部 RAM 常常配有电池, 用于在 Gameboy 关机时或者卡带被拔出时仍能维持已记录下的游戏进度以及高分表之类的东西. 具体详情请阅读 MBC 相关章节.


 视频显示

视频 I/O 寄存器
LCD 控制寄存器
LCD 状态寄存器
LCD 中断
LCD 位置与卷轴
LCD 单色调色板
LCD 彩色调色板 (仅 CGB)
LCD VRAM Bank (仅 CGB)
LCD OAM DMA 传输
LCD VRAM DMA 传输 (仅 CGB)

Video Memory
VRAM 图块数据
VRAM BG Map
VRAM 活动块属性表 (OAM)
访问 VRAM 与 OAM


 LCD 控制寄存器

FF40 - LCDC - LCD 控制 (读写)
  Bit 7 - 开启 LCD 显示                 (0=关, 1=开)
  Bit 6 - 窗口图块 Map 显示选择         (0=9800-9BFF, 1=9C00-9FFF)
  Bit 5 - 开启窗口显示                  (0=关, 1=开)
  Bit 4 - BG & 窗口图块数据源选择       (0=8800-97FF, 1=8000-8FFF)
  Bit 3 - BG 图块 Map 显示选择          (0=9800-9BFF, 1=9C00-9FFF)
  Bit 2 - OBJ (活动块) 大小             (0=8x8, 1=8x16)
  Bit 1 - 开启 OBJ (活动块) 显示        (0=关, 1=开)
  Bit 0 - BG 显示 (对于 CGB, 见下)      (0=关, 1=开)

LCDC.7 - 开启 LCD 显示
警告: 关闭 LCD 的操作 (Bit 7 由 1 设为 0) 仅可在 V-Blank 内进行, 在 V-Blank 时段之外关闭显示可能损坏硬件. 这是一个非常严重的问题, 据报道任天堂已宣布拒绝所有不符合这个规则的游戏.
V-Blank 可以利用 LY 大于等于 144 来判断. 当显示关闭时屏幕呈现空白 (白色), 此时 VRAM 和 OAM 可以随意访问.

--- LCDC.0 根据 Gameboy 类型有不同意义 ---

LCDC.0 - 1) 单色 Gameboy 和 SGB: BG 显示
当 Bit 0 处于清除时, BG 变为空白. 窗口和活动块仍可能在显示 (如果启用了 Bit 1 或 Bit 5).

LCDC.0 - 2) CGB 运行于 CGB 模式: BG 和窗口优先级
当 Bit 0 处于清除时, BG 和窗口失去他们的优先级 - 活动块将总是显示在 BG 和窗口之上, 独立于 OAM 与 BG Map 属性中的优先级设置.

LCDC.0 - 3) CGB 运行于非 CGB 模式: BG 和窗口显示
当 Bit 0 处于清除时, BG 和窗口变为空白, 在此情况下窗口显示位 (Bit 5) 将被忽略. 只有活动块仍可能在显示 (如果启用了Bit 1).
这可能造成兼容性问题 - 任何关闭了屏幕, 但仍想显示窗口的单色游戏可能不能在 CGB 上正确工作.


 LCD 状态寄存器

FF41 - STAT - LCDC 状态 (R/W)
  Bit 6 - LYC=LY 一致中断                (1=启用) (读写)
  Bit 5 - 模式 2 OAM 中断                (1=启用) (读写)
  Bit 4 - 模式 1 V-Blank 中断            (1=启用) (读写)
  Bit 3 - 模式 0 H-Blank 中断            (1=启用) (读写)
  Bit 2 - 一致标志位        (0:LYC<>LY, 1:LYC=LY) (只读)
  Bit 1-0 - 模式标志位           (模式 0-3, 见下) (只读)
            0: 处于 H-Blank
            1: 处于 V-Blank
            2: 处于检索 OAM-RAM 的状态
            3: 处于传送数据至 LCD 驱动的状态

STAT 的低两位表示当前 LCD 控制器的状态.
  模式 0: LCD 控制器处于 H-Blank 时段,
          CPU 可以访问显示 RAM (8000h-9FFFh) 和 OAM (FE00h-FE9Fh).

  模式 1: LCD 控制器处于 V-Blank 时段
          (或者屏幕处于关闭状态),
          CPU 可以访问显示 RAM (8000h-9FFFh) 和 OAM (FE00h-FE9Fh).

  模式 2: LCD 控制器正在从 OAM 存储中读取数据.
          CPU <不可以>在这个时段访问 OAM 存储 (FE00h-FE9Fh).

  模式 3: LCD 控制器正在从 OAM 和 VRAM 中读取数据,
          CPU <不可以>在这个时段访问 OAM 和 VRAM.
          CGB 模式: 也不可以放访问调色板数据 (FF69,FF6B).

下面是当显示开启时的典型时序:
  模式 2  2_____2_____2_____2_____2_____2___________________2____
  模式 3  _33____33____33____33____33____33__________________3___
  模式 0  ___000___000___000___000___000___000________________000
  模式 1  ____________________________________11111111111111_____

模式标志位经过值 0, 2, 3 一个时段大约需要 109 微秒. 模式 0 出现大约 48.6 微秒, 模式 2 大约 19 微秒, 模式 3 大约 41微秒. 这个循环每 16.6 毫秒被 VBlank (模式 1) 打断一次. 模式标志位设为 1 大约持续 1.08 毫秒.

模式 0 出现大约 201-207 个 CPU 时钟, 模式 2 大约 77-83 个 CPU 时钟, 模式 3 大约 169 - 175 个 CPU 时钟. 完整经过这几个状态的时段耗费 456 个 CPU 时钟. VBlank 持续 4560 个 CPU 时钟. 每 70224 个 CPU 时钟产生一次完整的屏幕刷新.


 LCD 中断

INT 40 - V-Blank 中断
V-Blank 中断在普通 GB 上每秒产生 59.7 次, 在 SGB 上每秒产生 61.1 次. 这个中断产生于 V-Blank 时段的开始 (LY=144).
这个时段内视频硬件不使用 VRAM, 所以此时 VRAM 可以随意访问. 这个时段大约持续 1.1 毫秒.

INT 48 - LCDC 状态中断
根据 STAT 寄存器 ($FF40) 的设置状态, 会有多种产生这个中断的原因. 一个最常见的原因是当视频硬件要重绘一条给定的 LCD 行时告知使用者. 这个在动态调整 SCX/SCY 寄存器 ($FF43/$FF42) 来实现特殊的画面效果时非常有用.


 LCD 位置与卷轴

FF42 - SCY - 卷轴 Y (读写)
FF43 - SCX - 卷轴 X (读写)
指定LCD屏幕左上角在在背景映射表(大小256x256像素,即32x32画片)中的位置
X/Y的可选数值范围是0-255。当绘图操作超出背景映射表的下边界(右边界)时,视频控制器会自动回程到背景映射表的上部(左部)。

FF44 - LY - LCDC Y 坐标 (只读)(译注:视频控制器纵坐标寄存器)
LY寄存器指明当前被传输到LCD驱动器的数据是哪一行。 LY寄存器可取0到153之间的任意数据。 当数据为144到153之间时,表明在纵向回程周期(V-Blank,译注:电子束扫描线在扫描完毕并准备生成新一帧时,必须回到起点,这段时间即纵向回程周期。液晶显示的Gameboy从NES继承了该显示机制,尽管液晶屏并不需要) 写操作将重置计数器。

FF45 - LYC - LY 比较 (读写)
Gameboy会一直比较LYC寄存器和LY寄存器的值。当二者值相同时,STAT寄存器的冲突位会被置1,并发起STAT中断请求(若启用)。

FF4A - WY - 窗口 Y 位置 (读写)
FF4B - WX - 窗口 X 位置 (值 = X 位置 + 7) (读写)
指定窗口区域的左上角坐标。(该窗口是另一个背景区域,并且可以显示在普通背景之上)。就像和普通背景交互那样,OBJs(精灵)依然可以显示在窗口之上或之下。
当坐标设置为WX=0..166,WY=0..143范围内时可以看见窗口。若在窗口左上角取坐标WX=7,WY=0,则它将完全覆盖普通背景。


 LCD 单色调色板

FF47 - BGP - 背景调色板数据 (读写) - 仅非 CGB 模式
该寄存器指派背景和窗口画片的颜色编号的灰度等级。
  比特位 7-6 - 颜色编号3的灰度等级
  比特位 5-4 - 颜色编号2的灰度等级
  比特位 3-2 - 颜色编号1的灰度等级
  比特位 1-0 - 颜色编号0的灰度等级
四种可选的灰度等级是:
  0  白色
  1  浅灰
  2  深灰
  3  黑色
在CGB模式中,颜色调色板则从CGB调色板存储中调用。

FF48 - OBP0 - 活动块调色板 0 数据 (读写) - 仅限非 CGB 模式
该寄存器指定精灵调色板0的灰度等级。它用起来和背景调色板寄存器BGP(FF47)完全一样,除过没有使用最低的两个数据位。这是因为精灵数据00是透明色。

FF49 - OBP1 - 活动块调色板 1 数据 (读写) - 仅限非 CGB 模式
该寄存器指定精灵调色板1的灰度等级。它用起来和背景调色板寄存器BGP(FF47)完全一样,除过没有使用最低的两个数据位。这是因为精灵数据00是透明色。


 LCD 彩色调色板 (仅 CGB)

FF68 - BCPS/BGPI - 仅 CGB 模式 - 背景调色板索引
该寄存器用来寻址CGB的背景调色板存储的一个字节。该存储中每两个字节定义一个颜色的值。前8个字节定义了调色板0(BGP0)的颜色0-3,BGP1-7以此类推。
  比特位 0-5   索引 (00-3F)
  比特位 7     自动递增  (0=禁用, 1=写操作后递增)
通过寄存器FF69,可以读取/写入指定的索引地址。当自动递增位被启用,那么每次<写入>FF69之后索引都会自动递增。而从FF69<读取>数据不会启用自动递增,因此在这种情况下需要手动递增索引。

FF69 - BCPD/BGPD - 仅限 CGB 模式 - 背景调色板数据
通过寄存器FF68寻址,该寄存器可读/写CGB的背景调色板存储。
每种颜色由两个字节定义 (比特位 0-7 在第一个字节).
  比特位 0-4   红色的强度   (00-1F)
  比特位 5-9   绿色的强度 (00-1F)
  比特位 10-14 蓝色的强度  (00-1F)
和显存(VRAM)一样,当LCD控制器从中读取数据时,调色板存储中的数据不可读/写。(此时即STAT寄存器指示的模式3).
注:在最开始,所有背景颜色都被初始化为白色。

FF6A - OCPS/OBPI - 仅限 CGB 模式 - 活动块调色板索引
FF6B - OCPD/OBPD - 仅限 CGB 模式 - 活动块调色板数据
和上文描述的背景调色板一样,这两个寄存器用来初始化精灵调色板OBP0-7。注意,每一个OBP调色板都可以定义四个颜色,但是每个调色板只会显示出颜色1-3。颜色0一直是透明色,并且可以被初始化为一个任意一个无所谓的值。
注:在最开始,所有精灵的颜色都是未初始化的。

CGB的RGB颜色转换
注意,在个人电脑上开发图像时,RGB数值在VGA显示器上和CGB的显示屏有不同的表现:
浓度最高的配色会显示出浅灰色,而不是白色。色彩浓度不是线性的。10h-1Fh之间的数值会显得非常亮,而中等和暗色在 00h-0Fh 之间。
CGB的显示屏会非常奇怪地混合颜色。仅仅增加一种R,G,B颜色的浓度也会影响其他两个R,G,B颜色。
举例来说,颜色值03EFh(蓝色=0,绿色=1Fh,红色=0Fh)在VGA显示器上看起来是荧光绿,然而在CGB上却是一个无比正确的褪色黄。

GBA的RGB颜色转换
尽管GBA被描述为可以兼容CGB游戏,但实际上大部分CGB游戏在GBA上完全不能玩,因为大部分颜色都看不见(黑色)。当然,像黑色和白色这样的颜色在CGB和GBA上是一样的,但是中间浓度的颜色却被处理得完全不一样。
在范围00h..0Fh区间的颜色浓度是看不见的/显示为黑色(除非偶尔在非常好的光照条件之下,同时以特定角度盯着屏幕),不幸的是,这部分区间的浓度通常被大部分已存在的CGB游戏用作中间及较暗的颜色。
新一些的CGB游戏可以在检测到GBA硬件时更换调色板数据,以避免这种效应。一个相对简单的方法是使用公式GBA=CGB /2+10h来转换每一个RGB颜色浓度。或许结果并不完美,并且(当能看见颜色时)颜色混合看起来也很奇怪,但聊胜于无,至少比没有转换好一些。
另外,这些颜色转换方法用GBA硬件实施的话是及其简单的,但显而易见,任天堂并没有这么做。所以他们是如何声称,本印章(译注,指任天堂在每个游戏卡带外的圆形印章图样)是为您提供杰出工艺及其它林林总总的担保?


 LCD VRAM Bank (仅 CGB)

FF4F - VBK - 仅 CGB 模式 - VRAM Bank
这个 1 位的寄存器用于选择当前的视频 RAM (VRAM) 的 Bank.
  Bit 0 - VRAM Bank (0-1)
Bank 0 含有 192 个图块, 和两张 BG Map, 仅用于单色游戏. Bank 1 还有另外的 192 个图块, 以及搭配 Bank 0 中的 BG Map 使用的颜色属性 Map.


 LCD OAM DMA 传输

FF46 - DMA - DMA 传输与开始地址 (只写)
Writing to this register launches a DMA transfer from ROM or RAM to OAM memory (sprite attribute table). The written value specifies the transfer source address divided by 100h, ie. source & destination are:
  Source:      XX00-XX9F   ;XX in range from 00-F1h
  Destination: FE00-FE9F
It takes 160 microseconds until the transfer has completed (80 microseconds in CGB Double Speed Mode), during this time the CPU can access only HRAM (memory at FF80-FFFE). For this reason, the programmer must copy a short procedure into HRAM, and use this procedure to start the transfer from inside HRAM, and wait until the transfer has finished:
   ld  (0FF46h),a ;start DMA transfer, a=start address/100h
   ld  a,28h      ;delay...
  wait:           ;total 5x40 cycles, approx 200ms
   dec a          ;1 cycle
   jr  nz,wait    ;4 cycles
Most programs are executing this procedure from inside of their VBlank procedure, but it is possible to execute it during display redraw also, allowing to display more than 40 sprites on the screen (ie. for example 40 sprites in upper half, and other 40 sprites in lower half of the screen).


 LCD VRAM DMA 传输 (仅 CGB)

FF51 - HDMA1 - 仅 CGB 模式 - 新 DMA 来源地址高位
FF52 - HDMA2 - 仅 CGB 模式 - 新 DMA 来源地址低位
FF53 - HDMA3 - 仅 CGB 模式 - 新 DMA 目标地址高位
FF54 - HDMA4 - 仅 CGB 模式 - 新 DMA 目标地址低位
FF55 - HDMA5 - 仅 CGB 模式 - 新 DMA 长度/模式/启动
这些寄存器用于发起一次从 ROM 或 RAM 到 VRAM 的 DMA 传送. 来源首地址定于 0000-7FF0 或者 A000-DFF0, 地址低四位将被忽略 (处理为0). 目标首地址定于 8000-9FF0, 地址低四位将被忽略 (处理为0), 地址高三位也将被忽略 (目标总是在VRAM内).

写入 FF55 启动传输, FF55 的低七位指定了传输长度 (值 = 传输长度 / 10h - 1). 例如, 10h-800h的长度可以对应指定值为00h-7Fh. FF55 的最高位表示传输模式:

Bit7=0 - 通用 DMA
当使用这种传输方式时, 所有数据将一次性传输. 程序的执行将停机, 直到传输完成. 需要注意通用 DMA 只会直接尝试复制数据, 甚至在 LCD 控制器正在访问 VRAM 时也是如此. 所以通用 DMA 只能在屏幕关闭时, 或处于 V-Blank 时, 再或者 (在传输小块的情况) 处于 H-Blank 时.
程序将在传输完成时继续执行, 此时 FF55 的值为 0FFh.

Bit7=1 - H-Blank DMA
H-Blank DMA 在每个 H-Blank 中传输 10h 字节的数据. 例如, 在 LY=0-143 的时候进行传输, 在 V-Blank 时数据暂停传输 (LY=144-153), 但是当 LY=00 时传输将继续进行. 程序在每个传输分片进行时停机, 但是程序将在每个分片之间的 '空闲时刻' 继续执行.
需要注意程序不能在传输结束之前改变目标 VRAM 的 Bank (FF4F), 或者来源 ROM/RAM 的 Bank (如果传输的数据来自于可切 Bank 的存储)!
从寄存器 FF55 读取将返回传输剩余的长度 (值 = 传输长度 / 10h - 1), 值 0FFh 代表传输已经完成. 要终止一个活动的 H-Blank 传输可以往 FF55 的 Bit 7 写入 0. 在这种情况下从 FF55 中读取数据, 返回值的低七位将是任意值, 但最高位将读取到 "1" .

确认 DMA 传输是否活动
读取 FF55 的 Bit 7 可以用于确认 DMA 传输是否活动 (1= 不活动, 0= 活动). 这种方式可以在任何情况下工作 - 在通用传输完成后, 在 H-Blank 传输结束之后, 以及手动终止 H-Blank 传输之后均可.

传输时间
普速模式和倍速模式均需要 8 微秒来传输一个 10h 字节块. 相当于普速模式下的 8 个周期, 倍速模式下的 16 个 '快' 周期.
较旧的 MBC (如 MBC1 到 3, 即 MBC5 之前) 与慢速 ROM 不保证支持通用或 H-Blank DMA, 因为即使程序运行于普速模式, 传输均是以 2 字节每毫秒的速度进行.


 VRAM 图块数据

图块 (Tile) 数据存储于 VRAM 地址 8000h-97FFh, 这个区域定义了 192 个图块的位图. 在 CGB 模式下, 因为使用了 0:8000h-97FFh 和 1:8000h-97FFh 的内存, 所以可定义 384 个图块.

每个图块为 8x8 像素大小, 色深为 4 色/灰度. 图块可作为背景/窗口 Map 的一个部分显示, 也/或可以作为 OAM 图块 (前景活动块) 显示. 注意前景活动块的颜色 0 为透明, 所以只有 3 种颜色可用.

如前所述, 两张图块样式表 (Pattern Table) 位于 $8000-8FFF 和 $8800-97FF. 第一张可以用于活动块和背景. 图块号从 0 编号到 255. 第二张可以用于背景和窗口显示, 图块号从 -128 编号到 127.

每个图块占有 16 个字节, 其中每 2 个字节代表一行:
  Byte 0-1  第一行 (最上方的 8 个像素)
  Byte 2-3  下一行
  以此类推.
对于每条线, 第一个字节定义了每个像素颜色号的低位, 第二个字节定义了每个像素颜色号的高位. 另外, Bit 7 是最左边的像素, Bit 0 是最右边的像素.

所以, 每个像素有范围 0-3 的颜色号, 颜色号将依据当前的调色板转换成实际颜色 (或者灰度). 调色板定义在寄存器 FF47-FF49 (非 CGB 模式), 和 FF68-FF6B (CGB 模式).


 VRAM BG Map

Gameboy 有两张 32x32 的图块 BG Map (背景分布) 于 VRAM 地址 9800h-9BFFh 和 9C00h-9FFFh. 每张可以用于显示 "普通" 的背景, 也可以用于显示 "窗口" 背景.

BG Map 图块号
VRAM 中作为 BG 图块 Map 的区域包含用于显示的图块所对应的编号. 这个区域组成为 32 行, 每行 32 个字节. 每个字节包含一个用于显示的图块编号. 图块样式表从位于 $8000-8FFF 或者 $8800-97FF 的图块数据表中得来. 第一种情况 ($8000-8FFF), 图块样式表以从 0 到 255 的无符号数作为编号 (如, 样式 #0 位于地址 $8000). 第二种情况 ($8800-97FF), 样式表以 -128 到 127 的有符号数作为编号 (如, 样式 #0 位于地址 $9000). 用于背景的图块数据表地址可通过 LCDC 寄存器选择.

BG Map 属性 (仅 CGB 模式)
在 CGB 模式中, 有一张附加的存于 VRAM Bank 1 的 32x32 字节 Map (每个字节一一对应 VRAM Bank 0 中的 BG 图块 Map, 用于定义图块属性):
  Bit 0-2  背景调色板编号           (BGP0-7)
  Bit 3    图块 VRAM Bank 号        (0=Bank 0, 1=Bank 1)
  Bit 4    不使用
  Bit 5    水平翻转                 (0=普通, 1=水平翻转)
  Bit 6    垂直翻转                 (0=普通, 1=垂直翻转)
  Bit 7    BG 与 OAM 优先级         (0=根据 OAM 优先位, 1=BG 优先)
当 Bit 7 处于设置时, 对应的 BG 图块将有高于所有活动块的优先度 (忽略 OAM 存储中所设的优先位). 另外, 在 LCDC 寄存器的 Bit 0 是主优先标志, 这个标志处于清除时, 标志的优先级位于其他所有优先度设置之上.

因为一个背景图块的大小是 8x8 像素, 所以一张 BG Map 能表示一张 256x256 像素的图像, 这张图像中的 160x144 可以被显示在 LCD 屏幕上.

普通背景 (BG)
SCY 和 SCX 寄存器可用于滚动背景, 允许在整张 256x256 像素的 BG Map 中选择可见的 160x144 像素区域的来源. 背景在屏幕上环绕 (如, 当背景的一部分穿出了屏幕, 这一部分将显示背景另一侧的内容.)

窗口
除了背景, 还有一个 "窗口" 叠放与背景层之上. 这个窗口是不可滚动的, 总是从 (Map 的) 左上角开始显示. 窗口在屏幕上的位置可以通过 WX 和 WY 寄存器调节. 窗口左上角在屏幕的坐标是 WX-7,WY. 用于窗口的图块存于图块数据表. 背景和窗口始终使用统一张图块数据表.

背景和窗口两者都可以各自独立通过 LCDC 寄存器中对应的位来开启或关闭.


 显存精灵属性表 (OAM)

Gameboy 的视频控制器可以显示至多40个精灵,以8x8像素或8x16像素格式。 由于硬件限制,一条扫描线仅可以同时显示10个精灵(由于硬件的图形合成时间限制,译注)。 精灵图案和背景图砖的格式一样,不同的是,它们取自位于$8000-8FFF的精灵图案表,并以无符号数编号。

精灵属性表(或记为,OAM - Object Attribute Memory)的精灵属性位于$FE00-FE9F。其共计40个条目,每一个条目包含四个字节,其定义如下:

字节0 - Y 位置
指定精灵在屏幕上的纵向位置 (减去 16)。
给定一个屏幕之外的值 (如,Y=0 或 Y>=160) 将隐藏该精灵。

字节1 - X 位置
指定精灵在屏幕上的横向位置 (减去 8)。
给定一个屏幕之外的值 (X=0 或 X>=168) 将隐藏改精灵,但是精灵仍将影响优先级排序。因此隐藏精灵的更合适的方法是,将它的Y坐标设置到屏幕之外。

字节2 - 图砖/图案编号
指定精灵的图砖编号 (00-FF)。该(无符号)值将从存储区间8000h-8FFFFh选定一个图砖。在CGB模式下,则可从显存容组(VRAM Bank)0或显存容组1中选取,其取决于下一个字节的第3位。
8x16模式下, 图砖编号的最低位将被忽略。举例来说,上半个8x8图砖是“NN AND EFh”,下半个8x8图砖是“NN OR 01h”

字节3 - 属性/标志位:
  比特位7   物体到背景(OBJ to BG)优先级 (0=物体在背景之上, 1=物体在背景颜色1-3下面)
         (适用于背景和窗口。背景颜色0一直在物体之下)
  比特位6   Y 翻转          (0=正常, 1=纵向镜像)
  比特位5   X 翻转          (0=Normal, 1=横向镜像)
  比特位4   调色板编号  **仅限非CGB模式** (0=OBP0, 1=OBP1)
  比特位3   图砖的显存容组  **仅限CGB模式**     (0=容组 0, 1=容组 1)
  比特位2-0 调色板编号  **仅限CGB模式**     (OBP0-7)

精灵的优先级和冲突
当具有不同横坐标的精灵重叠时,具有最小横坐标的那一个(更靠近左侧)是优先的,并且显示在其它精灵之上。这个规则仅限非CGB模式。
当具有相同横坐标的精灵重叠时,它们的优先级将以属性表的顺序为准(即 $FE00 - 最高级, $FE04 - 次高级,以此类推)。在CGB模式下,优先级一直以此安排。

任意一条线只可以显示10个精灵。当该限制被超出时,最低优先级的精灵(优先级参上)将不会被显示出来。若想未使用的精灵不影响屏幕上的精灵,将其纵坐标设置为Y=0 或 Y=>144+16即可。仅仅把精灵的横坐标设为X=0 或 X=>160+8是可以隐藏精灵,但它仍将影响同一条线上的其它精灵。

向OAM存储写数据
推荐的方法是,先将数据写入到普通的RAM里,然后再通过DMA寄存器(FF46)启用DMA传输功能,将数据从RAM复制到OAM中。
除此之外,也可通过LD指令将数据直接写入到OAM区域。但它仅可在横向回程(H-Blank)和纵向回程(V-Blank)期间使用。LCD控制器的当前状态可从STAT寄存器(FF41)中读出。


 访问 VRAM 和 OAM

警告
当 LCD 控制器绘制屏幕时, 它将直接读取视频存储 (VRAM) 和 OAM. 在这个时期内 Gameboy CPU 不可访问 VRAM 和 OAM. 在这时, 任何对 VRAM/OAM 的写入尝试将被忽略 (数据保持不变). 任何对 VRAM/OAM 的读取尝试将返回未定义数据 (一般来说是值 0FFh).

因为如此, 程序需要在写入或读取 VRAM/OAM 之前确认它们能否访问. 一般是通过读取 STAT 寄存器的模式位来确认的. 在做这个确认步骤时 (在下面的例子中说明) 你需要确认在等待循环和接下来的内存访问之间没有中断产生 - 对应的存储只在等待循环完成后的几个周期内能确保被访问.

VRAM (内存位于 8000h-9FFFh) 可以在模式 0-2 之间访问
  Mode 0 - H-Blank 时期
  Mode 1 - V-Blank 时期
  Mode 2 - 检索 OAM 时期
一个等待 VRAM 可访问的典型程序可以是:
  ld   hl,0FF41h    ;-STAT 寄存器
 @@wait:            ;\
  bit  1,(hl)       ; 等待直到模式为 0 或 1
  jr   nz,@@wait    ;/
就算程序在模式 0 或 1 的 <结尾> 执行, 因为这两种模式后面跟随着同样允许访问 VRAM 的模式 2 ,依旧能够推定此时 VRAM 仍有一些周期可以访问.
在 CGB 模式下, 一种写入 VRAM 的替代方式是使用 HDMA 功能 (FF51-FF55).

OAM (内存位于 FE00h-FE9Fh) 可以在模式 0-1 之间访问
  Mode 0 - H-Blank 时期
  Mode 1 - V-Blank 时期
除了这个方式之外, OAM 可以通过 DMA 功能 (FF46) 在任意时刻访问. 直接读写 OAM 时, 一个等待 OAM 存储可访问的典型程序可以是:
  ld   hl,0FF41h    ;-STAT 寄存器
 @@wait1:           ;\
  bit  1,(hl)       ; 等待直到模式 -不为- 0 或 1
  jr   z,@@wait1    ;/
 @@wait2:           ;\
  bit  1,(hl)       ; 等待直到模式 0 或 1 -开始-
  jr   nz,@@wait2   ;/
两个等待循环确保在程序完成后能维持在模式 0 或 1 中几个周期. 在 V-Blank 时期推荐跳过整个程序 - 同时更推荐在大部分情况下使用前面提到的 DMA 功能.

备注
当显示关闭时, VRAM 和 OAM 都可以在任意时刻访问. 这样的缺点是屏幕在这个时期显示空白, 所以只推荐在初始化时关闭显示.


 声音控制器

声音总览
声音通道 1 - 乐音和扫频
声音通道 2 - 乐音
声音通道 3 - 波形输出
声音通道 4 - 噪音
声音控制寄存器


 声音总览

有两个声音通道连接了输出端口SO1和SO2(Sound Output 1&2, 译注)。 另有一个输入端口Vin连接到卡带, 它可被连到两个输出端口其中的任意一个。 Gameboy 的电路允许以四种不同的方式产生声音:

   具有扫频和包络线功能的方波图形。
   具有包络线功能的方波图形。
   从波形存储器产生的自主波形图案。
   具有包络线功能的白噪音。

这四个声音可以被独立控制,并且针对某一个输出端口都可以独立地混音。

在产生声音时,声音寄存器可以一直被设置。

(SGB上的声音频率约高2.4%。)


 声音通道 1 - 乐音和扫频

FF10 - NR10 - 通道 1 扫频寄存器 (读/写)
  比特位 6-4 - 扫频时间
  比特位 3   - 递增/递减扫频
             0: 相加    (频率增加)
             1: 相减 (频率减少)
  比特位 2-0 - 扫频偏移数 (n: 0-7)
扫频时间:
  000: 扫频关闭 - 无频率变化
  001: 7.8 ms  (1/128Hz)
  010: 15.6 ms (2/128Hz)
  011: 23.4 ms (3/128Hz)
  100: 31.3 ms (4/128Hz)
  101: 39.1 ms (5/128Hz)
  110: 46.9 ms (6/128Hz)
  111: 54.7 ms (7/128Hz)

每次偏移时,频率(NR13,NR14)的变化按照下述公式计算,其中 X(0) 是起始频率,X(t-1) 是最末频率:
  X(t) = X(t-1) +/- X(t-1)/2^n

FF11 - NR11 - 通道 1 声音长度/波形图案工作周期 (读/写)
  比特位 7-6 - 波形图案工作周期  (读/写)
  Bit 5-0 - 声音长度数值 (只可写) (t1: 0-63)
波形工作周期:
  00: 12.5% ( _-------_-------_------- )
  01: 25%   ( __------__------__------ )
  10: 50%   ( ____----____----____---- ) (普通)
  11: 75%   ( ______--______--______-- )
声音长度 = (64-t1)*(1/256) 秒
仅当NR14的比特位6被置为1的时候,长度数值才有用。

FF12 - NR12 - 通道 1 音量包络线 (R/W)
  比特位 7-4 - 包络线起始音量 (0-0Fh) (0=无声音)
  比特位 3   - 包络线方向 (0=减少, 1=增加)
  比特位 2-0 - 包络线扫频数 (n: 0-7)
            (若为零,停止包络线操作。)
1步的长度 = n*(1/64) 秒

FF13 - NR13 - 通道 1 频率低位 (只写)

11位频率 (x) 的低8位。
接下来的3位在 NR14 ($FF14)中

FF14 - NR14 - 通道 1 频率高位 (读/写)
  比特位 7   - 启动 (1=重启声音)     (只写)
  Bit 6   - 计数器/连续性选择 (读/写)
            (1=达到NR11中指定的长度时,停止输出)
  Bit 2-0 - 频率的高3位 (x) (只写)
频率 = 131072/(2048-x) Hz


 声音通道 2 - 乐音

此声音通道和通道1完全一致,除了它没有乐音包络/扫频寄存器。

FF16 - NR21 - 通道 2 声音长度/波形图案工作周期 (读/写)
  比特位 7-6 - 波形图案工作周期 (读/写)
  比特位 5-0 - 声音长度数据 (只写) (t1: 0-63)
波形工作周期:
  00: 12.5% ( _-------_-------_------- )
  01: 25%   ( __------__------__------ )
  10: 50%   ( ____----____----____---- ) (普通)
  11: 75%   ( ______--______--______-- )
声音长度 = (64-t1)*(1/256) 秒
仅当NR24的比特位6被置位时使用长度数值。

FF17 - NR22 - 通道 2 声音包络线 (读/写)
  比特位 7-4 - 包络线起始音量 (0-0Fh) (0=无声音)
  比特位 3   - 包络线方向 (0=减少, 1=增加)
  比特位 2-0 - 包络线扫频数 (n: 0-7)
            (若为零,停止包络线操作。)
1步的长度 = n*(1/64) 秒

FF18 - NR23 - 通道 2 频率低位数据 (W)
11位频率数据(x)的低8位。
接下来的3位在 NR24 ($FF19) 中。

FF19 - NR24 - 通道 2 频率高位数据 (读/写)
  比特位 7   - 启动 (1=重启声音)     (只写)
  比特位 6   - 计数器/连续性选择 (读/写)
            (1=达到NR21中指定的长度时,停止输出)
  比特位 2-0 - 频率的高3位 (x) (只写)
频率 = 131072/(2048-x) Hz


 声音 3 - 波形输出

该通道可以用来输出数字声音,其采样缓冲(波形内存)的长度限制到32位。 若用方波初始化波形内存,本通道也可用来输出普通乐音。该通道没有音量包络线寄存器。

FF1A - NR30 - 通道 3 声音 打开/关闭 (R/W)
  比特位 7 - 声音通道 3 关闭  (0=停止, 1=回放)  (读/写)

FF1B - NR31 - 通道 3 声音长度
  比特位 7-0 - 声音长度 (t1: 0 - 255)
声音长度 = (256-t1)*(1/256) 秒
仅当NR34的比特位6被置位时使用该数值。

FF1C - NR32 - 通道 3 选择输出水平 (读/写)
  比特位 6-5 - 选择输出水平 (读/写)
可选输出水平:
  0: 静音 (无声音)
  1: 100% 音量 (原样产生波形图案内存数据)
  2:  50% 音量 (产生右移一位的波形图案内存数据)
  3:  25% 音量 (产生右移两位的波形图案内存数据)

FF1D - NR33 - 通道 3 频率低位数据 (写)
11位频率 (x) 的低8位。

FF1E - NR34 - 通道 3 频率高位数据 (读/写)
  比特位 7   - 启动 (1=重启声音)     (只写)
  比特位 6   - 计数器/连续性选择 (读/写)
            (1=达到NR31中指定的长度时,停止输出)
  比特位 2-0 - 频率的高3位 (x) (只写)
频率 = 4194304/(64*(2048-x)) Hz = 65536/(2048-x) Hz

FF30-FF3F - 波形图案内存
Contents - 任意声音数据的波形储存

该存储区域包含32个4比特采样。高4比特先回放。(即16个字节按序播放,每一个字节的高4位先回放,译注)


 声音通道 4 - 噪音

本通道用来产生白噪音。通过随机切换给定频率的高低幅值而实现。取决于具体的频率,噪音听起来会“硬一些”或“软一些”。

当然也可以影响随机数产生器功能,使得输出变得更规整一些。这样可以得一个有限的乐音,而不是噪音。

FF20 - NR41 - 通道 4 声音长度 (读/写)
  比特位 5-0 - 声音长度数据 (t1: 0-63)
声音长度 = (64-t1)*(1/256) 秒
仅当NR44的比特位6被置位时使用该数值。

FF21 - NR42 - 通道 4 声音包络线 (读/写)
  比特位 7-4 - 包络线起始音量 (0-0Fh) (0=无声音)
  比特位 3   - 包络线方向 (0=减少, 1=增加)
  比特位 2-0 - 包络线扫频数 (n: 0-7)
            (若为零,停止包络线操作。)
一步的长度 = n*(1/64) 秒

FF22 - NR43 - 通道 4 多项式计数器 (读/写)
噪音的幅值在给定频率的高和低之间随机切换。高一些的频率使得噪音听起来“软一些”。
当比特位3被置位时,输出会变得更规整,使得一些频率听起来更像是乐音而不是噪音。
  比特位 7-4 - 移位时钟频率(s)
  比特位 3   - 计数器 步长/宽度 (0=15 位, 1=7 位)
  比特位 2-0 - 频率相除系数 (r)
频率 = 524288 Hz / r / 2^(s+1) ;当 r=0 时用 r=0.5 替换

FF23 - NR44 - 通道 4 计数器/连续性; 启动 (R/W)
  比特位 7   - 启动 (1=重启声音)     (只写)
  比特位 6   - 计数器/连续性选择 (读/写)
            (1=达到NR41中指定的长度时,停止输出)


 声音控制寄存器

FF24 - NR50 - 通道控制 / 开启-关闭 / 音量 (读/写)
音量位指定了左/右声道输出的“主音量”。
  比特位 7   - 输出 Vin 到 SO2 端口 (1=启用)
  比特位 6-4 - SO2 输出水平 (音量)  (0-7)
  比特位 3   - 输出 Vin 到 SO1 端口 (1=启用)
  比特位 2-0 - SO1 输出水平 (音量)  (0-7)
Vin 信号接收自游戏卡匣总线,使得卡匣里的额外硬件可以在Gameboy内部的四个通道之外,提供第五个声音通道。然而据我所知,尚未有游戏使用了该功能。

FF25 - NR51 - 选择声音输出端口 (R/W)
  比特位 7 - 输出声音 4 到 SO2 端口
  比特位 6 - 输出声音 3 到 SO2 端口
  比特位 5 - 输出声音 2 到 SO2 端口
  比特位 4 - 输出声音 1 到 SO2 端口
  比特位 3 - 输出声音 4 到 SO1 端口
  比特位 2 - 输出声音 3 到 SO1 端口
  比特位 1 - 输出声音 2 到 SO1 端口
  比特位 0 - 输出声音 1 到 SO1 端口

FF26 - NR52 - 声音 开启/关闭
如果你的GB程序不使用声音,那么向该寄存器写入数值00h将减少至少16%的整机功耗。 清零比特位7销毁所有声音寄存器中的内容,从而禁用声音寄存器。 另外,当声音寄存器被禁用时,将无法访问任何声音寄存器(除了FF26)。
  比特位 7 - 全部声音 开启/关闭  (0: 停止所有声音电路) (读/写)
  比特位 3 - 声音 4 开启标志位 (只读)
  比特位 2 - 声音 3 开启标志位 (只读)
  比特位 1 - 声音 2 开启标志位 (只读)
  比特位 0 - 声音 1 开启标志位 (只读)
本寄存器的比特位0-3是只读的,向这些位写操作不可启用/禁用声音。 设定启动标志位(NR14-NR44的比特位7),声音输出被重启,使得这些标志位被置位。 这些标志位将一直保持被置位状态直到声音长度已达到。 减少到无声的声音包络线不会使得声音标志位关闭。


 手柄输入

FF00 - P1/JOYP - 手柄 (读/写)
Gameboy的八个按钮键/方向键以 2x4 矩阵的形式排列。 写入该寄存器来选择按钮键或者方向键,具体键位可在比特位0-3读出。
  Bit 7 - 未使用
  Bit 6 - 未使用
  Bit 5 - P15 选择按钮键      (0=选择)
  Bit 4 - P14 选择方向键   (0=选择)
  Bit 3 - P13 输入下或开始    (0=已按下) (只读)
  Bit 2 - P12 输入上或选择   (0=已按下) (只读)
  Bit 1 - P11 输入左或按钮B (0=已按下) (只读)
  Bit 0 - P10 输入右或按钮A (0=已按下) (只读)
提示:大部分程序反复读取该端口数次 (刚开始的读取作为短暂延迟,以便让输入稳定下来。只有最后一次读取的值才会被真正使用)。

在SGB软件中的使用
除过正常的手柄输入,SGB游戏也复用手柄寄存器来发送SGB命令包给SNES。另外,SGB程序也从接入到SNES,至多四个不同的手柄处读取游戏手柄状态。
详情在SGB描述一节。

INT 60 - 手柄中断
当上述任何一个输入线从高位变成低位时,会请求一个手柄中断。通常情况下,这应该发生在按键被按下之时(之前按钮键/方向键已通过上述的比特位4/5启用)。然而由于开关弹跳,按下或释放按键时,高位到低位的转变会发生一次或数次。

使用手柄中断
对于程序员来说并没什么用处,就算同时按下按钮键和方向键它依然无法识别出所有按键操作。因为有可能某比特位已被别的按键置低位,这个时候再按下相关方向键就不会有什么区别。按键操作中断唯一有用的地方是终止STOP (低功耗)待机状态。
另外,手柄中断在CGB和GBA硬件下不工作(但STOP功能依然可被按键操作终止)


 Serial Data Transfer (Link Cable)

FF01 - SB - Serial transfer data (R/W)
8 Bits of data to be read/written

FF02 - SC - Serial Transfer Control (R/W)
  Bit 7 - Transfer Start Flag (0=No Transfer, 1=Start)
  Bit 1 - Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only **
  Bit 0 - Shift Clock (0=External Clock, 1=Internal Clock)
The clock signal specifies the rate at which the eight data bits in SB (FF01) are transferred. When the gameboy is communicating with another gameboy (or other computer) then either one must supply internal clock, and the other one must use external clock.

Internal Clock
In Non-CGB Mode the gameboy supplies an internal clock of 8192Hz only (allowing to transfer about 1 KByte per second). In CGB Mode four internal clock rates are available, depending on Bit 1 of the SC register, and on whether the CGB Double Speed Mode is used:
    8192Hz -  1KB/s - Bit 1 cleared, Normal
   16384Hz -  2KB/s - Bit 1 cleared, Double Speed Mode
  262144Hz - 32KB/s - Bit 1 set,     Normal
  524288Hz - 64KB/s - Bit 1 set,     Double Speed Mode

External Clock
The external clock is typically supplied by another gameboy, but might be supplied by another computer (for example if connected to a PCs parallel port), in that case the external clock may have any speed. Even the old/monochrome gameboy is reported to recognizes external clocks of up to 500KHz. And there is no limitiation into the other direction - even when suppling an external clock speed of "1 bit per month", then the gameboy will still eagerly wait for the next bit(s) to be transferred. It isn't required that the clock pulses are sent at an regular interval either.

Timeouts
When using external clock then the transfer will not complete until the last bit is received. In case that the second gameboy isn't supplying a clock signal, if it gets turned off, or if there is no second gameboy connected at all) then transfer will never complete. For this reason the transfer procedure should use a timeout counter, and abort the communication if no response has been received during the timeout interval.

Delays and Synchronization
The gameboy that is using internal clock should always execute a small delay between each transfer, in order to ensure that the opponent gameboy has enough time to prepare itself for the next transfer, ie. the gameboy with external clock must have set its transfer start bit before the gameboy with internal clock starts the transfer. Alternately, the two gameboys could switch between internal and external clock for each transferred byte to ensure synchronization.

Transfer is initiated by setting the Transfer Start Flag. This bit is automatically set to 0 at the end of Transfer. Reading this bit can be used to determine if the transfer is still active.

INT 58 - Serial Interrupt
When the transfer has completed (ie. after sending/receiving 8 bits, if any) then an interrupt is requested by setting Bit 3 of the IF Register (FF0F). When that interrupt is enabled, then the Serial Interrupt vector at 0058 is called.

XXXXXX...

Transmitting and receiving serial data is done simultaneously. The received data is automatically stored in SB.

The serial I/O port on the Gameboy is a very simple setup and is crude compared to standard RS-232 (IBM-PC) or RS-485 (Macintosh) serial ports. There are no start or stop bits.

During a transfer, a byte is shifted in at the same time that a byte is shifted out. The rate of the shift is determined by whether the clock source is internal or external.
The most significant bit is shifted in and out first.

When the internal clock is selected, it drives the clock pin on the game link port and it stays high when not used. During a transfer it will go low eight times to clock in/out each bit.

The state of the last bit shifted out determines the state of the output line until another transfer takes place.

If a serial transfer with internal clock is performed and no external GameBoy is present, a value of $FF will be received in the transfer.

The following code causes $75 to be shifted out the serial port and a byte to be shifted into $FF01:

    ld   a,$75
    ld  ($FF01),a
    ld   a,$81
    ld  ($FF02),a


 定时与分频寄存器

FF04 - DIV - 分频寄存器 (读/写)
该寄存器以16384Hz为单位而递增(SGB上约为16779Hz)。 在CGB双倍速模式下,它以两倍速递增,即32768Hz。 向该寄存器写入任意值都会将其重置为00h。

FF05 - TIMA - 定时计数器 (读/写)
该寄存器以TAC寄存器($FF07)指定的时钟频率递增。 当发生溢出时(递增到比FFh还要大),它将重置为TMA(FF06)指定的值,并请求一个如后文描述的中断。

FF06 - TMA - 定时器模除(读/写)
当TIMA溢出时,该数据将被载入。(载入到TIMA中,译注)

FF07 - TAC - 定时器控制 (R/W)
  比特位 2    - 定时器停止  (0=停止, 1=开始)
  比特位 1-0 - 输入时钟选择
             00:   4096 Hz    (~4194 Hz SGB)
             01: 262144 Hz  (~268400 Hz SGB)
             10:  65536 Hz   (~67110 Hz SGB)
             11:  16384 Hz   (~16780 Hz SGB)

INT 50 - 定时器中断
当定时器溢出时, (如,TIMA递增到比FFh还要大),就会通过将IF寄存器(FF0F)的比特位2置为1请求一个中断。若该中断已启用,那么CPU将调用位于0050h的定时器中断向量来执行中断程序。

注意
上述定时器指的是Gameboy内建的定时器。它和MBC3型卡带的电池驱动真实时钟(RTC)无关。实际上,RTC是一个完全不同的东西,将会在存储容组控制器(MBC)一章中讲到。(bank暂译为容组,译注)


 中断

IME - 全局中断使能标志 (只写)
  0 - Disable all Interrupts
  1 - Enable all Interrupts that are enabled in IE Register (FFFF)
The IME flag is used to disable all interrupts, overriding any enabled bits in the IE Register. It isn't possible to access the IME flag by using a I/O address, instead IME is accessed directly from the CPU, by the following opcodes/operations:
  EI     ;Enable Interrupts  (ie. IME=1)
  DI     ;Disable Interrupts (ie. IME=0)
  RETI   ;Enable Ints & Return (same as the opcode combination EI, RET)
  <INT>  ;Disable Ints & Call to Interrupt Vector
Whereas <INT> means the operation which is automatically executed by the CPU when it executes an interrupt.

FFFF - IE - 中断使能 (读/写)
  Bit 0: V-Blank  Interrupt Enable  (INT 40h)  (1=Enable)
  Bit 1: LCD STAT Interrupt Enable  (INT 48h)  (1=Enable)
  Bit 2: Timer    Interrupt Enable  (INT 50h)  (1=Enable)
  Bit 3: Serial   Interrupt Enable  (INT 58h)  (1=Enable)
  Bit 4: Joypad   Interrupt Enable  (INT 60h)  (1=Enable)

FF0F - IF - 中断标识 (读/写)
  Bit 0: V-Blank  Interrupt Request (INT 40h)  (1=Request)
  Bit 1: LCD STAT Interrupt Request (INT 48h)  (1=Request)
  Bit 2: Timer    Interrupt Request (INT 50h)  (1=Request)
  Bit 3: Serial   Interrupt Request (INT 58h)  (1=Request)
  Bit 4: Joypad   Interrupt Request (INT 60h)  (1=Request)
When an interrupt signal changes from low to high, then the corresponding bit in the IF register becomes set. For example, Bit 0 becomes set when the LCD controller enters into the V-Blank period.

中断请求
Any set bits in the IF register are only <requesting> an interrupt to be executed. The actual <execution> happens only if both the IME flag, and the corresponding bit in the IE register are set, otherwise the interrupt 'waits' until both IME and IE allow its execution.

中断执行
When an interrupt gets executed, the corresponding bit in the IF register becomes automatically reset by the CPU, and the IME flag becomes cleared (disabeling any further interrupts until the program re-enables the interrupts, typically by using the RETI instruction), and the corresponding Interrupt Vector (that are the addresses in range 0040h-0060h, as shown in IE and IF register decriptions above) becomes called.

手动请求/放弃中断
As the CPU automatically sets and cleares the bits in the IF register it is usually not required to write to the IF register. However, the user may still do that in order to manually request (or discard) interrupts. As for real interrupts, a manually requested interrupt isn't executed unless/until IME and IE allow its execution.

中断优先级
In the following three situations it might happen that more than 1 bit in the IF register are set, requesting more than one interrupt at once:
  1) More than one interrupt signal changed from Low
     to High at the same time.
  2) Several interrupts have been requested during a
     time in which IME/IE didn't allow these interrupts
     to be executed directly.
  3) The user has written a value with several "1" bits
     (for example 1Fh) to the IF register.
Provided that IME and IE allow the execution of more than one of the requested interrupts, then the interrupt with the highest priority becomes executed first. The priorities are ordered as the bits in the IE and IF registers, Bit 0 (V-Blank) having the highest priority, and Bit 4 (Joypad) having the lowest priority.

中断嵌套
The CPU automatically disables all other interrupts by setting IME=0 when it executes an interrupt. Usually IME remains zero until the interrupt procedure returns (and sets IME=1 by the RETI instruction). However, if you want any other interrupts of lower or higher (or same) priority to be allowed to be executed from inside of the interrupt procedure, then you can place an EI instruction into the interrupt procedure.


 CGB Registers

Forward
This chapter describes only CGB (Color Gameboy) registers that didn't fit into normal categories - most CGB registers are described in the chapter about Video Display (Color Palettes, VRAM Bank, VRAM DMA Transfers, and changed meaning of Bit 0 of LCDC Control register). Also, a changed bit is noted in the chapter about the Serial/Link port.

Unlocking CGB functions
When using any CGB registers (including those in the Video/Link chapters), you must first unlock CGB features by changing byte 0143h in the cartridge header. Typically use a value of 80h for games which support both CGB and monochrome gameboys, and C0h for games which work on CGBs only. Otherwise, the CGB will operate in monochrome "Non CGB" compatibility mode.

Detecting CGB (and GBA) functions
CGB hardware can be detected by examing the CPU accumulator (A-register) directly after startup. A value of 11h indicates CGB (or GBA) hardware, if so, CGB functions can be used (if unlocked, see above).
When A=11h, you may also examine Bit 0 of the CPUs B-Register to separate between CGB (bit cleared) and GBA (bit set), by that detection it is possible to use 'repaired' color palette data matching for GBA displays.

FF4D - KEY1 - CGB Mode Only - Prepare Speed Switch
  Bit 7: Current Speed     (0=Normal, 1=Double) (Read Only)
  Bit 0: Prepare Speed Switch (0=No, 1=Prepare) (Read/Write)
This register is used to prepare the gameboy to switch between CGB Double Speed Mode and Normal Speed Mode. The actual speed switch is performed by executing a STOP command after Bit 0 has been set. After that Bit 0 will be cleared automatically, and the gameboy will operate at the 'other' speed. The recommended speed switching procedure in pseudo code would be:
  IF KEY1_BIT7 <> DESIRED_SPEED THEN
    IE=00H       ;(FFFF)=00h
    JOYP=30H     ;(FF00)=30h
    KEY1=01H     ;(FF4D)=01h
    STOP         ;STOP
  ENDIF
The CGB is operating in Normal Speed Mode when it is turned on. Note that using the Double Speed Mode increases the power consumption, it would be recommended to use Single Speed whenever possible. However, the display will flicker (white) for a moment during speed switches, so this cannot be done permanentely.
In Double Speed Mode the following will operate twice as fast as normal:
  The CPU (2.10 MHz, 1 Cycle = approx. 0.5us)
  Timer and Divider Registers
  Serial Port (Link Cable)
  DMA Transfer to OAM
And the following will keep operating as usual:
  LCD Video Controller
  HDMA Transfer to VRAM
  All Sound Timings and Frequencies

FF56 - RP - CGB Mode Only - Infrared Communications Port
This register allows to input and output data through the CGBs built-in Infrared Port. When reading data, bit 6 and 7 must be set (and obviously Bit 0 must be cleared - if you don't want to receive your own gameboys IR signal). After sending or receiving data you should reset the register to 00h to reduce battery power consumption again.
  Bit 0:   Write Data   (0=LED Off, 1=LED On)             (Read/Write)
  Bit 1:   Read Data    (0=Receiving IR Signal, 1=Normal) (Read Only)
  Bit 6-7: Data Read Enable (0=Disable, 3=Enable)         (Read/Write)
Note that the receiver will adapt itself to the normal level of IR pollution in the air, so if you would send a LED ON signal for a longer period, then the receiver would treat that as normal (=OFF) after a while. For example, a Philips TV Remote Control sends a series of 32 LED ON/OFF pulses (length 10us ON, 17.5us OFF each) instead of a permanent 880us LED ON signal.
Even though being generally CGB compatible, the GBA does not include an infra-red port.

FF70 - SVBK - CGB Mode Only - WRAM Bank
In CGB Mode 32 KBytes internal RAM are available. This memory is divided into 8 banks of 4 KBytes each. Bank 0 is always available in memory at C000-CFFF, Bank 1-7 can be selected into the address space at D000-DFFF.
  Bit 0-2  Select WRAM Bank (Read/Write)
Writing a value of 01h-07h will select Bank 1-7, writing a value of 00h will select Bank 1 either.

FF6C - Undocumented (FEh) - Bit 0 (Read/Write) - CGB Mode Only
FF72 - Undocumented (00h) - Bit 0-7 (Read/Write)
FF73 - Undocumented (00h) - Bit 0-7 (Read/Write)
FF74 - Undocumented (00h) - Bit 0-7 (Read/Write) - CGB Mode Only
FF75 - Undocumented (8Fh) - Bit 4-6 (Read/Write)
FF76 - Undocumented (00h) - Always 00h (Read Only)
FF77 - Undocumented (00h) - Always 00h (Read Only)
These are undocumented CGB Registers. The numbers in brackets () indicate the initial values. Purpose of these registers is unknown (if any). Registers FF6C and FF74 are always FFh if the CGB is in Non CGB Mode.


 SGB Functions

General Information
SGB Description
SGB Unlocking and Detecting SGB Functions
SGB Command Packet Transfers
SGB VRAM Transfers
SGB Command Summary
SGB Color Palettes Overview

SGB Commands
SGB Palette Commands
SGB Color Attribute Commands
SGB Sound Functions
SGB System Control Commands
SGB Multiplayer Command
SGB Border and OBJ Commands


 SGB Description

General Description
Basically, the SGB (Super Gameboy) is an adapter cartridge that allows to play gameboy games on a SNES (Super Nintendo Entertainment System) gaming console. In detail, you plug the gameboy cartridge into the SGB cartridge, then plug the SGB cartridge into the SNES, and then connect the SNES to your TV Set. In result, games can be played and viewed on the TV Set, and are controlled by using the SNES joypad(s).

More Technical Description
The SGB cartridge just contains a normal gameboy CPU and normal gameboy video controller. Normally the video signal from this controller would be sent to the LCD screen, however, in this special case the SNES read out the video signal and displays it on the TV set by using a special SNES BIOS ROM which is located in the SGB cartridge. Also, normal gameboy sound output is forwared to the SNES and output to the TV Set, vice versa, joypad input is forwared from the SNES controller(s) to the gameboy joypad inputs.

Normal Monochrome Games
Any gameboy games which have been designed for normal monochrome handheld gameboys will work with the SGB hardware as well. The SGB will apply a four color palette to these games by replacing the normal four grayshades. The 160x144 pixel gamescreen is displayed in the middle of the 256x224 pixel SNES screen (the unused area is filled by a screen border bitmap). The user may access built-in menues, allowing to change color palette data, to select between several pre-defined borders, etc.

Games that have been designed to support SGB functions may also access the following additional features:

Colorized Game Screen
There's limited ability to colorize the gamescreen by assigning custom color palettes to each 20x18 display characters, however, this works mainly for static display data such like title screens or status bars, the 20x18 color attribute map is non-scrollable, and it is not possible to assign separate colors to moveable foreground sprites (OBJs), so that animated screen regions will be typically restricted to using a single palette of four colors only.

SNES Foreground Sprites
Up to 24 foreground sprites (OBJs) of 8x8 or 16x16 pixels, 16 colors can be displayed. When replacing (or just overlaying) the normal gameboy OBJs by SNES OBJs it'd be thus possible to display OBJs with other colors than normal background area. This method doesn't appear to be very popular, even though it appears to be quite easy to implement, however, the bottommost character line of the gamescreen will be masked out because this area is used to transfer OAM data to the SNES.

The SGB Border
The possibly most popular and most impressive feature is to replace the default SGB screen border by a custom bitmap which is stored in the game cartridge.

Multiple Joypads
Up to four joypads can be conected to the SNES, and SGB software may read-out each of these joypads separately, allowing up to four players to play the same game simultaneously. Unlike for multiplayer handheld games, this requires only one game cartridge and only one SGB/SNES, and no link cables are required, the downside is that all players must share the same display screen.

Sound Functions
Beside for normal gameboy sound, a number of digital sound effects is pre-defined in the SNES BIOS, these effects may be accessed quite easily. Programmers whom are familiar with SNES sounds may also access the SNES sound chip, or use the SNES MIDI engine directly in order to produce other sound effects or music.

Taking Control of the SNES CPU
Finally, it is possible to write program code or data into SNES memory, and to execute such program code by using the SNES CPU.

SGB System Clock
Because the SGB is synchronized to the SNES CPU, the gameboy system clock is directly chained to the SNES system clock. In result, the gameboy CPU, video controller, timers, and sound frequencies will be all operated approx 2.4% faster as by normal gameboys.
Basically, this should be no problem, and the game will just run a little bit faster. However sensitive musicians may notice that sound frequencies are a bit too high, programs that support SGB functions may avoid this effect by reducing frequencies of gameboy sounds when having detected SGB hardware.
Also, I think that I've heard that SNES models which use a 50Hz display refresh rate (rather than 60Hz) are resulting in respectively slower SGB/gameboy timings ???


 SGB Unlocking and Detecting SGB Functions

Cartridge Header
SGB games are required to have a cartridge header with Nintendo and proper checksum just as normal gameboy games. Also, two special entries must be set in order to unlock SGB functions:
  146h - SGB Flag - Must be set to 03h for SGB games
  14Bh - Old Licensee Code - Must be set 33h for SGB games
When these entries aren't set, the game will still work just like all 'monochrome' gameboy games, but it cannot access any of the special SGB functions.

Detecting SGB hardware
The recommended detection method is to send a MLT_REQ command which enables two (or four) joypads. A normal handheld gameboy will ignore this command, a SGB will now return incrementing joypad IDs each time when deselecting keyboard lines (see MLT_REQ description for details).
Now read-out joypad state/IDs several times, and if the ID-numbers are changing, then it is a SGB (a normal gameboy would typically always return 0Fh as ID). Finally, when not intending to use more than one joypad, send another MLT_REQ command in order to re-disable the multi-controller mode.
Detection works regardless of whether and how many joypads are physically connected to the SNES. However, detection works only when having unlocked SGB functions in the cartridge header, as described above.

Separating between SGB and SGB2
It is also possible to separate between SGB and SGB2 models by examining the inital value of the accumulator (A-register) directly after startup.
  01h  SGB or Normal Gameboy (DMG)
  FFh  SGB2 or Pocket Gameboy
  11h  CGB or GBA
Because values 01h and FFh are shared for both handhelds and SGBs, it is still required to use the above MLT_REQ detection procedure. As far as I know the SGB2 doesn't have any extra features which'd require separate SGB2 detection except for curiosity purposes, for example, the game "Tetris DX" chooses to display an alternate SGB border on SGB2s.

Reportedly, some SGB models include link ports (just like handheld gameboy) (my own SGB does not have such an port), possibly this feature is available in SGB2-type models only ???


 SGB Command Packet Transfers

Command packets (aka Register Files) are transferred from the gameboy to the SNES by using P14 and P15 output lines of the JOYPAD register (FF00h), these lines are normally used to select the two rows in the gameboy keyboard matrix (which still works).

Transferring Bits
A command packet transfer must be initiated by setting both P14 and P15 to LOW, this will reset and start the SNES packet receiving program. Data is then transferred (LSB first), setting P14=LOW will indicate a "0" bit, and setting P15=LOW will indicate a "1" bit. For example:
       RESET 0   0   1   1   0   1   0
  P14  --_---_---_-----------_-------_--...
  P15  --_-----------_---_-------_------...
Data and reset pulses must be kept LOW for at least 5us. P14 and P15 must be kept both HIGH for at least 15us between any pulses.
Obviously, it'd be no good idea to access the JOYPAD register during the transfer, for example, in case that your VBlank interrupt procedure reads-out joypad states each frame, be sure to disable that interrupt during the transfer (or disable only the joypad procedure by using a software flag).

Transferring Packets
Each packet is invoked by a RESET pulse, then 128 bits of data are transferred (16 bytes, LSB of first byte first), and finally, a "0"-bit must be transferred as stop bit. The structure of normal packets is:
   1 PULSE Reset
   1 BYTE  Command Code*8+Length
  15 BYTES Parameter Data
   1 BIT   Stop Bit (0)
The above 'Length' indicates the total number of packets (1-7, including the first packet) which will be sent, ie. if more than 15 parameter bytes are used, then further packet(s) will follow, as such:
   1 PULSE Reset
  16 BYTES Parameter Data
   1 BIT   Stop Bit (0)
By using all 7 packets, up to 111 data bytes (15+16*6) may be sent.
Unused bytes at the end of the last packet must be set to zero.
A 60ms (4 frames) delay should be invoked between each packet transfer.


 SGB VRAM Transfers

Overview
Beside for the packet transfer method, larger data blocks of 4KBytes can be transferred by using the video signal. These transfers are invoked by first sending one of the commands with the ending _TRN (by using normal packet transfer), the 4K data block is then read-out by the SNES from gameboy display memory during the next frame.

Transfer Data
Normally, transfer data should be stored at 8000h-8FFFh in gameboy VRAM,
even though the SNES receives the data in from display scanlines, it will automatically re-produce the same ordering of bits and bytes, as being originally stored at 8000h-8FFFh in gameboy memory.

Preparing the Display
The above method works only when recursing the following things: BG Map must display unsigned characters 00h-FFh on the screen; 00h..13h in first line, 14h..27h in next line, etc. The gameboy display must be enabled, the display may not be scrolled, OBJ sprites should not overlap the background tiles, the BGP palette register must be set to E4h.

Transfer Time
Note that the transfer data should be prepared in VRAM <before> sending the transfer command packet. The actual transfer starts at the beginning of the next frame after the command has been sent, and the transfer ends at the end of the 5th frame after the command has been sent (not counting the frame in which the command has been sent).

Avoiding Screen Garbage
The display will contain 'garbage' during the transfer, this dirt-effect can be avoided by freezing the screen (in the state which has been displayed before the transfer) by using the MASK_EN command.
Of course, this works only when actually executing the game on a SGB (and not on normal handheld gameboys), it'd be thus required to detect the presence of SGB hardware before blindly sending VRAM data.


 SGB Command Summary

SGB System Command Table
  Code Name      Expl.
  00   PAL01     Set SGB Palette 0,1 Data
  01   PAL23     Set SGB Palette 2,3 Data
  02   PAL03     Set SGB Palette 0,3 Data
  03   PAL12     Set SGB Palette 1,2 Data
  04   ATTR_BLK  "Block" Area Designation Mode
  05   ATTR_LIN  "Line" Area Designation Mode
  06   ATTR_DIV  "Divide" Area Designation Mode
  07   ATTR_CHR  "1CHR" Area Designation Mode
  08   SOUND     Sound On/Off
  09   SOU_TRN   Transfer Sound PRG/DATA
  0A   PAL_SET   Set SGB Palette Indirect
  0B   PAL_TRN   Set System Color Palette Data
  0C   ATRC_EN   Enable/disable Attraction Mode
  0D   TEST_EN   Speed Function
  0E   ICON_EN   SGB Function
  0F   DATA_SND  SUPER NES WRAM Transfer 1
  10   DATA_TRN  SUPER NES WRAM Transfer 2
  11   MLT_REG   Controller 2 Request
  12   JUMP      Set SNES Program Counter
  13   CHR_TRN   Transfer Character Font Data
  14   PCT_TRN   Set Screen Data Color Data
  15   ATTR_TRN  Set Attribute from ATF
  16   ATTR_SET  Set Data to ATF
  17   MASK_EN   Game Boy Window Mask
  18   OBJ_TRN   Super NES OBJ Mode


 SGB Color Palettes Overview

Available SNES Palettes
The SGB/SNES provides 8 palettes of 16 colors each, each color may be defined out of a selection of 34768 colors (15 bit). Palettes 0-3 are used to colorize the gamescreen, only the first four colors of each of these palettes are used. Palettes 4-7 are used for the SGB Border, all 16 colors of each of these palettes may be used.

Color 0 Restriction
Color 0 of each of the eight palettes is transparent, causing the backdrop color to be displayed instead. The backdrop color is typically defined by the most recently color being assigned to Color 0 (regardless of the palette number being used for that operation).
Effectively, gamescreen palettes can have only three custom colors each, and SGB border palettes only 15 colors each, additionally, color 0 can be used for for all palettes, which will then all share the same color though.

Translation of Grayshades into Colors
Because the SGB/SNES reads out the gameboy video controllers display signal, it translates the different grayshades from the signal into SNES colors as such:
  White       -->  Color 0
  Light Gray  -->  Color 1
  Dark Gray   -->  Color 2
  Black       -->  Color 3
Note that gameboy colors 0-3 are assigned to user-selectable grayshades by the gameboys BGP, OBP1, and OBP2 registers. There is thus no fixed relationship between gameboy colors 0-3 and SNES colors 0-3.

Using Gameboy BGP/OBP Registers
A direct translation of color 0-3 into color 0-3 may be produced by setting BGP/OBP registers to a value of 0E4h each. However, in case that your program uses black background for example, then you may internally assign background as "White" at the gameboy side by BGP/OBP registers (which is then interpreted as SNES color 0, which is shared for all SNES palettes). The advantage is that you may define Color 0 as Black at the SNES side, and may assign custom colors for Colors 1-3 of each SNES palette.

System Color Palette Memory
Beside for the actually visible palettes, up to 512 palettes of 4 colors each may be defined in SNES RAM. Basically, this is completely irrelevant because the palettes are just stored in RAM whithout any relationship to the displayed picture, anyways, these pre-defined colors may be transferred to actually visible palettes slightly faster as when transferring palette data by separate command packets.


 SGB Palette Commands

SGB Command 00h - PAL01
Transmit color data for SGB palette 0, color 0-3, and for SGB palette 1, color 1-3 (without separate color 0).
  Byte  Content
  0     Command*8+Length (fixed length=01h)
  1-E   Color Data for 7 colors of 2 bytes (16bit) each:
          Bit 0-4   - Red Intensity   (0-31)
          Bit 5-9   - Green Intensity (0-31)
          Bit 10-14 - Blue Intensity  (0-31)
          Bit 15    - Not used (zero)
  F     Not used (00h)
The value transferred as color 0 will be applied for all eight palettes.

SGB Command 01h - PAL23
Same as above PAL01, but for Palettes 2 and 3 respectively.

SGB Command 02h - PAL03
Same as above PAL01, but for Palettes 0 and 3 respectively.

SGB Command 03h - PAL12
Same as above PAL01, but for Palettes 1 and 2 respectively.

SGB Command 0Ah - PAL_SET
Used to copy pre-defined palette data from SGB system color palette to actual SGB palette.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-2   System Palette number for SGB Color Palette 0 (0-511)
  3-4   System Palette number for SGB Color Palette 1 (0-511)
  5-6   System Palette number for SGB Color Palette 2 (0-511)
  7-8   System Palette number for SGB Color Palette 3 (0-511)
  9     Attribute File
          Bit 0-5 - Attribute File Number (00h-2Ch) (Used only if Bit7=1)
          Bit 6   - Cancel Mask           (0=No change, 1=Yes)
          Bit 7   - Use Attribute File    (0=No, 1=Apply above ATF Number)
  A-F   Not used (zero)
Before using this function, System Palette data should be initialized by PAL_TRN command, and (when used) Attribute File data should be initialized by ATTR_TRN.

SGB Command 0Bh - PAL_TRN
Used to initialize SGB system color palettes in SNES RAM.
System color palette memory contains 512 pre-defined palettes, these palettes do not directly affect the display, however, the PAL_SET command may be later used to transfer four of these 'logical' palettes to actual visible 'physical' SGB palettes. Also, the OBJ_TRN function will use groups of 4 System Color Palettes (4*4 colors) for SNES OBJ palettes (16 colors).
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-F   Not used (zero)
The palette data is sent by VRAM-Transfer (4 KBytes).
  000-FFF  Data for System Color Palette 0-511
Each Palette consists of four 16bit-color definitions (8 bytes).
Note: The data is stored at 3000h-3FFFh in SNES memory.


 SGB Color Attribute Commands

SGB Command 04h - ATTR_BLK
Used to specify color attributes for the inside or outside of one or more rectangular screen regions.
  Byte  Content
  0     Command*8+Length (length=1..7)
  1     Number of Data Sets (01h..12h)
  2-7   Data Set #1
          Byte 0 - Control Code (0-7)
            Bit 0 - Change Colors inside of surrounded area     (1=Yes)
            Bit 1 - Change Colors of surrounding character line (1=Yes)
            Bit 2 - Change Colors outside of surrounded area    (1=Yes)
            Bit 3-7 - Not used (zero)
            Exception: When changing only the Inside or Outside, then the
            Surrounding line becomes automatically changed to same color.
          Byte 1 - Color Palette Designation
            Bit 0-1 - Palette Number for inside of surrounded area
            Bit 2-3 - Palette Number for surrounding character line
            Bit 4-5 - Palette Number for outside of surrounded area
            Bit 6-7 - Not used (zero)
          Data Set Byte 2 - Coordinate X1 (left)
          Data Set Byte 3 - Coordinate Y1 (upper)
          Data Set Byte 4 - Coordinate X2 (right)
          Data Set Byte 5 - Coordinate Y2 (lower)
            Specifies the coordinates of the surrounding rectangle.
  8-D   Data Set #2 (if any)
  E-F   Data Set #3 (continued at 0-3 in next packet) (if any)
When sending three or more data sets, data is continued in further packet(s). Unused bytes at the end of the last packet should be set to zero. The format of the separate Data Sets is described below.

SGB Command 05h - ATTR_LIN
Used to specify color attributes of one or more horizontal or vertical character lines.
  Byte  Content
  0     Command*8+Length (length=1..7)
  1     Number of Data Sets (01h..6Eh) (one byte each)
  2     Data Set #1
          Bit 0-4 - Line Number    (X- or Y-coordinate, depending on bit 7)
          Bit 5-6 - Palette Number (0-3)
          Bit 7   - H/V Mode Bit   (0=Vertical line, 1=Horizontal Line)
  3     Data Set #2 (if any)
  4     Data Set #3 (if any)
  etc.
When sending 15 or more data sets, data is continued in further packet(s). Unused bytes at the end of the last packet should be set to zero. The format of the separate Data Sets (one byte each) is described below.
The length of each line reaches from one end of the screen to the other end. In case that some lines overlap each other, then lines from lastmost data sets will overwrite lines from previous data sets.

SGB Command 06h - ATTR_DIV
Used to split the screen into two halfes, and to assign separate color attributes to each half, and to the division line between them.
  Byte  Content
  0     Command*8+Length   (fixed length=1)
  1     Color Palette Numbers and H/V Mode Bit
          Bit 0-1  Palette Number below/right of division line
          Bit 2-3  Palette Number above/left of division line
          Bit 4-5  Palette Number for division line
          Bit 6    H/V Mode Bit  (0=split left/right, 1=split above/below)
  2     X- or Y-Coordinate (depending on H/V bit)
  3-F   Not used (zero)

SGB Command 07h - ATTR_CHR
Used to specify color attributes for separate characters.
  Byte  Content
  0     Command*8+Length (length=1..6)
  1     Beginning X-Coordinate
  2     Beginning Y-Coordinate
  3-4   Number of Data Sets (1-360)
  5     Writing Style   (0=Left to Right, 1=Top to Bottom)
  6     Data Sets 1-4   (Set 1 in MSBs, Set 4 in LSBs)
  7     Data Sets 5-8   (if any)
  8     Data Sets 9-12  (if any)
  etc.
When sending 41 or more data sets, data is continued in further packet(s). Unused bytes at the end of the last packet should be set to zero. Each data set consists of two bits, indicating the palette number for one character.
Depending on the writing style, data sets are written from left to right, or from top to bottom. In either case the function wraps to the next row/column when reaching the end of the screen.

SGB Command 15h - ATTR_TRN
Used to initialize Attribute Files (ATFs) in SNES RAM. Each ATF consists of 20x18 color attributes for the gameboy screen. This function does not directly affect display attributes. Instead, one of the defined ATFs may be copied to actual display memory at a later time by using ATTR_SET or PAL_SET functions.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-F   Not used (zero)
The ATF data is sent by VRAM-Transfer (4 KBytes).
  000-FD1  Data for ATF0 through ATF44 (4050 bytes)
  FD2-FFF  Not used
Each ATF consists of 90 bytes, that are 5 bytes (20x2bits) for each of the 18 character lines of the gameboy window. The two most significant bits of the first byte define the color attribute (0-3) for the first character of the first line, the next two bits the next character, and so on.

SGB Command 16h - ATTR_SET
Used to transfer attributes from Attribute File (ATF) to gameboy window.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1     Attribute File Number (00-2Ch), Bit 6=Cancel Mask
  2-F   Not used (zero)
When above Bit 6 is set, the gameboy screen becomes re-enabled after the transfer (in case it has been disabled/frozen by MASK_EN command).
Note: The same functions may be (optionally) also included in PAL_SET commands, as described in the chapter about Color Palette Commands.


 SGB Sound Functions

SGB Command 08h - SOUND
Used to start/stop internal sound effect, start/stop sound using internal tone data.
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1     Sound Effect A (Port 1) Decrescendo 8bit Sound Code
  2     Sound Effect B (Port 2) Sustain     8bit Sound Code
  3     Sound Effect Attributes
          Bit 0-1 - Sound Effect A Pitch  (0..3=Low..High)
          Bit 2-3 - Sound Effect A Volume (0..2=High..Low, 3=Mute on)
          Bit 4-5 - Sound Effect B Pitch  (0..3=Low..High)
          Bit 6-7 - Sound Effect B Volume (0..2=High..Low, 3=Not used)
  4     Music Score Code (must be zero if not used)
  5-F   Not used (zero)
See Sound Effect Tables below for a list of available pre-defined effects.
"Notes"
1) Mute is only active when both bits D2 and D3 are 1.
2) When the volume is set for either Sound Effect A or Sound Effect B, mute is turned off.
3) When Mute on/off has been executed, the sound fades out/fades in.
4) Mute on/off operates on the (BGM) which is reproduced by Sound Effect A, Sound Effect B, and the Super NES APU. A "mute off" flag does not exist by itself. When mute flag is set, volume and pitch of Sound Effect A (port 1) and Sound Effect B (port 2) must be set.

SGB Command 09h - SOU_TRN
Used to transfer sound code or data to SNES Audio Processing Unit memory (APU-RAM).
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1-F   Not used (zero)
The sound code/data is sent by VRAM-Transfer (4 KBytes).
  000      One (or two ???) 16bit expression(s ???) indicating the
           transfer destination address and transfer length.
  ...-...  Transfer Data
  ...-FFF  Remaining bytes not used
Possible destinations in APU-RAM are:
  0400h-2AFFh  APU-RAM Program Area (9.75KBytes)
  2B00h-4AFFh  APU-RAM Sound Score Area (8Kbytes)
  4DB0h-EEFFh  APU-RAM Sampling Data Area (40.25 Kbytes)
This function may be used to take control of the SNES sound chip, and/or to access the SNES MIDI engine. In either case it requires deeper knowledge of SNES sound programming.

SGB Sound Effect A/B Tables
Below lists the digital sound effects that are pre-defined in the SGB/SNES BIOS, and which can be used with the SGB "SOUND" Command.
Effect A and B may be simultaneously reproduced.
The P-column indicates the recommended Pitch value, the V-column indicates the numbers of Voices used. Sound Effect A uses voices 6,7. Sound Effect B uses voices 0,1,4,5. Effects that use less voices will use only the upper voices (eg. 4,5 for Effect B with only two voices).

Sound Effect A Flag Table
  Code Description             P V     Code Description             P V
  00  Dummy flag, re-trigger   - 2     18  Fast Jump                3 1
  80  Effect A, stop/silent    - 2     19  Jet (rocket) takeoff     0 1
  01  Nintendo                 3 1     1A  Jet (rocket) landing     0 1
  02  Game Over                3 2     1B  Cup breaking             2 2
  03  Drop                     3 1     1C  Glass breaking           1 2
  04  OK ... A                 3 2     1D  Level UP                 2 2
  05  OK ... B                 3 2     1E  Insert air               1 1
  06  Select...A               3 2     1F  Sword swing              1 1
  07  Select...B               3 1     20  Water falling            2 1
  08  Select...C               2 2     21  Fire                     1 1
  09  Mistake...Buzzer         2 1     22  Wall collapsing          1 2
  0A  Catch Item               2 2     23  Cancel                   1 2
  0B  Gate squeaks 1 time      2 2     24  Walking                  1 2
  0C  Explosion...small        1 2     25  Blocking strike          1 2
  0D  Explosion...medium       1 2     26  Picture floats on & off  3 2
  0E  Explosion...large        1 2     27  Fade in                  0 2
  0F  Attacked...A             3 1     28  Fade out                 0 2
  10  Attacked...B             3 2     29  Window being opened      1 2
  11  Hit (punch)...A          0 2     2A  Window being closed      0 2
  12  Hit (punch)...B          0 2     2B  Big Laser                3 2
  13  Breath in air            3 2     2C  Stone gate closes/opens  0 2
  14  Rocket Projectile...A    3 2     2D  Teleportation            3 1
  15  Rocket Projectile...B    3 2     2E  Lightning                0 2
  16  Escaping Bubble          2 1     2F  Earthquake               0 2
  17  Jump                     3 1     30  Small Laser              2 2
Sound effect A is used for formanto sounds (percussion sounds).

Sound Effect B Flag Table
  Code Description             P V     Code Description             P V
  00  Dummy flag, re-trigger   - 4     0D  Waterfall                2 2
  80  Effect B, stop/silent    - 4     0E  Small character running  3 1
  01  Applause...small group   2 1     0F  Horse running            3 1
  02  Applause...medium group  2 2     10  Warning sound            1 1
  03  Applause...large group   2 4     11  Approaching car          0 1
  04  Wind                     1 2     12  Jet flying               1 1
  05  Rain                     1 1     13  UFO flying               2 1
  06  Storm                    1 3     14  Electromagnetic waves    0 1
  07  Storm with wind/thunder  2 4     15  Score UP                 3 1
  08  Lightning                0 2     16  Fire                     2 1
  09  Earthquake               0 2     17  Camera shutter, formanto 3 4
  0A  Avalanche                0 2     18  Write, formanto          0 1
  0B  Wave                     0 1     19  Show up title, formanto  0 1
  0C  River                    3 2
Sound effect B is mainly used for looping sounds (sustained sounds).


 SGB System Control Commands

SGB Command 17h - MASK_EN
Used to mask the gameboy window, among others this can be used to freeze the gameboy screen before transferring data through VRAM (the SNES then keeps displaying the gameboy screen, even though VRAM doesn't contain meaningful display information during the transfer).
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1     Gameboy Screen Mask (0-3)
          0  Cancel Mask   (Display activated)
          1  Freeze Screen (Keep displaying current picture)
          2  Blank Screen  (Black)
          3  Blank Screen  (Color 0)
  2-F   Not used (zero)
Freezing works only if the SNES has stored a picture, ie. if necessary wait one or two frames before freezing (rather than freezing directly after having displayed the picture).
The Cancel Mask function may be also invoked (optionally) by completion of PAL_SET and ATTR_SET commands.

SGB Command 0Ch - ATRC_EN
Used to enable/disable Attraction mode. It is totally unclear what an attraction mode is ???, but it is enabled by default.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     Attraction Disable  (0=Enable, 1=Disable)
  2-F   Not used (zero)

SGB Command 0Dh - TEST_EN
Used to enable/disable test mode for "SGB-CPU variable clock speed function". This function is disabled by default.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     Test Mode Enable    (0=Disable, 1=Enable)
  2-F   Not used (zero)
Maybe intended to determine whether SNES operates at 50Hz or 60Hz display refresh rate ??? Possibly result can be read-out from joypad register ???

SGB Command 0Eh - ICON_EN
Used to enable/disable ICON function. Possibly meant to enable/disable SGB/SNES popup menues which might otherwise activated during gameboy game play. By default all functions are enabled (0).
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     Disable Bits
          Bit 0 - Use of SGB-Built-in Color Palettes    (1=Disable)
          Bit 1 - Controller Set-up Screen    (0=Enable, 1=Disable)
          Bit 2 - SGB Register File Transfer (0=Receive, 1=Disable)
          Bit 3-6 - Not used (zero)
  2-F   Not used (zero)
Above Bit 2 will suppress all further packets/commands when set, this might be useful when starting a monochrome game from inside of the SGB-menu of a multi-gamepak which contains a collection of different games.

SGB Command 0Fh - DATA_SND
Used to write one or more bytes directly into SNES Work RAM.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     SNES Destination Address, low
  2     SNES Destination Address, high
  3     SNES Destination Address, bank number
  4     Number of bytes to write (01h-0Bh)
  5     Data Byte #1
  6     Data Byte #2 (if any)
  7     Data Byte #3 (if any)
  etc.
Unused bytes at the end of the packet should be set to zero, this function is restricted to a single packet, so that not more than 11 bytes can be defined at once.
Free Addresses in SNES memory are Bank 0 1800h-1FFFh, Bank 7Fh 0000h-FFFFh.

SGB Command 10h - DATA_TRN
Used to transfer binary code or data directly into SNES RAM.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     SNES Destination Address, low
  2     SNES Destination Address, high
  3     SNES Destination Address, bank number
  4-F   Not used (zero)
The data is sent by VRAM-Transfer (4 KBytes).
  000-FFF  Data
Free Addresses in SNES memory are Bank 0 1800h-1FFFh, Bank 7Fh 0000h-FFFFh. The transfer length is fixed at 4KBytes ???, so that directly writing to the free 2KBytes at 0:1800h would be a not so good idea ???

SGB Command 12h - JUMP
Used to set the SNES program counter to a specified address. Optionally, it may be used to set a new address for the SNES NMI handler, the NMI handler remains unchanged if all bytes 4-6 are zero.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     SNES Program Counter, low
  2     SNES Program Counter, high
  3     SNES Program Counter, bank number
  4     SNES NMI Handler, low
  5     SNES NMI Handler, high
  6     SNES NMI Handler, bank number
  7-F   Not used, zero
Note: The game "Space Invaders 94" uses this function when selecting "Arcade mode" to execute SNES program code which has been previously transferred from the SGB to the SNES. The type of the CPU which is used in the SNES is unknown ???


 SGB Multiplayer Command

SGB Command 11h - MLT_REQ
Used to request multiplayer mode (ie. input from more than one joypad).
Because this function provides feedback from the SGB/SNES to the gameboy program, it is also used to detect SGB hardware.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     Multiplayer Control (0-3) (Bit0=Enable, Bit1=Two/Four Players)
          0 = One player
          1 = Two players
          3 = Four players
  2-F   Not used (zero)
In one player mode, the second joypad (if any) is used for the SGB system program. In two player mode, both joypads are used for the game. Because SNES have only two joypad sockets, four player mode requires an external "Multiplayer 5" adapter.

Reading Multiple Controllers (Joypads)
When having enabled multiple controllers by MLT_REQ, data for each joypad can be read out through JOYPAD register (FF00) as follows: First set P14 and P15 both HIGH (deselect both Buttons and Cursor keys), you can now read the lower 4bits of FF00 which indicate the joypad ID for the following joypad input:
  0Fh  Joypad 1
  0Eh  Joypad 2
  0Dh  Joypad 3
  0Ch  Joypad 4
Next, set P14 and P15 low (one after each other) to select Buttons and Cursor lines, and read-out joypad state as normally. When completed, set P14 and P15 back HIGH, this automatically increments the joypad number (or restarts counting once reached the lastmost joypad). Repeat the procedure until you have read-out states for all two (or four) joypads.


 SGB Border and OBJ Commands

SGB Command 13h - CHR_TRN
Used to transfer tile data (characters) to SNES Tile memory in VRAM. This normally used to define BG tiles for the SGB Border (see PCT_TRN), but might be also used to define moveable SNES foreground sprites (see OBJ_TRN).
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1     Tile Transfer Destination
          Bit 0   - Tile Numbers   (0=Tiles 00h-7Fh, 1=Tiles 80h-FFh)
          Bit 1   - Tile Type      (0=BG Tiles, 1=OBJ Tiles)
          Bit 2-7 - Not used (zero)
  2-F   Not used (zero)
The tile data is sent by VRAM-Transfer (4 KBytes).
  000-FFF  Bitmap data for 128 Tiles
Each tile occupies 16bytes (8x8 pixels, 16 colors each).
When intending to transfer more than 128 tiles, call this function twice (once for tiles 00h-7Fh, and once for tiles 80h-FFh). Note: The BG/OBJ Bit seems to have no effect and writes to the same VRAM addresses for both BG and OBJ ???

SGB Command 14h - PCT_TRN
Used to transfer tile map data and palette data to SNES BG Map memory in VRAM to be used for the SGB border. The actual tiles must be separately transferred by using the CHR_TRN function.
  Byte  Content
  0     Command*8+Length    (fixed length=1)
  1-F   Not used (zero)
The map data is sent by VRAM-Transfer (4 KBytes).
  000-7FF  BG Map 32x32 Entries of 16bit each (2048 bytes)
  800-87F  BG Palette Data (Palettes 4-7, each 16 colors of 16bits each)
  880-FFF  Not used, don't care
Each BG Map Entry consists of a 16bit value as such:
  Bit 0-9   - Character Number (use only 00h-FFh, upper 2 bits zero)
  Bit 10-12 - Palette Number   (use only 4-7, officially use only 4-6)
  Bit 13    - BG Priority      (use only 0)
  Bit 14    - X-Flip           (0=Normal, 1=Mirror horizontally)
  Bit 15    - Y-Flip           (0=Normal, 1=Mirror vertically)
Even though 32x32 map entries are transferred, only upper 32x28 are actually used (256x224 pixels, SNES screen size). The 20x18 entries in the center of the 32x28 area should be set to 0000h as transparent space for the gameboy window to be displayed inside. Reportedly, non-transparent border data will cover the gameboy window.

SGB Command 18h - OBJ_TRN
Used to transfer OBJ attributes to SNES OAM memory. Unlike all other functions with the ending _TRN, this function does not use the usual one-shot 4KBytes VRAM transfer method.
Instead, when enabled (below execute bit set), data is permanently (each frame) read out from the lower character line of the gameboy screen. To suppress garbage on the display, the lower line is masked, and only the upper 20x17 characters of the gameboy window are used - the masking method is unknwon - frozen, black, or recommended to be covered by the SGB border, or else ??? Also, when the function is enabled, "system attract mode is not performed" - whatever that means ???
  Byte  Content
  0     Command*8+Length (fixed length=1)
  1     Control Bits
          Bit 0   - SNES OBJ Mode enable (0=Cancel, 1=Enable)
          Bit 1   - Change OBJ Color     (0=No, 1=Use definitions below)
          Bit 2-7 - Not used (zero)
  2-3   System Color Palette Number for OBJ Palette 4 (0-511)
  4-5   System Color Palette Number for OBJ Palette 5 (0-511)
  6-7   System Color Palette Number for OBJ Palette 6 (0-511)
  8-9   System Color Palette Number for OBJ Palette 7 (0-511)
          These color entries are ignored if above Control Bit 1 is zero.
          Because each OBJ palette consists of 16 colors, four system
          palette entries (of 4 colors each) are transferred into each
          OBJ palette. The system palette numbers are not required to be
          aligned to a multiple of four, and will wrap to palette number
          0 when exceeding 511. For example, a value of 511 would copy
          system palettes 511, 0, 1, 2 to the SNES OBJ palette.
  A-F   Not used (zero)
The recommended method is to "display" gameboy BG tiles F9h..FFh from left to right as first 7 characters of the bottom-most character line of the gameboy screen. As for normal 4KByte VRAM transfers, this area should not be scrolled, should not be overlapped by gameboy OBJs, and the gameboy BGP palette register should be set up properly. By following that method, SNES OAM data can be defined in the 70h bytes of the gameboy BG tile memory at following addresses:
  8F90-8FEF  SNES OAM, 24 Entries of 4 bytes each (96 bytes)
  8FF0-8FF5  SNES OAM MSBs, 24 Entries of 2 bits each (6 bytes)
  8FF6-8FFF  Not used, don't care (10 bytes)
The format of SNES OAM Entries is:
  Byte 0  OBJ X-Position (0-511, MSB is separately stored, see below)
  Byte 1  OBJ Y-Position (0-255)
  Byte 2-3  Attributes (16bit)
    Bit 0-8    Tile Number     (use only 00h-FFh, upper bit zero)
    Bit 9-11   Palette Number  (use only 4-7)
    Bit 12-13  OBJ Priority    (use only 3)
    Bit 14     X-Flip          (0=Normal, 1=Mirror horizontally)
    Bit 15     Y-Flip          (0=Normal, 1=Mirror vertically)
The format of SNES OAM MSB Entries is:
  Actually, the format is unknown ??? However, 2 bits are used per entry:
  One bit is the most significant bit of the OBJ X-Position.
  The other bit specifies the OBJ size (8x8 or 16x16 pixels).


 CPU 寄存器与标志位

寄存器
  16位  高   低   名字/功能
  AF    A    -    累加器 & 标志位
  BC    B    C    BC
  DE    D    E    DE
  HL    H    L    HL
  SP    -    -    堆栈指针
  PC    -    -    程序计数器/指针
如上所示, 大部分寄存器能以1个16位寄存器, 或者2个独立的8位寄存器来访问.

标志位寄存器 (AF 寄存器的低8位)
  位   名字  设置 清除 说明
  7    zf    Z    NZ   零标志位
  6    n     -    -    加减标志位 (BCD)
  5    h     -    -    半溢出标志位 (BCD)
  4    cy    C    NC   溢出标志位
  3-0  -     -    -    不使用 (总是为0)
装有近期影响标志位的指令的结果.

零标志位 (Z)
这个标志位将在一个操作的结果为零 (0) 时被设置 (1). 用于条件跳转.

溢出标志位 (C 或者叫 Cy)
当一个加法结果大于 FFh (8位) 或者 FFFFh (16位) 时, 或者当减法/比较的结果小于零时, 这个标志位被设置 (减法的溢出设置方式与 Z80 与 80x86 的 CPU 相同, 但和 65XX 与 ARM 的 CPU 不同). 另外, 当移位/循环移位移出的位是 "1" 时, 这个标志位也被设置. 用于条件跳转, 以及如 ADC, SBC, RL, RLA 等指令.

BCD 标志位 (N, H)
These flags are (rarely) used for the DAA instruction only, N Indicates whether the previous instruction has been an addition or subtraction, and H indicates carry for lower 4bits of the result, also for DAA, the C flag must indicate carry for upper 8bits.
After adding/subtracting two BCD numbers, DAA is intended to convert the result into BCD format; BCD numbers are ranged from 00h to 99h rather than 00h to FFh.
Because C and H flags must contain carry-outs for each digit, DAA cannot be used for 16bit operations (which have 4 digits), or for INC/DEC operations (which do not affect C-flag).


 CPU 指令集

下面的表格依次列出了助记符, 操作码, 时钟周期, 影响的标志位 (顺序是 znhc), 指令说明.
周期数使得 CPU 的时钟频率设定在 4.194304 MHz (在 CGB 倍速模式下为 8.4 MHz),
因为 Gameboy 所有的周期数都可以被 4 整除, 许多人将周期数和时钟频率也除以 4.

GMB 8位装载指令
  ld   r,r         xx         4 ---- r=r
  ld   r,n         xx nn      8 ---- r=n
  ld   r,(HL)      xx         8 ---- r=(HL)
  ld   (HL),r      7x         8 ---- (HL)=r
  ld   (HL),n      36 nn     12 ---- (HL)=n
  ld   A,(BC)      0A         8 ---- A=(BC)
  ld   A,(DE)      1A         8 ---- A=(DE)
  ld   A,(nn)      FA        16 ---- A=(nn)
  ld   (BC),A      02         8 ---- (BC)=A
  ld   (DE),A      12         8 ---- (DE)=A
  ld   (nn),A      EA        16 ---- (nn)=A
  ld   A,(FF00+n)  F0 nn     12 ---- 从 I/O 端口 n 读取 (内存 FF00+n)
  ld   (FF00+n),A  E0 nn     12 ---- 向 I/O 端口 n 写入 (内存 FF00+n)
  ld   A,(FF00+C)  F2         8 ---- 从 I/O 端口 C 读取 (内存 FF00+C)
  ld   (FF00+C),A  E2         8 ---- 向 I/O 端口 C 写入 (内存 FF00+C)
  ldi  (HL),A      22         8 ---- (HL)=A, HL=HL+1
  ldi  A,(HL)      2A         8 ---- A=(HL), HL=HL+1
  ldd  (HL),A      32         8 ---- (HL)=A, HL=HL-1
  ldd  A,(HL)      3A         8 ---- A=(HL), HL=HL-1

GMB 16位装载指令
  ld   rr,nn       x1 nn nn  12 ---- rr=nn            ;rr 可以是 BC,DE,HL,SP
  ld   SP,HL       F9         8 ---- SP=HL
  ld   (nn),SP     08 nn nn  20 ---- (nn)=SP
  push rr          x5        16 ---- SP=SP-2  (SP)=rr ;rr 可以是 BC,DE,HL,AF
  pop  rr          x1        12 (AF) rr=(SP)  SP=SP+2 ;rr 可以是 BC,DE,HL,AF

GMB 8位算术运算/逻辑运算指令
  add  A,r         8x         4 z0hc A=A+r
  add  A,n         C6 nn      8 z0hc A=A+n
  add  A,(HL)      86         8 z0hc A=A+(HL)
  adc  A,r         8x         4 z0hc A=A+r+cy
  adc  A,n         CE nn      8 z0hc A=A+n+cy
  adc  A,(HL)      8E         8 z0hc A=A+(HL)+cy
  sub  r           9x         4 z1hc A=A-r
  sub  n           D6 nn      8 z1hc A=A-n
  sub  (HL)        96         8 z1hc A=A-(HL)
  sbc  A,r         9x         4 z1hc A=A-r-cy
  sbc  A,n         DE nn      8 z1hc A=A-n-cy
  sbc  A,(HL)      9E         8 z1hc A=A-(HL)-cy
  and  r           Ax         4 z010 A=A & r
  and  n           E6 nn      8 z010 A=A & n
  and  (HL)        A6         8 z010 A=A & (HL)
  xor  r           Ax         4 z000 A=A xor r
  xor  n           EE nn      8 z000 A=A xor n
  xor  (HL)        AE         8 z000 A=A xor (HL)
  or   r           Bx         4 z000 A=A | r
  or   n           F6 nn      8 z000 A=A | n
  or   (HL)        B6         8 z000 A=A | (HL)
  cp   r           Bx         4 z1hc 比较 A-r
  cp   n           FE nn      8 z1hc 比较 A-n
  cp   (HL)        BE         8 z1hc 比较 A-(HL)
  inc  r           xx         4 z0h- r=r+1
  inc  (HL)        34        12 z0h- (HL)=(HL)+1
  dec  r           xx         4 z1h- r=r-1
  dec  (HL)        35        12 z1h- (HL)=(HL)-1
  daa              27         4 z-0x 十进制调整 A
  cpl              2F         4 -11- A = A xor FF     ;A取反

GMB 16位算术运算/逻辑运算指令
  add  HL,rr     x9           8 -0hc HL=HL+rr         ;rr 可以是 BC,DE,HL,SP
  inc  rr        x3           8 ---- rr=rr+1          ;rr 可以是 BC,DE,HL,SP
  dec  rr        xB           8 ---- rr=rr-1          ;rr 可以是 BC,DE,HL,SP
  add  SP,dd     E8          16 00hc SP=SP +/- dd     ;dd 是8位符号数
  ld   HL,SP+dd  F8          12 00hc HL=SP +/- dd     ;dd 是8位符号数

GMB 位移/循环位移指令
  rlca           07           4 000c 循环左移 A
  rla            17           4 000c 带进位循环左移 A
  rrca           0F           4 000c 循环右移 A
  rra            1F           4 000c 带进位循环右移 A
  rlc  r         CB 0x        8 z00c 循环左移 r
  rlc  (HL)      CB 06       16 z00c 循环左移 (HL)
  rl   r         CB 1x        8 z00c 带进位循环左移 r
  rl   (HL)      CB 16       16 z00c 带进位循环左移 (HL)
  rrc  r         CB 0x        8 z00c 循环右移 r
  rrc  (HL)      CB 0E       16 z00c 循环右移 (HL)
  rr   r         CB 1x        8 z00c 带进位循环右移 r
  rr   (HL)      CB 1E       16 z00c 带进位循环右移 (HL)
  sla  r         CB 2x        8 z00c 算术左移 r        ;Bit 0=0
  sla  (HL)      CB 26       16 z00c 算术左移 (HL)     ;Bit 0=0
  swap r         CB 3x        8 z000 交换 r 高低半字节
  swap (HL)      CB 36       16 z000 交换 (HL) 高低半字节
  sra  r         CB 2x        8 z00c 算术右移 r        ;Bit 7=Bit 7
  sra  (HL)      CB 2E       16 z00c 算术右移 (HL)     ;Bit 7=Bit 7
  srl  r         CB 3x        8 z00c 逻辑右移 r        ;Bit 7=0
  srl  (HL)      CB 3E       16 z00c 逻辑右移 (HL)     ;Bit 7=0

GMB 位操作指令
  bit  n,r       CB xx        8 z01- 测试 Bit n
  bit  n,(HL)    CB xx       12 z01- 测试 Bit n
  set  n,r       CB xx        8 ---- 设置 Bit n
  set  n,(HL)    CB xx       16 ---- 设置 Bit n
  res  n,r       CB xx        8 ---- 清除 Bit n
  res  n,(HL)    CB xx       16 ---- 清除 Bit n

GMB CPU 控制指令
  ccf            3F           4 -00c cy=cy xor 1      ;cy取反
  scf            37           4 -001 cy=1
  nop            00           4 ---- 无操作
  halt           76         N*4 ---- 停机直到产生中断 (低功耗)
  stop           10 00        ? ---- 低功耗待机模式 (极低功耗)
  di             F3           4 ---- 关闭中断, IME=0
  ei             FB           4 ---- 开启中断, IME=1

GMB 跳转指令
  jp   nn        C3 nn nn    16 ---- 跳转到 nn, PC=nn
  jp   HL        E9           4 ---- 跳转到 HL, PC=HL
  jp   f,nn      xx nn nn 16;12 ---- 条件跳转, 如果 nz,z,nc,c
  jr   PC+dd     18 dd       12 ---- 相对跳转到 nn (PC=PC+/-7 位)
  jr   f,PC+dd   xx dd     12;8 ---- 相对条件跳转, 如果 nz,z,nc,c
  call nn        CD nn nn    24 ---- 调用 nn, SP=SP-2, (SP)=PC, PC=nn
  call f,nn      xx nn nn 24;12 ---- 条件调用, 如果 nz,z,nc,c
  ret            C9          16 ---- 返回, PC=(SP), SP=SP+2
  ret  f         xx        20;8 ---- 条件返回, 如果 nz,z,nc,c
  reti           D9          16 ---- 返回并开启中断 (IME=1)
  rst  n         xx          16 ---- 调用 00,08,10,18,20,28,30,38


 CPU Comparision with Z80

Comparision with 8080
Basically, the gameboy CPU works more like an older 8080 CPU rather than like a more powerful Z80 CPU. It is, however, supporting CB-prefixed instructions. Also, all known gameboy assemblers using the more obvious Z80-style syntax, rather than the chaotic 8080-style syntax.

Comparision with Z80
Any DD-, ED-, and FD-prefixed instructions are missing, that means no IX-, IY-registers, no block commands, and some other missing commands.
All exchange instructions have been removed (including total absence of second register set), 16bit memory accesses are mostly missing, and 16bit arithmetic functions are heavily cut-down.
The gameboy has no IN/OUT instructions, instead I/O ports are accessed directly by normal LD instructions, or by special LD (FF00+n) opcodes.
The sign and parity/overflow flags have been removed.
The gameboy operates approximately as fast as a 4MHz Z80 (8MHz in CGB double speed mode), execution time of all instructions has been rounded up to a multiple of 4 cycles though.

Moved, Removed, and Added Opcodes
  Opcode  Z80             GMB
  ---------------------------------------
  08      EX   AF,AF      LD   (nn),SP
  10      DJNZ PC+dd      STOP
  22      LD   (nn),HL    LDI  (HL),A
  2A      LD   HL,(nn)    LDI  A,(HL)
  32      LD   (nn),A     LDD  (HL),A
  3A      LD   A,(nn)     LDD  A,(HL)
  D3      OUT  (n),A      -
  D9      EXX             RETI
  DB      IN   A,(n)      -
  DD      <IX>            -
  E0      RET  PO         LD   (FF00+n),A
  E2      JP   PO,nn      LD   (FF00+C),A
  E3      EX   (SP),HL    -
  E4      CALL P0,nn      -
  E8      RET  PE         ADD  SP,dd
  EA      JP   PE,nn      LD   (nn),A
  EB      EX   DE,HL      -
  EC      CALL PE,nn      -
  ED      <pref>          -
  F0      RET  P          LD   A,(FF00+n)
  F2      JP   P,nn       LD   A,(FF00+C)
  F4      CALL P,nn       -
  F8      RET  M          LD   HL,SP+dd
  FA      JP   M,nn       LD   A,(nn)
  FC      CALL M,nn       -
  FD      <IY>            -
  CB3X    SLL  r/(HL)     SWAP r/(HL)
Note: The unused (-) opcodes will lock-up the gameboy CPU when used.


 卡带头部

一个内置的信息区位于每个卡带的 0100-014F.
它含有以下内容:

0100-0103 - 入口
在显示完任天堂标志后, 内建的启动程序跳转到这个地址 (100h), 这里应跳转到卡带实际的主程序. 一般这个 4 字节的区域含有一个 NOP 指令, 然后跟着一个 JP 0150h 指令. 但这不是绝对的.

0104-0133 - 任天堂标志
这些字节定义了 Gameboy 开机时显示的任天堂标志的位图. 这个位图的十六位数据是:
  CE ED 66 66 CC 0D 00 0B 03 73 00 83 00 0C 00 0D
  00 08 11 1F 88 89 00 0E DC CC 6E E6 DD DD D9 99
  BB BB 67 63 6E 0E EC CC DD DC 99 9F BB B9 33 3E
Gameboy 启动程序在显示这张位图后将验证其中的内容, 如果这些字节不匹配, Gameboy 将自锁. CGB 只验证位图的前 18h 个字节, 但是其他设备 (比如 Pocket Gameboy) 验证全部 30h 字节.

0134-0143 - 标题
大写 ASCII 的游戏标题. 如果标题少于 16 个字节, 剩余的字节填入 00. CGB 出现后, 任天堂减少了这个区域到 15 个字节. 再过了几个月后他们一个荒唐的主意让这个区域只剩 11 个字节. 这些原本是标题字节的新定义见下述.

013F-0142 - 生产商代码
早期卡带这个区域是标题的一部分 (见上), 在较新的卡带中这个区域包含以 4 个大写字母组成的生产商代码. 缘由未知.

0143 - CGB 标志
早期卡带这个字节是标题的一部分 (见上). 在 CGB 卡带中最高位被用于启用 CGB 功能. 这个位为 CGB 所需, 否则 CGB 将切换自己为非 CGB 模式. 典型值为:
  80h - 游戏支持 CGB 功能, 但是也能在旧 Gameboy 上运行.
  C0h - 游戏只在 CGB 上运行. (硬件上与 80h 相同).
设置值的 Bit 7, 以及 Bit 2 或者 3 被设置, 将切换 Gameboy 到一个有着未初始化调色板的特殊非 CGB 模式. 原因未知, 大概是用于彩色化在 ROM 的特殊位置带有固定调色板数据的单色游戏.

0144-0145 - 新授权代码
指定以两个 ASCII 字符组成的授权代码, 包含公司或游戏的发行商. 这两个字节只用于较新的游戏 (在 SGB 出现后所发行的游戏). 较旧的游戏使用头部项 014B.

0146 - SGB 标志
指定游戏是否支持 SGB 功能, 常见的值为:
  00h = 无 SGB 功能 (普通 Gameboy 或者 CGB 专用游戏)
  03h = 游戏支持 SGB 功能
如果这个字节不是 03h, SGB 将关闭 SGB 功能.

0147 - 卡带类型
指定卡带使用哪种 MBC (内存页面控制器) (如果有的话), 以及是否有外部硬件存在于卡带之内.
  00h  只有 ROM                 19h  MBC5
  01h  MBC1                     1Ah  MBC5+RAM
  02h  MBC1+RAM                 1Bh  MBC5+RAM+电池
  03h  MBC1+RAM+电池            1Ch  MBC5+震动
                                1Dh  MBC5+震动+RAM
  05h  MBC2                     1Eh  MBC5+震动+RAM+电池
  06h  MBC2+电池
                                20h  MBC6+FLASH+RAM+电池
  08h  ROM+RAM
  09h  ROM+RAM+电池             22h  MBC7+加速度传感器+震动+RAM+电池
       
  0Bh  MMM01                    FCh  口袋照相机
  0Ch  MMM01+RAM                FDh  万代拓麻歌子5
  0Dh  MMM01+RAM+电池           FEh  HuC3
                                FFh  HuC1+RAM+电池
  0Fh  MBC3+实时时钟+电池
  10h  MBC3+实时时钟+RAM+电池   
  11h  MBC3
  12h  MBC3+RAM
  13h  MBC3+RAM+电池

0148 - ROM 大小
指定卡带上 ROM 的大小. 通常计算方法是 "32KB shl N (32KB 乘 2 的 N 次方)".
  00h -  32K 字节 (ROM 没有分 Bank)
  01h -  64K 字节 (  4 个 Bank)
  02h - 128K 字节 (  8 个 Bank)
  03h - 256K 字节 ( 16 个 Bank)
  04h - 512K 字节 ( 32 个 Bank)
  05h -   1M 字节 ( 64 个 Bank) - MBC1 仅使用其中  63 个 Bank
  06h -   2M 字节 (128 个 Bank) - MBC1 仅使用其中 125 个 Bank
  07h -   4M 字节 (256 个 Bank)
  52h - 1.1M 字节 ( 72 个 Bank)
  53h - 1.2M 字节 ( 80 个 Bank)
  54h - 1.5M 字节 ( 96 个 Bank)

0149 - RAM 大小
指定卡带上外部 RAM 的大小 (如果有的话).
  00h -   0K 无
  01h -   2K 字节
  02h -   8K 字节
  03h -  32K 字节 ( 4 个 Bank, 每个 Bank 8K 字节)
  04h - 128K 字节 (16 个 Bank, 每个 Bank 8K 字节)
  05h -  64K 字节 ( 8 个 Bank, 每个 Bank 8K 字节)
使用 MBC2 芯片时, 此项指定为 00h, 虽然 MBC2 含有内建的 512 x 4 位 RAM.

014A - 区域代码
指定此版本游戏将要在日本或其他区域发售. 只有定义了两个值.
  00h - 日版
  01h - 非日版

014B - 旧授权代码
指定游戏公司/开发商代码, 范围 00-FFh. 值 33h 表示使用在头部字节 0144-0145 的新授权代码代替.
(Super GameBoy 功能在这个值不等于 $33 时不启用.)

014C - 掩模 ROM 版本号
指定游戏的版本号. 一般是 00h.

014D - 头部校验和
含有对卡带头部字节 0134-014C 的 8 位校验和. 校验和按如下方式计算:
  x=0:FOR i=0134h TO 014Ch:x=x-MEM[i]-1:NEXT
结果的低八位需要和这个值一样. 如果这个校验和不正确, 游戏将无法运行.

014E-014F - 全局校验和
含有一个对整个卡带 ROM 的 16 位校验和 (高位字节在前, 即大端序). 通过计算卡带所有字节的和 (除了这两个校验字节) 得到. Gameboy 不会验证这个校验和.


 MBC (存储页面控制器)

在 GameBoy 的 16 位地址总线只为 ROM 和 RAM 提供有限的空间的情况之下, 许多游戏使用 MBC (存储页面控制器) 来通过切换 Bank (切页) 扩展可用的地址空间. 这些 MBC 芯片位于游戏卡带上 (不在 GameBoy 机内), 可用以下几种不同的 MBC 类型:

无 (仅 32K 字节 ROM)
MBC1 (最大 2M 字节 ROM, 可选最大 32K 字节 RAM)
MBC2 (最大 256K 字节 ROM, 与 512x4 位 RAM)
MBC3 (最大 2M 字节 ROM, 可选最大 64K 字节 RAM, 实时时钟)
MBC5 (最大 8M 字节 ROM, 可选最大 128K 字节 RAM, 可选震动)
HuC1 (带有红外控制器的 MBC)

MBC 时间问题

对于每个卡带, 所用的 (或者所倾向的) MBC 类型应该在 ROM 的 0147h 指定. (在卡带头部章节已经介绍.)


 无 (仅 32K 字节 ROM)

不大于 32K 字节 ROM 的小游戏不需要 MBC 芯片来做 ROM 分页. ROM 可以直接映射到内存 0000-7FFFh. 可选的 8K 字节 RAM 可以连接到 A000-BFFFh, 虽然 RAM 可能需要一个微型的类 MBC 电路支持, 但不会有真的 MBC 芯片.


 MBC1 (最大 2M 字节 ROM, 可选最大 32K 字节 RAM)

这是 GameBoy 的第一款 MBC 芯片. 任何其他后期 MBC 芯片的工作方式均与此款相似, 所以从某款 MBC 芯片上程序更新到另一款 MBC 芯片上相对容易 - 甚至可以做到同时兼容多款不同类型的 MBC.

注意内存范围 0000-7FFF 同时用于从 ROM 中读取数据, 以及向 MBC 控制寄存器写入.

0000-3FFF - ROM Bank 00 (只读)
这个区域总是装入卡带 ROM 的前 16K 字节.

4000-7FFF - ROM Bank 01-7F (只读)
这个区域可装入 ROM 中更多的 16K 字节 Bank, 使得寻址多到 125 个 ROM Bank (接近 2M 字节). 下文会说明, 因为20h, 40h, 60h 号 Bank 不可用, 所以可用 Bank 的数量是奇怪的 125.

A000-BFFF - RAM Bank 00-03, 可选 (读写)
这个区域用于卡带中外部 RAM (即 ERAM, 可选) 的寻址. 外部 RAM 常有电池缓冲 (此时也叫 SRAM), 使得在 GameBoy 关机, 或将卡带从 GameBoy 上移除时, 仍旧维持游戏的位置和高分表等. 可选的 RAM 大小有: 2K 字节 (于 A000-A7FF), 8K 字节 (于 A000-BFFF), 和 32K 字节 (由四个于 A000-BFFF 的 8K Bank 组成).

0000-1FFF - 启用 RAM (只写)
在外部 RAM 可以读写之前, 必须通过写入这个地址区域来启用读写. 为了保护外部 RAM 的内容在 GameBoy 关闭电源时不受损坏, 推荐在访问结束之后关闭. 一般使用下面的值进行操作:
  00h  关闭 RAM (默认)
  0Ah  开启 RAM
实际上任何低四位是 0Ah 的值都能开启 RAM, 其他数值均能关闭 RAM.

2000-3FFF - ROM Bank 号 (只写)
写入这个地址区域来选择 ROM Bank 号的低五位 (在范围 01-1Fh). 当写入 00h 时, MBC 芯片会将其转换为 01h. 这个特性并没什么大问题, 因为 00h 号 ROM Bank 总是可以通过读取 0000-3FFF 来访问.
但是 (当使用下文的寄存器指定高位 ROM Bank 位时), 这个特性同样发生在20h, 40h, 60h 号 Bank. 任何对这些 ROM Bank 的寻址尝试将以选择21h, 41h, 61h 号 Bank 所代替.

4000-5FFF - RAM Bank 号 - 或 - ROM Bank 号 的高位 (只写)
这个两位的寄存器可以用于选择范围在 00-03h 的 RAM Bank 号, 或者指定 ROM Bank 号的高两位 (Bit 5-6), 具体取决于当前的 ROM/RAM 模式. (见下.)

6000-7FFF - ROM/RAM 模式选择 (只写)
这个一位的寄存器用于选择前面寄存器是作为 ROM Bank 号的高两位, 还是作为 RAM Bank 号.
  00h = ROM 切页模式 (最多 8K 字节 RAM, 2M 字节 ROM) (默认)
  01h = RAM 切页模式 (最多 32K 字节 RAM, 512K 字节 ROM)
程序可以在两个模式中自由切换, 唯一的限制是模式 0 下只有 00h 号 RAM Bank 可用, 模式 1 下只有 00-1Fh 号 ROM Bank 可用.


 MBC2 (最大 256K 字节 ROM, 512x4 位 RAM)

0000-3FFF - ROM Bank 00 (只读)
与 MBC1 相同.

4000-7FFF - ROM Bank 01-0F (只读)
与 MBC1 相同, 但是一共只支持 16 个 ROM Bank.

A000-A1FF - 512x4 位 RAM, 内建于 MBC2 芯片 (读写)
MBC2 不支持外部 RAM, 取而代之的是一个 512x4 位的内建 RAM (位于 MBC2 芯片内部). 它在关机时同样需要外接电池维持存档.
因为数据以 4 位的值构成, 这个存储区域只有每个 "字节" 的低 4 位可用.

0000-1FFF - 启用 RAM (只写)
地址高位字节的最低标志位需要为 0 来启用/禁用卡带 RAM. 比如下面的地址可以用于启用/禁用卡带 RAM: 0000-00FF, 0200-02FF, 0400-04FF, ..., 1E00-1EFF.
建议使用 0000-00FF 的地址范围来启用/禁用 MBC2 的 RAM.

2000-3FFF - ROM Bank 号 (只写)
写入值 (XXXXBBBB - X = 可忽略, B = Bank 选择位) 到 2000-3FFF 区域将选定对应的一个 ROM Bank 到 4000-7FFF.

地址高位字节的最低标志位需要为 1 来选择 ROM Bank. 比如下面的地址可以用于选择 ROM Bank: 2100-21FF, 2300-23FF, 2500-25FF, ..., 3F00-3FFF.
建议使用 2100-21FF 的地址范围来选择 MBC2 的 ROM Bank.


 MBC3 (最大 2M 字节 ROM, 可选最大 64K 字节 RAM, 实时时钟)

除了可以访问最大 2MB ROM (128 个 Bank) 以及 32KB (4 个 Bank, 典型 MBC3) / 64KB (8 个 Bank, 仅 MBC30 芯片支持) RAM 之外, MBC3 还包含一个内建的实时时钟 (RTC). 实时时钟需要外接一个 32.768 KHz 石英振荡器和外接一个电池 (如果需要在 GameBoy 关机时时钟能继续走动的话).

0000-3FFF - ROM Bank 00 (只读)
与 MBC1 相同.

4000-7FFF - ROM Bank 01-7F (只读)
与 MBC1 相同, 但支持访问 Bank 20h, 40h, 60h.

A000-BFFF - RAM Bank 00-07, 如果有的话 (读写)
A000-BFFF - RTC 寄存器 08-0C (读写)
取决于当前所选的 Bank 号/实时时钟寄存器(见下), 这个内存空间用于访问一个 8K 字节的外部 RAM Bank, 或者一个实时时钟寄存器.

0000-1FFF - 启用 RAM 和实时时钟 (只写)
基本与 MBC1 相同, 写入值 0Ah 将启用读写外部 RAM 和实时时钟寄存器! 写入 00h 也将禁用读写.

2000-3FFF - ROM Bank 号 (只写)
与 MBC1 相同, 但是整个 7 位的 ROM Bank 号是直接写入这个地址的. 和 MBC1 相同, 写入 00h 将会以选择 Bank 01h 替代. 其他的值 01-7Fh 选择对应的 ROM Bank.

4000-5FFF - RAM Bank 号 - 或 - 实时时钟寄存器选择 (只写)
如同 MBC1 的 RAM 切页模式, 写入范围在 00-07h 的值将映射对应的 RAM Bank (如果有的话) 到内存 A000-BFFF.
写入值 08-0Ch 将映射对应的实时时钟寄存器到内存 A000-BFFF. 寄存器可以通过访问这个地址区域的任意一个地址来读写, 一般使用地址 A000 进行.

6000-7FFF - 固定时钟数据 (只写)
当写入 00h, 再写入 01h 到这个寄存器, 当前时间将被固定在实时时钟寄存器中. 固定的数据将保持不变直到再次重复写入 00h->01h 的操作来解固为止.
这个功能用于从实时时钟寄存器中 <读取>. 可以确定从实时时钟寄存器中读取固定 (冻结) 的时间时, 时钟仍在后台自行走动.

时钟计数寄存器
  08h  RTC S   秒             0-59 (0-3Bh)
  09h  RTC M   分             0-59 (0-3Bh)
  0Ah  RTC H   时             0-23 (0-17h)
  0Bh  RTC DL  天数计数器的低 8 位 (0-FFh)
  0Ch  RTC DH  天数计数器的高 1 位, 溢出位, 停机位
        Bit 0  天数计数器的最高位 (Bit 8)
        Bit 6  停机               (0 = 时钟活动, 1 = 时钟停止)
        Bit 7  天数计数器溢出位   (1 = 计数器溢出)
停机位应该在 <写入> 实时时钟寄存器前被设置.

天数计数器
总共 9 位的天数计数器允许记录范围在 0-511 (0-1FFh) 的天数. 天数寄存器溢出位在天数值溢出时将设置. 这种情况下, 直到程序复位这个值之前,它将保持设置状态.
注意你可以存储一个天数计数器的偏移量在电池 RAM. 例如, 每次你从读取一个非零的天数计数器时, 将天数加到 RAM 中存储的偏移量上, 然后将计数器复位至 0. 这种方法允许你计数任意的天数, 只要你的卡带至少每 511 天使用一次, 你的程序就能有万年的保证.

延迟
在访问实时时钟寄存器时, 推荐在每个单独的访问之间, 执行一个 4 毫秒的延迟 (普速模式下的 4 个周期).


 MBC5 (最大 8M 字节 ROM, 可选最大 128K 字节 RAM, 可选震动)

用于支持 CGB 倍速模式, 任天堂特别提到了这款 MBC 对 MBC1 的高兼容性 (虽然可能需要修改程序). 除了可以访问最大 8MB ROM (512 个 Bank) 以及 32KB (4 个 Bank, 带震动) / 128KB RAM (16 个 Bank, 不带震动), MBC5 还可附带由一节 AAA 电池驱动的震动(RUMBLE).

0000-3FFF - ROM Bank 00 (只读)
与 MBC1 相同.

4000-7FFF - ROM Bank 001-1FF (只读)
与 MBC1 相同, 但支持访问 Bank 20h, 40h, 60h. 最大可访问 Bank 号扩充到 1FFh.

A000-BFFF - RAM Bank 00-0F (震动版范围 00-03), 如果有的话 (读写)
与 MBC1 相同. 但是最大可访问 Bank 号扩充到 0Fh (非震动版).

0000-1FFF - 启用 RAM (只写)
基本与 MBC1 相同, 写入值 0Ah 将启用读写外部 RAM 和实时时钟寄存器! 写入 00h 也将禁用读写.

2000-2FFF - ROM Bank 号低 8 位 (只写)
与 MBC1 相同, 但是 MBC5 的 ROM Bank 号最大支持 9 位, 只有其中低 8 位写入这个地址.

3000-3FFF - ROM Bank 号高 1 位 (只写)
9 位 Rom Bank 号的最高位写入这个地址. 另外, 在 MBC5 中, 当写入 Bank 号是 000h 时, 访问的是 000h 号 Bank, 而不是 001h 号 Bank. 已知 "电车 Go2" 使用全部 8M ROM, 其余游戏多是清除或忽略 ROM Bank 号的最高位.

4000-5FFF - RAM Bank 号 - 或 - 启用震动 (只写)
如同 MBC1 的 RAM 切页模式, 非震动版写入范围在 00-0Fh (震动版 00-03h) 的值将映射对应的 RAM Bank (如果有的话) 到内存 A000-BFFF.
震动版的 Bit 3 为震动控制, 设置时启用震动, 清除时停止震动. 通过不同的占空比可以实现不同力度的震动.


 HuC1 (带有红外控制器的 MBC)

这款哈德森软件 (Hudson Soft) 生产的控制器看起来与 MBC1 非常相似, 主要的不同是它支持红外 LED 的输入输出. (与后来加入到 CGB 的红外端口类似.)

已知日本卡带 "弹珠人" (内部卡带名: SUPER B DAMAN) 使用这个芯片.


 MBC 时间问题

在 CGB 倍速模式下使用 MBC
MBC5 设计成支持 CGB 的倍速模式.
有传闻说早期的 MBC (像 MBC1-3) 在那个模式下不够快. 若真是如此, 在倍速模式时只使用位于内部 RAM 的代码和数据依旧是可行的.
然而, 虽然有上述传闻, 我自己自制的 MBC1-EPROM 卡带在倍速模式下工作依旧稳定正常.


 Gamegenie/Shark Cheats

Game Shark and Gamegenie are external cartridge adapters that can be plugged between the gameboy and the actual game cartridge. Hexadecimal codes can be then entered for specific games, typically providing things like Infinite Sex, 255 Cigarettes, or Starting directly in Wonderland Level PRO, etc.

Gamegenie (ROM patches)
Gamegenie codes consist of nine-digit hex numbers, formatted as ABC-DEF-GHI, the meaning of the separate digits is:
  AB    New data
  FCDE  Memory address, XORed by 0F000h
  GI    Old data, XORed by 0BAh and rotated left by two
  H     Don't know, maybe checksum and/or else
The address should be located in ROM area 0000h-7FFFh, the adapter permanently compares address/old data with address/data being read by the game, and replaces that data by new data if necessary. That method (more or less) prohibits unwanted patching of wrong memory banks. Eventually it is also possible to patch external RAM ?
Newer devices reportedly allow to specify only the first six digits (optionally). As far as I rememeber, around three or four codes can be used simultaneously.

Game Shark (RAM patches)
Game Shark codes consist of eight-digit hex numbers, formatted as ABCDEFGH, the meaning of the separate digits is:
  AB    External RAM bank number
  CD    New Data
  GHEF  Memory Address (internal or external RAM, A000-DFFF)
As far as I understand, patching is implement by hooking the original VBlank interrupt handler, and re-writing RAM values each frame. The downside is that this method steals some CPU time, also, it cannot be used to patch program code in ROM.
As far as I rememeber, somewhat 10-25 codes can be used simultaneously.


 Power Up Sequence

When the GameBoy is powered up, a 256 byte program starting at memory location 0 is executed. This program is located in a ROM inside the GameBoy. The first thing the program does is read the cartridge locations from $104 to $133 and place this graphic of a Nintendo logo on the screen at the top. This image is then scrolled until it is in the middle of the screen. Two musical notes are then played on the internal speaker. Again, the cartridge locations $104 to $133 are read but this time they are compared with a table in the internal rom. If any byte fails to compare, then the GameBoy stops comparing bytes and simply halts all operations. If all locations compare the same, then the GameBoy starts adding all of the bytes in the cartridge from $134 to $14d. A value of 25 decimal is added to this total. If the least significant byte of the result is a not a zero, then the GameBoy will stop doing anything. If it is a zero, then the internal ROM is disabled and cartridge program execution begins at location $100 with the following register values:

   AF=$01B0
   BC=$0013
   DE=$00D8
   HL=$014D
   Stack Pointer=$FFFE
   [$FF05] = $00   ; TIMA
   [$FF06] = $00   ; TMA
   [$FF07] = $00   ; TAC
   [$FF10] = $80   ; NR10
   [$FF11] = $BF   ; NR11
   [$FF12] = $F3   ; NR12
   [$FF14] = $BF   ; NR14
   [$FF16] = $3F   ; NR21
   [$FF17] = $00   ; NR22
   [$FF19] = $BF   ; NR24
   [$FF1A] = $7F   ; NR30
   [$FF1B] = $FF   ; NR31
   [$FF1C] = $9F   ; NR32
   [$FF1E] = $BF   ; NR33
   [$FF20] = $FF   ; NR41
   [$FF21] = $00   ; NR42
   [$FF22] = $00   ; NR43
   [$FF23] = $BF   ; NR30
   [$FF24] = $77   ; NR50
   [$FF25] = $F3   ; NR51
   [$FF26] = $F1-GB, $F0-SGB ; NR52
   [$FF40] = $91   ; LCDC
   [$FF42] = $00   ; SCY
   [$FF43] = $00   ; SCX
   [$FF45] = $00   ; LYC
   [$FF47] = $FC   ; BGP
   [$FF48] = $FF   ; OBP0
   [$FF49] = $FF   ; OBP1
   [$FF4A] = $00   ; WY
   [$FF4B] = $00   ; WX
   [$FFFF] = $00   ; IE

It is not a good idea to assume the above values will always exist. A later version GameBoy could contain different values than these at reset. Always set these registers on reset rather than assume they are as above.

Please note that GameBoy internal RAM on power up contains random data. All of the GameBoy emulators tend to set all RAM to value $00 on entry.

Cart RAM the first time it is accessed on a real GameBoy contains random data. It will only contain known data if the GameBoy code initializes it to some value.


 Reducing Power Consumption

The following can be used to recude the power consumption of the gameboy, and to extend the life of the batteries.

PWR Using the HALT Instruction
PWR Using the STOP Instruction
PWR Disabeling the Sound Controller
PWR Not using CGB Double Speed Mode
PWR Using the Skills


 PWR Using the HALT Instruction

It is recommended that the HALT instruction be used whenever possible to reduce power consumption & extend the life of the batteries. This command stops the system clock reducing the power consumption of both the CPU and ROM.

The CPU will remain suspended until an interrupt occurs at which point the interrupt is serviced and then the instruction immediately following the HALT is executed.

Depending on how much CPU time is required by a game, the HALT instruction can extend battery life anywhere from 5 to 50% or possibly more.

When waiting for a vblank event, this would be a BAD example:
  @@wait:
   ld   a,(0FF44h)      ;LY
   cp   a,144
   jr   nz,@@wait

A better example would be a procedure as shown below. In this case the vblank interrupt must be enabled, and your vblank interrupt procedure must set vblank_flag to a non-zero value.
   ld   hl,vblank_flag  ;hl=pointer to vblank_flag
   xor  a               ;a=0
  @@wait:               ;wait...
   halt                 ;suspend CPU - wait for ANY interrupt
   cp   a,(hl)          ;vblank flag still zero?
   jr   z,@@wait        ;wait more if zero
   ld   (hl),a          ;set vblank_flag back to zero
The vblank_flag is used to determine whether the HALT period has been terminated by a vblank interrupt, or by another interrupt. In case that your program has all other interrupts disabled, then it would be proof to replace the above procedure by a single HALT instruction.


 PWR Using the STOP Instruction

The STOP instruction is intended to switch the gameboy into VERY low power standby mode. For example, a program may use this feature when it hasn't sensed keyboard input for a longer period (assuming that somebody forgot to turn off the gameboy).

Before invoking STOP, it might be required to disable Sound and Video manually (as well as IR-link port in CGB). Much like HALT, the STOP state is terminated by interrupt events - in this case this would be commonly a joypad interrupt. The joypad register might be required to be prepared for STOP either.


 PWR Disabeling the Sound Controller

If your programs doesn't use sound at all (or during some periods) then write 00h to register FF26 to save 16% or more on GB power consumption.
Sound can be turned back on by writing 80h to the same register, all sound registers must be then re-initialized.
When the gameboy becomes turned on, sound is enabled by default, and must be turned off manually when not used.


 PWR Not using CGB Double Speed Mode

Because CGB Double Speed mode consumes more power, it'd be recommended to use normal speed when possible.
There's limited ability to switch between both speeds, for example, a game might use normal speed in the title screen, and double speed in the game, or vice versa.
However, during speed switch the display collapses for a short moment, so that it'd be no good idea to alter speeds within active game or title screen periods.


 PWR Using the Skills

Most of the above power saving methods will produce best results when using efficient and tight assembler code which requires as less CPU power as possible. Thus, experienced old-school programmers will (hopefully) produce lower power consumption, as than HLL-programming teenagers, for example.


 Sprite RAM Bug

There is a flaw in the GameBoy hardware that causes trash to be written to OAM RAM if the following commands are used while their 16-bit content is in the range of $FE00 to $FEFF:
  inc rr        dec rr          ;rr = bc,de, or hl
  ldi a,(hl)    ldd a,(hl)
  ldi (hl),a    ldd (hl),a
Only sprites 1 & 2 ($FE00 & $FE04) are not affected by these instructions.


 External Connectors

Cartridge Slot
  Pin   Name    Expl.
  1     VDD     Power Supply +5V DC
  2     PHI     System Clock
  3     /WR     Write
  4     /RD     Read
  5     /CS     Chip Select
  6-21  A0-A15  Address Lines
  22-29 D0-D7   Data Lines
  30    /RES    Reset signal
  31    VIN     External Sound Input
  32    GND     Ground

Link Port
Pin numbers are arranged as 2,4,6 in upper row, 1,3,5 un lower row; outside view of gameboy socket; flat side of socket upside.
Colors as used in most or all standard link cables, because SIN and SOUT are crossed, colors Red and Orange are exchanged at one cable end.
  Pin Name Color  Expl.
  1   VCC  -      +5V DC
  2   SOUT red    Data Out
  3   SIN  orange Data In
  4   P14  -      Not used
  5   SCK  green  Shift Clock
  6   GND  blue   Ground
Note: The original gameboy used larger plugs (unlike pocket gameboys and newer), linking between older/newer gameboys is possible by using cables with one large and one small plug though.

Stereo Sound Connector (3.5mm, female)
  Pin     Expl.
  Tip     Sound Left
  Middle  Sound Right
  Base    Ground

External Power Supply
...



 END