gpt4 book ai didi

c++ - 获取可变长度操作码和 CPU 时序

转载 作者:行者123 更新时间:2023-11-30 04:17:00 28 4
gpt4 key购买 nike

我目前正在尝试用 C++ 编写一个 NES 模拟器,作为一个夏季编程项目,为下一学年的秋季学期做准备(我已经有一段时间没有编码了)。我已经编写了一个 Chip8 模拟器,所以我认为下一步是尝试编写一个 NES 模拟器。

无论如何,我被卡住了。我正在使用 this我的操作码表的网站,我遇到了障碍。在 Chip8 上,所有操作码都是两个字节长,因此很容易获取。但是,NES 似乎有 2 个或 3 个字节的操作码,具体取决于 CPU 所处的寻址模式。我想不出任何简单的方法来计算每个操作码需要读取多少字节(我唯一的想法是创建非常长的 if 语句来检查操作码的第一个字节以查看还有多少字节要读取)。

我也很难弄清楚如何计算周期。如何在编程语言中创建一个时钟,以便一切都同步?

在一个不相关的旁注中,由于 NES 是小端,我是否需要读取 programCounter + 1 然后读取 programCounter 以获得正确的操作码?

最佳答案

However, the NES seems to have either 2 or 3 byte opcodes depending on what addressing mode the CPU is in. I can't think of any easy way to figure out how many bytes I need to read for each opcode.

操作码仍然只有一个字节。额外的字节指定那些具有显式操作数的指令的操作数。要进行解码,您可以创建一个包含 256 个案例的 switch block (实际上不会是 256 个案例,因为有些操作码是非法的)。它可能看起来像这样:

opcode = ReadByte(PC++);
switch (opcode) {
...
case 0x4C: // JMP abs
address = ReadByte(PC++);
address |= (uint16_t)ReadByte(PC) << 8;
PC = address;
cycles += 3;
break;
...
}

编译器通常会为案例创建一个跳转表,因此您最终会得到相当高效(尽管有点臃肿)的代码。

另一种方法是创建一个数组,每个操作码有一个条目。这可以简单地是一组函数指针,每个操作码一个函数——或者该表可以包含一个指向一个函数的指针,用于获取操作数,一个用于执行实际操作,以及有关指令所需周期数的信息。这样你就可以共享很多代码。一个例子:

const Instruction INSTRUCTIONS[] =
{
...
// 0x4C: JMP abs
{&jmp, &abs_operand, 3},
...
};

I'm also having trouble with figuring how to count cycles. How do I create a clock within a programming language so that everything is in sync?

计算 CPU 周期只是递增计数器的问题,就像我在上面的代码示例中展示的那样。

要与 CPU 同步视频,最简单的方法是让 CPU 运行与单个扫描线的事件显示周期对应的周期数,然后绘制一条扫描线,然后运行 ​​CPU 对应的周期数到水平消隐期,重新开始。

当您开始涉及音频时,同步内容的方式可能在一定程度上取决于您使用的音频 API。例如,某些 API 可能会向您发送一个回调,您可以通过用样本填充缓冲区并返回生成的样本数来响应该回调。在这种情况下,您可以计算自上次回调以来模拟的 CPU 周期数,并根据此确定要生成的样本数。


On an unrelated side note, since the NES is little-endian, do I need to read programCounter + 1 and then read programCounter to get the correct opcode?

由于操作码是单个字节,并且 6502 上的指令不像其他一些 CPU 架构那样打包成一个字,因此字节顺序并不重要。它确实与 16 位操作数相关,但另一方面,PC 和大多数手机也基于小端 CPU。

关于c++ - 获取可变长度操作码和 CPU 时序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17377372/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com