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も初期化するよう処理を増やしてやれば良いだろう。