2011-08-19 103 views
5

我打算在接下来的几个月内创建一个世嘉主系统模拟器,作为Java中的一个业余爱好项目(我知道这不是最好的语言,但我发现它工作起来非常舒适,并且作为Windows和Linux的常用用户,我认为跨平台应用会很棒)。我的问题是关于周期盘点;关于模拟CPU时的周期计数精度的问题

我看过了另一个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个周期是低的,但这只是一个例子。

非常感谢, 菲尔

回答

2

是在Arstechnica最近谈论控制台模拟一个相当有趣的文章,还链接到了不少模拟器,可能使相当好的研究:

Accuracy takes power: one man's 3GHz quest to build a perfect SNES emulator

相关的一点是,作者提到,而且我倾向于同意,即使定时偏差为+/- 20%,大多数游戏的功能也会相当正常。你提到的问题看起来可能永远不会引入超过百分之一的时间误差百分比,在玩最后一场比赛时这可能是不可察觉的。作者可能不认为值得处理。

+0

感谢:-)几天前我看到这篇文章,这是一个非常有趣的阅读。看起来我可以忽略这个问题 - 把我的工作剪掉,但应该很有趣! :-P – PhilPotter1987

0

我想这取决于你想如何精确你的模拟器是。我不认为它必须那么准确。考虑x86平台的仿真,处理器有很多种变体,每种变体都有不同的执行延迟和问题发生率。

+0

嗯,我想只要我把它绑帧率 - 说50fps的,如果我仿效PAL控制台 - 然后这些帧之间,如果我执行如何进行多次循环,然后暂停,同时更新应该适当的屏幕。猜猜我会发现:-p感谢您的答案。 – PhilPotter1987

4
  1. 大多数仿真器/处理只是CPU时钟模拟抽动

    这是好的游戏等等......所以,你得到了一些定时器或什么都和CPU运行的模拟,直到CPU模拟定时器的持续时间。然后休眠直到下一个定时器间隔发生。这很容易模拟。您可以通过您询问的方法来减少计时错误。但正如这里所说的游戏,这通常是不必要的。

    这种方法有一个明显的缺点这就是你的代码只是实时的一小部分。如果定时器间隔(定时粒度)足够大,即使在游戏中也可以引起注意。例如,您在模拟时按下键盘键然后睡觉,则无法检测到。 (键有时不工作)。您可以通过使用更小的时间粒度来弥补这一点,但这在某些平台上非常困难。在这种情况下,定时错误可以在软件生成中更“可见”声音(至少对于那些能够听到它并且对我这样的事物没有耳聋的人)。

  2. 如果你,如果你想连接真实HW到您的仿真/模拟需要一些更复杂的

    例如,那么你需要模拟/仿真BUS'es。还有像浮动总线争用系统是很难添加到方法#1(这是可行的,但有很大的痛苦)。

    如果端口时序和仿真,以机器周期事情变得多容易得多突然之类的东西争或硬件中断,浮动BUS'es正在解决自己几乎自己。我将ZXSpectrum Z80仿真器移植到这种时序并看到灯光。许多事情变得明显(如Z80操作码文档中的错误,时间等)。此外,争用从那里变得非常简单(几乎每个指令类型条目几行代码,而不是可怕的解码表)。硬件仿真也很容易我添加了像FDC控制器这样的东西AY以这种方式将仿真仿真到Z80(没有黑客真的在他们原来的代码上运行......甚至软盘格式化:)),所以没有更多的TAPE加载黑客和不工作对于像TURBO这样的定制装载机来说,为了做到这一点,我创建了我的仿真/仿真模型Z80,其方式是为每条指令使用类似微码的东西。由于我经常更正指令集中的错误(因为没有单个100%正确的文档,我知道即使他们中的一些人声称他们没有bug并且完整)我带着一种方式来处理如何处理它不会痛苦地重新编程模拟器。

    每条指令都由一个表中的条目表示,包含关于时序,操作数,功能的信息......整个指令集是所有指令的所有条目表。然后我为我的指令集组成一个MySQL数据库。并形成我找到的每个指令集的类似表格。然后痛苦地比较他们选择/修复什么是错的,什么是正确的。结果被导出到在仿真启动时加载的单个文本文件。它听起来很可怕,但实际上它简化了很多事情甚至加速了仿真,因为指令解码现在只是访问指针。该指令集的数据文件例如可以在这里找到What's the proper implementation for hardware emulation

几年前我也发表对本文(即认为,会议已经不存在,所以服务器关闭为好这些旧报纸幸运的是我黯然机构仍然有一个副本)所以这里的图像从它描述的问题群:

CPU Scheduling

  • 一)全部throtlle没有同步只是原始速度
  • 二)#1具有造成硬件的同步问题
  • 三)#2需要睡觉了很多非常小的粒度(可能是有问题的,慢下来)很大的差距,但这些指令非常接近执行他们的实时...
  • 红线是主机CPU处理速度(明显的是它上面花费更多的时间,所以应该被削减,下一条指令之前插入但它是很难正确地画出)
  • 品红线是仿真/模拟CPU的处理速度
  • 交替素摹green/blue颜色代表下一条指令
  • 两个轴系是时间