0319-Chip8-完善内存结构定义
环境
- Time 2023-07-26
- 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
其中最后一个提供了测试的套件,实现的过程中,可以检测哪些指令有问题,帮助很大。
目标
- 将屏幕和键盘映射到内存中。
- 内存支持栈结构,可以入栈和出栈。
- 定义屏幕的清屏和设置像素操作。
memory.zig
- 定义了 16 级的栈结构和栈指针。
- 映射屏幕和键盘到内存中。
- 实现了入栈 push 和出栈 pop 方法。
- 实现了清屏 clearScreen 和 绘制像素 drawPixel 方法。
const Screen = @import("screen.zig").Screen;
const Keypad = @import("keypad.zig").Keypad;
pub const Memory = struct {
ram: [4096]u8 = undefined,
stack: [16]u16 = undefined,
sp: u8 = 0,
screen: *Screen = undefined,
keypad: *Keypad = undefined,
pub fn new(rom: []const u8, entry: u16) Memory {
var memory = Memory{};
@memcpy(memory.ram[0..fonts.len], &fonts);
@memcpy(memory.ram[entry .. entry + rom.len], rom);
return memory;
}
pub fn load(self: *Memory, pc: u16) u16 {
const high: u8 = self.ram[pc];
return (@as(u16, high) << 8) | self.ram[pc + 1];
}
pub fn get(self: *Memory, index: usize) u8 {
return self.ram[index];
}
pub fn set(self: *Memory, index: usize, value: u8) void {
self.ram[index] = value;
}
pub fn clearScreen(self: *Memory) void {
var screen1 = self.screen;
screen1.clear();
}
pub fn drawPixel(self: *Memory, x: usize, y: usize) bool {
return self.screen.setPixel(x, y);
}
pub fn push(self: *Memory, value: u16) void {
self.stack[self.sp] = value;
self.sp += 1;
}
pub fn pop(self: *Memory) u16 {
self.sp -= 1;
return self.stack[self.sp];
}
};
const fonts = [_]u8{
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
0x20, 0x60, 0x20, 0x20, 0x70, // 1
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
0x90, 0x90, 0xF0, 0x10, 0x10, // 4
0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
0xF0, 0x10, 0x20, 0x40, 0x40, // 7
0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
0xF0, 0x90, 0xF0, 0x90, 0x90, // A
0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
0xe0, 0x90, 0x90, 0x90, 0xE0, // D
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
0xF0, 0x80, 0xF0, 0x80, 0x80, // F
};
chip8.zig
将屏幕和键盘映射到内存空间。
const cpu = @import("cpu.zig");
const memory = @import("memory.zig");
const screen = @import("screen.zig");
const keypad = @import("keypad.zig");
const ENTRY = 0x200;
const HZ = 500;
const FPS = 60;
pub const Emulator = struct {
cpu: cpu.CPU,
memory: memory.Memory,
screen: screen.Screen,
keypad: keypad.Keypad,
pub fn new(rom: []const u8) Emulator {
return Emulator{
.cpu = cpu.CPU{ .pc = ENTRY },
.memory = memory.Memory.new(rom, ENTRY),
.screen = screen.Screen{},
.keypad = keypad.Keypad{},
};
}
pub fn run(self: *Emulator) void {
self.screen.init();
defer self.screen.deinit();
self.memory.screen = &self.screen;
self.memory.keypad = &self.keypad;
var index: usize = 0;
while (self.keypad.poll()) : (index += 1) {
for (0..(HZ / FPS)) |_|
self.cpu.cycle(&self.memory);
if (index % 44 == 0) self.screen.clear();
_ = self.screen.setIndex(index);
self.screen.update(FPS);
}
}
};
启动
zig build run
效果

总结
完善了内存结构的定义,新增了栈操作和屏幕的操作。

浙公网安备 33010602011771号