From ae2b91fbe3f2b2925361135d0057f2cb9e2d9007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20=C5=9Een?= Date: Thu, 23 Jul 2026 20:15:40 +0200 Subject: [PATCH] add cpu register types, flags, and helper utilities --- src/cpu/m6502/types.zig | 50 +++++++++++++++++++++++++++++++++++++++++ src/cpu/m6502/utils.zig | 39 ++++++++++++++++++++++++++++++++ src/cpu/root.zig | 1 + 3 files changed, 90 insertions(+) create mode 100644 src/cpu/m6502/types.zig create mode 100644 src/cpu/m6502/utils.zig create mode 100644 src/cpu/root.zig diff --git a/src/cpu/m6502/types.zig b/src/cpu/m6502/types.zig new file mode 100644 index 0000000..b1a06a2 --- /dev/null +++ b/src/cpu/m6502/types.zig @@ -0,0 +1,50 @@ +pub const Status = packed struct(u8) { + carry: bool = false, + zero: bool = false, + interrupt_disable: bool = true, + decimal: bool = false, + break_command: bool = false, + unused: bool = true, + overflow: bool = false, + negative: bool = false, + + pub fn toByte(self: Status, break_set: bool) u8 { + var copy = self; + copy.break_command = break_set; + copy.unused = true; + return @bitCast(copy); + } + + pub fn fromByte(value: u8) Status { + var status: Status = @bitCast(value); + status.break_command = false; + status.unused = true; + return status; + } +}; + +pub const Registers = struct { + a: u8 = 0, + x: u8 = 0, + y: u8 = 0, + sp: u8 = 0xfd, + pc: u16 = 0, + status: Status = .{}, + + pub fn dumpRegisters(self: Registers) void { + const std = @import("std"); + std.debug.print("A:{X:02} X:{X:02} Y:{X:02} SP:{X:02} PC:{X:04}\n", .{ + self.a, self.x, self.y, self.sp, self.pc, + }); + } +}; + +pub const Model = enum { + mos6502, + mos6507, + mos6510, + ricoh2a03, + ricoh2a07, + wdc65c02, + r65c02, +}; diff --git a/src/cpu/m6502/utils.zig b/src/cpu/m6502/utils.zig new file mode 100644 index 0000000..a0e1ac6 --- /dev/null +++ b/src/cpu/m6502/utils.zig @@ -0,0 +1,39 @@ +const std = @import("std"); + +pub inline fn packAddress(low: u8, high: u8) u16 { + return @as(u16, low) | (@as(u16, high) << 8); +} + +pub inline fn unpackAddress(addr: u16) struct { low: u8, high: u8 } { + return .{ + .low = @truncate(addr), + .high = @truncate(addr >> 8), + }; +} + +pub inline fn makeWord(low: u8, high: u8) u16 { + return @as(u16, low) | (@as(u16, high) << 8); +} + +pub fn addRelative(base: u16, offset: i8) u16 { + const signed_offset: i16 = offset; + const unsigned_offset: u16 = @bitCast(signed_offset); + return base +% unsigned_offset; +} + +pub fn pageCrossed(base: u16, address: u16) bool { + return (base & 0xff00) != (address & 0xff00); +} + +pub fn bitNumber(operation: anytype, first: anytype) u3 { + return @intCast(@intFromEnum(operation) - @intFromEnum(first)); +} + +pub fn validateBus(comptime Bus: type) void { + if (!@hasDecl(Bus, "read")) { + @compileError("Bus must define read(self: *Bus, address: u16) u8"); + } + if (!@hasDecl(Bus, "write")) { + @compileError("Bus must define write(self: *Bus, address: u16, value: u8) void"); + } +} diff --git a/src/cpu/root.zig b/src/cpu/root.zig new file mode 100644 index 0000000..9422196 --- /dev/null +++ b/src/cpu/root.zig @@ -0,0 +1 @@ +pub const m6502 = @import("m6502/root.zig");