MAIN-ROMのスロット番号を得る

MSXのBIOSワークエリアには、下記のようなものが存在します。

EXPTBL (0FCC1h) ... Slot#0 の拡張の有無, MAIN-ROM のスロット番号
MAINROM (0FFF7h) ... MAIN-ROM のスロット番号

このうち 0FFF7h の方は、MSX2から追加になったワークエリアです。
MSX1で MAIN-ROM のスロット番号を得るためには、0FCC1h の方を読むしかありません。

しかし、Slot#0 の拡張の有無と、MAIN-ROM のスロット番号が同じアドレスというのが奇妙です。
販売された MSX は、確かにみな Slot#0 か Slot#0-0 に MAIN-ROM が存在していますが、
MSX1 を MSX2にアップグレードする「MSXバージョンアップアダプタ」という製品が実在していました。
これは、MSX1 のスロットに MSX2用の MAIN-ROM, SUB-ROM, VDP を増設することによって、MSX2 にバージョンアップ
してしまおうという製品です。
カートリッジスロットとして Slot#0 が出ていることはありませんから、バージョンアップアダプタを使った場合にのみ
MAIN-ROM が Slot#0 以外に配置されるケースが発生します。
そうなると、0FCC1h が「Slot#0 の拡張の有無」という情報と「MAIN-ROM のスロット番号」という情報とが共存出来なくなります。
実際どうなっているのでしょうか?

Twitterで情報が集まりましたのでここにまとめます。↓これはそのときのやりとり。
[外部リンク] Twitter
バージョンアップアダプタを所有している ぱるぷさん、有識者である ごりぽんさん・TINY野郎さん との情報交換の記録です。

【疑問点】
バージョンアップアダプタを使った場合、0FCC1h には一体何が格納されるのか?

【結論】
0FCC1h には、MAIN-ROM (バージョンアップアダプタ内の MSX2版) のスロット番号が、拡張の有無にかかわらず MSB=1 で格納される。
バージョンアップアダプタを使っている場合でも、0FCC1h を MAIN-ROMスロットとして使って問題ない。

【結論に至るまでの課程】
バージョンアップアダプタを装着した状態の MSX1 で起動して、MSX-BASIC上で下記を実行してもらう。
 10 PRINT PEEK(&HFCC1)
 20 PRINT PEEK(&HFFF7)
その結果、
 129
 129
が得られる。

[外部リンク] その確認のTwitter

129 といえば、二進数表記で 10000001 です。スロット番号のフォーマットと見なすと、Slot#1-0 (拡張有り) という意味です。
この時点で、本体内蔵 MAIN-ROM は Slot#0 か Slot#0-0 にしかあり得ないことから、0FCC1h はバージョンアップアダプタによって
上書きされていることが明らかです。

興味深いことに、この試した機種は Slot#0 は拡張されておらず、かつ Slot#1 には 基本スロットに直接 バージョンアップアダプタ が装着
されているのです。

[外部リンク] この機種の Slot#0 は拡張されていない

このカートリッジは、拡張スロットに装着して動作することが確認されています。

[外部リンク] その確認のTwitter

そのため、このバージョンアップアダプタカートリッジは、内部に拡張スロットを持っていない普通の ROMカートリッジであることが分かります。

[外部リンク] SUB-ROMはVDPカートリッジの中にある

では、0FCC1h に書き込まれる 129 = 0x81 という数値は何か?
ここで、0FFF7h の値も 0x81 であったことを思い出して下さい。Slot#1 は拡張されていないのに MSB = 1 になっています。

[外部リンク] 拡張の有無にかかわらず強制的に MSB=1 になる

TINY野郎さんの話と、実際の挙動が一致しています。そういうものなのでしょう。

ここからは、私の考察になります。

・バージョンアップアダプタによる MSX2版MAIN-ROM は、Slot#1, #2, #3 のいずれかの基本スロットか拡張スロットに搭載される。
・基本スロットに装着された場合、そのスロットにはバージョンアップアダプタしか存在しないため、そのスロットの 0FFFFh に何か書き込まれても無視される。
・拡張スロットに装着された場合、同一スロットの別の拡張スロットに何が装着されているか不明だが、0FFFFh は拡張スロット自身のレジスタが優先する。
・従って、拡張の有無にかかわらず、拡張されているものとして 0FFFFh の拡張スロットレジスタに書き込んでも、無視されるか、拡張スロットが順当に切り替わるか、だけなので問題は起きない。

・もともと MAIN-ROM は Slot#0 か Slot#0-0 のいずれかに搭載されている
・MAIN-ROM に切り替える場合、拡張されていなければ基本スロットレジスタ( I/O A8h )へ書き込む、拡張されてる場合はそれに加えて拡張スロットレジスタ (Memory 0FFFFh) に書き込む
・そのため、Slot#0 の拡張の有無 = MAIN-ROM のスロット番号、という扱いで問題なかった
・0FCC1h をそのままスロット選択に使うこと自体が普通だった

・ここに 0FCC1h の MSBはSlot#0 の拡張の有無・LSB側4bitはMAIN-ROMのスロット、のような使い方でバージョンアップアダプタが値を書き込むと不具合が起きる
→ MSB と LSB側4bit の指し示す内容が Slot#0のこと、MAIN-ROMのこと、と分かれてしまうため、それらが一致している前提のゲームなどが軒並み動かなくなる

・そこでそういった問題が起きにくい回避策として「拡張の有無にかかわらず MSB=1 にして LSB側4bit に MSX2版MAIN-ROMのスロット番号を書き込む」が採用されたのだと思います。

その回避策の場合、
・Slot#0 が拡張されていない場合、Slot#0 には本体内蔵の MAIN-ROM が存在するため、Slot#0 の Page3 は「未接続」か「MemoryMapperではない RAM」か「何らかのROM」であり、
 その 0FFFFh に書き込んでも、「未接続」「ROM」の場合は無視され、「RAM」の場合は書き込んだ値が保持されるのみ。
・Slot#0 が拡張されている場合、0FFFFh は拡張スロットレジスタであるため、Slot#0-x に MemoryMapperRAM が接続されていても、0FFFFh への書き込みでそのRAMに書き込まれることはない。
・バージョンアップアダプタが装着されたスロットも同様。
このような理由から、拡張されていなくても、拡張されているかのようなアクセスをして問題は起こらない。(余計な "0FFFFh への書き込み" という処理負荷は掛かるが、それだけ)
逆に、拡張されている可能性があるのに、拡張されていない指定(MSB=0)にしていると、拡張スロットが期待通りに設定されないため、うまく動かない問題が生じる。
MSB=1 を立てることによって、Slot#0 の拡張有無の値保持のフリ・Slot#N (バージョンアップアダプタのスロット) の拡張有無の値保持のフリの両方を兼ねられるのである。


厳密には、スロットが拡張されていなくても拡張されているかのような値になるので、
正確に拡張の有無を調べたいケースでは不具合が生じる。

Tiny Slot Checker での表示の崩れ

しかし、そういった使い方の方が希なので、バージョンアップアダプタの設計者は、より一般的な使い方を救える「常に MSB=1 で上書き」を採用したのだと思います。

【Special Thanks!!】
ふと疑問に思って、Twitterでダメ元で軽く投げかけたところ、あっという間に欲しい情報が手に入ってビックリしました。
情報を提供頂いたお三方には感謝です。特に、貴重なバージョンアップアダプタで実際の値を確認して頂いた ぱるぷさん には、大感謝です!
おかげさまで、もしかしたら一生真実に気が付かないかもしれないと思った疑問が氷解しました。
それとともに、0FCC1h の値を MAIN-ROM のスロット番号として使っただけでは、まだ「バージョンアップアダプタに対応」と言えることが分かりました。

2020年12月09日 更新
[戻る]