「X68000エミュレータ開発って、そんなに難しいの?」

X68000 EMULATOR XM6の作者さんによるエミュレータ開発に関するツイートと関連ツイートをまとめました。
182
PI. @xm6_original

68000エミュレータその4。SCSIについて。現在のX68000エミュレータでSPC(MB89352)を実装しているものはXM6とXEiJの2種類のみとなっている。px68kを改造して(SPCの実装を避け)IOCS $F5のフックで簡易SCSI対応している方のブログを読んだが落とし穴が複数あって大変そうだ。→

2022-11-26 19:24:31
PI. @xm6_original

MB89352の情報は少ないがXM6 2.06/XEiJ/MAMEのソースを読めば実装はできると思う。しかしSCSIを実現するには広く言えばSCSIバス全体のエミュレーションが必要になる。つまりSCSIハードディスクやSCSI MOで実装されているSCSIコマンドを実デバイス同様に実装する必要がある。→

2022-11-26 19:24:31
PI. @xm6_original

有名なINQUIRYやMODE SENSEは勿論、READ/WRITE/VERIFYやSTART/STOP UNITなどCCS準拠の沢山のSCSIコマンドを実際のSCSIデバイスに載っているマイコン(或いはLSI)同様に解釈し、ホストへの応答データを作成しなければならない。これが非常にメンドイ。→

2022-11-26 19:24:32
PI. @xm6_original

ここまでやればサードパーティ含めSCSIボードから吸い出したROMデータを使い、SUSIE.x等でアクセスできるようになる。XM6で私が作成したHDD/MO/CD-ROM等のSCSIデバイスのコードがRaSCSIの源流になり、現在のGitHubのPiSCSIまで至るわけで、当時の努力は無駄ではなかった、というところだろうか。(完)

2022-11-26 19:24:32

PI. @xm6_original

X68000エミュレータその5。SCC(Z8530)について。以前もツイートしたがこの石は詳細なユーザーズマニュアルが現在でも入手できるので、規模がやや大きめなこと以外はそんなに難しくない。ポイントはRx FIFOが3バイトだけ存在すること。名著「Inside X68000」には、この事実が記載されていない。→

2022-11-27 20:43:40
PI. @xm6_original

チャネルB(マウス)から送信されるデータも奇しくも3バイト一組なので、普通にマウスデータを受信するときはRxオーバーランやマウスデータの欠損は発生しない。チャネルBの通信パラメータは通常マウスに対応する形で固定されるが、チャネルA(RS-232C)は様々なボーレート・通信パラメータが有り得る。→

2022-11-27 20:43:40
PI. @xm6_original

どこまで対応するかはエミュレータ開発者の思想次第になってくる。WinX68k系はチャネルB(マウス)のみ対応、XEiJは仮想マシンでROMデバッガを動かすことを前提としている。XM6はシリアルポートとして汎用対応しているが完全なサポートは行えていない。この辺りは「終わりがない」のかもしれない。(完)

2022-11-27 20:43:40

PI. @xm6_original

X68000エミュレータその6。グラフィックスのレンダリングについて。ここはGIMONSさんが詳しい分野だが概論を述べる。X68000は1987年当時、破格と言えるスペックで、テキスト・グラフィック・BG・スプライトを自由度の高い優先度で重ね合わせでき、多彩な画面モードを持つ。→

2022-11-28 19:39:51
PI. @xm6_original

任意のラスタで割り込みが掛けられ、超連射68k(XSP)などのスプライトダブラでフル活用されているのは周知の通り。これを真面目にエミュレーションするとラスタ(水平ライン)毎にスクロールレジスタ、パレットレジスタ、VRAMを参照して表示要素ごとの表示データを作成し、優先度に従い合成する。→

2022-11-28 19:39:51
PI. @xm6_original

しかし少なくとも2000年代前半はこんなことを毎フレーム行っていてはリアルタイムエミュレーションなど論外の世界で、「いかに前回のフレームと変わっていないところを抽出し、スキップするか」が重要だった。例えば背景に対しパレットで明暗グラデーションを付けるソフトは極端に合成負荷が上がる。→

2022-11-28 19:39:52
PI. @xm6_original

また見過ごされやすい点として「表示領域がそもそも広い」ことを指摘しておきたい。一例としてSFCと比較すると256x224(SFC)対512x512(X68k)なので4.57倍の負荷が掛かることになる。すなわち実現可能フレームレートは22%まで低下する。→

2022-11-28 19:39:52
PI. @xm6_original

ただしグラフィックレンダリングはマルチコア化が望める。私も現在はRyzen7 5700G(8コア)を使用している。テキスト・グラフィック・BG&スプライトで3コアに分割し、「一つ上のラスタを、各々の表示要素を元に最終合成する」コアを更に追加する形も有望と思われる。→

2022-11-28 19:39:53
PI. @xm6_original

この方式は仮想時間1ライン毎に、そのときの表示レジスタ値およびVRAMデータを各コア毎の作業メモリにコピーしておかなければならないで、帯域幅性能のよいメモリと組み合わせないと逆効果になる。またコアごとの機能分担(ロード・バランシング)も今後のテーマになるだろう。(完)

2022-11-28 19:39:53

PI. @xm6_original

X68000エミュレータその7。MFP(MC68901)について。現在はSoCに内蔵される様なGPIO・タイマ・UART・割り込みコントローラをまとめたチップだ。MFPの割り込みコントローラはX68000エミュレータ開発で最大の難関といっても過言ではない。「えっそうなの?」と思う方もいるはず。詳しく解説したい。→

2022-11-29 20:48:52
PI. @xm6_original

X68000の割り込みは、ペリフェラル割り込み要求→割り込みコントローラ→68000のSRレジスタ(割り込みレベル)の経路を通る。ペリフェラルからの割り込み要求時に割り込みコントローラのIER(割り込みEnable)が許可、IMR(割り込みMask)が非マスク、割り込みレベルが低い場合に割り込み処理が起こる。→

2022-11-29 20:48:52
PI. @xm6_original

手堅いソフト作法は(1)68000の割り込みを禁止(2)ペリフェラル側の割り込み出力をクリア(3)MFPのIERとIMRを許可(4)ペリフェラル動作開始&割り込み許可(5)68000の割り込みを許可、の手順になるが、この手順でないソフトも沢山ある。「実機では問題ないので意図せず手抜きになった」ケースも多い。→

2022-11-29 20:48:53
PI. @xm6_original

特に周辺機能から割り込み要求が出ているとき(68000側は割り込み禁止)のタイミングでIERやIPR(IMRではない)をオフにするとペリフェラルからの割り込み要求そのものが取り消される。「実機では動くがエミュレータでは動かない」ソフトは、割り込みコントローラの振る舞いが異っている場合が多い。→

2022-11-29 20:48:53
PI. @xm6_original

またMFPから68000への割り込み要求は400ns程度の遅延が発生する事も判明している。これを考慮しないとV-DISP→V-SYNCへの変化をポーリングし、かつV-SYNC割り込みを有効にしている場合に前者のポーリングが機能しない。これは知らないとハマってしまう「X68000エミュレータあるある」である。(完)

2022-11-29 20:48:53

PI. @xm6_original

X68000エミュレータその8。スケジューリングについて。エミュレータの時間管理はホスト側と仮想マシン側の2系統があり、ざっくり言うとホスト側が10ms経過したタイミングで仮想マシン側を10ms実行すればリアルタイムエミュレーションになる。しかしリアルタイム要求は、重要度としては低い。むしろ→

2022-11-30 22:21:31
PI. @xm6_original

重要なのは仮想マシン側のスケジューリングになる。エミュレータの実機互換性を高めるには、様々なデバイスから割り込みやメモリマップドI/O読み込みを通してMPUに伝えられるイベントの順序や、その間隔(具体的には、実行可能なMPUサイクル数)を可能な限り実機に近づけることが求められる。→

2022-11-30 22:21:32
PI. @xm6_original

ホスト側のCPUパワーに余力があるからといって68000を必要以上に速く駆動してしまうと、IOCS _TXRASCPYのような「MPUが一定速度以下で動作する」前提のソフトがクロックアップ機同様に誤動作してしまう。MPUサイクル数を厳密に制御することで、ゲームにおける「処理落ち」も実機同様になる。→

2022-11-30 22:21:32