From ff8ea796205ccf942c517008653c8a285979aaa6 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:12:59 -0300 Subject: [PATCH] feat: implement force irqs for GPIO/RTC --- src/core/Bus.zig | 2 +- src/core/bus/GamePak.zig | 39 ++++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/core/Bus.zig b/src/core/Bus.zig index 2a89e72..893b9bf 100644 --- a/src/core/Bus.zig +++ b/src/core/Bus.zig @@ -51,7 +51,7 @@ sched: *Scheduler, pub fn init(self: *Self, allocator: Allocator, sched: *Scheduler, cpu: *Arm7tdmi, paths: FilePaths) !void { self.* = .{ - .pak = try GamePak.init(allocator, paths.rom, paths.save), + .pak = try GamePak.init(allocator, cpu, paths.rom, paths.save), .bios = try Bios.init(allocator, paths.bios), .ppu = try Ppu.init(allocator, sched), .apu = Apu.init(sched), diff --git a/src/core/bus/GamePak.zig b/src/core/bus/GamePak.zig index 383d5c0..2f8934f 100644 --- a/src/core/bus/GamePak.zig +++ b/src/core/bus/GamePak.zig @@ -1,5 +1,6 @@ const std = @import("std"); +const Arm7tdmi = @import("../cpu.zig").Arm7tdmi; const Bit = @import("bitfield").Bit; const Bitfield = @import("bitfield").Bitfield; const Backup = @import("backup.zig").Backup; @@ -14,7 +15,7 @@ allocator: Allocator, backup: Backup, gpio: *Gpio, -pub fn init(allocator: Allocator, rom_path: []const u8, save_path: ?[]const u8) !Self { +pub fn init(allocator: Allocator, cpu: *Arm7tdmi, rom_path: []const u8, save_path: ?[]const u8) !Self { const file = try std.fs.cwd().openFile(rom_path, .{}); defer file.close(); @@ -28,7 +29,7 @@ pub fn init(allocator: Allocator, rom_path: []const u8, save_path: ?[]const u8) .allocator = allocator, .title = title, .backup = try Backup.init(allocator, kind, title, save_path), - .gpio = try Gpio.init(allocator, .Rtc), + .gpio = try Gpio.init(allocator, cpu, .Rtc), }; } @@ -242,8 +243,7 @@ const Gpio = struct { switch (self.kind) { .Rtc => { const clock = @ptrCast(*Clock, @alignCast(@alignOf(*Clock), self.ptr.?)); - - clock.step(Clock.GpioData{ .raw = value }); + clock.step(Clock.Data{ .raw = value }); }, .None => {}, } @@ -260,7 +260,7 @@ const Gpio = struct { Control, }; - fn init(allocator: Allocator, kind: Device.Kind) !*This { + fn init(allocator: Allocator, cpu: *Arm7tdmi, kind: Device.Kind) !*This { const self = try allocator.create(This); self.* = .{ @@ -271,7 +271,7 @@ const Gpio = struct { .device = switch (kind) { .Rtc => blk: { const clock = try allocator.create(Clock); - clock.init(self); + clock.init(cpu, self); break :blk Device{ .kind = kind, .ptr = clock }; }, @@ -339,6 +339,7 @@ const Clock = struct { minute: u7, second: u7, + cpu: *Arm7tdmi, gpio: *const Gpio, const Register = enum { @@ -418,8 +419,8 @@ const Clock = struct { } fn handleCommand(self: *const Command, rtc: *Clock) State { - log.info("RTC: Failed to handle Command 0b{b:0>8} aka 0x{X:0>2}", .{ self.buf, self.buf }); const command = self.getCommand(); + log.info("RTC: Failed to handle Command 0b{b:0>8} aka 0x{X:0>2}", .{ command, command }); const is_write = command & 1 == 0; const rtc_register = @intCast(u3, command >> 1 & 0x7); // TODO: Make Truncate @@ -450,7 +451,7 @@ const Clock = struct { } }; - const GpioData = extern union { + const Data = extern union { sck: Bit(u8, 0), sio: Bit(u8, 1), cs: Bit(u8, 2), @@ -473,7 +474,7 @@ const Clock = struct { raw: u8, }; - fn init(ptr: *This, gpio: *const Gpio) void { + fn init(ptr: *This, cpu: *Arm7tdmi, gpio: *const Gpio) void { ptr.* = .{ .cmd = .{ .buf = 0, .i = 0 }, .writer = .{ .buf = 0, .i = 0, .count = 0 }, @@ -486,16 +487,13 @@ const Clock = struct { .hour = 0, .minute = 0, .second = 0, - .gpio = gpio, + .cpu = cpu, + .gpio = gpio, // Can't use Arm7tdmi ptr b/c not initialized yet }; } - fn attachGpio(self: *This, gpio: *const Gpio) void { - self.gpio = gpio; - } - - fn step(self: *This, value: GpioData) void { - const cache: GpioData = .{ .raw = self.gpio.data }; + fn step(self: *This, value: Data) void { + const cache: Data = .{ .raw = self.gpio.data }; switch (self.state) { .Idle => { @@ -558,8 +556,11 @@ const Clock = struct { log.info("RTC: Reset executed (control register was zeroed)", .{}); } - fn irq(_: *const This) void { - // TODO: Force GamePak IRQ - log.err("RTC: TODO: Force GamePak IRQ", .{}); + fn irq(self: *This) void { + // TODO: Confirm that this is the right behaviour + + log.debug("RTC: Force GamePak IRQ", .{}); + self.cpu.bus.io.irq.game_pak.set(); + self.cpu.handleInterrupt(); } };