ネームテーブル初期化ルーチンを弄ってVRAM初期化ルーチンを作成した。
こちらはネームテーブル初期化ルーチン。
clearNT:
ldy
cmp
bne .clear1
.clear0:
lda $2002
lda
sta $2006
lda
sta $2006
tax
beq .loop
.clear1:
lda $2002
lda
sta $2006
lda
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前半・後半を
確実に初期化するには以下のように書く。
clearVRam:
ldy
cmp
bne .clear1
.clear0:
lda $2002
lda
sta $2006
lda
sta $2006
tax
beq .loop
.clear1:
lda $2002
lda
sta $2006
lda
sta $2006
tax
.loop:
sta $2007
inx
bne .loop
dey
bne .loop
rts
なお、マッパー30のような外部RAMを利用した4画面モードの場合、
サクッと対応させるなら前述のネームテーブル初期化ルーチンに
ネームテーブル2・3も初期化するよう処理を増やしてやれば良いだろう。