Phi*_*987 6 z80 emulation cpu-cycles
我打算在接下来的几个月里创建一个Sega Master System模拟器,作为Java中的一个爱好项目(我知道它不是最好的语言,但我发现它很舒服,并且作为一个频繁的用户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.
}
}
Run Code Online (Sandbox Code Playgroud)
在此特定循环示例结束后,numOfCycles将为-2.这只会是一个小小的不准确,但在人们的经历中总体上是否重要?我很欣赏任何人对这一点的见解.我计划在每帧之后中断CPU,因为这似乎合适,所以1000个周期很低我知道,这只是一个例子.
非常感谢,菲尔
大多数仿真器/模拟器只处理CPU时钟抽搐
对游戏来说这很好......所以你有一些计时器或者什么都可以运行CPU模拟,直到CPU模拟计时器的持续时间.然后它会一直睡到下一个定时器间隔.这很容易模拟.您可以通过您询问的方法减少计时错误.但正如这里所说的游戏通常是不必要的.
这种方法有一个明显的缺点,那就是你的代码只是实时的一小部分.如果定时器间隔(定时粒度)足够大,即使在游戏中也是如此.例如,当仿真睡眠时,您及时按下键盘键,然后未检测到.(键有时候不起作用).您可以通过使用较小的时序粒度来解决这个问题,但这在某些平台上非常困难.在这种情况下,定时错误在软件生成的声音中可能更"明显" (至少对那些能够听到它并且对我这样的事情没有聋的人来说是这样).
如果你需要更复杂的东西
例如,如果您想将真实硬件连接到仿真/模拟,那么您需要模拟/模拟BUS'es.此外,像浮动公交车或系统争用这样的事情很难添加到方法#1(这是可行的,但有很大的痛苦).
如果将时间和仿真移植到机器周期,事情变得容易得多,突然之间的事情就像争用或硬件中断,浮动的BUS'es几乎都在自己解决.我将我的ZXSpectrum Z80仿真器移植到这种时序并看到了光.很多事情都很明显(比如Z80操作码文档中的错误,时间等).此外,争用变得非常简单(只需几行代码而不是几乎每个指令类型条目的可怕解码表).硬件模拟也很容易我用这种方式添加了像FDC控制器AY芯片仿真到Z80的东西(没有黑客它真正运行在他们的原始代码上......甚至软盘格式化:))所以没有更多的TAPE加载hacks而不是工作适用于TURBO等定制装载机
为了完成这项工作,我创建了我对Z80的仿真/模拟,其方式是为每条指令使用微码.因为我经常纠正Z80指令集中的错误(因为没有单一的100%正确的文档,我知道即使其中一些人声称它们没有bug并且完整)我有一种方法如何处理它没有痛苦地重新编程模拟器.
每条指令由表中的条目表示,其中包含有关时序,操作数,功能的信息......整个指令集是所有指令的所有这些条目的表.然后我为我的指令集形成一个MySQL数据库.并为我找到的每个指令集形成类似的表.然后痛苦地比较所有选择/修复错误和正确的错误.结果将导出到单个文本文件,该文件在仿真启动时加载.这听起来很可怕但实际上它简化了很多事情甚至加速了仿真,因为指令解码现在只是访问指针.可以在此处找到指令集数据文件示例什么是硬件仿真的正确实现
几年前我也发表了关于此的论文(遗憾的是,机构认为会议不再存在,所以服务器在那些旧报纸上表现不错,幸运的是我仍然得到了副本)所以这里的图像描述了问题:
green/blue颜色代表下一条指令最近 Arstechnica 上有一篇非常有趣的文章谈论控制台模拟,还链接到相当多的模拟器,这些模拟器可能有助于很好的研究:
准确性决定力量:一个人构建完美 SNES 模拟器的 3GHz 追求
相关的一点是,作者提到,而且我倾向于同意,即使时间偏差为 +/-20%,大多数游戏看起来也能正常运行。您提到的问题看起来可能永远不会真正引入超过百分之一的计时误差,这在玩最终游戏时可能是难以察觉的。作者可能认为不值得处理。