Ubuntuでファミコンプログラム その3(背景描画とパレット)

Ubuntuでファミコンエミュレーターで動くプログラムを作ってみてます。
Ubuntuでファミコンプログラム その2(YY-CHR)


こちらのサンプルソースとにらめっこしている状態です。
http://hp.vector.co.jp/authors/VA042397/nes/sample.html

前回までのソースは、
https://bitbucket.org/symfo/nes_sample/src
こちらのsample2においてます。





背景(ネームテーブル)



背景は、アドレス0x2000(エミュレーターによっては0x2020からが有効)からデータを書きこめば良いのでした。
この0x2000からの領域を「ネームテーブル」と言うようです。

YY-CHRを使用して、背景データ「character.chr」を編集してみます。

0x01の箇所に、四色の色を使った図形を定義しました。

266_01.png


パレットテーブルの出力をこのように修正しました。


  1. ; パレットテーブル
  2. palettes:
  3.     .byte    $0f, $17, $28, $39
  4.     .byte    $0f, $0f, $0f, $0f
  5.     .byte    $0f, $0f, $0f, $0f
  6.     .byte    $0f, $0f, $0f, $0f




左上に4つ上下に並べて0x01の図形を描画するようプログラムを修正し実行してみます。

266_02.png








パレット



ここからが本題なのですが、パレットでは4色の組み合わせを4つ、16色定義しています。
図形により使用する色を変更できるはずなのですがやり方がわからない。

例によって

ギコ猫でもわかるファミコンプログラミング - 第11章 BGスクロール
NES研究室 - グラフィック

ここを穴が開くほど眺めてわかったこと。



1.パレットは4色1セット。16色定義しているので、4色4セットある。

266_03.png




2.使用する色セットの指定は、0x23c0から書き始める。

この領域のことを「属性テーブル」と言うようです。




3.8x8の背景1つにつき、1つの色指定ができるというわけではなく、
8x8の背景を4ブロックまとめた塊に対して色の指定を行なっていく。

上手い説明が思いつかないのですが、背景を4x4の塊に分けて、左上を0x23c0とし、右下に向けて0x23ffまでのブロックに分けます。
各々のアドレスに対して、使用する色情報を指定していきます。

266_04.png




4.色の指定は8bitを4つに分けて、それぞれに0から3の色番号を指定する。

指定はビットの左側から「右下」「左下」「右上」「左上」になります。

これ、「左上」「右上」「左下」「右下」の順だと思ってて相当ハマりました。
冷静に考えると、ビットの下の方から見るとこの順になってますね。

266_05.png


この図のように色番号を指定したい場合は、
0x23c0のアドレスに11100100(二進数)を書きこめば良いことになります。




これらを踏まえて、属性テーブルのアドレス「0x23c8」の領域に
4x4の背景を描画します。

266_06.png

このパターンの色を変化させてやります。




パレットテーブルは、適当にこんな感じで定義します。


  1. ; パレットテーブル
  2. palettes:
  3.     .byte    $0f, $17, $28, $39
  4.     .byte    $01, $02, $03, $04
  5.     .byte    $05, $06, $07, $08
  6.     .byte    $09, $0a, $0b, $0c




属性テーブルへの書き込みはこんな感じ。


  1. ;属性テーブルへ転送
  2.     lda #$23 ;$23c8への書きこみ開始を通知
  3.     sta $2006
  4.     lda #$c8
  5.     sta $2006
  6.     
  7.     ldx #$00
  8.     lda #%11100100 ;左下3,右下2,左上1,右下0の色番号を適応
  9.     sta    $2007 ;go!




ちなみに、数値に%をつけると二進数表記になるそうです。$だと16進数。
#は即値で有ることを示しています。
これを付けないと、メモリのアドレスとして解釈されるようです。

このへんも勉強しなきゃいけません。


実行すると、狙い通りの動作になってくれました。長かった。

266_07.png


色は4つセットで指定しますが、最初の指定は無視される仕様だそうです。
実質使えるのは3色です。








サブルーチン(関数)の書き方



アセンブラのことがよくわかってないので、背景の描画はこんなソースを書いてます。


  1. ; ネームテーブルへ転送(画面の左上)
  2.     lda    #$20
  3.     sta    $2006
  4.     lda    #$80
  5.     sta    $2006
  6.     
  7.     ldx    #$00
  8.     ldy    #$04        ; 4文字表示
  9. copymap:
  10.     ;lda    string, x
  11.     lda #$01
  12.     sta    $2007
  13.     inx
  14.     dey
  15.     bne    copymap
  16. ;ネームテーブルへ転送(画面の左上2行目)
  17.     lda    #$20
  18.     sta    $2006
  19.     lda    #$a0
  20.     sta    $2006
  21.     
  22.     ldx    #$00
  23.     ldy    #$04        ; 4文字表示
  24. copymap2:
  25.     lda #$01
  26.     sta    $2007
  27.     inx
  28.     dey
  29.     bne    copymap2
  30.     
  31. ;ネームテーブルへ転送(画面の左上3行目)
  32.     lda    #$20
  33.     sta    $2006
  34.     lda    #$c0
  35.     sta    $2006
  36.     
  37.     ldx    #$00
  38.     ldy    #$04        ; 4文字表示
  39. copymap3:
  40.     lda #$01
  41.     sta    $2007
  42.     inx
  43.     dey
  44.     bne    copymap3
  45.     
  46. ;ネームテーブルへ転送(画面の左上4行目)
  47.     lda    #$20
  48.     sta    $2006
  49.     lda    #$e0
  50.     sta    $2006
  51.     
  52.     ldx    #$00
  53.     ldy    #$04        ; 4文字表示
  54. copymap4:
  55.     lda #$01
  56.     sta    $2007
  57.     inx
  58.     dey
  59.     bne    copymap4




あんまりなので修正しようと思います。
しかし、普通の言語なら関数にしてしまえば良いのですが、アセンブラでどう書くかわからず。


取っ掛かりがなくて困っていたのですが、ヒントになったのはこのサイト
65816命令表

関数の呼び出しと終了
JSR、JSL、RTS、RTL


なるほど、普通にプログラム書いてた時のノウハウは捨てて、
困ったときはCPUの命令表を見れば良いわけです。

「6502 命令表」で検索するといくつか候補が出てくると思います。

Mnemonic6502 for NES
NES研究室 - 6502


サブルーチンに行きたい時は、


jsr [ラベル名]




サブルーチンから呼び出し元に戻るには


rts





これを踏まえて、こんな感じにしてみました。


  1. ; ネームテーブルへ転送(画面の左上)
  2.     lda    #$20
  3.     sta    $2006
  4.     lda    #$80
  5.     sta    $2006
  6.     
  7.     ldx    #$00
  8.     ldy    #$04        ; 4文字表示
  9.     jsr copymap
  10. ;ネームテーブルへ転送(画面の左上2行目)
  11.     lda    #$20
  12.     sta    $2006
  13.     lda    #$a0
  14.     sta    $2006
  15.     
  16.     ldx    #$00
  17.     ldy    #$04        ; 4文字表示
  18.     jsr copymap
  19.     
  20. ;ネームテーブルへ転送(画面の左上3行目)
  21.     lda    #$20
  22.     sta    $2006
  23.     lda    #$c0
  24.     sta    $2006
  25.     
  26.     ldx    #$00
  27.     ldy    #$04        ; 4文字表示
  28.     jsr copymap
  29.     
  30. ;ネームテーブルへ転送(画面の左上4行目)
  31.     lda    #$20
  32.     sta    $2006
  33.     lda    #$e0
  34.     sta    $2006
  35.     
  36.     ldx    #$00
  37.     ldy    #$04        ; 4文字表示
  38.     jsr copymap




サブルーチン部分はこんな感じ。


  1. copymap:
  2.     lda #$01
  3.     sta    $2007
  4.     inx
  5.     dey
  6.     bne    copymap
  7.     rts





たかがこれだけのことでも知らないとわかんないもんです。



ソースは、
https://bitbucket.org/symfo/nes_sample/src
こちらのsample3においてます。




続きはこちら。
Ubuntuでファミコンプログラム その4(スプライト)




【参考URL】

ギコ猫でもわかるファミコンプログラミング - 第11章 BGスクロール
NES研究室 - グラフィック
NES研究室 - 6502
Mnemonic6502 for NES
関連記事

コメント

非公開コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ