runs error-free
This commit is contained in:
parent
ea17044d73
commit
4e97fd872e
1 changed files with 65 additions and 40 deletions
105
src/main.zig
105
src/main.zig
|
@ -1,38 +1,52 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
// var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
// defer _ = gpa.deinit();
|
||||
// const allocator = gpa.allocator();
|
||||
|
||||
const mem: [0xFFFF]u8 = undefined;
|
||||
const ws: [0xFF]u8 = undefined;
|
||||
const rs: [0xFF]u8 = undefined;
|
||||
var uxn = Uxn{
|
||||
.mem = try allocator.alloc(u8, 0xFFFF),
|
||||
.ws = .{
|
||||
.s = try allocator.alloc(u8, 0xFF),
|
||||
.sp = 0,
|
||||
},
|
||||
.rs = .{
|
||||
.s = try allocator.alloc(u8, 0xFF),
|
||||
.sp = 0,
|
||||
},
|
||||
.pc = 0x0100,
|
||||
.mem = .{ .m = mem },
|
||||
.ws = .{ .s = ws },
|
||||
.rs = .{ .s = rs },
|
||||
.pc = 0x100,
|
||||
};
|
||||
defer allocator.free(uxn.mem);
|
||||
defer allocator.free(uxn.ws.s);
|
||||
defer allocator.free(uxn.rs.s);
|
||||
|
||||
while (true) uxn.loop();
|
||||
}
|
||||
|
||||
pub const Uxn = struct {
|
||||
mem: [0xFFFF]u8,
|
||||
mem: Memory,
|
||||
ws: Stack,
|
||||
rs: Stack,
|
||||
pc: u16,
|
||||
|
||||
const Memory = struct {
|
||||
m: [0xFFFF]u8,
|
||||
|
||||
pub fn peek(self: *Memory, comptime T: type, idx: u16) T {
|
||||
return switch (T) {
|
||||
u8 => self.m[idx],
|
||||
u16 => self.m[idx],
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn poke(self: *Memory, comptime T: type, idx: u16, val: T) void {
|
||||
switch (T) {
|
||||
u8 => self.m[idx] = val,
|
||||
u16 => {},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Stack = struct {
|
||||
s: [0xFF]u8,
|
||||
sp: u8,
|
||||
sp: u8 = 0,
|
||||
|
||||
pub fn peek(self: *Stack, comptime T: type) T {
|
||||
return switch (T) {
|
||||
|
@ -72,7 +86,7 @@ pub const Uxn = struct {
|
|||
},
|
||||
u16 => {
|
||||
self.sp +%= 2;
|
||||
self.s[self.sp] = v;
|
||||
self.s[self.sp] = @truncate(v);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
@ -80,7 +94,7 @@ pub const Uxn = struct {
|
|||
};
|
||||
|
||||
pub fn loop(self: *Uxn) void {
|
||||
switch (self.mem[self.pc]) {
|
||||
switch (self.mem.m[self.pc]) {
|
||||
0x00 => {}, // BRK
|
||||
0x01 => inc(&self.ws, u8, false), // INC
|
||||
0x02 => pop(&self.ws, u8, false), // POP
|
||||
|
@ -421,7 +435,7 @@ pub const Uxn = struct {
|
|||
fn jmp(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(T) else stack.pop(T);
|
||||
switch (T) {
|
||||
u8 => self.pc +%= @as(i8, @bitCast(addr)),
|
||||
u8 => self.pc = @intCast(@as(i32, @intCast(self.pc)) + @as(i8, @bitCast(addr))),
|
||||
u16 => self.pc = addr,
|
||||
else => unreachable,
|
||||
}
|
||||
|
@ -432,7 +446,7 @@ pub const Uxn = struct {
|
|||
const addr = if (keep) stack.peek(T) else stack.pop(T);
|
||||
if (cond == 0) return;
|
||||
switch (T) {
|
||||
u8 => self.pc +%= @as(i8, @bitCast(addr)),
|
||||
u8 => self.pc = @intCast(@as(i32, @intCast(self.pc)) + @as(i8, @bitCast(addr))),
|
||||
u16 => self.pc = addr,
|
||||
else => unreachable,
|
||||
}
|
||||
|
@ -442,55 +456,56 @@ pub const Uxn = struct {
|
|||
self.rs.push(u16, self.pc);
|
||||
const addr = if (keep) stack.peek(T) else stack.pop(T);
|
||||
switch (T) {
|
||||
u8 => self.pc +%= @as(i8, @bitCast(addr)),
|
||||
u8 => self.pc = @intCast(@as(i32, @intCast(self.pc)) + @as(i8, @bitCast(addr))),
|
||||
u16 => self.pc = addr,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn sth(self: *Uxn, comptime swap: bool, comptime T: type, comptime keep: bool) void {
|
||||
const src = if (swap) self.rs else self.ws;
|
||||
const dst = if (swap) self.ws else self.rs;
|
||||
var src = if (swap) self.rs else self.ws;
|
||||
var dst = if (swap) self.ws else self.rs;
|
||||
const a = if (keep) src.peek(T) else src.pop(T);
|
||||
dst.push(T, a);
|
||||
}
|
||||
|
||||
fn ldz(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(u8) else stack.pop(u8);
|
||||
switch (T) {
|
||||
u8 => stack.push(T, self.mem[addr]),
|
||||
u16 => {},
|
||||
else => unreachable,
|
||||
}
|
||||
stack.push(T, self.mem.peek(T, addr));
|
||||
// switch (T) {
|
||||
// u8 => stack.push(T, self.mem[addr]),
|
||||
// u16 => {},
|
||||
// else => unreachable,
|
||||
// }
|
||||
}
|
||||
|
||||
fn stz(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(u8) else stack.pop(u8);
|
||||
const val = if (keep) stack.peek(T) else stack.pop(T);
|
||||
self.mem[addr] = val;
|
||||
self.mem.poke(T, addr, val);
|
||||
}
|
||||
|
||||
fn ldr(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(u8) else stack.pop(u8);
|
||||
const val = self.mem[self.pc +% @as(i8, @intCast(addr))];
|
||||
const val = self.mem.peek(T, @intCast(@as(i32, @intCast(self.pc)) + @as(i8, @intCast(addr))));
|
||||
stack.push(T, val);
|
||||
}
|
||||
|
||||
fn str(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(u8) else stack.pop(u8);
|
||||
const val = if (keep) stack.peek(T) else stack.pop(T);
|
||||
self.mem[self.pc +% @as(i8, @bitCast(addr))] = val;
|
||||
self.mem.poke(T, @intCast(@as(i32, @intCast(self.pc)) + @as(i8, @bitCast(addr))), val);
|
||||
}
|
||||
|
||||
fn lda(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(u16) else stack.pop(u16);
|
||||
stack.push(T, self.mem[addr]);
|
||||
stack.push(T, self.mem.peek(T, addr));
|
||||
}
|
||||
|
||||
fn sta(self: *Uxn, stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const addr = if (keep) stack.peek(u16) else stack.pop(u16);
|
||||
const val = if (keep) stack.peek(T) else stack.pop(T);
|
||||
self.mem[addr] = val;
|
||||
self.mem.poke(T, addr, val);
|
||||
}
|
||||
|
||||
fn dei(stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
|
@ -550,9 +565,19 @@ pub const Uxn = struct {
|
|||
fn sft(stack: *Stack, comptime T: type, comptime keep: bool) void {
|
||||
const a = if (keep) stack.peek(T) else stack.pop(T);
|
||||
const b = if (keep) stack.peek(T) else stack.pop(T);
|
||||
const right = b & 0b00001111;
|
||||
const left = (b & 0b11110000) >> 4;
|
||||
stack.push(T, (a >> right) << left);
|
||||
switch (T) {
|
||||
u8 => {
|
||||
const right: u3 = @truncate(b & 0b00001111);
|
||||
const left: u3 = @truncate((b & 0b11110000) >> 4);
|
||||
stack.push(T, (a >> right) << left);
|
||||
},
|
||||
u16 => {
|
||||
const right: u4 = @truncate(b & 0b0000000011111111);
|
||||
const left: u4 = @truncate((b & 0b1111111100000000) >> 8);
|
||||
stack.push(T, (a >> right) << left);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -667,12 +692,12 @@ test "uxnasm" {
|
|||
const ws: [0xFF]u8 = undefined;
|
||||
const rs: [0xFF]u8 = undefined;
|
||||
var uxn = Uxn{
|
||||
.mem = mem,
|
||||
.mem = .{ .m = mem },
|
||||
.ws = .{ .s = ws, .sp = 0 },
|
||||
.rs = .{ .s = rs, .sp = 0 },
|
||||
.pc = 0x100,
|
||||
};
|
||||
@memcpy(uxn.mem[0x100 .. 0x100 + rom.len], &rom);
|
||||
@memcpy(uxn.mem.m[0x100 .. 0x100 + rom.len], &rom);
|
||||
|
||||
while (true) uxn.loop();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue