0324-Chip8-实现指令 8
环境
- 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
其中最后一个提供了测试的套件,实现的过程中,可以检测哪些指令有问题,帮助很大。
目标
实现 0x8nnn 指令。
execute
cpu 文件中其它不相关代码已省略,增加一条 0x8 指令的分支,单独进行实现。
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),
else => std.log.info("unknown opcode: 0x{X:0>4}", .{ins.opcode}),
}
}
code8
- 前四条指令都是寄存器 x 和 y 操作,然后赋值给寄存器 y。
- 第五条是两个数加,溢出标志影响 F 寄存器,结果存 x 寄存器。
- 第六条和第八条是相减,溢出影响 F,结果存 x。
- 第七和第九条是移位操作。
fn code8(self: *CPU, reg: *[16]u8, ins: *Instruct) void {
switch (ins.n) {
0x0 => reg[ins.x] = reg[ins.y],
0x1 => reg[ins.x] |= reg[ins.y],
0x2 => reg[ins.x] &= reg[ins.y],
0x3 => reg[ins.x] ^= reg[ins.y],
0x4 => {
const sum = @addWithOverflow(reg[ins.x], reg[ins.y]);
reg[ins.x] = sum.@"0";
reg[0xF] = sum.@"1";
},
0x5 => self.subWithFlag(reg[ins.x], reg[ins.y]),
0x6 => {
reg[0xF] = reg[ins.x] & 0x1;
reg[ins.x] = reg[ins.x] >> 1;
},
0x7 => self.subWithFlag(reg[ins.y], reg[ins.x]),
0xE => {
reg[0xF] = (reg[ins.x] >> 7) & 0x1;
reg[ins.x] = reg[ins.x] << 1;
},
else => std.log.info("unknow opcode: 0x{X:0>4}", .{ins.opcode}),
}
}
启动
zig build run
效果

总结
实现了 code8,并进行验证。对于测试 rom 还有 F 指令没有实现。

浙公网安备 33010602011771号