我正在用 C 编写一个 GameBoy 颜色模拟器,只是为了向这个世界介绍自己,它被解释了,没有动态或静态重新编译:P
现在我正忙于用 C 代码实现所有 CPU 操作码的繁琐任务,我必须编写所有这些: http: //www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html我不想从另一个模拟器中获取它们。
问题是,有什么方法可以自动编写操作码吗?也许这是一个愚蠢的问题,它会有一个愚蠢的答案,但我想尽可能少地工作。:)
我正在用 C 编写一个 GameBoy 颜色模拟器,只是为了向这个世界介绍自己,它被解释了,没有动态或静态重新编译:P
现在我正忙于用 C 代码实现所有 CPU 操作码的繁琐任务,我必须编写所有这些: http: //www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html我不想从另一个模拟器中获取它们。
问题是,有什么方法可以自动编写操作码吗?也许这是一个愚蠢的问题,它会有一个愚蠢的答案,但我想尽可能少地工作。:)
我以前做过这种事情,我做的方式是使用宏,但是这样做会导致大量的代码重复,这会溢出 cpu 缓存并使事情变慢。如果我今天要这样做,我会摆脱除晦涩/稀有操作码之外的整个“操作码切换/跳转”习语,并使用一些基于操作码编号。想一想:
operand1 = regs[operand1_table[opcode]];
operand2 = regs[operand2_table[opcode]];
res[ADD] = operand1+operand2;
res[SUB] = operand1-operand2;
res[OR] = operand1|operand2;
/* ... */
regs[dest_table[opcode]] = res[optype_table[opcode]];
这段代码当然被过度简化了,但可以扩展以处理内存操作数等。还要注意,跳转指令只是一个以程序计数器作为其操作数之一的加法指令。
对于 Z80(或其 GB 变体)或 x86 等 CISC 架构,您还必须处理条件代码标志。然而,它们可以像res[...] = ...;
上面那样作为第二组计算来完成。
我知道这是一个古老且已回答的问题,但为了记录,如果有人最终遇到同样的问题:
我编写了一个快速脚本来解析这个文档页面并生成一个带有操作码描述的 JSON。
您可以只加载此 JSON 并从中生成 GB [反] 汇编程序代码的样板,这显然可以节省时间,因为 JSON 很容易从大多数脚本语言中操作。
代码和生成的 JSON:
这就是为什么到目前为止,我只为 msp430、6502 和拇指...少打字做过模拟器或静态重新编译器。为了打破单调,我通常会做一个我想查看并执行的程序/游戏,直到它遇到我尚未实现的操作码,然后实现该操作码并重试。
更糟糕的是,您可能需要两到三个仿真器或对该仿真器进行两到三次重写,然后您才能了解如何节省大量打字和/或如何更好地设计重新设计。使用/逻辑。通过尝试执行最喜欢的 rom,您会得到一个随机指令组合,将您放入操作码表的各个部分,并且当您为这些操作码重用代码时,您可能...可能...能够用更少的资源改进您的设计重写。
正如 R. 所描述的,如果您改为创建电子表格或其他软件可解析表,您可以从该表编写和重写模拟器代码生成器。再次在这里,您可以从小处着手,您不必制作完整的表格,尝试几种不同风格的操作码,看看您是否无法找出允许解析器为模拟器生成代码的表格格式。您可以稍后添加标志和其他内容,并使整个过程随着它的改进而增长。但归根结底,无论是表格还是实际代码,您最终都必须输入所有这些操作码。