C-如何学习编程游戏机模拟器(专门的硬件知识)



我之前曾问了一个类似的问题,关于如何编写仿真器,当我看到答案并查找一些开源的游戏男孩模拟器时,我发现还有更多需要更多比对"低级别"语言的中间理解(即C)。我实际上想知道的是,我需要了解硬件,以便能够编程这种模拟器。我正在关闭Java的"很好",但这对我没有很大帮助。我已经开始学习C,现在已经走了很长一段路,但是我有兴趣知道我必须在硬件上学习什么才能编写这样的控制台仿真器。

我问这个问题的原因是我一直在互联网上搜索有关仿真的书籍和资源,每当我遇到仿真器教程时,总是就像是"您需要对C的基本理解才能成为能够遵循本教程。"当我尝试遵循它时,我不能,仅仅是因为我不知道该到底是什么编程。我从来没有对硬件一无所知。(我的父亲努力将其显示器连接到PC的父亲可能对此有所了解)

所以我的问题是,我需要学习什么(微处理器,记忆等?),是否有任何好消息来源可以教我这些东西,而无需我上大学或其他东西(已经进行软件工程)?

我很抱歉,如果这不是一个真正的问题,或者不够清楚,或者类似的东西。我只是对这个主题非常感兴趣。

认为这可能更适合programmers.stackexchange.com,但无论如何:

我不会说您需要任何特定的知识。了解微处理器和内存管理工作将如何对汇编器知识有所帮助(因为您本质上是为汇编器式代码编写解释器)。假设您已经知道目标硬件是如何工作的,那么您本质上要做的就是实现以下组件(即伪造真实的硬件并模仿/模仿其行为):

  • 模拟CPU解析并运行机器代码。
  • 模拟输入组件(将键盘,鼠标或操纵杆输入等事物转换为CPU可以访问的" PIN信号")。
  • 模拟输出组件(将图像和音频数据转换为可见的东西,例如在屏幕上显示某些内容或生成声音,例如真实硬件组件)。
  • 模拟其他组件,例如内存包,内置电池,墨盒,扩展芯片等

作为一般建议,我会说忘了现在写任何模拟器。而是通过尝试编写自己的字节代码解释器来开始简单的内容。

作为一个例子,您可以使用简单的伪代码序列:

x = 5
y = 10
print(x + y)

用伪汇编器编写,这可能是这样的:

mov x, 5
mov y, 10
add x, y // to be honest, this is essentially x += y; not just x + y
prt x
end

现在用(代码)编号替换所有指令。所有变量都被数字替换:

0x01 0x00 0x05
0x01 0x01 0x0a
0x02 0x00 0x01
0x03 0x00
0x00

这看起来可能有些奇怪,但是我一直保持着订单和线路断路。请注意,我使用0x01用于第一个指令,而不是0x00。这仅是为了方便的,因此我可以将0x00用于" NOOP/NO操作"或终止器(如在这种情况下)。现在,只需删除线路休息,您最终将使用自定义字节代码。

char code[] = {0x01, 0x00, 0x05, 0x01, 0x01, 0x0a, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00};

要运行此代码,您可以编写一个简单的"模拟器"。它只是有限的指令集,但它会起作用。我实际上没有测试此代码,因此请记住,我可能会在某个时候搞砸了。但是,应该足以让您了解如何/如何做。请注意,在此示例中,我不拆分数据存储器和指令内存。这将增加更多的复杂性。

int pos = 0; // essentially being our "instruction pointer"
char registers[10];
while(code[pos]) { // still some instruction
    switch(code[pos++]) { // determine what to do and move the instruction pointer
    // 0x00 isn't handled here, as that's part of our loop already
    case 0x01: // mov(e)
        registers[code[pos++]] = code[pos++]; // read the value into the register
        break;
    case 0x02: // add
        registers[code[pos++]] += registers[code[pos++]];
        break;
    case 0x03: // prn
        printf("%d", registers[code[pos++]]);
        break;
    }
}

一旦您理解我在这里所做的事情,我敢肯定,您也应该有更轻松的时间来理解其他来源。哦,这是一个有趣的事实:如果您是出于教育目的而进行的,而不仅仅是为了撰写有效的模拟器,就可以开始使用Java。它的最佳和速度越慢,但是您本质上可以做同样的事情,甚至可能至少在途中删除。

只是一个快速注意:在上面的示例中,您可以在屏幕上不断地写下registers[]的内容。这样,您可以从本质上模仿一些视频硬件(例如电视屏幕或LED)。

如果您正在寻找更多的来源阅读,我会尝试获取一些简单的处理器并开始学习汇编代码。如果可能的话,请选择一个非常简单的体系结构。这些概念总是相同的,但是随着越来越多的指令集,地址空间虚拟化等,事情可能会变得复杂。

我建议学习一种汇编语言,以获取您在此处需要的基本知识。如果您对超级Nintnedo感兴趣,则可以尝试学习65816组装,这是该控制台使用的处理器的汇编语言。首先,您可以在这里开始阅读:http://en.wikibooks.org/wiki/super_nes_programming。其他控制台也存在类似的资源。我还建议您获得具有调试功能的模拟器,例如Geiger的调试SNES9X,它将让您踏上游戏的执行,抛弃它在做什么,检查内存等。仿真器,它将为您提供一些您要寻找的背景。

说实话,如果C对您来说完全是陌生的,最好在尝试组装之前学习一些。C比集会更抽象,但仍会为您提供许多重要概念的基础,最重要的是指针。

,但基本上,模拟器的作用是逐步浏览游戏的机器代码,通过指令执行指令。控制台是一只相当复杂的野兽,有几个处理器和联合处理器以及相关的硬件一致工作。因此,您可能应该从更简单的仿真器开始,该模拟器仅模拟CPU,而忽略其余的模拟器。为此,学习组装如此有用的原因是,汇编具有与机器代码的1:1翻译。仿真器应该处理。

如果,正如您所说,您对硬件一无所知,然后编写仿真器并不容易。了解硬件的基本功能可能比了解任何特定的编程语言更公正。

我可以推荐Noam Nisan和Shimon Schocken的书计算系统的要素及其相关的Internet资源(http://www.nand2tetris.org/)。这本书将您从简单的Nand大门到构建功能计算机,然后再写一个汇编程序,编译器和操作系统,最后是Tetris的游戏。在每个级别上,您都可以"构建自己的"或使用网络可用答案来为下一个级别构建。

首先,首先编程模拟器需要来自多个领域的知识。您需要牢固地掌握的两个大领域是计算机架构和您选择的编程语言。如果您根本没有编程经验,则创建模拟器不是一个好主意。话虽如此,只要您知道它,您就可以用任何您希望的语言创建模拟器!

为了了解系统的工作方式,建议您在计算机体系结构上进行刷新。我建议阅读一本关于该主题的好书,例如计算机架构:一种定量方法,这对于大多数建筑课程来说是一本非常常见的书。

一旦有了对系统运行的工作(基本)知识(基本)知识(CPU,内存,寄存器,指令集等),您就可以尝试模仿您选择的系统。在此阶段,我建议您四处浏览有关您选择的系统的尽可能多的信息。Zophar.net在许多视频游戏机上都有很多技术文档集合。

一旦有了要模拟系统的工作知识,我建议写代码以读取ROM文件并提取文件内容(特别是指令)。下一步是为每个说明效仿体系结构的CPU和编写处理程序。我通过从ROM加载的实际说明上运行CPU来测试CPU。实施了大量指令后,您可以开始实现其他子系统,例如图形和事件/中断系统。我通常实现的最终系统是合理的。

(无耻的插头)我在一本名为仿真的书中写了这一切 - 逐步,我希望在几个月内发布。我还没有看到有关该主题的另一本书,这是可耻的,因为这是一个有趣的话题!

最新更新