Chapter.0-B 下準備

作るのはシューティングゲームです。
まぁ、スター○ォースみたいなのが出来ればいいかなと思います。
ターゲットマシンは、MSX2以上。
SCREEN4 を使って、多重スクロールとかも実現していこうと思います。
開発は、Windowsマシンを使います。

ちゃんと仕様を練ってから作った方が良いのですが、早く動きを見て楽しみたいので、
そういうめんどくさいことは省いていきます (^_^;

最終的に ROM化も考慮して、フルアセンブラでつくります。
BASIC や C は使いません。ただし、各部の単体テストには BASIC を活用していきます。

■アセンブラの準備

Z80等のマイコン向け Cコンパイラとして、SDCC というものがあります。
gcc をベースに、マイコン向けに機能修正したモノのようですが、この Windows版をダウンロードして、
Z80用のアセンブラ AS-Z80 と、リンカ LINK-Z80 を利用させて貰うことにします。

SDCC のページ: http://sourceforge.net/projects/sdcc/files/

無くなると困るので、抜き出したモノを置きました。

[これ]

このリンカは、ROMへ焼くために便利なように出力するので、この出力そのままでは使いにくいです。
当面は BASIC で動作テストを実施するので、BASIC から気軽に読み込める BSAVE形式に変換するツール
ihx2bin を別途作成して、[これ]
に入れておきました。
そのツールの中身については、後ほど解説します。今は、BSAVEに変換するツール程度の認識でかまいません。

■アセンブラは何をするソフトか?

アセンブラは、ニーモニックで書かれたアセンブリリストを、機械語に変換するツールです。
ここでは、機械語とは、表1 のようなものを指します。

表1 機械語
3E 01 CD 80 01 C9

この記述で、「aレジスタに 1 を代入して、0180h番地をコールするサブルーチン」になるわけですが、
これがたとえば 16KB も続いていたら、どこが区切り目なのか分かりづらいので、せっかくの「作りたい」
という意欲が削がれてしまいます。
そこで、「3E 01」→「ld a,#1」、「CD 80 01」→「call #0x0180」と言った具合に、CPU が解釈できる
1機能を、比較的わかりやすい記号(「ld a,#1」等) に対応させて記述することにします。この記号を
ニーモニックと呼びます。
ニーモニックを組み合わせて記述するプログラムのことを、アセンブリリストなどと呼びます。
上の機械語を、アセンブリリストで記述すると表2 のようになります。

表2 アセンブリリスト
	ld	a, #1
	call	#0x0180
	ret

そして、普通はこのアセンブリリストの方だけを作ります。
これをアセンブラに通すことで、機械語を得るのです。

ちなみに、アセンブリリストを機械語に変換することを、アセンブルと呼びます。

■リンカとは何をするソフトか?

リンカは、複数のプログラムを結合(リンク)するツールです。

CPU が用意している命令は非常に細かい単位のものしかありません。
しかし、普通は1行に1命令ずつ記述します。
なので、ゲームなどになるとかなりの行数になります。
それを1つのプログラムリスト(以下ソース)で作ると、管理が大変になってしまいますので、複数の
ソースに分けて記述するのが一般的です。

たとえば、自機の処理は player.asm に記述、敵1の処理は enemy1.asm に記述・・と言った具合です。
これなら、目的の処理の場所にたどり着くのも早いですよね。

これらをくっつけて、一つのプログラムに仕立てるのがリンカの役割です。

ただし、これらを個別にアセンブルすると、アセンブラはそれぞれがどのように組み合わされるのか
分からないためにサブルーチンなどのアドレス情報が確定しません。

たとえば、player.asm から、sprite.asm の中のサブルーチンを呼んでいたとします。
普通はサブルーチンにも名前を付けて呼び出しますが、その名前がどのアドレスになるのか分からない
ために、player.asm の機械語の一部が確定しません。上の例の CD 80 01 の 80 01 がサブルーチンアドレス
ですが、こいつが分からないと CD ?? ?? になってしまいますよね。

実は、用意したアセンブラは、名前とそれが使われれている場所の情報を含めてアセンブルします。
そして、リンカが具体的に名前に対応するアドレスを決定し、最終的なメモリイメージをはき出すのです。

■変換

用意した SDCC のアセンブラ/リンカは、MSX用に作られたモノではありません。
MSX の BASIC から呼び出すためには、BSAVE形式が最適だと思いますが、BSAVE形式は MSX 独自の形式
であるため、SDCC のリンカは BSAVE形式をサポートしていません。

SDCC のリンカは、より一般的な "ROM writer" という装置が読み取りやすいヘキサファイルを出力します。
ROM writer とは、MSX でも使われている ROMカートリッジの中にある ROM IC に、プログラムを書き込む装置
です。

今回は、ヘキサファイルの一種である IntelHEXファイル (*.ihx) を BSAVE形式に変換するツールを私の方で
作成しました。ihx2bin.exe がそれです。
この中身を理解しなくても問題ないので解説しませんが、ソースリストは置いておきます。
興味がある場合は、自分で解析してください (^_^;

ihx2bin.c

■フォルダ構成

アセンブラ as-z80.exe とリンカ link-z80.exe と変換ツール ihx2bin.exe
を、bin フォルダに入れます。
bin フォルダと同じ場所に並べて、chapter1 フォルダを作成します。そのフォルダの中に、chapter1 のファイル類
入れます。

bin
  as-z80.exe
  link-z80.exe
  ihx2bin.exe
chapter1
  mk.bat
  sca_player.asm
  test_main.asm
  test1.bas
  test2.bas
  (略)

こんな感じの階層構造にします。chapter2 以降も、chapter1 と並べて置いてください。
*.asm が作成したプログラムです。エディタで開いて内容を確認出来ます。タブ文字は半角4の幅で見ることを推奨します。

この状態で、chapter1\mk.bat をダブルクリックすると、プログラムをアセンブルして、chapter1.bin が出来上がります。
chapter1.bin, test1.bas, test2.bas を 2DD ディスクに入れて、MSX で test1.bas や test2.bas を実行すると、動作を確認出来ます。
BlueMSX を使う場合は、「ファイル→ディレクトリ挿入」で chapter1 フォルダを指定して起動。run "test2.bas" などで、動作を確認出来ます。

■ビルド
実行できる機械語ファイルを生成することを「ビルド」と呼ぶことにします。
通常、ビルドには、makefile というスクリプトを使って、タイムスタンプを見ながら更新があったファイルだけをアセンブルしたりリンクしたりします。
ファイルがたくさん出来ると、時間がかかるという理由から、必要最小限の動作にして、ビルド時間を短縮しているわけです。

しかし、今時のパソコンなら、MSX のプログラムサイズは、一瞬でアセンブル&リンクしてしまいます。
また、makefile の文法は、記号主体のもので、慣れていない人には難解です。
なので、ここでは makefile は使わず、必ず全てのファイルをアセンブルして、リンクしていく方法にします。


AS-Z80.exe は、アセンブラリストを機械語に変換します。
たとえば、test_main.asm をアセンブルして test_main.o を作ります。
test_main.o もテキストファイルですので、エディタで開いてみてください。
16進数表記による機械語が並んでいると思います。
アドレスを示す名前も並んでいると思います。
この時点では、ニーモニックに対応する機械語コードだけが確定していて、具体的なメモリ上のアドレスは確定していない状態
ですので、アドレス部分には 00 00 が入っていたりします。

LINK-Z80.exe は、複数の *.o をリンクして、具体的なアドレスに配置していきます。
たとえば、10個の *.o があった場合に、.org 0xC000 が書かれている test_main はアドレスが決まっていますが、
それ以外の *.o は、test_main の後にどの順番で並べていくかによってアドレスが決まらないわけです。
そもそも、sca_player.asm だけを AS-Z80.exe に通す段階で、AS-Z80.exe は「test_main.asmとリンクされることを知らない」わけです。
なので、AS-Z80.exe にはアドレスが確定できないことは分かると思います。
LINK-Z80.exe には、chapter1.link のようなテキストファイルを渡し、どの *.o をリンクするのか、どの順番で繋げるのか・・を知らせます。
つまり、chapter1.link には、リンク対象となる *.o の一覧と、その結合順序が記述されているわけです。

chapter1.link の中身は以下のようになっています。

  -im chapter1
  test_main.o
  sca_player.o

最初の行の -im chapter1 は、「出力として chapter1.ihx と chapter1.map を書き出しなさいよ」という意味です。
chapter1.ihx がアセンブル結果で、chapter1.map は どのようにメモリ上にマッピングしたのかを示す情報ファイルです。
両方ともテキストファイルなので、エディタで開いて確認することが出来ます。

MSX-BASIC から呼び出そうとすると、ihx ファイルは簡単に読めないので、BLOAD形式に変換する必要があります。
そのためのツールが ihx2bin.exe になります。

これらの一連の処理をまとめたバッチファイルが mk.bat になります。

最初の方に if exist 〜 なんて文が少しありますが、これは前のビルド結果を削除する処理です。
もしエラーが出た場合に、*.o が生成されなかったとしても、前のビルド結果である *.o が残っていると、それをリンクして最後まで流れてしまう
場合があります。そのままエラーを見逃してしまう可能性もあるので、そうならないように先に綺麗にしてからビルドを開始するようにしてあります。

■準備完了

以上で、準備は完了です。
いよいよ次のchapterからは、実際にプログラムを組んでいきます。


[▲トップページへ]