5.2 FM音源をコントロール  いまやゲームのBGMや効果音には欠かせない存在となったFM音源。このページでは、マシン語プログラムからFM音源をコントロールすることに、挑戦してみよう。 5.2.1 マシン語プログラムで音を出してみよう。  前のページでも紹介していたように、拡張BAICを使えば、簡単にFM音源を操作することができた。でも、ゲームの効果音やBGMとして応用するには、マシン語プログラムが直接"FM-BIOS"を呼び出して、FM音源を操作する必要がある。  ここからは、MSX-Cで作られたプログラムがFM音源を操作するための、ライブラリーとプログラム例を紹介しようと思う。当然のことながら、このプログラムをコンパイルして実行可能なマシン語プログラムにするためには、"MSX-DOS TOOLS(またはDOS2 TOOLS)と、"MSX-C ver1.1(または ver1.2)"がそれぞれ必要になってくる。  さて、リスト5.3は、MSX-Cで作られたテストプログラムの"TESTFM.C"。"fmdata"という配列がテストデータで、バスドラムとスネアドラムを叩きながら、"ドレミファソラシド"を4回演奏させるものだ。このデータの作り方は、アスキーネットMSXにある、msx.specのボードで公開された資料にも書かれている。  それでは、プログラムを簡単に説明していこう。まずは、大きさが"FMWORK"バイトのauto配列である"fmwork"を用意する。そして、その番地からわたして、ライブラリーの"fmopen"を呼び出す。この配列は8000H以上の番地に置かれる必要があるので、staticではなくautoで宣言しておこう。  以上の手続きにより、FM音源の準備に成功すれば0が、FM音源がなければ1が、"fmwork"の番地が7FFFH以下ならば2が、それぞれ"fmopen"から返されるはずだ。  このとき注意しなければいけないのは、FM音源を使う前にかならず"fmopen"を呼び出し、プログラムが終了する前に、プログラムを終了してしまうと都合が悪いので、このライブラリーでは、CTRL+CキーやCTRL+STOPキーが押されても、無視するようになっている。  もしもFM音源を使ったプログラムを自作しようとしたときは、CTRL+Cキーや、ディスクエラーに対する処理をきちんとすることが大切だ。どんな場合でも、"fmclose"を呼び出してから、終了させるように注意しよう。  さて、データが入った番地と、演奏回数のパラメーターをわたして"fmstart"を呼び出すと、すぐにFM-BIOSが演奏を始める。このFM-BIOSは、タイマー割り込みで動くようになっているので、演奏を続けながらもプログラムを先に進めることも可能だ。このプログラムでは、演奏しながら画面に"Playing."とひょうじさせるようにしてみた。  "fmtest"は、演奏中ならば1を、演奏が終わっていれば0を返す。また"fmstop"は、演奏を終了させて、FM-BIOS"を初期化するためのもの。 5.2.2 ライブラリーの概要を説明する  リスト5.4に掲載したのは、FM音源ライブラリーの関数と定数を定義するための、ヘッダーファイル"FMLIB.H"。  そして、次の長大なリスト5.5が、FM音源ライブラリーだ。リストのはじめから順番に、BIOSなどの番地の定義、FM-BIOSを呼び出すマクロ定義、ライブラリーが使用するワークエリアの定義、そしてライブラリーのプログラム本体が書かれている。  プログラムのポイントを解説すると、まず"fmopen@"は、"ontime"からのタイマー割り込み処理プログラムをべつの番地に転送し、FM-BIOSが置かれているスロットを探し、初期化し、タイマー割り込みフックを設定するためのもの。割り込み処理プログラムと、それが参照するデータは、8000H番地以上に置かれる必要があるので、プログラムを転送して、"ld iy,0"という部分を、"ld iy,FM-BIOSのスロット番号*256"に置き換えている。  FM-BIOSが置かれているスロットを探すプログラム自体は、アスキーネットMSXに公開されている、FM-BIOSの仕様書から引用した。全部のスロットについて、401CH番地に、"OPLL"という文字列があるかを調べることで、FM-BIOSを探している。  さて、"fmopen@"にわたされた192バイトのワークエリアは、割り込み処理プログラム、"h.timi"の元の内容の保存場所、FM-BIOSのワークエリア(160バイト)に使われている。このときにFM-BIOSのワークエリアを用意し開始番地を切り上げている。  これは仕様書にかかれていなかったけど、"CALLFM_iniopl"で、FM-BIOSを初期化すると、ページ1がべつのスロットに切り替えられたまま戻ってくることがあった。かならず、ページ1を元のスロットに戻す必要がある。  前にも書いたように、タイマー割り込みフックを書き換えたままプログラムを終了すると困るので、MSX-DOSのワークエリアのF325H番地を書き換えてCTRL+Cキーを処理するプログラムを追加する必要がある。そして"fmclose@"は、タイマー割り込みフックとCTRL+Cキーの処理を元に戻すためのものだ。  ライブラリーの残り部分については、レジスターに必要な値を入れて、FM-BIOSを呼び出すだけで使用することができる。各自にいろいろ試してみよう。 5.2.3 MSX-Cでコンパイルしよう  MSX-DOSのMEDやKIDなどのエディターでリストを打ち込んだら、リスト5.3を"TESTFM.C"、リスト5.4を"FMLIB.H"、そしてリスト5.5を"FMLIB.Z80"というファイル名をセーブしよう。次の手順でコンパイルすると、"TESTFM.COM"ができるはずだ。プログラムを実行するには、MSX-DOSのコマンドラインから"TESTFM←"と入力すればいい。