模拟器如何工作以及它们是如何编写的?

时间:2009-01-15 22:10:16

标签: emulation c64

模拟器如何工作?当我看到NES / SNES或C64模拟器时,它让我震惊。

http://www.tommowalker.co.uk/snemzelda.png

您是否必须通过解释其特定的装配说明来模拟这些机器的处理器?还有什么进入它?它们通常是如何设计的?

您是否可以为有兴趣编写模拟器(特别是游戏系统)的人提供建议?

16 个答案:

答案 0 :(得分:1126)

答案 1 :(得分:126)

一位名叫Victor Moya del Barrio的人写了关于这个话题的论文。 152页的很多好消息。您可以下载PDF here

如果您不想在scribd注册,可以谷歌搜索PDF标题"Study of the techniques for emulation programming"。 PDF有几个不同的来源。

答案 2 :(得分:43)

仿真可能看起来令人生畏,但实际上比模拟更容易。

任何处理器通常都有一个编写良好的规范,用于描述状态,交互等。

如果您根本不关心性能,那么您可以使用非常优雅的面向对象程序轻松模拟大多数旧处理器。例如,X86处理器需要一些东西来维护寄存器的状态(简单),一些东西来维持内存状态(简单),以及一些可以接收每个传入命令并将其应用到机器当前状态的东西。如果你真的想要准确性,你也会模仿内存翻译,缓存等,但这是可行的。

事实上,许多微芯片和CPU制造商针对芯片的仿真器测试程序,然后针对芯片本身,这有助于他们发现芯片的规格是否存在问题,或者芯片的实际实现是否存在问题在硬件中。例如,可以编写会导致死锁的芯片规范,并且当硬件中出现截止日期时,重要的是看它是否可以在规范中再现,因为这表明比芯片实现中的问题更大的问题。

当然,视频游戏的模拟器通常关心性能,因此它们不使用天真的实现,它们还包括与主机系统的操作系统接口的代码,例如使用绘图和声音。

考虑到旧视频游戏(NES / SNES等)的性能非常低,现代系统上的仿真非常简单。事实上,你可以下载一套有史以来每一款SNES游戏或任何Atari 2600游戏更令人惊讶,因为当这些系统受欢迎时,可以自由访问每个盒式磁带将是梦想成真。

答案 3 :(得分:29)

我知道这个问题有点陈旧,但我想在讨论中加入一些内容。这里的大部分答案都围绕着模拟器解释他们模拟的系统的机器指令。

然而,有一个非常着名的例外,称为“UltraHLE”(WIKIpedia article)。 UltraHLE是有史以来最着名的模拟器之一,它被广泛认为是不可能的,仿效商用Nintendo 64游戏(在家用电脑上具有不错的性能)。事实上,当创建UltraHLE时,任天堂仍在为Nintendo 64制作新游戏!

我第一次看到有关印刷杂志中模拟器的文章,之前我只是在网上讨论过它们。

UltraHLE的概念是通过模拟C库调用而不是机器级调用来实现不可能的。

答案 4 :(得分:22)

值得一看的是Imran Nazar尝试用JavaScript编写Gameboy模拟器。

答案 5 :(得分:18)

创建了我自己的80年代BBC微型计算机模拟器(将VBeeb输入Google),有很多事情需要了解。

  • 你不会仿效真实的东西,那将是一个复制品。相反,你正在模仿状态。一个很好的例子是计算器,真实的东西有按钮,屏幕,外壳等。但是要模拟计算器,你只需要模拟按钮是向上还是向下,LCD的哪些部分打开等等。基本上,一组数字表示计算器中可能发生变化的所有可能组合。
  • 您只需要模拟器的界面出现并且表现得像真实的一样。这越有说服力就越接近仿真。幕后发生的事情可以是你喜欢的任何事情。但是,为了便于编写仿真器,在真实系统(即芯片,显示器,键盘,电路板和抽象计算机代码)之间会发生心理映射。
  • 要模拟计算机系统,最简单的方法是将其分解为较小的块并单独模拟这些块。然后将整批产品串在一起作为成品。就像一组带输入和输出的黑盒子一样,它非常适合面向对象的编程。您可以进一步细分这些块以使生活更轻松。

实际上,您通常希望编写速度和仿真保真度。这是因为目标系统上的软件(可能)运行速度比源系统上的原始硬件慢。这可能会限制编程语言,编译器,目标系统等的选择 此外,您必须限制您准备模拟的内容,例如,不必模拟微处理器中晶体管的电压状态,但可能需要模拟微处理器寄存器组的状态。
一般来说,仿真的细节程度越小,您对原始系统的保真度就越高。
最后,旧系统的信息可能不完整或不存在。因此,掌握原始设备至关重要,或者至少要珍惜其他人写过的另一个优秀的模拟器!

答案 6 :(得分:17)

是的,您必须“手动”解释整个二进制机器代码混乱。不仅如此,大多数时候您还必须模拟一些在目标机器上没有等效物的奇特硬件。

简单的方法是逐个解释说明。这很好,但速度很慢。更快的方法是重新编译 - 将源机器代码转换为目标机器代码。这更复杂,因为大多数指令不会一对一映射。相反,您将不得不进行涉及其他代码的详细解决方案。但最终它要快得多。大多数现代模拟器都是这样做的。

答案 7 :(得分:15)

开发仿真器时,您正在解释系统正在处理的处理器组件(Z80,8080,PS CPU等)。

您还需要模拟系统具有的所有外围设备(视频输出,控制器)。

你应该开始为simpe系统编写模拟器,比如好的Game Boy(使用Z80处理器,我不是没有误)或者是C64。

答案 8 :(得分:10)

  

模拟器非常难以创建,因为有许多黑客(如不常见的   您需要模拟的效果),时间问题等。

有关此示例,请参阅http://queue.acm.org/detail.cfm?id=1755886

这也将向您展示为什么您需要一个用于模拟1MHz的多GHz CPU。

答案 9 :(得分:9)

另请查看Darek Mihocka的Emulators.com,获取有关JIT指令级优化的建议,以及构建高效仿真器的许多其他好处。

答案 10 :(得分:7)

我从来没有做过模仿游戏控制台这么花哨的事情,但我确实选择了一个课程,其中的任务是为Andrew Tanenbaums Structured Computer Organization中描述的机器编写模拟器。这很有趣,给了我很多时刻。在潜入编写真正的模拟器之前,您可能想要选择该书。

答案 11 :(得分:4)

有关模拟真实系统或您自己的事情的建议吗? 我可以说模拟器通过模拟整个硬件来工作。也许没有下到电路(因为移动位像硬件一样。移动字节是最终结果所以复制字节很好)。模拟器非常难以创建,因为您需要模拟许多黑客(如不常见的效果),计时问题等。如果一个(输入)部分错误,整个系统可以关闭或最多有一个错误/故障。

答案 12 :(得分:4)

Shared Source Device Emulator包含PocketPC / Smartphone模拟器的可构建源代码(需要Visual Studio,在Windows上运行)。我参与了二进制版本的V1和V2。

它解决了许多仿真问题: - 从客户虚拟到客户物理到主机虚拟的高效地址转换 - 客户代码的JIT编译 - 模拟外围设备,如网络适配器,触摸屏和音频 - UI集成,用于主机键盘和鼠标 - 保存/恢复状态,用于模拟从低功耗模式恢复

答案 13 :(得分:1)

添加@Cody Brocious提供的答案
在虚拟化环境中,您要为虚拟机模拟新系统(CPU,I / O等),我们可以看到以下类别的仿真器。

解释:bochs是一个解释器的例子,它是一个x86 PC模拟器,它从来宾系统的每条指令转换它在另一组指令(主机ISA)中产生预期的效果。是的,它很慢,它不会缓存任何内容,因此每条指令都经历相同的循环。

动态电子邮件:Qemu是一个动态模拟器。它即时转换客户指令也可以缓存结果。最好的部分是直接在主机系统上执行尽可能多的指令,以便仿真更快。同样如Cody所述,它将代码分成块(1个单独的执行流程)。

静态模拟器:据我所知,没有静态模拟器可以帮助虚拟化。

答案 14 :(得分:1)

我将如何开始模拟。

1.获取基于低级编程的书籍,你需要它为任天堂的“假装”操作系统...游戏男孩......

2.专门获得有关模拟的书籍,也许还有开发。 (你不会制作一个操作系统,但最接近它。

3.查看一些开源模拟器,尤其是您想要为其制作模拟器的系统。

4.将更复杂的代码片段复制到IDE / compliler中。这将节省您编写长代码。这是我为os开发所做的,使用linux的区域

答案 15 :(得分:1)

我写了一篇关于模仿Chip-8 system in JavaScript的文章。

这是一个很好的起点,因为系统不是很复杂,但您仍然可以了解操作码,堆栈,寄存器等是如何工作的。

我将很快为NES写一篇更长的指南。