我正计划写一个新的模拟器。但是首先,为了理解仿真是如何工作的,我将编写一个芯片-8模拟器。
仿真器已接近完成。我在游戏中有一些bug,但这个很快就会修复的。我的问题1是同步仿真器与芯片-8的时钟速度。在互联网上,我经常读到,一般的时钟速度应该是540 be。芯片的定时器应该在频率为60 of的频率上滴答作响。
为了使模拟器与芯片-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微秒。结果将是540个周期在每秒等于540赫兹。但我对这种逻辑不太满意。
有人有更好的主意,如何同步时钟的速度?
发布于 2016-05-27 12:06:40
这是典型的方法,并且有许多缺点--最明显的是,不必要的CPU使用和潜在的调度问题(您的应用程序将被视为100%的CPU猛增,因此其他应用程序可能会在负载下得到线程量)。
一种更好的方法是使用睡眠--但是,默认情况下,系统计时器远远不能满足小于2ms的等待。因此,如果您想要使用睡眠,您将需要更改系统计时器。这在旧的Windows上有点棘手(这是一个系统范围的设置,对其他应用程序和一般CPU的使用都有明显的影响),但是即使在这种情况下,它也比“繁忙的循环”要好--只要您事后恢复系统设置。在Windows 8上(在某种程度上,7和Vista),计时器是异步的,不再需要繁忙的循环,因此获得更高的定时器分辨率要容易得多。
.NET不公开系统计时器API,因此需要使用P/调用(旧风格API的timeBeginPeriod和timeEndPeriod )。如果这是不可用的,您总是可以回到繁忙的循环:)
https://stackoverflow.com/questions/37482614
复制相似问题