以前作ったROMリーダを応用して、ROMカートリッジのリーダ&ライタを作ってみました。前回同様、I2C用のIOエキスパンダを使って、MSXカートリッジの信号線を制御することでカートリッジを分解せずともROMを読み出せるようになりました。
Read制御だけでなく、Write制御もできるようにしたため、メガロムのゲームも吸い出すことができます。
以前ブレッドボードで作ったROMリーダの記事はこちら
MSXカートリッジの信号線
MSXカートリッジの端子部分には50本の信号線が通っています。50本の信号線のアサインは以下のサイトに載っています。
これとZ80 CPUの信号線を見比べてみます。
電源など一部を除いた信号線をまとめたものが以下の表です。これをみると、Z80 CPUのほとんどの信号線がカートエッジコネクタに接続されていることがわかります。
Z80の信号線 | カードエッジコネクタ |
A0-A15 | あり |
D0-D7 | あり |
/M1 | あり |
/MREQ | あり |
/IORQ | あり |
/RD | あり |
/WR | あり |
/RFSH | あり |
/HALT | – |
/WAIT | あり |
/INT | あり |
/NMI | – |
/BUSRQ | – |
/BUSAK | – |
/CLK | あり |
/RESET | あり |
カートエッジコネクタに出ていない Z80 信号線は、/NMI, /HALT, /BUSRQ, /BUSAK のみです。Z80で実現できることは MSX ではほとんどのものは実現できそうです。MSXの仕様策定当初から、ゲームができるだけでなく、HWの拡張性に重きをおいていたことが伺えます。
/BUSRQ, /BUSAK は Z80 からバスの制御権を取得する信号線ですが、これが使えないということはカートリッジ側からDMAでデータをメインRAMに転送するというような使い方はできないようです。バスの主導権はCPUが常に握っているということですね。
ROMカートリッジへのメモリアクセス
ではカートリッジ内のROMにアクセスするにはどのように信号線を制御すればよいのでしょうか。その方法も以下のサイトに記載されています。
上記サイトの図1.27 メモリサイクル(基本スロット) の図を以下に引用します。
基本的なパラレルRAMのRead/Writeアクセスと同じです。
細かいタイミングは無視して、Readする手順を順番に書くと以下のようになります。
- A0〜A15にアドレスを出力する
- /MREQ, /SLTSL, /CS, /RD を Low にする
- しばらくすると D0〜D7 にデータが出てくるので読み取る
- /MREQ, /SLTSL, /CS, /RD を High にする
Writeは以下です。
- A0〜A15にアドレスを出力する
- /MREQ, /SLTSL, /CS を Low にする
- D0〜D7に書き込むデータを出力する
- /WR を Low にする
- /MREQ, /SLTSL, /CS, /WR を High にする
このように、A0〜A15, D0〜D7、/MEMRQ, /SLTSL, /CS, /WR, /RD を制御できればROMカートリッジからデータを読み書きできることがわかります。
MSXのアドレスマップ
カートリッジのアドレスバスは16本あることがわかりました。16本ということは 2^16 = 64kByte のアドレス空間を持ちます。
MSXでは、それを16kBごとの4つのブロック(ページと呼びます)に分割し、各ページごとに別々のスロットに切り替えることができるようになっています。スロットは4つまであります。(拡張スロットもありますが今回は省略します)
このスロット切り替えはいわゆる「バンク切り替え」のような機能で、例えばページ0 は BIOS ROMを、ページ1 と 2 にはカートリッジのROMを、ページ 3 には RAM をマップすることで、BIOSの機能を使いつつ、RAMをワークエリアにしてROMカートリッジを動作させることができます。
ただし、ページを変更してマッピングすることはできません。スロット1のページ0のメモリを、ページ3のアドレスにマップさせる、といったことはできません。上の図でいうと横のスロット方向のみ切り替えられる感じです。
ROMカートリッジのアドレスマップ
MSXのアドレスマップはわかったので、カートリッジのアドレスマップに目を向けてみましょう。
カートリッジ内のマップはROMの容量によって変わります。カードエッジコネクタに /CS1, /CS2 という信号線があります。/CS1 は 0x4000〜0x7fff にアクセスしたときに Low にアサートされるようになっています。/CS1 をROMの/CSまたは/OEに接続することで、0x4000〜0x7fff のページ1にROMを割り当てることができるようになっています。/CS2 は同様に 0x8000〜0xbfff のページ2にアクセスしたときにLowになります。
これらのことから、16KB ROM はページ1か2に存在すると考えられます。
もう1つ、/CS12 という信号線もあります。これは、/CS1 と /CS2 を AND したような信号線で、0x4000〜0xbfff にアクセスしたときにLowになります。32KB ROM を接続するために用意された信号です。
このことから、32KB ROM はページ1と2に存在すると考えられます。
ROMカートリッジの中には32KB以上のROMを持たせるために、メガロムコントローラとよばれる制御ICを持っているものがあります。ページ1と2の部分を更にバンク切り替えできるようすることで、1Mbit(128KB)から4Mbit(512KB)といった大容量のデータを扱うことを可能にしています。
メガロムコントローラについてはまた別途記事にしたいと思います。
カートリッジリーダの回路図
まだ作り途中ですが、現時点の回路図はこちらです。(回路設計は素人なので間違っている箇所もあるかもしれません)
前回はRaspberryPiを使いましたが、PCに直結する形で使えるようにしたいので、Raspberry Pi Pico(以下Pico)を繋げるようにしました。
Picoは3.3Vで、MSXカートリッジは5V(TTLレベル)なので、レベル変換が必要です。IOエキスパンダを5Vで動かすことで5VのIO拡張として使用します。
(今考えると、Pico→カートリッジ方向の信号線は、受け側がTTLレベルなので3.3V直結でも問題なかったかも・・)
IOエキスパンダは16個のIOピンを持つものを2つ使い、アドレスバスの16本、データバスの8本と、制御線としてCLOCK, /WR, /RD, M1, RFSH, /IORQ, /MERQ(/SLTSL) の8本を制御する形にしました。
CLOCK, M1, RFSH は通常のROMリーダには不要なのですが、メガロムコントローラにこれらの信号線が入っており、メガコンの挙動を調査するために接続しています。/INT, /WAIT, /BUSDIR も同様にカートリッジの挙動を調査するために Pico の GPIO に接続していますが、これらが不要であれば、/CS1, /CS2, /CS12 をIOエキスパンダから出力するようにすれば 74HC139 を不要にできそうです。
/CS12はこれ以上ICを増やしたくなかったのでダイオードのAND回路で生成しています。今の所これで動作していますが、相性が悪いカートリッジも出てくるかもしれません。
/INT, /WAIT に関してはオープンコレクタなので、3.3Vでプルアップすることでレベル変換しています。/BUSDIRについては抵抗で分圧して5Vから3.3Vに変化する方式にしてみました。(まだこれらの信号線を使うカートリッジを持っていないので正常に動作するかは確認できてないですが・・)
データバスはROMが接続されていない箇所では確実に0xFFになるように47kΩで弱めにプルアップしています。
また、カートリッジの各ピンの信号線を取り出せるように、ピンソケットをつけています。
作り始めたけど・・
1つしかいらないから基板までは作らずにユニバーサル基板で手ハンダで行こうと作り始めたのですが・・
はじめからわかっていたことですが、配線が多い!
最初は意気込んで作り始めたのですが、↓の頃にはもう心が折れていました。まだ半分くらいでしょうか・・
心が折れながらも無心ではんだ付けし続けて、最低限できたのがこちら。(未完成です)
動作確認のために、Picoは使わず前回同様RaspberryPiを繋げて動かすことにしました。そのため /INT, /WAIT, /BUSDIR の部分はまだ未搭載です。(ハンダ付けで疲れ果ててPicoのコードを作る気力が・・)
苦労したウラ面はこちら。
結局累計で7,8時間くらいかかったんじゃないでしょうか。ハンダする時間も考えると1枚からでも基板注文しちゃったほうがコスパいいですね。もう2つ目は作りたくないです・・(まだ未完成ですが)
RaspberryPiをつなげるとこんな感じです。5V, 3.3V, GND と I2Cの SCK, SDA のみつなげています。
写真ではメガロムの「信長の野望 全国版」を挿していますが、まずは16KB, 32KB ROMのゲームから読み出せるようにソフトを作成していきました。
ROMを吸い出してみました(非メガロム)
手持ちのカートリッジでメガロムではないものから試していきました。
HAL研究所の「ドラゴンアタック」と「てつまん」です。
これらはどちらも16KB ROMだったのですが、ドラゴンアタックは0x4000〜0x7FFF、てつまんは0x8000〜0xBFFFと配置されるページが違っていました。自動でROMを認識して吸い出すためにはROMがどこに配置されているかをスキャンする必要がありそうです。
吸い出したROMをMSXエミュレータで動かしてみたところ正常に動作しました。正しく読み出せているようです。
同じ16KBのROMイメージなのですが、エミュレータは元々ページ1と2のどちらに配置されていたROMなのかを自動で認識するんですね。知りませんでした。
次は BLACK ONYX と RAMBO です。どちらも32KB ROMでした。
32KB ROMの場合はアドレスマップのパターンはなく、0x4000〜0xBFFFを読み出せばOKです。
こちらも無事に吸い出すことができました。
余談: ヤフオクでROMカートリッジを調達中・・
余談になりますが、MSX用のROMソフトで元々持っていたのは激突ペナントレースのみで、それ以外は最近購入したものです。
ヤフオクで安めのソフトを見つけてはちょこちょこ買っています。ゲームが欲しいというよりはカートリッジのケースとメガロムコントローラが欲しくて、ヤフオクでMSX用の安いカートリッジを狙って買っています。
新品のカートリッジケースって2千円くらいするんですよね。今後カートリッジ側の基板も作ってみたいという思っているので、その時用にケースを確保してます。自分用なので多少傷があっても気にしないですし中古で十分かなと。
また、いずれ似非RAMディスクを作りたいということもあり、メガロムのソフトも安いものを狙って買ってます。
レトロゲームのROMを吸い出しつつ、基板は実験基板にできるし、カートリッジケースまでついてきて送料込み2千円以内で買えるのは結構お得じゃないかと思っています。
今までで一番良かったのはパナソフトのMSX BASEBALLです。
ケースはラベルを剥がさなくてもアクセスできるネジ止めで、基板も50Pin全てのカードエッジコネクタのパターンがあるので、/IORQなど普通のROMゲームでは使われていない信号線も取り出せます。SST29F010などのFlash ROMを取り付ければ、32KBまでの自作ゲームも動かせそうです。
まとめ
MSX用のROMカードリッジからROMの内容を読み出す装置を作りました。まだRaspberry Pi Pico を使っていないなど最終形には到達していませんが、ROMを読み出せることは確認できました。
今回はまだ開発途上なためソフトウェアは公開していませんが最終形に近づいたら公開しようと思います。
今後はメガロムのゲームの読み出しや、これを使ってメガロムコントローラの調査なども行ってみたいと思います。