[MSX0][実験] 16KBのROMイメージをRAMにロードして起動するプログラムをCプログラム(Z88DK)で作成してみる #MSX #MSX0

能書き

MSX実機やMSX0のBASICモードにおいて、ディスクに保存されている16KBのROMイメージファイルをRAMにロードしてリセットし、そのRAM領域をROMカートリッジとして認識させ、ゲームソフトなどを起動するための手順です。

本エントリの内容はあくまで個人的に実験したいからやっているものであり、MSX-DOS環境が使える場合、SofaRunなどすでに同種のソフトは存在しており、そちらを使うほうが16KB以外のサイズのROMイメージにも対応しており、簡単便利かつ確実かと思われますので、あしからずご了承ください。

ROMイメージをRAMにロードしてROMカートリッジとして認識させるには

MSXでRAMを64KB搭載している場合、BASICモードではページ0〜3のうち、ページ0〜1はBASIC ROMとして使われている(ROMのあるスロットが選択されてCPUから見える状態になっている)ので、ページ0と1に割り当てられているRAMは特に使われていない状態です。

このうち、ページ1に割りあたっているRAMに16KBのROMイメージの内容を転送し、ソフトリセット(0000H番地へのジャンプ)をすることによって、MSXのブートシーケンス内で、RAMに書かれた内容があたかもROMカートリッジの内容のように認識され、ROMカートリッジを挿したのと同じような状態でソフトを起動させることができます。

手順

MSXのBIOS(ENASLT)を使うと、メモリ空間上の特定のページを、任意のスロットのページに切り替えることができます。 ただし、ページ0については、BASICモードでは各種BIOSの内容が格納されている領域のため、ENASLTではページ0を別のスロットのものに切り替えることはできません。 16KBのROMカートリッジは、たいていページ1に割り当てられていることが多いので、ページ1にロードします。

手順の概略は次のとおりです。

  • 現状のスロット構成を読み込んで、変数に格納しておく
  • ページ1にRAMが格納されているスロットを特定する
    • BIOSで調べる方法もあると思われますが、この記事では手動で指定させています。
  • ENASLTをコールし、ページ1をRAMの格納されているスロットに切り替える
  • ディスクから1024バイト読み込む
  • LDIRを使って、読み込んだ内容が格納されているメモリ領域を、ページ1のメモリに転送する
  • 次の1024バイトをディスクから読み込み、以下同様に繰り返す
  • 全部ロードし終わったら、ROMイメージの先頭から3〜4バイト目に書かれたアドレス(INIT)を読み取る
  • INITが0でない場合は、INITのアドレスにインタースロットコールする
  • INITが0の場合は、0000H番地にジャンプ(ソフトリセット)

ソースコード

GitHubにアップしていますので、そちらをご覧ください。

https://github.com/MobileFF/msx0_sample/tree/main/ROMLOAD

注意点

MSX2+以降では、ブートシーケンス中に、RAMの内容をクリアする処理が追加されています。そのため、ソフトリセットしてROMイメージを起動させることはできません。 MSXのROMイメージにおいては、先頭から3バイト目(4002H)以降に記載の2バイトがINIT(初期処理としてジャンプする先の番地)になっていますので、ROMイメージロード後にスロット構成を元に戻さずに、直接INITの示す番地にジャンプするか、BIOSコールのCALSLTを使ってROMイメージの入っているRAMのINITへインタースロットコールすれば、MSX2+以降でも起動が可能なようです。一部のROMで試しましたが、問題なく起動できましたので、上記の起動手順もそのように修正しました。

コメント