我想为运行频率在600千赫左右的特别慢的CPU编写一个模拟器。如果我以一种天真的方式为CPU编写一个模拟器(即一次模拟一条指令,而不做任何其他事情),模拟将比600千赫快得多。
如何编程模拟器以正确的速度模拟CPU,而不管主机的速度如何?真实世界的模拟器通常使用什么技术来实现这一点?如何避免抖动减慢模拟速度?
在一个典型的平台上,唯一可用的"周期性事件"是不准确和低频的,当然一点也不像0.6MHz。但使用"慢速"计时器(可能是100Hz左右),你可以"跑很多短的冲刺",中间有足够的时间"休息",平均每秒模拟合适的周期。时间通常可以相当准确地测量,因此您可以在每次"冲刺"中准确地模拟正确数量的周期。
在高水平上,这可能看起来像这样:
int cycle_budget = 0;
time last_sprint = something;
// on timer fire
cycle_budget += (current_time - last_sprint) * clock_rate;
last_sprint = current_time;
while (cycle_budget >= slowest_instruction)
tick(); // emulates one instruction, subtracts from cycle_budget
有一些明显的变化,例如,你可以让预算为负,而不是测试是否有足够的资金来运行一个缓慢的指令。或者你可以解码指令,然后测试是否有足够的预算来运行它。这一切都假设一条指令不会花费任意长的时间,但据我所知,这从来都不是问题(即使是像z80的字符串指令这样的指令,它们实际上也会通过分支返回并重新执行自己来循环)。