- ようやく捌き終えたテープの中身を、フロッピーと言う皿に盛り付けにかかるわけである。ここからが、また、悩み多き道のりであった。
ディスク版ローダを作成する †
ディスク版ローダ作成にあたってのネック †
- 取り出したマシン語ファイルをどのような手順でロード(メモリー上にセット)していくかが次の課題である。オリジナルのテープ版IPLの様に、ディスク版を全部マシン語で書ければ話は簡単なのだが、残念ながら能力オーバーだ(^^;)ディスドライブのコントロール部分がよく分からない。まして、独力でルーチン作るなど逆立ちしても無理な話だ。
- 従って、N60m_Basicのディスク関係のコマンドを利用してマシン語ファイルを順次Bloadすることを考えたのだが、2つの大きな制約があって最後までBasicだけでLoaderを動作させることはなかなか難しい。その理由は、
- フリーアリアをすべて使い切っている。
メインプログラム”DoorM3.PRG”をLoadするとBasic領域も消滅する
- Workエリアも使い切っている
”DoorM0.CHR”(EF00H~)をLoadすると、システムが暴走する恐れ
ぎりぎりまでBasic環境を使い切るには †
- こうしたエリア不足に対してどうするかが、知恵の絞りどころだ。 マシン語の処理は避けられないが、どうしたら最小限で済むかだ。
- まず、”DoorM3.PRG"のBLOADについてだが、そもそもアドレスがBasic領域と重なるのため、直接Basicコマンドに頼ることはできない。ただ、マシン語といっても、ROM内ルーチンを呼び出す方法を使えば、これで何とかなると見通しがつく。
- 一方、”DoorM0.CHR"については、どこか邪魔にならないアドレス領域のすき間に仮Loadしておいて、ゲーム実行(マシン語のMainProgramが走る)直前に、正規のアドレスにブロック転送するという方法が考えられる。仮ロード先としては、タイトル画面用のGV-RAMをつぶししかないだろう。
- マシン語のお世話になる必要は免れないが、フロッピーからのマシン語ファイルの読み込みさえ完了してしまえば、後は何とか組み立てられそうだ。もっとも、このマシン語の「スタートルーチン」自体をどこにおくのか? それが、また問題だ。
ディスク版ローダの基本機能 †
- 基本的には、オリジナルのテープ版BASICのIPLを踏襲するのだが、いろいろ欲も出てきて盛りだくさんとなる。
- 面選択処理はそのまま利用する
- タイトル表示方法も、オリジナルと同じに上下から縞状表示にしたい
- 当然、タイトル表示と同時にBGMも流したい
- 無敵化も隠しコマンドで仕込みたい
- その上で、前項のBasicの制約を回避するため、マシン語ルーチンをいくつか作成する必要がある
- 以下に、これらの検討結果をまとめる。
①面選択 †
- 面選択画面はテープ版をそのまま拝借する、特に問題ない
④無敵化などの改造 †
- 無敵化とは、主人公CHUNが敵に触れても数が減らないようにすることである。
- これはメインプログラムを調べて、CHUNの数を格納しているデータエリアの減算処理を無効にするのが基本的な方法である。
- 手探りだが、何とかデータエリアは見つかる。また、この値を減算する処理も判明した。
- もうひとつの改造は、ゲームの開始面を途中からにできないかと考えた。いくら無敵化しても、毎度毎度1面からプレイしなきゃならないのはシンドイわけ。
- これも、play面数を管理しているデータエリアを探ることからはじめる。同様に見つけたのだが、実際の処理は複雑で、意味がよく分からないのだが、50面か35面かを判定して何やらやっているようだ。試行錯誤で、このチェック面の数値を書き換えれば何とかなることが分かった。
②タイトル表示 †
- テープから1バイトずつ読み込むように、上下から縞状斜め表示をさせるにはどうするか!
- あらかじめ縞状に配置したデータを読み込んでも、一方向でスクロールするだけでは、つまらないし。
- 表示用のGV-RAMの実アドレスはPage3(0000h~)だが、裏のPage2(4000h~)が空いているので、いったんそこへLoadして、そのデータをピックアップしながら、本来のPage3のアドレスに転送していくことにした。
- このデータのピックアップと転送処理は簡単なマシン語で作成することにした。4000h~は通常ROM領域であるが、これをRAMに切り替えてデータを読込む必要があるが、これはBIOSルーチン(FE8Dh)をCALLすれば簡単だ。
- ただ、マシン語で処理すると表示が速く進みすぎて、テープと比べてかなり違和感がある。BGMが尻切れトンボと言う感じになってしまうので、少しウェイトをかけて表示スピードを落とすことにした。
③BGMの処理 †
- BasicIPLの解析でも書いたように、BGMの処理ルーチンはデータ含め5100h~635Fhに配置されていた。エントリーアドレスは55BBhである。
- ここは裏RAM領域なので、Basicのコマンドを使ってDISKからファイルを読み込んでいる間は、実行することができない。それではBGMにならない
- 従って「ユーザエリアB」に置いても問題なく動作するかが鍵だ。 つまり、再配置可能(ReLocatable)にできるか、それはプログラムに絶対アドレス依存性があるかどうかなのだ。もしあれば、転送先のアドレスに合わせて内容を修正する必要がある。
- 解析の結果、BGM処理モジュール内で実アドレスを直接指定している個所が確かにあった。これを変更するほか、割り込みワークエリアを変更している個所もあって、そのアドレスも変更すればよいことが判明した。
- データ部については元来アドレスに依存しないと思っていたのだが、何とそのままではとんでもないメロディになってしまった。よく調べたら、5630h~635Fh間にアドレスに関係ありそうなデータが埋め込まれているようで、この辺を拾い出して変更したらメロディが復活した。
- 最終的に修正したBGM処理モジュールはE100h~にセットすることにした。実は、”M0”や”M1”の配置とも絡んでくるのだが、両者のファイル構成を組みなおして空き領域を確保することにした。(後述)
最終的なDisk版Loaderの構成方法 †
- オリジナルのBasicIPLをベースに、上記の変更や追加を行うことにする。
- 面選択までは、オリジナルのBasicプログラムを使う。
選択した情報により、ロードする面データファイルを指定する形にする
- 無敵化については、面選択時の隠しコマンドで画面を表示して、
全マシン語ファイルをロード後に、該当アドレスにパッチを当てる形にする
- 基本的に抽出したマシン語ファイルのLOADはBasicで行う。
従って、一部は隙間の空きアドレスに仮配置しておく。
また、システムの制約上、BasicROMルーチンを直接CALLしてBLOADする必要もある。
- こうした特殊な処理をするためのマシン語によるスタートルーチンは別個に作成し、空きアドレスに配置しておく。
キャラクタデータの再構成による空メモリーの確保 †
- ファイルのLoadが終わるまでのマシン語処理は2つ必要になる。一つは、BGMの再生ルーチン。もう一つは、最後のマシン語ファイル”M0”や”M3”をBloadするためのスタートルーチンである。
- ”M3”のLoadでフリーエリアの大部分は消滅するが、Basicシステムとしての動作はまだ持続させておく必要がある。従って、これらのルーチンは、「ユーザエリアB」(高位32KBエリア)に配置場所を確保しなければならない。
- そこで一考。BGMルーチンも含めて、まとまったメモリー領域を確保するため、キャラクタデータ”M0”と”M1”を再構成することにした。
- ”M1”の後半0F00h分を削って、”M0”先頭に結合することにした。これでE000h~のメモリ領域を確保できるようになる。
- そもそも”M0”と”M1”は、最終的には”M1”-”M0”の順で連続したメモリー配置になるものだし、切り出す時の作業の関係上分離したものとも言える。また、”M0”は裏RAM(GV-RAM)へ仮配置して最終段階で実アドレス転送するものだから、多少サイズが大きくなっても何ら問題はない。
- ”M0”の”M1”ファイル構成の変化を整理しておくと、
ファイル名 | 旧アドレス | サイズ | → | 新アドレス | 新サイズ | 保存アドレス |
”DoorM0.CHR” | EF00h-FEFFh | 1000h | → | E000h-FEFFh | 1F00h | 2000h-3EFFh(仮) |
”DoorM1.CHR" | B220h-EEFFh | 3CE0h | → | B220h-DFFFh | 2DE0h | B220h-DFFFh(実) |
- ディスクファイル化したマシン語ファイルの最終構成は、以下のようになる。