優音デバッキングローダ
まずは優音のお勉強
96年夏に優音の配給を受けてから、ってちゃんと買ったんですが、かねてから温めていたμITRONの実装をしようといろいろ考えていました。が、やっぱり何か手をつけないとよくわからない。てぇんでまずは必要な「ローダ」を作ってみようということになりました。だってですね、優音にはコンソールも外部記憶も何もないんです。一頃はやった、98用のZ80/64180ボードみたいに拡張スロットに入っているだけのCPUボードですから、それなりのプログラムは必要ってわけです。とりあえずこれで優音は、いや64180ってのはどんなもんか理解できそうですしね。
優音って何ぞね?
一応説明せねばなるまい。優音というのは「MIDI I/Fを備えた64180ボード」のこと。64180を10MHzで動かし、512KBのRAMと2KBの共有RAMを持ち、標準のシリアルポートからMIDI信号を入出力することのできるボードのことです。これをMZ、標準的にはMZ-2500のスロットに挿入して使用します。別にMZ-2500でないといけないわけでなくて、MZ-80B以来のスロットと同じ物を備えたマシンならどれでも挿入できます。元々の設計思想としては、ゲーム等のBGMとする場合を考えると本体CPUに負担をかけたくない、MIDIの速度ってけっこう重い、それなら外部プロセッサにデータをまるごと渡せば事実上のバックグラウンドで演奏してくれる、というのがあったのではないかと思われます。それが、本体より大きいメモリ、本体より速いCPUというスペックがゆえに「アクセラレータ」と言われることが多々ありました。いや、今でもそう思っている人がいるような気がしますね。
優音とMZとのI/Fに割り込みを使用することができます。この割り込みをモード2としようと考えたのが優音の不幸の始まりだったのかもしれません。なぜなら、モード2割り込みを実現するにはデイジーチェーンが必要、しかしそれをディスクリートで実装するにはちょっとどころではない大変さがあります。これを楽に済ませるには、割り込み駆動回路としてZ80の周辺LSIを使用すること。設定のしやすさや汎用性からZ80PIOが選ばれました。しかし。
MZ-2500で動かしている分には何も問題はありませんでした。ところが、MZ-2800で動かそうとしても何の反応もないのです。どうもPIOが動いてない様子。制作者のtreeさんはついに音を上げてNiftyに質問の書き込みをしました。この時の書き込みを私も見たのですけど、私もおざなりの知識しか持ち合わせてなくて、「タイミングかなぁ」とかしか答えられなかったのでした。結局この時は、MZ-2800向けにはPIOでなくて8255を使用したもの、割り込みもモード2でなくてモード1で使用することで妥協しました。いや、発案者のY'Seena.さんは納得しなかったそうですが。
時は流れて、数年が過ぎていましたが、treeさんはまだ悩んでいました。またしてもMLで質問(というよりグチ)を流したのです。私もまだ解決してなかったことに驚きましたが、今度は工学社からI/O誌に掲載された回路図を入手していたので対応が違いました。結局は「M1に1ウェイト入るのに、*IORQと*IORDが合成されているMZ-2800ではリセットがかかりっぱなしになる」ということが判明してすぐ対処が施され、プリント基板化され、配布されたのです。
まぁ、スペックみたいなのはここのほうが詳しいでしょうからそちらをご覧あれ。
プログラムを転送せんと話になりまへん
スペックを見るとわかりますが、まずROMが搭載されてません。共有RAMにプログラムを載せられますので、そこの0番地から何か書いてあげればそれでブートできることになります。じゃ、2KB以上のプログラムはどうしましょう?ということでローダが必要になるわけです。どこかの番地にローダがいて、ハンドシェイクしながらデータをやりとりすれば、単位転送バイト数は少なくてもいくらでも転送できます。
ハンドシェイクといえば、実はtreeさんはdraft案ではありましたが共有RAMのいくつかの番地に特定の意味を持たせ、標準的なハンドシェイクプロトコルを規定しました。実はこれにそのまま従うと転送単位は256バイトになってしまうのですが、機能としては確かに必要なものを備えていたので従う価値のあるものだと感じました。実際にはちょっとだけ変更したのですけど。
そのハンドシェイクというかプロトコルには2種類あって、それぞれIDを確認するのとメッセージ通信に使用するのとに用途が分かれています。ID確認というのは、今優音にどんなプログラムが載っているのか、それに合わせてMZ側の振る舞いを変えるのか新たに優音にプログラムを転送するのかを判断する材料にするためのものです。こういう関係の配慮までしてあるというのはさすがです。というわけで、プロトタイプとなる私の初プログラムfor優音はそのID確認の返事をするプログラム。でもこれだけでも割り込みをかけてかかったら必要なデータを転送して、ときちんとプログラムしてあるのです。逆に、この辺りがちゃんとできたら今回のプログラムはできたも同然です。
増えるのは貯金だけにしてもらいたいもんだ
IDの確認ができたら同様にメッセージ通信のプログラムを作成。要は指定した範囲のデータをLDIRで転送するだけです。ですが、リセット直後はメモリ上には共有RAMしかありません。ローダは共有RAMに乗っかってしまうのでいいんですけど、他のメモリはどうしましょ。てなわけでMMUの設定をしないといけなくなりました。でも専用のコマンド作っても使い道少ないし、どうせI/Oポートをいじるだけなら汎用的に使えるものがいいよね、ということで単純にI/Oにデータを転送する(あるいは読み出す)コマンドに落ち着きました。でも転送データって論理メモリ(MMUで設定されてメインメモリに見えてるメモリ)だけじゃないとこにも転送したいよね。とすると論理と物理の両方のアドレスモードに対応したコマンドをそれぞれ用意することに。メモリが読めるんならレジスタもできると便利かもしれない。だったらブレークポイントで止まれたらなおいいか。てな感じにどんどん機能追加されていきました。
ミシンが勝手に裁縫するわけではない
今回作ったデバッキングローダは、いわば「ファームウェア」の範疇に入るものです。本当のデバッガとしての機能はMZに任せ、外から制御できない部分に対してデバッキングローダが適切な情報をMZとの間でやりとりするのです。ですから、MZの方に載せる「ホストプログラム」が必要です。96年年末に向けて、簡単に作ってしまおうということでMZ-2500のBASICでデバッガのようなものを制作しました。ここはユーザーインタフェースを提供する部分でもあるので、単なるI/Oボート入出力機能でしかなくなった該当コマンドを巧みに制御して、人間からはある程度視覚的にメモリの設定状態を見せながらMMUを設定するように工夫したりもしています。
96年冬コミOFFにようやく間に合わせ、そこでデモなどを行ったわけですが、treeさんなぞは「初めて人の作ったプログラムが動いているのを見た」と感動していらっしゃいました。最近でこそ「同人ハード」というのが増えましたが、それでもなかなか自分の作ったハードを人に提供してプログラムを作ってもらうなんていう機会はありませんからね。そういう意味ではうらやましくもあります。
意外と使わないかも
プログラムとしては、共有RAMにスタックも含めて全て収め、MMUを含む全てのI/Oとメインメモリを開放、呼び出し競合はMZ側で調停してもらいますがアプリが平行して走っていたとしてもNMIによって呼び出すので共存可能(アプリはINTで呼び出すと仮定している)ということで、わりかし高い要求レベルにも対応できるかと思うんですけど、もしかしたら自分でもどこまで使うかわからないような気がしています。ローダとしては余計な機能がつきすぎ、しかも転送単位が256バイトですからね。単機能なローダは新たに作り直すかもしれません。ではデバッガとしてはどうかというと、ホスト側のプログラムが結構面倒なんで、できるだけデバッガを使わないでソフトを制作するんではないかと思ったりもします。
では結局なんだったんだといえば、やっぱり冒頭に述べた「優音のお勉強」、つまり習作ですね。ただそんなにいい加減に作ってるわけではないので、ソフト制作にブランクが開いてもそれを参考にして思い出すことはできると思います。で、これを公開すれば他の人の参考にもなるかな、と。
優音って何人持ってたっけ…
ということで、制作したデバッキングローダをここに置いておきます。先ほどちらっと述べたBASICで作ったデバッガは入っていません。入れた方がいいかな。ちょっと別のとこにあるのでそれは改めてということにしてください。
その他のドキュメント、つまりファンクションとかを解説してあるものはちゃんと同梱してあります。何かの参考にしてください。