init: abstractions over chip8 stuff
This commit is contained in:
commit
40223a179d
18 changed files with 443 additions and 0 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
use flake
|
||||||
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
### Nix ###
|
||||||
|
# Ignore build outputs from performing a nix-build or `nix build` command
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
|
||||||
|
# Ignore automatically generated direnv output
|
||||||
|
.direnv
|
||||||
|
### End of Nix ###
|
||||||
|
|
||||||
|
### Zig ###
|
||||||
|
.zig-cache/
|
||||||
|
zig-out/
|
||||||
|
*.o
|
||||||
|
### End of Zig ###
|
||||||
|
|
||||||
36
build.zig
Normal file
36
build.zig
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) !void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const mod = b.createModule(.{
|
||||||
|
.root_source_file = b.path("./src/octochip/root.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const raylib_dep = b.dependency("raylib_zig", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "octochip",
|
||||||
|
.root_module = b.createModule(.{
|
||||||
|
.root_source_file = b.path("./src/main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.imports = &.{
|
||||||
|
.{ .name = "octochip", .module = mod },
|
||||||
|
.{ .name = "raylib", .module = raylib_dep.module("raylib") },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run octochip");
|
||||||
|
const run_exe = b.addRunArtifact(exe);
|
||||||
|
run_step.dependOn(&run_exe.step);
|
||||||
|
}
|
||||||
17
build.zig.zon
Normal file
17
build.zig.zon
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
.{
|
||||||
|
.name = .octochip,
|
||||||
|
.version = "0.0.0",
|
||||||
|
.fingerprint = 0xd60bf7ea9ec78472,
|
||||||
|
.minimum_zig_version = "0.15.2",
|
||||||
|
.dependencies = .{
|
||||||
|
.raylib_zig = .{
|
||||||
|
.url = "git+https://github.com/raylib-zig/raylib-zig#cd71c85d571027ac8033357f83b124ee051825b3",
|
||||||
|
.hash = "raylib_zig-5.6.0-dev-KE8REENOBQC-m5nK7M2b5aKSIubJPbPLUYcRhT7aT3RN",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.paths = .{
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
|
},
|
||||||
|
}
|
||||||
77
flake.lock
generated
Normal file
77
flake.lock
generated
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772408722,
|
||||||
|
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"import-tree": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772999353,
|
||||||
|
"narHash": "sha256-dPb0WxUhFaz6wuR3B6ysqFJpsu8txKDPZvS47AT2XLI=",
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"rev": "545a4df146fce44d155573e47f5a777985acf912",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "vic",
|
||||||
|
"repo": "import-tree",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1773122722,
|
||||||
|
"narHash": "sha256-FIqHByVqxCprNjor1NqF80F2QQoiiyqanNNefdlvOg4=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "62dc67aa6a52b4364dd75994ec00b51fbf474e50",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1772328832,
|
||||||
|
"narHash": "sha256-e+/T/pmEkLP6BHhYjx6GmwP5ivonQQn0bJdH9YrRB+Q=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "c185c7a5e5dd8f9add5b2f8ebeff00888b070742",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"import-tree": "import-tree",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
11
flake.nix
Normal file
11
flake.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
import-tree.url = "github:vic/import-tree";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = inputs:
|
||||||
|
inputs.flake-parts.lib.mkFlake {inherit inputs;}
|
||||||
|
(inputs.import-tree ./packages/nix);
|
||||||
|
}
|
||||||
19
packages/nix/shell.nix
Normal file
19
packages/nix/shell.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{...}: {
|
||||||
|
perSystem = {pkgs, ...}: {
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
packages = [
|
||||||
|
pkgs.zig
|
||||||
|
|
||||||
|
pkgs.libGLX
|
||||||
|
pkgs.libx11
|
||||||
|
pkgs.libxcursor
|
||||||
|
pkgs.libxext
|
||||||
|
pkgs.libxfixes
|
||||||
|
pkgs.libxi
|
||||||
|
pkgs.libxinerama
|
||||||
|
pkgs.libxrandr
|
||||||
|
pkgs.libxrender
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
3
packages/nix/systems.nix
Normal file
3
packages/nix/systems.nix
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{...}: {
|
||||||
|
systems = ["x86_64-linux"];
|
||||||
|
}
|
||||||
7
src/main.zig
Normal file
7
src/main.zig
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const octo = @import("octochip");
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
const ins = try octo.machine.Instruction.from_bytes(0xabcd);
|
||||||
|
std.log.info("instruction: {f}", .{ins});
|
||||||
|
}
|
||||||
7
src/octochip/components/display.zig
Normal file
7
src/octochip/components/display.zig
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
pub const Display = struct {
|
||||||
|
pixels: [32][64]bool = .{},
|
||||||
|
|
||||||
|
fn new() @This() {
|
||||||
|
return .{};
|
||||||
|
}
|
||||||
|
};
|
||||||
40
src/octochip/components/keyboard.zig
Normal file
40
src/octochip/components/keyboard.zig
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
pub const Keyboard = struct {
|
||||||
|
// FEDCBA9876543210
|
||||||
|
pressed: u16 = 0,
|
||||||
|
|
||||||
|
fn new() @This() {
|
||||||
|
return .{};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn released(self: *const @This()) u16 {
|
||||||
|
return ~self.pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mask(key: u4) u16 {
|
||||||
|
return (@as(u16, 1) << key);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn press(self: *@This(), key: u4) void {
|
||||||
|
self.pressed |= mask(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn release(self: *@This(), key: u4) void {
|
||||||
|
self.pressed &= ~mask(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn press_or_release_if(self: *@This(), key: u4, cond: bool) void {
|
||||||
|
if (cond) {
|
||||||
|
self.press(key);
|
||||||
|
} else {
|
||||||
|
self.release(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_pressed(self: *const @This(), key: u4) bool {
|
||||||
|
return (self.pressed & mask(key)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_released(self: *const @This(), key: u4) bool {
|
||||||
|
return !self.is_pressed(key);
|
||||||
|
}
|
||||||
|
};
|
||||||
15
src/octochip/components/memory.zig
Normal file
15
src/octochip/components/memory.zig
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
pub const Memory = struct {
|
||||||
|
memory: [4096]u8 = .{},
|
||||||
|
|
||||||
|
pub fn new() @This() {
|
||||||
|
return .{};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn put(self: *@This(), addr: usize, value: u8) void {
|
||||||
|
self.memory[addr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn peek(self: *const @This(), addr: usize) u8 {
|
||||||
|
return self.memory[addr];
|
||||||
|
}
|
||||||
|
};
|
||||||
20
src/octochip/components/registers.zig
Normal file
20
src/octochip/components/registers.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
pub const Registers = struct {
|
||||||
|
V: [16]u8 = .{},
|
||||||
|
DT: u8 = 0,
|
||||||
|
ST: u8 = 0,
|
||||||
|
I: u16 = 0,
|
||||||
|
PC: u16 = 0x200,
|
||||||
|
SP: u8 = 0,
|
||||||
|
|
||||||
|
pub fn new() Registers {
|
||||||
|
return Registers{};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(self: *const Registers, index: u4) u8 {
|
||||||
|
return self.V[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(self: *Registers, index: u4, value: u8) void {
|
||||||
|
self.V[index] = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
4
src/octochip/components/root.zig
Normal file
4
src/octochip/components/root.zig
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub const Memory = @import("memory.zig").Memory;
|
||||||
|
pub const Registers = @import("registers.zig").Registers;
|
||||||
|
pub const Keyboard = @import("keyboard.zig").Keyboard;
|
||||||
|
pub const Display = @import("display.zig").Display;
|
||||||
167
src/octochip/machine/instruction.zig
Normal file
167
src/octochip/machine/instruction.zig
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// NOTE: Some instructions have X and then XR
|
||||||
|
// It means that X operates on values (xkk) and XR operates on registers Vx and Vy
|
||||||
|
// An instance of this can be found with SE and SER
|
||||||
|
|
||||||
|
// NOTE: Packed structs for instructions.
|
||||||
|
// Variants for E--- and F--- can simply use Xxkk with pattern matching
|
||||||
|
const Xnnn = packed struct { nnn: u12, X: u4 };
|
||||||
|
const Xxkk = packed struct { kk: u8, x: u4, X: u4 };
|
||||||
|
const XxyY = packed struct { Y: u4, y: u4, x: u4, X: u4 };
|
||||||
|
const Xxyn = packed struct { n: u4, y: u4, x: u4, X: u4 };
|
||||||
|
|
||||||
|
pub const Instruction = union(enum) {
|
||||||
|
SYS: struct { location: u12 },
|
||||||
|
CLS: void,
|
||||||
|
RET: void,
|
||||||
|
JP: struct { location: u12 },
|
||||||
|
CALL: struct { subroutine: u12 },
|
||||||
|
SE: struct { register: u4, value: u8 },
|
||||||
|
SNE: struct { register: u4, value: u8 },
|
||||||
|
SER: struct { first: u4, second: u4 },
|
||||||
|
LD: struct { register: u4, value: u8 },
|
||||||
|
ADD: struct { register: u4, value: u8 },
|
||||||
|
LDR: struct { first: u4, second: u4 },
|
||||||
|
OR: struct { first: u4, second: u4 },
|
||||||
|
AND: struct { first: u4, second: u4 },
|
||||||
|
XOR: struct { first: u4, second: u4 },
|
||||||
|
ADDR: struct { first: u4, second: u4 },
|
||||||
|
SUB: struct { first: u4, second: u4 },
|
||||||
|
SHR: struct { register: u4 },
|
||||||
|
SUBN: struct { first: u4, second: u4 },
|
||||||
|
SHL: struct { register: u4 },
|
||||||
|
SNER: struct { first: u4, second: u4 },
|
||||||
|
LDI: struct { value: u12 },
|
||||||
|
JPV0: struct { add: u12 },
|
||||||
|
RND: struct { register: u4, value: u8 },
|
||||||
|
DRW: struct { x_register: u4, y_register: u4, bytes: u4 },
|
||||||
|
SKP: struct { key: u4 },
|
||||||
|
SKNP: struct { key: u4 },
|
||||||
|
LDDTIN: struct { register: u4 },
|
||||||
|
LDK: struct { register: u4 },
|
||||||
|
LDDT: struct { register: u4 },
|
||||||
|
LDST: struct { register: u4 },
|
||||||
|
ADDI: struct { register: u4 },
|
||||||
|
LDF: struct { register: u4 },
|
||||||
|
LDB: struct { register: u4 },
|
||||||
|
LDRO: struct { until_register: u4 },
|
||||||
|
LDRI: struct { until_register: u4 },
|
||||||
|
|
||||||
|
pub fn from_bytes(instruction: u16) !@This() {
|
||||||
|
switch (instruction) {
|
||||||
|
0x00E0 => return .CLS,
|
||||||
|
0x00EE => return .RET,
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
const xnnn: Xnnn = @bitCast(instruction);
|
||||||
|
const xxkk: Xxkk = @bitCast(instruction);
|
||||||
|
const xxyy: XxyY = @bitCast(instruction);
|
||||||
|
const xxyn: Xxyn = @bitCast(instruction);
|
||||||
|
|
||||||
|
switch (xnnn.X) {
|
||||||
|
0x0 => return .{ .SYS = .{ .location = xnnn.nnn } },
|
||||||
|
0x1 => return .{ .JP = .{ .location = xnnn.nnn } },
|
||||||
|
0x2 => return .{ .CALL = .{ .subroutine = xnnn.nnn } },
|
||||||
|
0xA => return .{ .LDI = .{ .value = xnnn.nnn } },
|
||||||
|
0xB => return .{ .JPV0 = .{ .add = xnnn.nnn } },
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (xxkk.X) {
|
||||||
|
0x3 => return .{ .SE = .{ .register = xxkk.x, .value = xxkk.kk } },
|
||||||
|
0x4 => return .{ .SNE = .{ .register = xxkk.x, .value = xxkk.kk } },
|
||||||
|
0x6 => return .{ .LD = .{ .register = xxkk.x, .value = xxkk.kk } },
|
||||||
|
0x7 => return .{ .ADD = .{ .register = xxkk.x, .value = xxkk.kk } },
|
||||||
|
0xC => return .{ .RND = .{ .register = xxkk.x, .value = xxkk.kk } },
|
||||||
|
0xE => switch (xxkk.kk) {
|
||||||
|
0x9E => return .{ .SKP = .{ .key = xxkk.x } },
|
||||||
|
0xA1 => return .{ .SKNP = .{ .key = xxkk.x } },
|
||||||
|
else => return error.InvalidInstruction,
|
||||||
|
},
|
||||||
|
0xF => switch (xxkk.kk) {
|
||||||
|
0x07 => return .{ .LDDTIN = .{ .register = xxkk.x } },
|
||||||
|
0x0A => return .{ .LDK = .{ .register = xxkk.x } },
|
||||||
|
0x15 => return .{ .LDDT = .{ .register = xxkk.x } },
|
||||||
|
0x18 => return .{ .LDST = .{ .register = xxkk.x } },
|
||||||
|
0x1E => return .{ .ADDI = .{ .register = xxkk.x } },
|
||||||
|
0x29 => return .{ .LDF = .{ .register = xxkk.x } },
|
||||||
|
0x33 => return .{ .LDB = .{ .register = xxkk.x } },
|
||||||
|
0x55 => return .{ .LDRO = .{ .until_register = xxkk.x } },
|
||||||
|
0x65 => return .{ .LDRI = .{ .until_register = xxkk.x } },
|
||||||
|
else => return error.InvalidInstruction,
|
||||||
|
},
|
||||||
|
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (xxyy.X) {
|
||||||
|
0x5 => return .{ .SER = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x8 => switch (xxyy.Y) {
|
||||||
|
0x0 => return .{ .LDR = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x1 => return .{ .OR = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x2 => return .{ .AND = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x3 => return .{ .XOR = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x4 => return .{ .ADDR = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x5 => return .{ .SUB = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0x6 => return .{ .SHR = .{ .register = xxyy.x } },
|
||||||
|
0x7 => return .{ .SUBN = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
0xE => return .{ .SHL = .{ .register = xxyy.x } },
|
||||||
|
else => return error.InvalidInstruction,
|
||||||
|
},
|
||||||
|
0x9 => return .{ .SNER = .{ .first = xxyy.x, .second = xxyy.y } },
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (xxyn.X) {
|
||||||
|
0xD => return .{ .DRW = .{ .x_register = xxyn.x, .y_register = xxyn.y, .bytes = xxyn.n } },
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.InvalidInstruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format(
|
||||||
|
self: @This(),
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
switch (self) {
|
||||||
|
.CLS => try writer.writeAll("CLS"),
|
||||||
|
.RET => try writer.writeAll("RET"),
|
||||||
|
.SYS => |v| try writer.print("SYS {x}", .{v.location}),
|
||||||
|
.JP => |v| try writer.print("JP {x}", .{v.location}),
|
||||||
|
.CALL => |v| try writer.print("CALL {x}", .{v.subroutine}),
|
||||||
|
.SE => |v| try writer.print("SE V{X}, {x}", .{ v.register, v.value }),
|
||||||
|
.SNE => |v| try writer.print("SNE V{X}, {x}", .{ v.register, v.value }),
|
||||||
|
.SER => |v| try writer.print("SE V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.LD => |v| try writer.print("LD V{X}, {x}", .{ v.register, v.value }),
|
||||||
|
.ADD => |v| try writer.print("ADD V{X}, {x}", .{ v.register, v.value }),
|
||||||
|
.LDR => |v| try writer.print("LD V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.OR => |v| try writer.print("OR V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.AND => |v| try writer.print("AND V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.XOR => |v| try writer.print("XOR V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.ADDR => |v| try writer.print("ADD V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.SUB => |v| try writer.print("SUB V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.SHR => |v| try writer.print("SHR V{X}", .{v.register}),
|
||||||
|
.SUBN => |v| try writer.print("SUBN V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.SHL => |v| try writer.print("SHL V{X}", .{v.register}),
|
||||||
|
.SNER => |v| try writer.print("SNE V{X}, V{X}", .{ v.first, v.second }),
|
||||||
|
.LDI => |v| try writer.print("LD I, {x}", .{v.value}),
|
||||||
|
.JPV0 => |v| try writer.print("JP V0, {x}", .{v.add}),
|
||||||
|
.RND => |v| try writer.print("RND V{X}, {x}", .{ v.register, v.value }),
|
||||||
|
.DRW => |v| try writer.print("DRW V{X}, V{X}, {}", .{ v.x_register, v.y_register, v.bytes }),
|
||||||
|
.SKP => |v| try writer.print("SKP V{X}", .{v.key}),
|
||||||
|
.SKNP => |v| try writer.print("SKNP V{X}", .{v.key}),
|
||||||
|
.LDDTIN => |v| try writer.print("LD V{X}, DT", .{v.register}),
|
||||||
|
.LDK => |v| try writer.print("LD V{X}, K", .{v.register}),
|
||||||
|
.LDDT => |v| try writer.print("LD DT, V{X}", .{v.register}),
|
||||||
|
.LDST => |v| try writer.print("LD ST, V{X}", .{v.register}),
|
||||||
|
.ADDI => |v| try writer.print("ADD I, V{X}", .{v.register}),
|
||||||
|
.LDF => |v| try writer.print("LD F, V{X}", .{v.register}),
|
||||||
|
.LDB => |v| try writer.print("LD B, V{X}", .{v.register}),
|
||||||
|
.LDRO => |v| try writer.print("LD [I], V0..V{X}", .{v.until_register}),
|
||||||
|
.LDRI => |v| try writer.print("LD V0..V{X}, [I]", .{v.until_register}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
1
src/octochip/machine/machine.zig
Normal file
1
src/octochip/machine/machine.zig
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
// the part that actually executes chip8
|
||||||
1
src/octochip/machine/root.zig
Normal file
1
src/octochip/machine/root.zig
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub const Instruction = @import("instruction.zig").Instruction;
|
||||||
2
src/octochip/root.zig
Normal file
2
src/octochip/root.zig
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub const components = @import("components/root.zig");
|
||||||
|
pub const machine = @import("machine/root.zig");
|
||||||
Loading…
Add table
Add a link
Reference in a new issue