PPU (Picture Processing Unit)
_
|
アドレス | 説明 |
$2000 |
コントロールレジスタ1
bit 用途 -------------------------------------------------------- 7 VBlank時にNMIを発生 0:無効、1:発生 6 PPUマスタースレーブ、常に1 5 スプライトサイズ 0:8x8、1:8x16 4 背景パターンテーブルアドレス指定 0:$0000、1:$1000 3 スプライトパターンテーブルアドレス指定 0:$0000、1:$1000 2 PPUメモリアドレスインクリメント 0:+=1、1:+=32 1-0 ネームテーブルアドレス指定 +-----------+-----------+ | 2 ($2800) | 3 ($2C00) | +-----------+-----------+ | 0 ($2000) | 1 ($2400) | +-----------+-----------+ |
$2001 |
コントロールレジスタ2
bit 説明 ------------------------------------------ 7-5 背景色 000:黒 001:緑 010:青 100:赤 4 スプライト有効 0:無効、1:有効 3 背景有効 0:無効、1:有効 2 スプライトマスク、画面左8ピクセルを描画しない。0:描画しない、1:描画 1 背景マスク、画面左8ピクセルを描画しない。0:描画しない、1:描画 0 ディスプレイタイプ 0:カラー、1:モノクロ |
$2003 |
スプライトメモリアドレス $2004を経由してスプライトメモリへ書き込む8ビットアドレスを指定。 |
$2004 |
スプライトメモリデータ $2003によって指定されたスプライトメモリアドレスへデータを書き込む。 書き込む度にスプライトメモリアドレスはインクリメント(+=1)される。 |
$2005 |
背景スクロールオフセット スクロール値を垂直、水平の順に書き込み。 指定した値によってネームテーブルアドレスが設定される。 |
$2006 |
PPUメモリアドレス $2007を経由してPPUメモリへ書き込む16ビットアドレスを指定する。 上位8ビット、下位8ビットの順に書き込む。 |
$2007 |
PPUメモリデータ $2006によって指定されたPPUメモリアドレスへデータを書き込む。 書き込む度にメモリアドレスはインクリメント($2000のビット2によって+=1、+=32)する。 |
読み込み
アドレス | 説明 |
$2002 |
ステータスレジスタ 読み込みによって$2005の書き込み順序がクリアされる。 bit 用途 -------------------------------------------------------- 7 VBlank時に1、読み込みでクリアする。 6 スプライトヒット ヒット時に1 5 スキャンラインスプライト数 0:8個以下、1:9個以上 4-0 無効 (ビット4はVRAM書き込みフラグ[0:成功,1:失敗] との情報もあるが、NESにその機能はない) |
$2007 |
PPUメモリデータ PPUメモリのデータをバッファを経由して読み込む。 PPUメモリアドレスは+=1、もしくは+=32される。 |
パターンテーブルは$0000もしくは$1000から開始し、 それぞれ256個のパターンを持っています。 一つのパターンは8x8ピクセルで構成され、16バイトを要します。 各ピクセルはカラーパレットの下位2ビットのデータを保持します。
例として、パターンテーブル$1000を使用し、 53番目のパターン(パターンIDは$34)を描画すると次のようになります。
ADDR DATA $1340 $C0 11000000 -- $1341 $C0 11000000 | $1342 $C0 11000000 | $1343 $F0 11110000 | $1344 $F8 11111000 | $1345 $DC 11011100 | Low -- 01 01 00 00 00 10 10 00 $1346 $CE 11001110 |======| 01 01 00 00 10 10 00 00 $1347 $00 00000000 -- | 01 01 00 10 10 00 00 00 | 01 11 11 11 00 00 00 00 $1348 $06 00000110 -- | 01 01 11 11 11 00 00 00 $1349 $0C 00001100 | High | 01 01 00 11 11 11 00 00 $134A $18 00011000 |======| 01 01 00 00 11 11 11 00 $134B $70 01110000 | -- 00 00 00 00 00 00 00 00 $134C $38 00111000 | $134D $1C 00011100 | $134E $0E 00001110 | $134F $00 00000000 -- |
カラーパレット下位2ビット
|
BG(Back Ground)は8×8のタイルパターンを32×30個配置することで、 256×240ピクセルの解像度を持ちます。 BG描画は、まずスキャン座標と設定されたスクロール値によって算出された座標を、 範囲内に持つネームテーブルから描画するパターンのアドレスIDをフェッチします。 また、色情報として属性テーブルからデータをフェッチします。 次にパターンアドレスIDに対応する下位パターンと上位パターンをフェッチします。 パターンは上位ビットから描画され、 下位パターンと上位パターンの各ビットが有効なら、 色情報とパターンビットによりBGパレットから色が選択されます。 パターンのいずれのビットも有効でなければ透過色となり、 スプライトパレットの$3F10の色が選択されます。
アドレス | サイズ | 用途 |
$0000〜$0FFF | $1000 | パターンテーブル#0 |
$1000〜$1FFF | $1000 | パターンテーブル#1 |
$2000〜$23BF | $03C0 | ネームテーブル#0 |
$23C0〜$23FF | $0040 | 属性テーブル#0 |
$2400〜$27BF | $03C0 | ネームテーブル#1 |
$27C0〜$27FF | $0040 | 属性テーブル#1 |
$2800〜$2BBF | $03C0 | ネームテーブル#2 |
$2BC0〜$2BFF | $0040 | 属性テーブル#2 |
$2C00〜$2FBF | $03C0 | ネームテーブル#3 |
$2FC0〜$2FFF | $0040 | 属性テーブル#3 |
$3000〜$3EFF | $2000-$2EFFのミラー | |
$3F00〜$3F0F | $0010 | バックグラウンドパレット |
$3F10〜$3F1F | $0010 | スプライトパレット |
$3F20〜$3FFF | $3F00-$3F1Fのミラー×7 |
PPUはVRAM、スプライトRAM、パレットRAM、カートリッジのCHR-ROMにアクセスし、 メモリマップは表のようになっています。 パターンテーブルはカートリッジへのアクセスとなります。 ネームテーブルと属性テーブルは4組あり、 画面のスクロールに関連してVRAMとカートリッジ内の拡張RAMにマップされ、 その割り当てはカートリッジによって異なります。
スプライトRAMは256バイトが存在します。 一つのスプライトに4バイトが割り当てられるため、64個分のスプライトデータが保持できます。
offset | 用途 |
0 | Y座標-1 |
1 | パターンインデックス |
2 |
アトリビュート VHP000CC ||| || ||| ++-カラーパレット上位2ビット ||+------BGとの優先順位、0:SPR優先、1:BG優先 |+-------左右反転フラグ、1:反転 +--------上下反転フラグ、1:反転 |
3 | X座標 |
描画されるべきスプライトのために、 スプライトテンポラリレジスタとスプライトバッファレジスタが8スプライト分だけ存在します。 あるラインにおいて次のラインで描画されるべきスプライトが見つかった場合、 スプライトテンポラリレジスタに保持されます。 スプライトの探索の後、 スプライトテンポラリレジスタに基づいてスプライトバッファレジスタにスプライトのパターンがフェッチされます。 このパターンデータが次のラインで描画されます。 またスプライト用レジスタの最初のスプライトはスプライト#0と呼ばれます。 このスプライトがBG上に描画されるピクセルにおいて、ヒットフラグがセットされます。 このヒットフラグの利用例として横スクロールゲームなどでは、 ヒットするまでは横スクロール値を0として点数やタイムなどの情報を描画し、 ヒットが検出されたら横スクロール値を設定してスクロールしたゲーム画面を描画しています。
PPUは341クロックで一つのラインの描画と次のラインの準備を行います。 最初の256クロックでBGとスプライトの描画を行いながら、 次のスキャンラインで描画されるべきスプライトの探索を行います。 残りのクロックで探索されたスプライトのパターンを取得します。
PPUの外部へのメモリアクセスは、BGの256ピクセルを描画する間、
を33回繰り返します。 また、水平帰還の間に次のスキャンラインで描画されるスプライトのために、 スプライトパターンから2バイトのフェッチを8回繰り返します。
フレームは262本のスキャンラインで構成されます。 最初の240本で画面が描画され、残りのスキャンラインは垂直回帰時間となり、 CPUはこの時間を利用してVRAMへの書き込みを行います。 この垂直回帰タイミングのために,PPUはCPUに対してNMI割り込みを発生させます。