2016-05-27 6 views
1

私はnesエミュレータを書くつもりです。しかし、まず、エミュレーションの仕組みを理解するために、私はChip-8エミュレータを作成します。Chip-8エミュレータ:クロック速度を遅くする

エミュレータはほぼ完成です。私はゲームでいくつかのバグを抱えていますが、これはまもなく修正されます。 私の問題番号1は、エミュレータをChip-8のクロック速度と同期させることです。 インターネットでは、一般的なクロック速度は〜540Hzであることがよくあります。チップのタイマーは、60Hzの周波数でチェックする必要があります。あなたが見ることができるように、それぞれのために、https://github.com/Marcel-Hoffmann/Chip-8-Emulator

:私のレポを見て、より詳細な情報について

private void GameTick() 
{ 
    Stopwatch watch = new Stopwatch(); 
    var instructionCount = 0; 
    _gameIsRunning = true; 

    while (_gameIsRunning) 
    { 
     watch.Restart(); 

     EmulateCycle(); 

     //Updates the internal timer at a 60hz frequenz 
     //540hz (game tick) divided by 9 equals 60hz (timer tick) 
     instructionCount++; 
     if(instructionCount == 9) 
     { 
      UpdateSoundAndDelay(); 
      instructionCount = 0; 
     } 

     if (_readyToDraw) 
     { 
      DrawGraphics(); 
      _readyToDraw = false; 
     } 

     SetKeys(); 

     //Pause the game to get a virtual clock speed of ca. 540mhz 
     var elapsedMicroseconds = watch.ElapsedTicks/(Stopwatch.Frequency/(1000L * 1000L));  
     while(elapsedMicroseconds < 1852) 
     { 
      elapsedMicroseconds = watch.ElapsedTicks/(Stopwatch.Frequency/(1000L * 1000L)); 
     }  
    } 
} 

はチップ-8私が書いたフォローロジックと私のエミュレータを同期するにはCPUサイクル、私は1852マイクロ秒待つでしょう。結果は540Hzに等しい秒で〜540サイクルになります。 しかし、私はこの論理にあまり満足していません。

は、誰かにクロック速度を同期させるためにどのようにより良いアイデアを持っていますか?

答えて

2

これは典型的なアプローチであり、多くの欠点があります。特に、不必要なCPU使用率とスケジューリングの問題があります(アプリケーションは100%のCPUビートと見なされるため、 。

より良いアプローチでは、代わりにスリープが使用されますが、デフォルトでは、システムタイマーは2ms未満の待機に対応できる周波数に近くありません。したがって、スリープを使用する場合は、システムタイマーを変更する必要があります。これは古いWindowsでは少し難解です(システム全体の設定で、他のアプリケーションや一般的なCPU使用に顕著な影響を与えます)が、その場合でも、システムを復元している限りは "ビジーループ"より優れていますその後の設定。 Windows 8(とある程度は7とVista)では、タイマーは非同期で、もはやビジーループを必要としないので、タイマーの分解能を上げる方がはるかに簡単です。

システムタイマーAPIは.NETでは公開されていないため、P/Invokes(旧式のAPIにはtimeBeginPeriodおよびtimeEndPeriod)を使用する必要があります。これが利用できない場合は、常にビジーループにフォールバックすることができます:)

関連する問題