画面表示 > VRAMとOAMへのアクセス

注意事項


LCD コントローラは、画面を描画している間、ビデオメモリ (VRAM) とスプライト属性テーブル (OAM) へ直接アクセスしています。
この期間中、 CPU は VRAM と OAM へアクセスできません。
この期間中に CPU が VRAM と OAM へ書き込みを行ったとしても、データは変更されません。
また、読み込みを行った場合は、戻り値が未定義になります (通常、 FFh になります)。

VRAM または OAM へアクセスする時は、アクセス可能かどうかチェックする必要があります。
STAT レジスタ (FF41) のモードビットを読み込むことで、チェックすることができます。
チェック時に (下のサンプルのコードを実行する時にも)、待ちループ内と、その後のメモリアクセス時に
割り込みが発生しないように気を付ける必要があります。
(VRAM と OAM へアクセスできるのは、待ちループ後のわずかな時間の間だけになるため)

モード 0 から 2 の間の VRAM (8000 - 9FFF) へのアクセス


 モード 0 - H-Blank 中
 モード 1 - V-Blank 中
 モード 2 - OAM 読み込み中

通常、 VRAM がアクセス可能になるのを待つコードは次のようになります。

 ld   hl,0FF41h    ; STAT レジスタの読み込み
@@wait:            ; \
 bit  1,(hl)       ;   モード 0 または 1 になるまで待つ
 jr   nz,@@wait    ; /

モード 0 か 1 の終了時に、この処理が実行された場合、
どちらのモードでも、次に続くモードが 2 になるため (OAM へのアクセスになるため)、
まだほんの少しのサイクルの間は、 VRAM にアクセスできます。

ゲームボーイカラーモードでは、 VRAM へのアクセス時に HDMA 機能 (FF51 から FF55) を使うこともできます。

モード 0 から 1 の間の OAM (FE00 - FE9F) へのアクセス


 モード 0 - H-Blank 中
 モード 1 - V-Blank 中

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   ; /

これら 2 つのループを通すことで、この処理の終了時点で、
モード 0 か 1 があと少し続くことを保証します。
V-Blank 期間中は、この処理を通さないことをお勧めします。

たいていの場合、上で書いたように、 DMA でアクセスする方法が一番お勧めです。

注意:
画面が非表示になっている時、 VRAM と OAM へはいつでもアクセスできます。
ただし、表示内容が空 (白) になってしまうため、初期化時にのみ、非表示状態に切り替えることをお勧めします。
最終更新:2017年08月30日 18:38