diff --git a/src/core/io.zig b/src/core/io.zig index 51d1a37..9b7403c 100644 --- a/src/core/io.zig +++ b/src/core/io.zig @@ -204,6 +204,33 @@ const IpcFifoCnt = extern union { raw: u32, }; +pub const masks = struct { + const Bus9 = @import("nds9/Bus.zig"); + const Bus7 = @import("nds7/Bus.zig"); + + pub inline fn ipcFifoSync(bus: anytype, value: anytype) @TypeOf(value) { + comptime verifyBusType(@TypeOf(bus)); + const T = @TypeOf(value); + const mask: T = 0xF; + + return value & ~mask | @as(T, @intCast(bus.io.shared.ipc_fifo.sync.raw & mask)); + } + + pub inline fn ipcFifoCnt(bus: anytype, value: anytype) @TypeOf(value) { + comptime verifyBusType(@TypeOf(bus)); + const T = @TypeOf(value); + const mask: T = 0x0303; + + return value & ~mask | @as(T, @intCast(bus.io.shared.ipc_fifo.cnt.raw & mask)); + } + + fn verifyBusType(comptime BusT: type) void { + std.debug.assert(@typeInfo(BusT) == .Pointer); + std.debug.assert(@typeInfo(BusT).Pointer.size == .One); + std.debug.assert(@typeInfo(BusT).Pointer.child == Bus9 or @typeInfo(BusT).Pointer.child == Bus7); + } +}; + pub const nds7 = struct { pub const IntEnable = extern union { raw: u32, diff --git a/src/core/nds7/io.zig b/src/core/nds7/io.zig index 4dcbf03..7dae8c5 100644 --- a/src/core/nds7/io.zig +++ b/src/core/nds7/io.zig @@ -5,8 +5,7 @@ const Bit = @import("bitfield").Bit; const Bus = @import("Bus.zig"); const SharedIo = @import("../io.zig").Io; -const writeToAddressOffset = @import("../io.zig").writeToAddressOffset; -const valueAtAddressOffset = @import("../io.zig").valueAtAddressOffset; +const masks = @import("../io.zig").masks; const log = std.log.scoped(.nds7_io); @@ -51,13 +50,8 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void { else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }), }, u16 => switch (address) { - 0x0400_0180 => bus.io.shared.ipc_fifo.sync.raw = blk: { - const ret = value & ~@as(u16, 0xF) | (bus.io.shared.ipc_fifo.sync.raw & 0xF); - log.debug("IPCFIFOSYNC <- 0x{X:0>8}", .{ret}); - - break :blk ret; - }, - 0x0400_0184 => bus.io.shared.ipc_fifo.cnt.raw = value, + 0x0400_0180 => bus.io.shared.ipc_fifo.sync.raw = masks.ipcFifoSync(bus, value), + 0x0400_0184 => bus.io.shared.ipc_fifo.cnt.raw = masks.ipcFifoCnt(bus, value), else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }), }, u8 => switch (address) { diff --git a/src/core/nds9/io.zig b/src/core/nds9/io.zig index 38e1bc2..1421830 100644 --- a/src/core/nds9/io.zig +++ b/src/core/nds9/io.zig @@ -5,8 +5,7 @@ const Bit = @import("bitfield").Bit; const Bus = @import("Bus.zig"); const SharedIo = @import("../io.zig").Io; -const writeToAddressOffset = @import("../io.zig").writeToAddressOffset; -const valueAtAddressOffset = @import("../io.zig").valueAtAddressOffset; +const masks = @import("../io.zig").masks; const log = std.log.scoped(.nds9_io); @@ -54,13 +53,8 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void { switch (T) { u32 => switch (address) { 0x0400_0000 => bus.ppu.io.dispcnt_a.raw = value, - 0x0400_0180 => bus.io.shared.ipc_fifo.sync.raw = blk: { - const ret = value & ~@as(u32, 0xF) | (bus.io.shared.ipc_fifo.sync.raw & 0xF); - log.debug("IPCFIFOSYNC <- 0x{X:0>8}", .{ret}); - - break :blk ret; - }, - 0x0400_0184 => bus.io.shared.ipc_fifo.cnt.raw = value, + 0x0400_0180 => bus.io.shared.ipc_fifo.sync.raw = masks.ipcFifoSync(bus, value), + 0x0400_0184 => bus.io.shared.ipc_fifo.cnt.raw = masks.ipcFifoCnt(bus, value), 0x0400_0188 => bus.io.shared.ipc_fifo.send(.arm9, value) catch |e| std.debug.panic("IPC FIFO Error: {}", .{e}), 0x0400_0240 => { @@ -79,13 +73,8 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void { else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }), }, u16 => switch (address) { - 0x0400_0180 => bus.io.shared.ipc_fifo.sync.raw = blk: { - const ret = value & ~@as(u16, 0xF) | (bus.io.shared.ipc_fifo.sync.raw & 0xF); - log.debug("IPCFIFOSYNC <- 0x{X:0>8}", .{ret}); - - break :blk ret; - }, - 0x0400_0184 => bus.io.shared.ipc_fifo.cnt.raw = value, + 0x0400_0180 => bus.io.shared.ipc_fifo.sync.raw = masks.ipcFifoSync(bus, value), + 0x0400_0184 => bus.io.shared.ipc_fifo.cnt.raw = masks.ipcFifoCnt(bus, value), 0x0400_0208 => bus.io.shared.ime = value & 1 == 1, else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }),