1

私はNESエミュレーターを書く予定です。しかしまず、エミュレーションのしくみを理解するために、Chip-8 エミュレーターを作成します。

エミュレーターはほぼ完成しています。ゲームにいくつかのバグがありますが、これはすぐに修正されます。私の問題番号 1 は、エミュレーターを Chip-8 のクロック速度と同期させることです。私がよく読んだインターネットでは、一般的なクロック速度は〜540Hzである必要があります。チップのタイマーは、60Hz の周波数で刻む必要があります。

エミュレータを Chip-8 と同期させるために、次のロジックを記述しました。

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));
        }     
    }
}

詳細については、私のリポジトリをご覧ください: https://github.com/Marcel-Hoffmann/Chip-8-Emulator

ご覧のとおり、CPU サイクルごとに 1852 マイクロ秒待機します。結果は、540Hz に等しい 1 秒間に ~ 540 サイクルになります。しかし、私はこの論理にあまり満足していません。

クロック速度を同期する方法について、誰かがより良いアイデアを持っていますか?

4

1 に答える 1

2

これは典型的なアプローチであり、多くの欠点があります。最も顕著なのは、不必要な CPU 使用率と潜在的なスケジューリングの問題です (アプリケーションは 100% CPU ビーストと見なされるため、負荷がかかる前に他のアプリケーションがスレッドの量を取得する可能性があります)。

代わりにスリープを使用することをお勧めします。ただし、デフォルトでは、システム タイマーは 2 ミリ秒未満の待機に対応できる周波数に近くありません。そのため、スリープを使用する場合は、システム タイマーを変更する必要があります。これは、古い Windows では少し注意が必要です (システム全体の設定であり、他のアプリケーションや一般的な CPU 使用率に顕著な影響を与えます) が、その場合でも、システムを復元する限り、「ビジー ループ」よりはましです。設定はその後。Windows 8 (およびある程度、7 と Vista) では、タイマーは非同期であり、ビジー ループが不要になったため、タイマーの解像度を高くするのがはるかに簡単になりました。

システム タイマー API は .NET によって公開されていないため、P/Invokes を使用する必要があります (timeBeginPeriod古いtimeEndPeriodスタイルの API の場合)。これが利用できない場合は、いつでもビジー ループに戻ることができます :)

于 2016-05-27T12:06:40.927 に答える