VRAM初期化ルーチンの作成
ネームテーブル初期化ルーチンを弄ってVRAM初期化ルーチンを作成した。
こちらはネームテーブル初期化ルーチン。
; ネームテーブルの消去 ; A=消去するネームテーブル clearNT: ldy #4 cmp #00 ; Aレジスタ分岐 bne .clear1 .clear0: ; ネームテーブル0 ($2000-$23FF) lda $2002 lda #$20 sta $2006 lda #$00 sta $2006 tax beq .loop .clear1: ; ネームテーブル1 ($2400-$27FF) lda $2002 lda #$24 sta $2006 lda #$00 sta $2006 tax .loop: sta $2007 inx bne .loop dey bne .loop rts
でもって、野うさぎ亭さんのところの解説を改めて読み返し。
※以下表の引用
■PPUアドレス空間に対する画面の割り付け
NESDEV wikiより引用 (0,0) (256,0) (511,0) +-----------+-----------+ | | | | | | | $2000 | $2400 | | | | | | | (0,240)+-----------+-----------+(511,240) | | | | | | | $2800 | $2C00 | | | | | | | +-----------+-----------+ (0,479) (256,479) (511,479)
■ミラーリング選択時におけるPPU用RAMアドレスの変化
PPUのアドレス | RAMのアドレス (水平ミラーリング) |
RAMのアドレス (垂直ミラーリング) |
---|---|---|
$2000~$23ff | $0000~$03ff | $0000~$03ff |
$2400~$27ff | $0000~$03ff | $0400~$07ff |
$2800~$2bff | $0400~$07ff | $0000~$03ff |
$2c00~$2fff | $0400~$07ff | $0400~$07ff |
上記を踏まえた上で先のコードを見てみると、
垂直ミラーリング設定時にしかVRAM全体が初期化出来ていない事が分かる。
(水平ミラーリング設定時、ネームテーブル1を指定しても
VRAMアドレスはネームテーブル0と等しいままなので、
結果VRAM前半を2回初期化してしまっている。)
ミラーリング設定に関係無くVRAM前半・後半を
確実に初期化するには以下のように書く。
; 内蔵VRAM領域をクリアする ; A=消去するVRAM範囲 0:VRAM前半, 1:VRAM後半 clearVRam: ldy #4 cmp #00 ; Aレジスタ分岐 bne .clear1 .clear0: ; VRAM前半 ($0000-$03FF) lda $2002 lda #$20 sta $2006 lda #$00 sta $2006 tax beq .loop .clear1: ; VRAM後半 ($0400-$07FF) lda $2002 lda #$2c sta $2006 lda #$00 sta $2006 tax .loop: sta $2007 inx bne .loop dey bne .loop rts
なお、マッパー30のような外部RAMを利用した4画面モードの場合、
サクッと対応させるなら前述のネームテーブル初期化ルーチンに
ネームテーブル2・3も初期化するよう処理を増やしてやれば良いだろう。