簡略化その②
前々回、同じ処理の繰り返しをループを使って簡略化(?)したわけですが…
例えば画面に表示したい背景の種類が増えてきた場合、この戦法は使えないわけで![]()
その都度プログラムで指定していたらめちゃくちゃ読みにくくなってしまうので、例えば今までで言うと、
- パレットの色
- どこにどの背景を表示するか
- どこにどのパレットを使うか
のデータをどこか下の方にまとめて入れて置いて、そこから順番にループでロードしてくる、みたいなやり方が出来ないかな?と。
と言いますか・・・ NES研究所さんのサンプル「Hello, World!」を見ると、下の方に
; パレットテーブルpalettes:.byte $0f, $00, $10, $20.byte $0f, $06, $16, $26.byte $0f, $08, $18, $28.byte $0f, $0a, $1a, $2a; 表示文字列string:.byte "HELLO, WORLD!"
って書いてあって、これを
ldx #$00ldy #$10copypal:lda palettes, xsta $2007inxdeybne copypal
とか
ldx #$00ldy #$0dcopymap:lda string, xsta $2007inxdeybne copymap
みたいに扱っていて、これをアセンブラでアセンブルするとプログラムの末尾にデータ部分がくっ付くみたいで、同じようにやりたいなっと。
で、いつも使ってる簡易アセンブラの方も同じやり方に対応しました✊
(というかまだ既成のアセンブラ使ってない💦)
ただ、例えば背景データを1画面(32×30=960タイル)分一気に読み込むのはループに使うレジスタが8ビット(最大256回)までなので、それ以下に分けて書かなければなりません・・
(現時点では他にいい方法を知りません💦💦)
そんなわけで、前回のプログラムを下記のように書き直しました。
;##################################################################################################; Famicom Programming "original" ©2023 gocchan.com;##################################################################################################START:LDA $2002BPL START;PPU初期化LDA #%00001000STA $2000LDA #%00000110STA $2001;パレットの設定LDA #$3FSTA $2006LDA #$00STA $2006LDX #$00LOAD-PAL:LDA PALETTES, XSTA $2007INXCPX #$20BNE LOAD-PAL;ネームテーブル書き出し(背景タイル)LDA #$20STA $2006LDA #$00STA $2006LDX #$00LOAD-NT1:LDA NT1, XSTA $2007INXCPX #$C0BNE LOAD-NT1LDX #$00LOAD-NT2:LDA NT2, XSTA $2007INXCPX #$C0BNE LOAD-NT2LDX #$00LOAD-NT3:LDA NT3, XSTA $2007INXCPX #$C0BNE LOAD-NT3LDX #$00LOAD-NT4:LDA NT4, XSTA $2007INXCPX #$C0BNE LOAD-NT4LDX #$00LOAD-NT5:LDA NT5, XSTA $2007INXCPX #$C0BNE LOAD-NT5;属性テーブル書き出し(割り当てパレット)LDA #$23STA $2006LDA #$C0STA $2006LDX #$00LOAD-ATTR:LDA ATTR, XSTA $2007INXCPX #$40BNE LOAD-ATTR;スクロール設定(背景のスクロール座標を0, 0にセット)LDA #$00STA $2005STA $2005;書き出した内容を画面に表示LDA #%00011110STA $2001PALETTES:.BYTE $0F, $11, $00, $00.BYTE $0F, $20, $00, $00.BYTE $0F, $17, $00, $00.BYTE $0F, $00, $00, $00.BYTE $29, $00, $00, $00.BYTE $0F, $00, $00, $00.BYTE $0F, $00, $00, $00.BYTE $0F, $00, $00, $00NT1:.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16NT2:.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16NT3:.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $0B, $0C, $0D, $0E, $0F, $10, $11, $12, $13, $14, $15, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16NT4:.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16NT5:.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16.BYTE $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16, $16ATTR:.BYTE $00, $00, $00, $00, $00, $00, $00, $00.BYTE $00, $00, $00, $00, $00, $00, $00, $00.BYTE $00, $00, $00, $00, $00, $00, $00, $00.BYTE $00, $00, $00, $10, $20, $00, $00, $00.BYTE $00, $00, $00, $00, $00, $00, $00, $00.BYTE $00, $00, $00, $00, $00, $00, $00, $00.BYTE $00, $00, $00, $00, $00, $00, $00, $00.BYTE $00, $00, $00, $00, $00, $00, $00, $00
このバイトデータ、殆どが"$16"(17枚目の背景)なんだけど、これが色々あったらねぇ…
こうしておけば画面のイメージも沸きやすいかな、と。
ドット絵職人🖌
プログラムの勉強だとしても「안녕하세요(アンニョンハセヨ)」の表示だけじゃつまんないなぁ。
なんかドラクエとかパックマンのキャラ表示して遊びたいなぁ…
とか思ったけど、たった16x16ドットでも著作権とかなんかメンドクサそう?
ならドット絵を自作しよう💡 ってことで、ツール「YY-CHR」を使って数時間かけて作った力作たちがコチラ✋
|
木 |
![]() |
石畳 |
![]() |
|---|---|---|---|
|
水面 |
![]() |
文字 | ![]() |
前回안녕하세요を表示するのに無駄にパレットを使っちゃったから、そのパレットを活かした感じでこれぐらいしか作れませんでした💧
あ、文字はNES研究所さんのサンプル「Hello, World!」に入ってるやつをお借りしました。
$31~$6Fまではアドレスと文字コード(ASCIIコード)を合わせてあるので文字列を渡すだけではその文字の背景を指定出来るようになってるみたい。
で、足りない部分はテキトーに自作して補充しました。
今回の簡略化で背景の指定もしやすくなったので、안녕하세요も順序よりツールでの見やすさ重視で並べ替えました。
CHRデータのテキストデータを作る
YY-CHRツールで保存すればCHRデータ(バイナリファイル)が出来るんだけど、今までのやり方だとテキストファイルのCHRデータが必要です。
テキスト➝バイナリならコマンドプロンプトでWindows標準の「certutil」を使えばいいんだけどその逆は・・・
とりま、うん十年前から愛用してるバイナリエディタ「Stirling」を使います✊
(ほかにいいソフトがあったら知りたいです💧)
ツールで保存したバイナリファイル「original.chr」をバイナリエディタ「Stirling」で開いて
左上から右下まで選択。
コピーしてテキストファイル「chr.txt」に貼り付けて保存するという力技を使います✊
データ部分の書き換え
今回はバイナリデータ部分を下記のように、
- パレットの色
背景用パレット1
0F 11 21 0D 背景用パレット2
0F 30 10 0D 背景用パレット3
0F 16 06 0D 背景用パレット4
0F 1A 27 0D スプライト用パレット1
29 00 00 00 スプライト用パレット2
0F 00 00 00 スプライト用パレット3
0F 00 00 00 スプライト用パレット4
0F 00 00 00 - 背景の番号(どこにどの背景を表示するか)
- 木(左上$80, 右上$81, 左下$90, 右下$91)
- 石畳(左上$82, 右上$83, 左下$92, 右下$93)
- 水面(左上$84, 右上$85, 左下$94, 右下$95)
- 文字=文字コード(ASCIIコード表 https://e-words.jp/p/r-ascii.html)
(例:A=$41)
- パレットの番号(どこにどのパレットを使うか)
- 木(%11)
- 石畳・세(%10)
- 水面・안・하・요・?(%00)
- 文字・녕(%01)
- 例)赤太枠23F1は右下何もなし(とりま%00)、左下木(%11)、右上石畳($%10)、左上石畳(%10)なので「%00111010」となります。(16進数で「$3A」って書いてもOK)
この表と見比べながら書き換えました。
バイナリデータ部分をこのように書き換えました
PALETTES:.BYTE $0F, $11, $21, $0D.BYTE $0F, $30, $10, $0D.BYTE $0F, $16, $06, $0D.BYTE $0F, $1A, $27, $0D.BYTE $29, $00, $00, $00.BYTE $0F, $00, $00, $00.BYTE $0F, $00, $00, $00.BYTE $0F, $00, $00, $00NT1:.BYTE $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $80, $81, $80, $81, $20, $20.BYTE $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $90, $91, $90, $91, $20, $20.BYTE $20, $20, $20, $20, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $80, $81, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $90, $91, $20, $20NT2:.BYTE $20, $20, $20, $20, $82, $83, $80, $81, $80, $81, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $84, $85, $84, $85, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $90, $91, $90, $91, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $94, $95, $94, $95, $92, $93, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $82, $83, $80, $81, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $84, $85, $84, $85, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $90, $91, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $94, $95, $94, $95, $92, $93, $20, $20, $20, $20.BYTE $82, $83, $82, $83, $82, $83, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $82, $83, $20, $20, $20, $20.BYTE $92, $93, $92, $93, $92, $93, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $92, $93, $20, $20, $20, $20NT3:.BYTE $20, $20, $20, $20, $82, $83, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $92, $93, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $82, $83, $20, $20, $20, $20, $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $20, $20, $20, $20, $20, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $20, $20, $20, $20, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1A, $20, $20, $20, $20, $20, $92, $93, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $82, $83, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $82, $83, $82, $83, $82, $83.BYTE $20, $20, $20, $20, $92, $93, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $92, $93, $92, $93, $92, $93NT4:.BYTE $20, $20, $20, $20, $82, $83, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $82, $83, $82, $83, $82, $83.BYTE $20, $20, $20, $20, $92, $93, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $92, $93, $92, $93, $92, $93.BYTE $20, $20, $20, $20, $82, $83, $84, $85, $84, $85, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $80, $81, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $94, $95, $94, $95, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $90, $91, $92, $93, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $82, $83, $84, $85, $84, $85, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $80, $81, $80, $81, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $92, $93, $94, $95, $94, $95, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $90, $91, $90, $91, $92, $93, $20, $20, $20, $20NT5:.BYTE $20, $20, $80, $81, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $82, $83, $20, $20, $20, $20.BYTE $20, $20, $90, $91, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $92, $93, $20, $20, $20, $20.BYTE $20, $20, $80, $81, $80, $81, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20.BYTE $20, $20, $90, $91, $90, $91, $20, $20, $20, $20, $20, $20, $20, $7F, $7F, "2023 gocchan.com", $20.BYTE $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20.BYTE $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20ATTR:.BYTE %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %11000000, %00110000.BYTE %00000000, %11101010, %00111010, %00001010, %00001010, %00001010, %10001010, %00000011.BYTE %10100000, %00101110, %00000000, %00000000, %00000000, %00000000, %10001000, %00000000.BYTE %00001010, %00100010, %00000000, %00010000, %10000000, %00000000, %10001000, %00000000.BYTE %00000000, %00100010, %00000000, %00000000, %00000000, %00000000, %10001000, %10101010.BYTE %00000000, %00100010, %00000000, %00000000, %00000000, %11000000, %10111011, %00000000.BYTE %11001100, %00111010, %00001010, %01011010, %01011010, %01011010, %01011010, %01010000.BYTE %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
ファイル結合&バイナリに変換と動作確認
ここでやったようにiNESヘッダーとPRG(命令)データ「prg.txt」とCHR(画像)データ「chr.txt」を結合し、バイナリデータを作成。
ファミコンエミュレータで実行すると、ちゃんと表示されました![]()
参考文献
魔法使いの森.“ファミコンの画面について”.https://www.wizforest.com/OldGood/ntsc/famicom.html
AnayaSoft.“ファミコンゲーム製作入門(SPECIAL版)“.書籍
ギコ猫でもわかるファミコンプログラミング.“第4章 パレット”.http://gikofami.fc2web.com/nes/nes004.html
NES研究室.“6502”.http://hp.vector.co.jp/authors/VA042397/nes/6502.html









