0323-Chip8-实现更多的指令

环境

  • Time 2023-07-27
  • Zig 0.11.0-dev.4191+1bf16b172
  • SLD2 2.28.1

前言

说明

参考资料:

  1. https://en.wikipedia.org/wiki/CHIP-8
  2. https://austinmorlan.com/posts/chip8_emulator/
  3. https://rsj217.github.io/chip8-py/
  4. https://github.com/Timendus/chip8-test-suite

其中最后一个提供了测试的套件,实现的过程中,可以检测哪些指令有问题,帮助很大。

目标

新增 00EE、2NNN、3XNN、4XNN、5XY0、9XY0、BNNN 几个指令。

main.zig

  1. 加载第三个测试 rom。
const std = @import("std");
const chip8 = @import("chip8.zig");

pub fn main() !void {
    // const rom = @embedFile("roms/1-chip8-logo.ch8");
    // const rom = @embedFile("roms/2-ibm-logo.ch8");
    const rom = @embedFile("roms/3-corax+.ch8");
    var emulator = chip8.Emulator.new(rom);
    emulator.run();
}

execute

cpu 文件中其它不相关代码已省略。

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,
        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}),
    }
}

00EE

从子调用返回,只需要将压入栈中的地址返回给 PC 寄存器。

2NNN

子过程调用,将当前的地址压入栈中,并且跳转到对应的地址上。

3XNN

检查寄存器 x 的值和 nn 是否相等,相关跳过下一条指令。

4XNN

和 3XNN 相反,不相等的时候,跳过下一条指令。

5XY0

x 寄存器和 y 寄存器中的值相等时跳过下一条指令。

9XY0

和 5XY0 相反,不相等时跳过下一条指令。

BNNN

跳转到第一个寄存器加上 nnn 处执行。

启动

zig build run

效果

窗口

总结

实现了更多的指令,使用测试三 rom 进行验证,可以看到控制台提示指令 8 和 F 还没有实现。

附录

posted @ 2025-12-04 09:59  jiangbo4444  阅读(6)  评论(0)    收藏  举报