タイルセットタイルセットとは、ステージ内で使用するスプライト以外のグラフィックデータを束ねた管理ファイルです。
このデータは構造化されており、このタイルセットを通して、実際の地形/背景用グラフィックファイルをVRAMに転送しています。
タイルセットは1項目7バイトで、そのデータは次のようになっています。
転送するグラフィックファイルのバンク (1バイト)
転送するグラフィックファイルの16bitアドレス (2バイト)
グラフィックファイルの転送先VRAMアドレスおよびデータフォーマット指定 (2バイト)
VRAMに転送するサイズ (2バイト)
〇バンク
文字通り、転送するグラフィックファイルのバンクを指定します。0の場合、タイルセット定義の終了です。
〇グラフィックファイルのアドレス
文字通り、転送するグラフィックファイルの16bitアドレスです。上位8bitを先に読込んだバンク、下位16bitをこのアドレスとした場所からタイルセットは転送されます。
〇転送先VRAMアドレスおよびフォーマット指定
下位15bitが転送先のアドレスとなります。なお、実際の転送先アドレスはこの値の2倍です。
最上位ビットが立っている場合、このグラフィックファイルは圧縮されていることを示します。したがって、VRAMへの転送前に解凍処理が行われます。
最上位ビットがクリアされている場合、非圧縮生データですので直接VRAMへの転送が行われます。
〇転送サイズ
VARMに転送するサイズを指定します。このサイズ設定は、展開後のデータを基準にして行うため、
必ずしも個々のグラフィックファイルそのもののサイズではないことに注意してください。
なお、グラフィックファイルの転送はDMAを介して高速に行われます。
以下、タイルセット処理コードの逆アセンブリ(日本語版 V1.0)
Spoiler!
- Code: Select all
タイルセット転送
エントリポイント BB:80B0
BB:8CB5 8B PHB ;
BB:8CB6 F4 81 FD PEA #$FD81 ;
BB:8CB9 AB PLB ;
BB:8CBA AB PLB ; DB=$FD
BB:8CBB 0A ASL A ; タイルセット番号
BB:8CBC A8 TAY ;
BB:8CBD BE 9A 81 LDX $819A,Y ; タイルセットポインタ
BB:8CC0 E2 20 SEP #$20 ; A:8
BB:8CC2 BD 9A 81 LDA $819A,X ; バンク
BB:8CC5 F0 4D BEQ $8D14 ;
BB:8CC7 BD 9E 81 LDA $819E,X ; VRAMエントリ上位
BB:8CCA 30 4C BMI $8D18 ;
BB:8CCC C2 20 REP #$20 ; A:16
BB:8CCE 82 83 00 BRL $8D54 ;
//DMA転送準備
BB:8D54 E2 20 SEP #$20 ; A:8
BB:8D56 BD 9A 81 LDA $819A,X ; バンク
BB:8D59 85 28 STA $28 ;
BB:8D5B A9 7F LDA #$7F ; コピーデータの所在バンク(常に$7F)
BB:8D5D 8F 04 43 00 STA $00:4304 ; DMA A1B0
BB:8D61 C2 20 REP #$20 ; A:16
BB:8D63 A9 00 00 LDA #$0000 ; コピーデータの所在アドレス(常に$0000)
BB:8D66 8F 02 43 00 STA $00:4302 ; DMA A1T0L
BB:8D6A BD 9B 81 LDA $819B,X ; データアドレス
BB:8D6D 85 26 STA $26 ;
BB:8D6F BD 9D 81 LDA $819D,X ; VRAMエントリ
BB:8D72 8F 16 21 00 STA $00:2116 ; PPU VMADDL
BB:8D76 DA PHX ;
BB:8D77 BD 9F 81 LDA $819F,X ; 転送サイズ
BB:8D7A 1A INC A ;
BB:8D7B 29 FE FF AND #$FFFE ; 2バイトずつ転送するので偶数に切り上げ
BB:8D7E A8 TAY ;
BB:8D7F AA TAX ;
BB:8D80 B7 26 LDA [$26],Y ;
BB:8D82 9F 00 00 7F STA $7F:0000,X ; 転送するデータを7F:0000にコピー
BB:8D86 88 DEY ;
BB:8D87 88 DEY ;
BB:8D88 BB TYX ;
BB:8D89 10 F5 BPL $8D80 ;
BB:8D8B FA PLX ; コピー終了
BB:8D8C E2 20 SEP #$20 ; A:8
BB:8D8E 82 5B FF BRL $8CEC ;
BB:8CEC BD 9F 81 LDA $819F,X ; 転送サイズ下位
BB:8CEF 8F 05 43 00 STA $00:4305 ; DMA DAS0L
BB:8CF3 BD A0 81 LDA $81A0,X ; 転送サイズ上位
BB:8CF6 8F 06 43 00 STA $00:4306 ; DMA DAS0H
BB:8CFA A9 18 LDA #$18 ;
BB:8CFC 8F 01 43 00 STA $00:4301 ; DMA BBAD0
BB:8D00 A9 01 LDA #$01 ;
BB:8D02 8F 00 43 00 STA $00:4300 ; DMA DMAP0
BB:8D06 8F 0B 42 00 STA $00:420B ; CPU MDMAEN DMA転送開始
BB:8D0A C2 20 REP #$20 ; A:16
BB:8D0C 8A TXA ;
BB:8D0D 18 CLC ;
BB:8D0E 69 07 00 ADC #$0007 ; 次のデータを読み込む
BB:8D11 AA TAX ;
BB:8D12 80 AC BRA $8CC0 ;
//タイルセット読込終了処理
BB:8D14 C2 20 REP #$20 ; A:16
BB:8D16 AB PLB ;
BB:8D17 60 RTS ;
//VRAMエントリ上位が負数のとき:圧縮データ
BB:8D18 C2 20 REP #$20 ; A:16
BB:8D1A BC 9B 81 LDY $819B,X ; データアドレス
BB:8D1D BD 9A 81 LDA $819A,X ; バンク
BB:8D20 29 FF 00 AND #$00FF ;
BB:8D23 DA PHX ;
BB:8D24 BB TYX ;
BB:8D25 A8 TAY ;
BB:8D26 8B PHB ;
BB:8D27 4B PHK ;
BB:8D28 AB PLB ;
BB:8D29 22 9E 8D BB JSL $BB:8D9E ; 解凍ルーチン(割愛)
//DMA転送準備
BB:8D2D AB PLB ;
BB:8D2E FA PLX ;
BB:8D2F E2 20 SEP #$20 ; A:8
BB:8D31 BD 9D 81 LDA $819D,X ; VRAMエントリ下位
BB:8D34 8F 16 21 00 STA $00:2116 ; PPU VMADDL
BB:8D38 BD 9E 81 LDA $819E,X ; VRAMエントリ上位
BB:8D3B 29 7F AND #$7F ; 正数にする
BB:8D3D 8F 17 21 00 STA $00:2117 ; PPU VMADDH
BB:8D41 A9 7F LDA #$7F ; 展開後データの所在バンク(常に7F)
BB:8D43 8F 04 43 00 STA $00:4304 ; DMA A1B0
BB:8D47 C2 20 REP #$20 ; A:16
BB:8D49 A9 00 00 LDA #$0000 ; 展開後データの所在アドレス(常に0000)
BB:8D4C 8F 02 43 00 STA $00:4302 ; DMA A1T0L
BB:8D50 E2 20 SEP #$20 ; A:8
BB:8D52 80 98 BRA $8CEC ;
//未使用?
//ROMから直読みするようにDMAを設定している以外は処理は同じ。
//おそらくROMからの直読みの場合、前回のDMA転送が間に合わずバッティングすることがあるため、コピー処理で時間稼ぎをするようになっていると思われる。
BB:8CD1 E2 20 SEP #$20 ; A:8
BB:8CD3 BD 9A 81 LDA $819A,X ;
BB:8CD6 8F 04 43 00 STA $00:4304 ; DMA A1B0
BB:8CDA C2 20 REP #$20 ; A:16
BB:8CDC BD 9B 81 LDA $819B,X ;
BB:8CDF 8F 02 43 00 STA $00:4302 ; DMA A1T0L
BB:8CE3 BD 9D 81 LDA $819D,X ;
BB:8CE6 8F 16 21 00 STA $00:2116 ; PPU VMADDL
BB:8CEA E2 20 SEP #$20 ; A:8