とうとうMULTI 8エミュレータに手をつけちゃった日記。 へっぽこプログラマは日々こんなこと考えながらエミュ開発しています(笑) 2004/11/19-20 PASOPIA7が実装レベルでは完了しましたので、MULTI 8に取り掛かります。 某スレッドで「マイナー機は俺に任せろ」と吼えてから、丁度1年。 とうとうここまで来てしまったんだなあ、という感慨がありますね。 後は、FP-1100とJR-100/200と初代PASOPIA辺りを片せば、表現が変ですけど メジャーなマイナー機はほぼ一通り揃ったことになるんでしょうか。 実機は以前に虎菊コレクションから借りてきたものを使用。 めがきらさんに借用をお願いしていたマニュアル類が今日到着しましたので、 軽くアーキテクチャの確認をしておきます。 んー、メモリマップとかは載ってますけど、I/O周りは殆ど情報ないですね。 OUT命令の項のサンプルプログラムから、3nhがパレット操作だということ、 INP関数の項のサンプルプログラムから、00h,01hがキー入力っぽいということが 判る程度です。 これは自力で調査しないことには、どうにもならないなあ。 取り合えず、ROM吸出しから。 モニタ機能から、0000-7fffの内容をデータレコーダに出力してやります。 幸い特にバンク操作しない限り、ROMイメージはそのままアクセスできるようです。 PASOPIA7では、ROMにアクセスするだけで一苦労でしたから。 で、データレコーダへの出力をそのままPCで録音して、波形解析。 基本的に波長は2400Hzまたは1200Hz。 長長で0、短短短短で1を表している模様。 データは11bitで1word、110--------という形になっています。 モニタから保存したバイナリの場合、256bytesおきに3bytesのチェックサム?が 出力されているようです。 これを元に、ROMイメージを抽出してやります。 フォントROMは、取り合えずPASOPIAのものを流用。 2004/11/20-21 ハードウェアの解析。 カートリッジ端子脇のねじを外せば、後は爪で引っ掛けてあるだけ。 解体しやすくていいですね。 基板を見られるようにしたところで、主要なチップを確認します。 uPD780C, AY-3-8912, HD46505, 8251, 8253, 8255, 8259。 水晶は15.9744MHzのものと、14.31818のものを使用しています。 15.9744MHzを4分周してCPUのクロックにしているのかな? I/O周りのアドレスデコードは、74159と74139でやっているようです。 テスターで74139の出力の行き先を調べてみると、1Y3=HD46505, 2Y0=8251, 2Y1=8253,2Y2=8255, 2Y3=8259となっています。他は不明。 8253の端子を確認。 out0は8251のTXCへ。RS-232Cの基準クロックとして使うのかな? out1はclk2および8259のIR5へ。システム駆動用のタイマ割込み? out2は8259のIR6へ。こちらは低速なタイマ割込みだから、時計駆動用? clk0, clk1は同一クロックが入ってます。 clk2はout1の出力をカウント。 gate0-2は全てGNDに落ちているようです。 入力されているクロックの周波数は不明、んー、オシロスコープとは 言わないから、せめて周波数カウンタくらいは欲しいですね。 ROMをディスアセンブルして、OUT,IN命令を検索。 使用されているI/Oのアドレスをリストアップします。 あとは、74139のデコード内容やI/Oの使われ方を比較検討したり、実機での 挙動を参考にしながら、I/Oマップを作成していきます。 こういう手探りの解析って久しぶりですけど、やっぱ楽しいですね。 nester時代に謎のマッパーの解析をしたのを思い出します。 最近は潤沢に資料のあるものばかり相手にしていたから、自分で解析すると いうことを忘れてしまっていたようです、反省。 2004/11/21-22 昨晩までに解析した内容を元に、実装を開始します。 大半は、いままでに作成したエミュレータのコードを流用。 楽でいいですね。 8251は、すぐには必要ないので、雛形だけ用意。 8253は、EmuZ-2500で実装したものを流用。 8255は、ポートの使われ方を固定にして手抜き実装。 8259は、取り合えずMESSのコードを参考にして実装。 CPUコアが従来mode2前提で組んでましたので、mode0でcall命令がくる場合も 想定して修正しておきます。 HD46505は、EmuPIA7から。 AY-3-8912は、すぐには必要ないので、雛形だけ用意。 将来的には、cisc師のfmgenを使用させて頂く予定です。 そんなこんなで、取り合えず仮想マシンを動かしてみます。 I/Oの初期化処理の途中で暴走。 どうも、RAM領域にジャンプしたところで、ジャンプ先のRAMがクリアされた ままなのが原因なようです。 I/Oの入出力周りが原因でもないようだし、何だろう。 暫く悩んで、ふと思い立ってROMのチェックサムを取ってみると、あちこち 化けてるやん。 よくよく確認してみると、データレコーダの出力は、256bytesではなく 255bytesおきにチェックサム?を出力していたようで、これの除去に失敗 していたのが原因でした。 で、もう一度ROMイメージを生成しなおして再挑戦。 今度はbeepを鳴らしながら無限ループをしてしまっているようです。 コードを逆に折ってみたところ、00h/01hの出力が気に入らない模様。 多分、キーボード用サブCPUの診断を行って、エラーと判定したんでしょう。 初期化処理が気に入るような値を出力するように修正して再挑戦。 そんなこんなで、VRAMに起動画面っぽい内容が出力されるところまで動作 するようになりました。 割込みを有効にすると消えてしまうんですが、その辺はまた後日調査します。 2004/11/23 ディスクドライブ他を所有されている方からご連絡頂きました。 これで諦めていたディスク対応もできるかも。ありがたや。 起動画面ができているっぽいので、画面生成処理を実装してやります。 EmuZ-2500やEmuPIA7で散々やってきたことと同じですから、今更特に悩むような ことはないですね。 で、めでたく起動画面が表示されるようになりました。 40/80桁の切り替えがどうなっているかとか不明な点も多いですが、この辺は BASICが動作するようになってから調査することにしましょう。 割込みを有効にすると、暫くたって暴走する件。 CPUをトレースしてみると、スタックがずれてしまっている模様。 …割込み発生したときに、PUSH(PC)を2重にやってしまってた。 駄目やん>自分 取り合えず暴走しなくなったので、キーボード周りを実装してみる。 MULTI8では、キーボードの駆動にサブCPUを使用していて、I/Oにアスキー コードが返ってくるようになっています。 これを実現するために、ctrl, graph, kana, shiftの状態毎に、 変換マトリックスを用意してやります。 結構な量になりますので大変でしたけど、取り合えず完了。 実験してみたところ、キー入力を受け付けるようになり、一応M-BASICが 動作することを確認しました。 解析を開始してから4日、概ね順調ですね。 80桁モードとかテキストアトリビュートの問題を解決したら公開します。 2004/11/24 早朝5:00。 何か目が覚めてしまったので、作業の続きでも。 いかんな、4時間睡眠が定着してしまっているようだ。 手始めに、80桁モードやテキストの白黒/カラーモードの切り替え、 グラフィックの白黒/カラーモードの切り替え、表示ページの選択など、 画面生成周りのI/O調査から。 BASICが起動するようになりましたから、I/Oの調査が楽です。 単にそのように動作させて、I/Oのログを眺めるだけですから。 ちょっと面白いのがグラフィックの白黒/カラー切り替え。 30h-37hがパレットの指定なんですが、全パレットに0を指定すると、 白黒モードになるようです。 この辺を実装して、出勤。 帰ってきたので作業続き。 PSGの実装は、cisc氏のfmgenを使用させて頂きます。 基本的にはEmuZ-2500の実装をそのまま引っ張ってきただけ。 ベースクロックは、14.31818MHzを4分周でいいのかな? beepは、on/offの指定は判っているんですが、大元の波形の生成部が よく判らないので、取り合えず保留とします。 データレコーダ周り。 実装はまた後日ですが、調査だけでもしておきます。 これが中々面白い仕様でして、録音時は8251に書き込むデータをそのまま 渡してます。シリアル出力をそのまま録音しているのかな? で、再生時は8251で受信、ではなく、普通に1bit入力で波形を読んでいます。 HPC2000版の作成。 win32側の実装は最初からCE対応のを使い回してますので、プロジェクトを 用意してビルドするだけです。 取り合えず、ここまでで一度公開します。 2004/11/25 キーボードの入力について。 キーコードの返り値は、次のキーが押されるまではそのまま保持される、 ステータスのbit0は、キーコードを読み込むまで立ったまま、 という仕様に合わせて修正してやります。 これでモニタ機能内でキー入力が正しく機能していなかったり、ESCや BREAKが機能しなかった問題が解決しました。 データレコーダ。 もう少し良く調べてみると、やはり再生時も8251で受信しているようです。 PSGのR14のbit1=1でリレーをonにして、8255のport aのbit2=1を確認した上で、 RXRDY=1を確認しながら読み込んでいます。 という訳で、実装するにあたっては、単純に8251のデータバスを読書きして やるだけで良さそうです。 但し、実機のカセットを使用するためには、wavの波形から最終的に読み込まれる バイナリ列を生成してやる必要があります。 この辺は、どのみちROM吸出しツールのために実装する必要がありますので、 さくっと作ってやりましょう。 で、動作確認。 手持ちのソフトのうち、ピラミッド、サーチャー、付属テープについては 特に問題なく読み込むことが出来ました。 ROM吸出しについても、一応は問題ないようです。 ディスクドライブを貸して頂きました。 週末はこいつと格闘する予定です。 2004/12/4 ディスクドライブの検証で行き詰ってます。 他で多少の進展がありましたので、そちらでも。 爆弾男や4人麻雀のようにMONからロードするタイプのゲームの場合、 0000-7fffにプログラムをロードしています。 0000-7fffは普段はROMがマッピングされていますが、8255のport cの b5=1でRAMに切り替わるようです。 CP/Mモードでも全領域をRAMにマッピングして使用されます。 8255のport aのbit6=0のとき、漢字ROMが存在すると判定します。 漢字ROMのアクセスは、40h,41hに漢字ROMのアドレスの下位、上位を 指定して、40h,41hでパターンを読み込みます。 ROMイメージの内容についてはまだ未検証です。 2004/12/13 最近の作業。 FDCのROM吸出し作業。 バンク切り替えは、78hのbit0で指定を行う。 FDCのI/Oポートの調査。 FDCの存在判定は、8255のport aのbit1。 使用しているチップはuPD765A(多分) 70hがstatus, 71hがdata/cmd。 但し、データの受け渡し時は、73hのbit7を監視して、72hに対して入出力を しているなど、uPD765A以外のポートも存在する模様。 uPD765AをEmuPIA7のソースから引っ張ってきて仮実装。 1セクタ読み込んだ後のループ抜けは、割込みによって行っている? BASICを起動して、How many files?が出るところまではいくが、 完全に読み込みが行えていないらしく、データのないところにジャンプして 暴走してしまっている。 取り合えず、保留。 2004/12/14 漢字ROMの配列調査。 コードに対するパターンの配列は、ある程度は規則的なところもありますが、 どうも理屈はよく判りません。 手作業で配列を調査しつつ、定義ファイルを作成します。 定義ファイルとwindowsのフォントからROMイメージを生成するのは、 EmuPIA7で作成したツールをそのまま流用します。 取り合えず完成したので、デモを表示してみました。 取り合えず問題はないようですね。 2004/12/15-16 FDCの作業の続き。 データの読み込み処理ですが、マルチセクタ読み込みで連続してデータを 読み込みつつ、読み込んだバイト数をカウントして、指定回数だけ 読み込んだら、74hに適当なデータを出力してループに戻っています。 これではループから抜ける手段は割込みだけですので、74hへの出力は TC ONとして、ディスク読み込みを中断しつつ割込みを発生させていると 仮定します。 これで実装すると、実機でDISK BASICを起動したときと同じようなデータが 読み込まれていることを確認しました。 ただ、やっぱりhow many filesに回答したあとで、異常動作をしてしまいます。 まだ何かおかしいみたいですね。 解析資料を、html化してみました。 ちゃんとtableにすると、結構それっぽく見えるものですね。 2005/8/15-16 QC-10で再現性の向上したuPD765Aコアを使用して再実装していますが、どうにも うまく動作してくれません。 8255のコントロールレジスタによるport cのビット操作周りで不具合があったのを 発見したので修正しておきましたが、これも無関係。 FDC周りの処理を全部追いかけて見ましたが、ディスクからデータを読み込む辺り までは、間違いなく正常に動作しているはずです。 メモリのバンク切り替え周りに何か未知の仕様があるのか、ディスクイメージに 問題があるのか。 帰省先で実機が手元にない現状では、これ以上はちょっと手が出なさそうです。 ソースのバックアップの意味も込みで、取り敢えずここまでで公開しておきます。