0325-Chip8-实现指令 F
环境
- Time 2023-07-27
- Zig 0.11.0-dev.4191+1bf16b172
- SLD2 2.28.1
前言
说明
参考资料:
- https://en.wikipedia.org/wiki/CHIP-8
- https://austinmorlan.com/posts/chip8_emulator/
- https://rsj217.github.io/chip8-py/
- https://github.com/Timendus/chip8-test-suite
其中最后一个提供了测试的套件,实现的过程中,可以检测哪些指令有问题,帮助很大。
目标
部分实现 0xFnnn 指令,包括 0x1E、0x29、0x33、0x55、0x65。
execute
cpu 文件中其它不相关代码已省略,增加一条 0xF 指令的分支,单独进行实现。
fn execute(self: *CPU, memory: *Memory) void {
const ins = &self.instruct;
var reg = &self.register;
switch (ins.code) {
0x0 => {
if (ins.opcode == 0x00E0) memory.clearScreen();
if (ins.opcode == 0x00EE) self.pc = memory.pop();
},
0x1 => self.pc = ins.nnn,
0x2 => {
memory.push(self.pc);
self.pc = ins.nnn;
},
0x3 => if (reg[ins.x] == ins.nn) self.next(),
0x4 => if (reg[ins.x] != ins.nn) self.next(),
0x5 => if (reg[ins.x] == reg[ins.y]) self.next(),
0x6 => reg[ins.x] = ins.nn,
0x7 => reg[ins.x] +%= ins.nn,
0x8 => self.code8(reg, ins),
0x9 => if (reg[ins.x] != reg[ins.y]) self.next(),
0xA => self.index = ins.nnn,
0xB => self.pc = reg[0] + ins.nnn,
0xD => self.draw(memory),
0xF => self.codef(ins, memory),
else => std.log.info("unknown opcode: 0x{X:0>4}", .{ins.opcode}),
}
}
codef
fn codef(self: *CPU, ins: *Instruct, memory: *Memory) void {
switch (ins.nn) {
0x1E => self.index += self.register[ins.x],
0x29 => self.index = self.register[ins.x] * 5,
0x33 => {
var num = self.register[ins.x];
memory.set(self.index + 2, num % 10);
num /= 10;
memory.set(self.index + 1, num % 10);
num /= 10;
memory.set(self.index, num % 10);
},
0x55 => {
for (0..ins.x + 1) |i| {
memory.set(self.index + i, self.register[i]);
}
},
0x65 => {
for (0..ins.x + 1) |i| {
self.register[i] = memory.get(self.index + i);
}
},
else => std.log.info("unknown opcode: 0x{X:0>4}", .{ins.opcode}),
}
}
0x1E
将 x 寄存器中的值加到索引寄存器 index 中。
0x29
将索引寄存器中的值指向 x 寄存器中指向的精灵的地址。
0x33
将二进制转为十进制的 BCD 形式。
0x55
从索引寄存器开始,将寄存器的值保存到内存中,数量由指令指定。
0x65
从索引寄存器开始,将内存中的值加载到寄存器中,数量由指令指定。
启动
zig build run
效果

总结
部分实现了 F 指令,现在验证第三个测试 rom,发现所有的测试都已经通过。第四个测试 rom 也通过了部分,其余和怪异模式相关,不处理。

浙公网安备 33010602011771号