20080.128u7出た0.128u7の差分ソースがリリースされました。グローバルMachine変数の削除が完了しました。20080.128u6出た0.128u6の差分ソースがリリースされました。コンテキスト切り替えの残り、新しく出たバグの修正など。20080.128u5出た0.128u5の差分ソースがリリースされました。u4で起きたバグはかなり修正されています。ST-Vの速度改善とDIPスイッチ設定も保存できる新INPフォーマット追加の他、引き続きCPUのポインタ化も進んでいます。Aaron0.128u4でCPUとメモリ周りの大幅な変更が行われましたが、その背景と未実装部分を含む変更点の具体的な解説がAaronさんのところに出ています。CPUコンテキスト切り替えMAMEが設計された当初、将来的に複数のCPUをエミュレートして同時使用することは想定されていませんでした。v0.1は、Nicola氏によるパックマン系ハードをエミュレートする「Muilti-Pac」エミュレータが元になっています。これはZ80CPU1個だけで構成されています。似たようなハードウェアで動作するアーケードゲームが次第に見つかり、多くのZ80ベースのゲームがすぐにサポートされました。シングルZ80以外に様々な種類のアーケードハードがあることはすぐにわかりました。そこで、6502や6809などの8ビットCPUがサポートされることになります。多くのゲームが複数のCPUを使っていることも分かり、マルチCPU機能もサポートされました。問題というのは、CPUエミュレータ用のコードが、同じCPUの複数インスタンスを動作させるようには設計されていなかったということです。マルチCPUを動作させるために、"コンテキスト切り替え"というコンセプトが導入されたこともあります。ここでは例としてZ80を採り上げます。2個以上のZ80CPUを同時使用する場合、Z80CPUエミュレータがCPUの状態をグローバル変数で保持することが主な問題点になります。当時(386やDOSの時代)には、Z80それぞれにメモリを割り当て、CPUの状態をポインタで参照するよりも、グローバル変数からデータを取得する方が高速だったのです。この方法を使ってもZ80コアが動作し続けられるように導入されたのが、コンテキスト切り替えです。コンテキスト切り替えを使うと、MAMEは別のZ80を実行するために、一旦今のZ80の動作を止める必要がある場合、最初のZ80に関係するグローバル変数データを全て一時メモリにコピーします。次に、2番目のZ80の状態を一時メモリからグローバル変数へ戻します。この時点で、グローバル変数は2番目のZ80用になり、正しく実行できるようになるのです。MAMEでは、最初のZ80を数千サイクル実行→コンテキスト切り替え→2番目のZ80を数千サイクル実行→コンテキスト切り替え...という動作をしていたので、実際にはこの方法で全く問題なく動作しました。コンテキストの切り替え自体は、エミュレーションサイクル数千回に1回しか行わないので、必要な時間はトータルの実行時間に比べてわずかだからです。この2つのZ80を"サイクル単位で正確に"動作させたいケースでこれが問題となります。この場合、実際に1サイクルか2サイクル毎にそれぞれのZ80を動作させるため、切り替え動作が非常に多く起こります。最初のZ80を1、2サイクル→コンテキスト切り替え→2番目のZ80を1、2サイクル→また切り替え、という具合です。この状況では、CPU動作よりも切り替え動作の方に時間がかかる結果となりました。この問題の解決方法は、コンテキスト切り替えを無くすことです。そのために、グローバル変数ではなく、各Z80割り当てたメモリから全てのデータを参照するようにしなくてはいけません。以前であれば、この方法ではパフォーマンスにある程度の影響が出ましたが、今のプロセッサとコンパイラを使えばその違いはほとんどありません。0.128u4での変更というは、このCPUのコンテキスト切り替えを一掃するというのが最大の動機になったのです。このために、全てのCPUコアへのインタフェースを変更し、各コアがグローバル変数ではなく、メモリポインタから状態を取得するように修正する必要があります。0.128u4の段階では、重要なCPUについてはコンバートが終わっていますが、その他についてはまだ作業中です。メモリコンテキスト切り替えCPUがコンテキスト切り替えを行う方法に加えて、MAMEのメモリシステムでも同様のことを行ってきました。これは、CPUがメモリの読み書きをするとき、メモリシステムに対して、どこに読み書き動作を行えばよいかを探し出します。あるCPUの実行動作をMAMEが切り替える場合は、新しいCPUが正しいメモリにアクセスできるよう、メモリコンテキストの切り替えも必要なのです。メモリのコンテキスト切り替えを無くすには、メモリサブシステムの状態をグローバル変数から、割り当てたメモリへ移動する必要があります。メモリシステムがこの方法のために構成されていないため、大幅な変更が必要になりました。最終的に、メモリサブシステムの状態を表すため、"アドレス空間"のコンセプトを導入しています。各CPUは1つ以上のアドレス空間を持つことができ、CPUとメモリシステムの通信が必要なときは、メモリシステムがメモリアクセスのマッピング方法がわかるように、メモリシステムに対し関連するアドレス空間へのポインタを渡します。ゲーム内でリード、ライト処理に使う個々のコールバックを特定するときにも、アドレス空間へのポインタを渡します。これらがすべて動作するために、システム内のリードライトハンドラ用インターフェイスの更新、メモリシステムの書き直し、さらに全てのCPUコアでのこれらのアドレス空間オブジェクトも渡すような変更が必要となります。0.128u4の時点で、メモリコンテキスト切り替えは完全に取り除かれています。CPUのコンテキスト切り替えを無くす前に、この作業を終わらせることが不可欠なのです。「アクティブ」なCPUコンテキスト切り替えと同じく「アクティブ」CPUという考え方も今回の変更対象のひとつです。これは、グローバル変数に現在コピーされているCPUを定義するものです。CPUのコンテキスト切り替えを削除するにあたり、アクティブCPUというものも意味を持たなくなります。Bとします)のメモリ空間に書き込みができる場合を考えてみましょう。Aの状態がロードされています。Aのメモリリードライトは、メモリアクセス時の挙動を知るためにグローバルなメモリ状態情報を使います。AがアクティブなCPUとなります。Bのメモリ空間を更新するような動作をする場合はどうなるでしょう。Bの状態をロードします。BがアクティブなCPUになります。Bのメモリ空間にアクセスします。Aの状態はメモリ空間内にあり、いつでもアクセスできます。アドレス空間も同じように設定され、コンテキスト切り替え無しでいつでもアクセス可能です。Bのメモリ関数を更新するとすれば、コンテキスト切り替えは一切必要ありません。Bのメモリを直接いじることができます。これら2つには大きな違いがあるのは明白で、新システムの方が高速になるはずです。それよりも重要なのは、「アクティブ」なCPUというもの自体が存在しないということです。Aが実行中なのだから、それを「アクティブ」と指定するべきだという反論もあるでしょう。Bがアクティブとはみなされません。突き詰めると、もし実行中のCPUを「アクティブ」だと定義するなら、「アクティブ」な状態になれるCPUは1つだけですから、同時実行できるCPUは結局1つのみということになってしまいます。したがって、「アクティブ」なCPUという概念自体を取り払うことが正しい解決法と言えます。残念なことに、MAMEのドライバやコアにはアクティブCPUを参照する箇所がかなりあるのですが、これらは徐々に取り除いていく必要があります。ひとつでも参照箇所があれば、コンテキスト切り替えを完全に削除することはできません。アクティブCPUへの参照が存在する限り、アクティブCPUというものの定義を有効にするため、コンテキスト切り替えをし続けなければならないということです。結局のところは?ユーザの視点からみると、既存のゲームは動作し続けますし、特にコンテキスト切り替えが激しく起きている状況では、動作速度も同等、あるいは少し向上するはずです。コンテキスト切り替えを全て削除してしまえば、CPU切り替えを頻繁に行う際にMAMEが実行することは減るはずです。長い期間でみれば、このようなケースでは再び速度が落ちるかもしれません。初期のゲームの多くでは、複数のCPUがとても密接な動作をしており、正確な動作を追及するならば、理想的には各CPUが命令を同時に実行することが望まれるため、切り替えを交互に素早く行う必要があります。現状のコンテキスト切り替えでもしこれを行うとパフォーマンスは大きく低下します。コンテキスト切り替えの削除が進めば、8-bitシステムなら最低限、許容範囲に収まればと考えています。開発者にとっては、この変更でMAMEのオブジェクト指向がさらに強まることになります。MAMEはC++ではなく普通のC言語で書かれてはいますが、running_machine、device_config、address_spaceなど、システムのコアストラクチャはオブジェクトであり、ほとんどのシステム系コールではこれらへのポインタを渡しています。「アクティブ」なCPUが必要になるケースは今後ほとんど無いでしょうし、独自の関数へmachineへのポインタを渡す方向なので、グローバルなMachine(Mは大文字)への参照は削除します。これらの変更は、ソフトウェア設計という視点から見れば、特に目新しいものではありません。MAMEの設計という観点では大きな革新と言えます。CPUコンテキスト切り替えの削除を進めるにあたって、その他の変更も多く行われる予定です。コアの基本構造に手を加えるためには、0.128u4の段階で適切だったと思われます。今回の変更自体でバグもいろいろ起きていますが、今後の更新は小規模なものになるはずです。20080.128u4出た2週間をおいて0.128u4の差分ソースがリリースされました。アーキテクチャの大変更が続いているため、通常の更新は推奨されていません。2008cheat更新Pugsyさんの新フォーマットのcheatファイルが更新されています。xmlのパースエラーが出ていたものを修正しています。2008Haze氏WIPHazeさんWIP更新。ジャッキー系とギャルズパニック3などの進捗状況が出ています。未解決なのは、スプライトズーム、操作(2ボタンのみ動作)、サウンド、レイヤーオフセット、タイルマップとスプライトの表示順位とのこと。20080.128u3出た0.128u3の差分ソースがリリースされました。Worldの掲示板によると、m68kconf.hが無くてコンパイルエラーが出る場合、src/emu/cpu/m68000に空のm68kconf.hを作ると解決するとのことです。20080.128u2出た0.128u2の差分ソースがリリースされました。mamedev.orgMAMEDevサイトリニューアルアナウンスにあったとおり、オフィシャルサイトがとてもかっちょよくリニューアルされています。拙作なヒストリーグラフも更新しました(Wikipediaでも利用可能です)。20080.128u1出た0.128u1の差分ソースがリリースされました。v0.60a14出来M1フロントエンド更新しました。次のコアはいつ出るのかな?検索結果の整合性をとるため、発売元の表記違い、ばらつきなどを統一。メインプレーヤーの曲名部分のユニコード文字が正しく表示されないのを修正。ウィンドウの重ね合わせを今度こそ修正(多分)。ROMロード中にコアが固まった場合に終了できるよう変更(エラーが出るかも)。マルチインスタンスのチェック方法を改良。プレイカウント追加とカラムソートの古いコード削除。テーマフォルダを"theme2"から"themes"に変更。デフォルトの音量設定をアップデートしてあります。2のバランス、YM2203のFM音源とPSGのバランス改善など。詰めが甘いのもありますが、前よりはましになっていると思います。"m1cfg¥default.cfg"を忘れずに新しい物に入れ替えて下さい。Tafoidさんによる定義ファイル「m1.xml」は10月5日版が最新です。ダウンロードはこちらより。0.128出た0.128がリリースされました。20080.127u8出た0.127u8の差分ソースがリリースされました。本当は0.128になる予定でしたが、不具合があちこち出ていたのでuリリースが一回追加されました。セガC2、NeoGeoなどの修正が入っています。2008cheatベータ版更新Pugsyさんの新フォーマット対応版チートファイルが更新されました。xmlのパースエラーを起こしていたコメント部分が修正されています。新フォーマットなので、デフォルトではcheat.zipファイルのまま、本体と同じ所に配置します。20080.127u7出た0.127u7の差分ソースがリリースされました。