画面表示

目次


LCD コントロールレジスタ


FF40 - LCDC - LCD Control (読み込み/書き込み可能)


 Bit 7 - LCD 表示有効                       (0 = オフ、 1 = オン)
 Bit 6 - ウインドウタイルマップ表示選択     (0 = 9800 - 9BFF、 1 = 9C00 - 9FFF)
 Bit 5 - ウインドウ表示有効                 (0 = オフ、 1 = オン)
 Bit 4 - 背景 & ウインドウタイルデータ選択  (0 = 8800 - 97FF、 1 = 8000 - 8FFF)
 Bit 3 - 背景タイルマップ表示選択           (0 = 9800 - 9BFF、 1 = 9C00 - 9FFF)
 Bit 2 - OBJ (スプライト) サイズ            (0 = 8x8、 1 = 8x16)
 Bit 1 - OBJ (スプライト) 表示有効          (0 = オフ、 1 = オン)
 Bit 0 - 背景表示 (機種ごとに異なる)        (0 = オフ、 1 = オン)

LCDC.7 - LCD 表示有効


注意: LCD 操作 (ビット 7 を 1 から 0 にする) は、 V-Blank 期間中にのみ行うことができます。
V-Blank 期間外に表示を無効にすると、ハードウェアが壊れる場合があります。

V-Blank は、 LY が 144 以上 (LY >= 144) になっているかどうかで確認することができます。

表示が無効にされている時、表示内容は空 (白) になります。
また、 VRAM と OAM へは自由にアクセスすることができます。

LCDC のビット 0 は、ゲームボーイの種類ごとに意味が異なります。

LCDC.0 - 1) 白黒のゲームボーイとスーパーゲームボーイの時: 背景表示


ビット 0 が 0 の時、背景は空 (白) になります。
ウインドウとスプライトは表示されたままになります (ビット 1 とビット 5 で有効になっている場合)。

LCDC.0 - 2) ゲームボーイカラーモードの時: 背景とウインドウのマスター優先度


ビット 0 が 0 の時、背景とウインドウは、 OAM と背景マップ属性の値で
それぞれ設定している優先度の設定を無視するようになり、スプライトが常に最前面に表示されるようになります。

LCDC.0 - 3) ゲームボーイカラー本体で、ゲームボーイカラーモードでない時: 背景とウインドウの表示


ビット 0 が 0 の時、背景とウインドウは空 (白) になります。
この時、ウインドウ表示ビット (ビット 5) は無視されます。
スプライトは表示されたままになります (ビット 1 で有効になっている場合)。

この動作は、互換性に問題があります。
ゲームボーイカラー本体で白黒のゲームを起動した時、

  • 背景を非表示
  • ウインドウを表示

に設定しても、うまく動きません。

LCD ステータスレジスタ


FF41 - STAT - LCDC ステータス (読み込み/書き込み可能)


 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 の下位 2 ビットは、 LCD コントローラの現在の状態を表します。

モード 0:
LCD コントローラが H-Blank 期間中。
CPU は VRAM (8000 - 9FFF) と OAM (FE00 - FE9F) の両方にアクセス可能。

モード 1:
LCD コントローラが V-Blank 期間中 (または、画面の停止中)。
CPU は表示 RAM (8000 - 9FFF) と OAM (FE00 - FE9F) の両方にアクセス可能。

モード 2:
LCD コントローラが OAM の読み込み中。
CPU は、この期間中 OAM (FE00 - FE9F) へのアクセスが不可能。

モード 3:
LCD コントローラが VRAM、 OAM の読み込み中。
CPU は VRAM (8000 - 9FFF) と OAM (FE00 - FE9F) の両方にアクセスが不可能。
ゲームボーイカラーモードの時は、パレットデータ (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 と 3 つ切り替わる期間は、時間でいうと約 109 マイクロ秒になります。

  • モード 0: 48.6 マイクロ秒
  • モード 2: 19 マイクロ秒
  • モード 3: 41 マイクロ秒

上記の状態は、 V-Blank によって 16.6 ミリ秒ごとに中断されます (モード 1)。
モード 1 になっている時間は、 1.08 ミリ秒です。

モードフラグが 0、2、3 と 3 つ切り替わる期間を、クロック換算でいうと合計 456 クロックになります。

  • モード 0: 201 から 207 クロックの間
  • モード 2: 77 から 83 クロックの間
  • モード 3: 169 から 175 クロックの間

V-Blank 期間 (モード 1) は、 4560 クロックです。
画面全体の更新は、 70224 クロックごとに発生することになります。

LCD 割り込み


INT 40 - V-Blank 割り込み


V-Blank 割り込みは、普通のゲームボーイでは 1 秒間に約 59.7 回発生します。
スーパーゲームボーイでは、 1 秒間に約 61.1 回発生します。

この割り込みは、 V-Blank の開始時に発生します (LY = 144)。
V-Blank 期間中、表示用のハードウェアがビデオ RAM を使わないため、自由にアクセスすることができます。
V-Blank 期間は、およそ 1.1 ミリ秒です。

INT 48 - LCDC ステータス割り込み


この割り込みは STAT レジスタ (FF41) の説明で書いたように、さまざまな理由によって発生します。
LCD の横のラインを書き換える時の割り込み (H-Blank 割り込み) 時に、
SCX / SCY レジスタ (FF43 / FF42) を書き換えることにより、
特別な画面エフェクトをかけることができます (ラスターエフェクト)。


LCD 表示位置とスクロール


FF42 - SCY - スクロール Y 座標 (読み込み/書き込み可能)

FF43 - SCX - スクロール X 座標 (読み込み/書き込み可能)


256x256 ピクセルの背景マップ (32x32 タイル) の、位置を指定します。
液晶画面の、左上に表示される位置を指定します。

これらの値は 0 から 255 の範囲で、 X 座標、 Y 座標をそれぞれ別に指定します。
画面の上下方向、左右方向にハミ出た部分は、自動的に反対側の部分に繋がるように表示されます。

FF44 - LY - LCDC Y 座標 (読み込み専用)


LY レジスタの値は、現在 LCD ドライバによって転送中のデータの、垂直方向の座標を表します。
LY の値は 0 から 153 の間の値を取ります。
144 から 153 の間にある時、 V-Blank 期間を表します。
書き込みすると、カウンタがリセットされます。

FF45 - LYC - LY 比較 (読み込み/書き込み可能)


ゲームボーイの起動中、常に LYC レジスタと LY レジスタの値が比較されます。
LYC と LY が一致した時、 STAT レジスタ (FF41) のビット 2 がセットされ、
LCDC ステータス割り込みが有効になっている場合は、割り込みが発生します (STAT レジスタで有効にする)。

FF4A - WY - ウインドウ Y 座標 (読み込み/書き込み可能)

FF4B - WX - ウインドウ X 座標 - 7 (読み込み/書き込み可能)


ウインドウ領域の、左上の座標を指定します。
ウインドウというのは、もう 1 つの背景の領域のことで、通常の背景の上に表示されます。
OBJ (スプライト) は、ウインドウの上または下に表示されます。

ウインドウが有効になっている場合、次の範囲で値が指定されます。

  • WX: 0 から 166
  • WY: 0 から 143

WX = 7、 WY = 0 を指定した時、ウインドウは左上に表示されます。
(7 ピクセルずらすことによって、画面全体を覆うことができます。)

LCD モノクロパレット


FF47 - BGP - 背景パレットデータ (読み込み/書き込み可能) - ゲームボーイカラーモードでない時のみ


このレジスタで、背景とウインドウのタイルに使用するための色を指定することができます。

 Bit 7-6 - パレット番号 3 の色
 Bit 5-4 - パレット番号 2 の色
 Bit 3-2 - パレット番号 1 の色
 Bit 1-0 - パレット番号 0 の色

次の 4 つの中から色を選びます。

  • 0: 白
  • 1: 薄いグレー
  • 2: 濃いグレー
  • 3: 黒

ゲームボーイカラーモードの時は、CGB パレットメモリを代わりに使用します。

FF48 - OBP0 - オブジェクトパレットデータ 0 (読み込み/書き込み可能) - ゲームボーイカラーモードでない時のみ


スプライトパレット 0 用の色を指定します。
BGP (FF47) と同じようにパレットの色を指定しますが、
スプライト用タイルデータの 00 は常に透明を表すため、下位 2 ビットは使用されません。

FF49 - OBP1 - オブジェクトパレットデータ 1 (読み込み/書き込み可能) - ゲームボーイカラーモードでない時のみ


スプライトパレット 1 用の色を指定します。
BGP (FF47) と同じようにパレットの色を指定しますが、
スプライト用タイルデータの 00 は常に透明を表すため、下位 2 ビットは使用されません。

LCD カラーパレット (ゲームボーイカラーのみ)


FF68 - BCPS/BGPI - ゲームボーイカラーモードのみ - 背景パレットインデックス


このレジスタは、ゲームボーイカラーの背景パレットメモリのアドレスを指定するために使用されます。
背景パレットメモリのそれぞれの値は、色の値を指定します。色の値は 2 バイトで構成されます。
最初の 8 バイトは、パレット 0 の色 0 から 3 (BGP0) を指定します。
また、同じように BGP1 から BGP7 まであります。

 Bit 0-5   インデックス値        (00 - 3F)
 Bit 7     オートインクリメント  (0 = 無効、 1 = 書き込み後、インクリメント)

データの内容は、 FF69 のレジスタを通して読み書きします。
オートインクリメントビットが 1 の時、 FF69 への書き込み後に、インデックス値が自動でインクリメントされます。
FF69 からの読み込み時は、インデックス値はインクリメントされないため、手動でインクリメントする必要があります。

FF69 - BCPD/BGPD - ゲームボーイカラーモードのみ - 背景パレットデータ


このレジスタ経由で、ゲームボーイカラーのパレットメモリに対して読み書きします。
アドレスは FF68 で指定します。

それぞれの色は 2 バイトで表します (ビット 0 - 7 が最初のバイトになります)。

 Bit 0-4   赤   (00 - 1F)
 Bit 5-9   緑   (00 - 1F)
 Bit 10-14 青   (00 - 1F)

VRAM の動作に似ていて、 LCD コントローラがパレットメモリのデータをアクセスしている間は、読み書きできません。
(STAT レジスタがモード 3 になっている時。)

初期化時に、すべての背景色は白で初期化されます。

FF6A - OCPS/OBPI - ゲームボーイカラーモードのみ - スプライトパレットインデックス

FF6B - OCPD/OBPD - ゲームボーイカラーモードのみ - スプライトパレットデータ


これらのレジスタは、スプライトパレットの OBP0 から OBP7 までを初期化するために使用され、
上記の背景パレットと同じように値を指定します。

OBP パレットも背景と同様に、パレットごとに 4 つの色を指定しますが、
色 0 は常に透明になるため、実際には色 1 から色 3 のみが画面に表示されます。
注意: リセット時、すべてのスプライト用の色は未定になっています。

ゲームボーイカラーでの RGB 値の扱い


ゲームボーイカラーの RGB 値の扱い方は、パソコンの場合と異なります。

色の値が最大値に設定されている時、白ではなく薄いグレーになります。
色の値は線形に増えるわけではなく、値が 10h - 1Fh の時は明るい色、値が 00h - 0Fh の時は中間の色から暗い色になります。

また、ゲームボーイカラーの色の混ぜ方は変わっていて、 RGB のどれかの色の値を増やした時、他の RGB の値に影響があります。
例えば、 03EFh の値 (青 = 0、緑 = 1Fh、赤 = 0Fh) を指定した時、 PC では明るい緑色になりますが、
ゲームボーイカラーでは、少し濁った黄色になります。

ゲームボーイアドバンスでの RGB 値の扱い


ゲームボーイアドバンス (GBA) と、ゲームボーイカラー (CGB) の色の互換性については、次のようになります。

CGB の色は、そのままでは GBA 上で、ほとんどの場合見えなくなります (黒で表示される)。
両方とももちろん、黒も白も表示できるのですが、中間の色の合成の仕方が異なります。

色の濃さの値、 00h から 0Fh は不可視または黒になりますが、
CGB では、実際にはこれらの値は、中間色から暗めの色で使われています。

新しい CGB のゲームでは、GBA のハードウェアを検出して、このように色が変化しないようになっています。
簡単な方法が使われていて、 RGB のそれぞれの色に対して、 GBA = CGB / 2 + 10h の式を適用しています。
完全に色が一致するわけではないですが、一応、画面が見られるようにはなります。
全く変換されないよりは良い状態になります。

LCD VRAM バンク (ゲームボーイカラーのみ)


FF4F - VBK - ゲームボーイカラーモードのみ - VRAM バンク


これは 1 ビットのレジスタで、ビデオメモリ (VRAM) のバンクを指定します。

 Bit 0 - VRAM バンク (0 - 1)

白黒のゲームでは、バンク 0 には 192 個のタイルと、2 つの背景マップが入っています。
バンク 1 では、さらに 192 個のタイルと、バンク 0 の背景マップで使われる、色の属性マップが入っています。

LCD OAM DMA 転送


FF46 - DMA - DMA 転送と開始アドレス (書き込み専用)


このレジスタに書き込みを行うことで、 DMA 転送が開始されます。
転送開始場所は ROM または RAM、転送先は OAM メモリ (スプライト属性テーブル) です。
転送元のアドレスは、 100h で割った値を指定します。

  • 転送元: XX00 - XX9F ;XX の範囲は 00 - F1h
  • 転送先: FE00 - FE9F

転送完了には、 160 マイクロ秒かかります (ゲームボーイカラーの倍速モードでは 80 マイクロ秒)。
DMA の転送中、 CPU は HRAM (FF80 - FFFE) にのみアクセスすることができます。
この制限があるため、 HRAM 領域に短い処理を入れておく必要があります。
HRAM 上から DMA の転送を開始し、転送の完了を待つ処理を入れます。

  ld  (0FF46h),a ; DMA 転送の開始。 a = 開始アドレス / 100h
  ld  a,28h      ; 待つ処理
 wait:           ; 合計 5x40 サイクルで、約 200 マイクロ秒
  dec a          ; 1 サイクル
  jr  nz,wait    ; 4 サイクル

多くのプログラムで、上の処理が V-Blank 処理の中から呼ばれています。

また、この処理を画面の更新中に呼び出すことで、 40 個以上のスプライトを表示することもできます。
例えば、画面の上半分の描画中に 40 個、下半分の描画中に 40 個のスプライトを表示する時に呼び出します。

LCD VRAM DMA 転送 (ゲームボーイカラーのみ)


FF51 - HDMA1 - ゲームボーイカラーモードのみ - 新しい DMA の転送元 (上位)

FF52 - HDMA2 - ゲームボーイカラーモードのみ - 新しい DMA の転送元 (下位)

FF53 - HDMA3 - ゲームボーイカラーモードのみ - 新しい DMA の転送先 (上位)

FF54 - HDMA4 - ゲームボーイカラーモードのみ - 新しい DMA の転送先 (下位)

FF55 - HDMA5 - ゲームボーイカラーモードのみ - 新しい DMA の長さ/モード/開始


これらのレジスタに書き込みを行うことで、 DMA 転送が開始されます。
転送開始場所は ROM または RAM、転送先は OAM メモリ (スプライト属性テーブル) です。

転送元のアドレスは 0000 - 7FF0 または A000 - DFF0 のいずれかで、下位 4 ビットは使われません (0 になります)。
転送先のアドレスは 8000 - 9FF0 の範囲で、下位 4 ビットは使われません (0 になります)。
また、上位 3 ビットも同様に指定できません (転送先は常に VRAM になります)。

FF55 への書き込みによって、転送が開始されます。
FF55 の下位 7 ビットは、転送するデータの長さ (10h で割って 1 を引いた数) を指定します。
10h から 800h の長さを、 00h から 7Fh の値で指定します。
FF55 の最上位ビットは転送モードを指定します。

ビット 7 = 0 - 汎用 DMA


DMA の転送の処理では、すべてのデータが一度に転送されます。
転送が完了するまで、プログラムは停止されます。

汎用 DMA では、LCD コントローラが VRAM にアクセスしている最中にも転送の処理を行おうとします。
このため、表示が停止されている時か、 V-Blank 期間中、 H-Blank 期間中のいずれかの間に使用する必要があります。

転送完了後、 FF55 の値が FFh となり、プログラムが再開されます。

ビット 7 = 1 - H-Blank DMA


H-Blank DMA では、 10h バイトのデータを H-Blank 期間中に転送します。
LY レジスタの値が 0 から 143 の間に使用します。 V-Blank 期間中 (LY = 144 から 153) は転送されません。
LY = 00 になった時、転送は再開されます。

転送ごとに、プログラムは停止します。
また、転送ごとの隙間の時間ごとに、プログラムは再開されます。

注意: 転送が完了するまで、転送先の VRAM バンク (FF4F) または、
ROM/RAM バンク (バンク切り替え可能なメモリから転送している場合) を切り替えてはいけません。

FF55 のレジスタを読み込むと、残りの長さを返します (10h で割って 1 を引いた数)。
FFh が返ってきた時は、転送が完了しています。
また、 FF55 のビット 7 へ 0 を書き込むことで、 H-Blank 転送を停止することができます。

DMA 転送がアクティブになっているか確認する


FF55 のビット 7 を読み込むことで、 DMA 転送がアクティブになっているか確認することができます (1 = アクティブでない、 0 = アクティブ)。
汎用 DMA、 H-Blank DMA の完了時や、 H-Blank DMA を手動で停止させる時等の状況で、この機能を使用します。

転送タイミング


通常スピード、倍速モードの両方で、 10h バイトのブロックを転送するごとに 8 マイクロ秒かかります。
通常スピードモードの場合 8 サイクル、倍速モードの時は 16 "高速" サイクルです。
古い MBC コントローラ (MBC 1 から 4) の場合と、遅い ROM の場合では、汎用 DMA、 H-Blank DMA の動作保証がありません。
(通常スピードモードの場合でも、 1 マイクロ秒ごとに 2 バイト転送する必要があるため。)
最終更新:2017年08月30日 18:56