chore: early stages for irq impl

FIXME: what do we do since access to the CPU is behind an interface?
This commit is contained in:
Rekai Nyangadzayi Musuka 2023-10-03 23:59:53 -05:00
parent 3a35c5b428
commit 0765682035
3 changed files with 54 additions and 53 deletions

View File

@ -10,31 +10,9 @@ const log = std.log.scoped(.shared_io);
// every other "shared I/O register" is just duplicated on both CPUs. So they shouldn't be here
pub const Io = struct {
/// Interrupt Master Enable
/// Read/Write
ime: bool = false,
/// Interrupt Enable
/// Read/Write
///
/// Caller must cast the `u32` to either `nds7.IntEnable` or `nds9.IntEnable`
ie: u32 = 0x0000_0000,
/// IF - Interrupt Request
/// Read/Write
///
/// Caller must cast the `u32` to either `nds7.IntRequest` or `nds9.IntRequest`
irq: u32 = 0x0000_0000,
/// Inter Process Communication FIFO
ipc_fifo: IpcFifo = .{},
/// Post Boot Flag
/// Read/Write
///
/// Caller must cast the `u8` to either `nds7.PostFlg` or `nds9.PostFlg`
post_flg: u8 = @intFromEnum(nds7.PostFlag.in_progress),
wramcnt: WramCnt = .{ .raw = 0x00 },
// TODO: DS Cartridge I/O Ports
@ -271,24 +249,7 @@ pub const masks = struct {
}
};
pub const nds7 = struct {
pub const IntEnable = extern union {
raw: u32,
};
pub const IntRequest = IntEnable;
pub const PostFlag = enum(u8) { in_progress = 0, completed };
};
pub const nds9 = struct {
pub const IntEnable = extern union {
raw: u32,
};
pub const IntRequest = IntEnable;
pub const PostFlag = enum(u8) { in_progress = 0, completed };
};
pub const PostFlag = enum(u1) { in_progress = 0, completed };
const Fifo = struct {
const Index = u8;

View File

@ -5,6 +5,7 @@ const Bit = @import("bitfield").Bit;
const Bus = @import("Bus.zig");
const SharedIo = @import("../io.zig").Io;
const PostFlag = @import("../io.zig").PostFlag;
const masks = @import("../io.zig").masks;
const log = std.log.scoped(.nds7_io);
@ -12,6 +13,20 @@ const log = std.log.scoped(.nds7_io);
pub const Io = struct {
shared: *SharedIo,
// IME - Interrupt Master Enable
/// Read / Write
ime: bool = false,
/// IE - Interrupt Enable
/// Read / Write
ie: Interrupt = .{ .raw = 0x0000_0000 },
/// IF - Interrupt Request
/// Read / Write
irq: Interrupt = .{ .raw = 0x0000_0000 },
postflg: PostFlag = .in_progress,
pub fn init(io: *SharedIo) @This() {
return .{ .shared = io };
}
@ -20,9 +35,9 @@ pub const Io = struct {
pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
return switch (T) {
u32 => switch (address) {
0x0400_0208 => @intFromBool(bus.io.shared.ime),
0x0400_0210 => bus.io.shared.ie,
0x0400_0214 => bus.io.shared.irq,
0x0400_0208 => @intFromBool(bus.io.ime),
0x0400_0210 => bus.io.ie.raw,
0x0400_0214 => bus.io.irq.raw,
0x0410_0000 => bus.io.shared.ipc_fifo.recv(.nds7),
else => warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
@ -44,9 +59,9 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
switch (T) {
u32 => switch (address) {
0x0400_0208 => bus.io.shared.ime = value & 1 == 1,
0x0400_0210 => bus.io.shared.ie = value,
0x0400_0214 => bus.io.shared.irq = value,
0x0400_0208 => bus.io.ime = value & 1 == 1,
0x0400_0210 => bus.io.ie.raw = value,
0x0400_0214 => bus.io.irq.raw = value,
0x0400_0188 => bus.io.shared.ipc_fifo.send(.nds7, value) catch |e| std.debug.panic("FIFO error: {}", .{e}),
else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }),
@ -73,3 +88,7 @@ pub const Vramstat = extern union {
vramd_enabled: Bit(u8, 1),
raw: u8,
};
const Interrupt = extern union {
raw: u32,
};

View File

@ -5,6 +5,7 @@ const Bit = @import("bitfield").Bit;
const Bus = @import("Bus.zig");
const SharedIo = @import("../io.zig").Io;
const PostFlag = @import("../io.zig").PostFlag;
const masks = @import("../io.zig").masks;
const sext = @import("../../util.zig").sext;
@ -14,6 +15,22 @@ const log = std.log.scoped(.nds9_io);
pub const Io = struct {
shared: *SharedIo,
// IME - Interrupt Master Enable
/// Read / Write
ime: bool = false,
/// IE - Interrupt Enable
/// Read / Write
ie: Interrupt = .{ .raw = 0x0000_0000 },
/// IF - Interrupt Request
/// Read / Write
irq: Interrupt = .{ .raw = 0x0000_0000 },
// TODO: move postflg
postflg: PostFlag = .in_progress,
/// POWCNT1 - Graphics Power Control
/// Read / Write
powcnt: PowCnt = .{ .raw = 0x0000_0000 },
@ -33,9 +50,9 @@ pub const Io = struct {
pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
return switch (T) {
u32 => switch (address) {
0x0400_0208 => @intFromBool(bus.io.shared.ime),
0x0400_0210 => bus.io.shared.ie,
0x0400_0214 => bus.io.shared.irq,
0x0400_0208 => @intFromBool(bus.io.ime),
0x0400_0210 => bus.io.ie.raw,
0x0400_0214 => bus.io.irq.raw,
0x0400_02A0 => @truncate(bus.io.div.result),
0x0400_02A4 => @truncate(bus.io.div.result >> 32),
@ -80,9 +97,9 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
bus.ppu.vram.io.cnt_d.raw = @truncate(value >> 24); // 0x0400_0243
},
0x0400_0208 => bus.io.shared.ime = value & 1 == 1,
0x0400_0210 => bus.io.shared.ie = value,
0x0400_0214 => bus.io.shared.irq = value,
0x0400_0208 => bus.io.ime = value & 1 == 1,
0x0400_0210 => bus.io.ie.raw = value,
0x0400_0214 => bus.io.irq.raw = value,
0x0400_0290 => {
bus.io.div.numerator = masks.mask(bus.io.div.numerator, value, 0xFFFF_FFFF);
@ -116,7 +133,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
u16 => switch (address) {
0x0400_0180 => bus.io.shared.ipc_fifo.setIpcSync(.nds9, value),
0x0400_0184 => bus.io.shared.ipc_fifo.setIpcFifoCnt(.nds9, value),
0x0400_0208 => bus.io.shared.ime = value & 1 == 1,
0x0400_0208 => bus.io.ime = value & 1 == 1,
0x0400_0280 => {
bus.io.div.cnt.raw = value;
@ -437,3 +454,7 @@ const AtomicKeyInput = struct {
_ = @atomicRmw(u16, &self.inner.raw, .And, value, ordering);
}
};
const Interrupt = extern union {
raw: u32,
};