6

私は、Javaでの趣味のプロジェクトとして、今後数か月にわたってSega Master Systemエミュレーターを作成することを計画しています(これには最適な言語ではないことはわかっていますが、作業が非常に快適で、 WindowsとLinuxの両方で、クロスプラットフォームアプリケーションが素晴らしいと思いました)。私の質問はサイクルカウントに関するものです。

別のZ80エミュレーター、および他のエミュレーターのソースコードを調べましたが、特に実行ループに興味をそそられます。呼び出されると、intが引数として渡されます(例として1000としましょう)。これで、各オペコードの実行にかかるサイクル数が異なり、これらが実行されると、サイクル数が全体の数値から減少することがわかります。残りのサイクル数が0未満になると、実行ループは終了します。

私の質問は、これらのエミュレーターの多くは、実行される最後の命令がサイクル数を負の値に押し上げる可能性があるという事実を考慮していないということです-つまり、実行ループ間で、たとえば1002サイクルになる可能性があります1000の代わりに実行されます。これは重要ですか?一部のエミュレーターは、次の実行ループで補正することによってこれを説明しますが、そうでないエミュレーターもあります-どちらのアプローチが最適ですか?私は自分自身を横切るのが特に得意ではないので、私の質問を説明させてください。

public void execute(int numOfCycles) 
{ //this is an execution loop method, called with 1000.
   while (numOfCycles > 0)
   {
      instruction = readInstruction();
      switch (instruction)
      {
         case 0x40: dowhatever, then decrement numOfCycles by 5;
         break; 
         //lets say for arguments sake this case is executed when numOfCycles is 3.
      }
}

この特定のループの例が終了すると、numOfCyclesは-2になります。これはほんのわずかな不正確さですが、人々の経験では全体的に重要ですか?これについて誰かの洞察をいただければ幸いです。これが適切だと思われるので、フレームごとにCPUに割り込む予定なので、1000サイクルは低いと思いますが、これは単なる例です。

どうもありがとう、フィル

4

3 に答える 3

5
  1. CPUクロックティックのみを扱うほとんどのエミュレータ/シミュレータ

    それはゲームなどには問題ありません...したがって、タイマーなどを取得し、CPUがタイマーの持続時間をシミュレートするまでCPUのシミュレーションを実行します。その後、次のタイマー間隔が発生するまでスリープします。これは非常に簡単にシミュレートできます。あなたが求めているアプローチによってタイミングエラーを減らすことができます。しかし、ここでゲームについて述べたように、これは通常不要です。

    このアプローチには重大な欠点が 1 つあります。それは、コードが実際の時間のほんの一部しか機能しないことです。タイマー間隔 (タイミングの粒度) が十分に大きい場合、これはゲームでも目立つことがあります。たとえば、エミュレーションがスリープ状態のときにキーボード キーを押しても検出されません。(キーが機能しない場合があります)。これは、タイミングの粒度を小さくすることで解決できますが、一部のプラットフォームでは非常に困難です。その場合、タイミング エラーは、ソフトウェアで生成されたサウンドでより「目に見える」可能性があります(少なくとも、それを聞くことができ、私のようなものに耳が聞こえない人にとっては)。

  2. より洗練されたものが必要な場合

    たとえば、実際のハードウェアをエミュレーション/シミュレーションに接続する場合は、バスをエミュレート/シミュレートする必要があります。また、フローティングバスやシステムの競合などをアプローチ#1に追加するのは非常に困難です(実行可能ですが、大きな苦痛を伴います)。

    タイミングとエミュレーションをマシン サイクルに移植すると、事態ははるかに簡単になり、突然、競合や HW 割り込みなどの問題が発生し、フローティング バスはほとんど自力で解決します。ZXSpectrum Z80 エミュレーターをこのようなタイミングで移植し、光が見えてきました。多くのことが明らかになります (Z80 オペコード ドキュメントのエラー、タイミングなど)。また、競合はそこから非常に単純になりました (ほとんどの命令タイプ エントリごとの恐ろしいデコード テーブルではなく、わずか数行のコードです)。HWエミュレーションも非常に簡単になり、FDCコントローラーAYチップエミュレーションなどをこのようにZ80に追加しました(元のコードで実際に実行されるハックはありません...フロッピーフォーマットでさえ:))ので、TAPEロードハックがなくなり、機能しなくなりましたTURBOなどのカスタムローダー用

    この作業を行うために、各命令にマイクロコードのようなものを使用する方法で、Z80のエミュレーション/シミュレーションを作成しました。私は非常に頻繁にZ80命令セットのエラーを修正しているので (バグがなく完全であると主張しているものがあっても、私が知っている 100% 正しいドキュメントは 1 つも存在しないため)、エミュレーターを痛々しく再プログラミングします。

    各命令は、タイミング、オペランド、機能に関する情報を含むテーブル内のエントリによって表されます... 命令セット全体は、すべての命令のすべてのこれらのエントリのテーブルです。次に、命令セット用の MySQL データベースを作成します。私が見つけた各命令セットと同様の表を作成します。次に、何が間違っていて何が正しいかを選択/修復して、それらすべてを痛々しく比較しました。結果は、エミュレーションの起動時に読み込まれる単一のテキスト ファイルにエクスポートされます。恐ろしいように聞こえますが、実際には、命令のデコードがポインターにアクセスするだけなので、物事が大幅に簡素化され、エミュレーションが高速化されます。命令セット データ ファイルの例は、ここにありますハードウェア エミュレーションの適切な実装は何ですか

数年前、私はこれに関する論文も発表しました(残念ながら、その会議を開催する機関はもう存在しないため、サーバーは幸運にもそれらの古い論文で永久にダウンしています)私はまだコピーを入手しています)。

CPU スケジューリング

  • a)フルスロットルには同期がなく、生の速度だけです
  • b) #1にはハードウェア同期の問題を引き起こす大きなギャップがあります
  • c)#2は非常に小さな粒度で多くのスリープを行う必要があります(問題が発生し、速度が低下する可能性があります)しかし、命令はリアルタイムに非常に近く実行されます...
  • 赤い線はホストCPUの処理速度です(明らかにそれより上にあるものはもう少し時間がかかるので、次の命令の前に切り取って挿入する必要がありますが、適切に描画するのは難しいでしょう)
  • マゼンタの線は、エミュレート/シミュレートされた CPU 処理速度です。
  • 交互のgreen/blue色は次の命令を表します
  • 両軸は時間

[編集1] より正確な画像

上のものは手描きです... これは VCL/C++ プログラムによって生成されます:

タイミング

これらのパラメーターによって生成されます。

const int iset[]={4,6,7,8,10,15,21,23}; // possible timings [T]
const int n=128,m=sizeof(iset)/sizeof(iset[0]); // number of instructions to emulate, size of iset[]
const int Tps_host=25;  // max possible simulation speed [T/s]
const int Tps_want=10;  // wanted simulation speed [T/s]
const int T_timer=500;  // simulation timer period [T]

そのため、ホストは必要な速度の 250% でシミュレートでき、シミュレーションの粒度は 500T です。疑似ランダムに生成された命令...

于 2015-10-24T10:36:08.860 に答える
3

Arstechnica の最近のコンソール シミュレーションに関する記事は非常に興味深いものでした。また、かなりの数のシミュレーターへのリンクもあり、非常に優れた研究に役立つ可能性があります。

精度が力を発揮: 1 人の男の 3GHz クエストで完璧な SNES エミュレーターを構築

関連するビットは、著者が言及していることであり、私は同意する傾向がありますが、ほとんどのゲームはタイミングのずれが +/-20% であってもかなり正しく機能するように見えます。あなたが言及した問題は、最終的なゲームをプレイしている間はおそらく感知できない、ほんの数パーセントのタイミングエラーを実際に導入することは決してないように見えます. 著者はおそらく、それを扱う価値があるとは考えていませんでした。

于 2011-08-19T14:50:43.653 に答える
0

それは、エミュレータをどれだけ正確にしたいかによると思います。それほど正確である必要はないと思います。x86 プラットフォームのエミュレーションを考えてみてください。プロセッサには非常に多くのバリエーションがあり、それぞれ実行レイテンシと発行率が異なります。

于 2011-08-19T14:25:30.420 に答える