feat: implement force irqs for GPIO/RTC

This commit is contained in:
Rekai Nyangadzayi Musuka 2022-10-21 05:12:59 -03:00
parent fe19b19fc7
commit ff8ea79620
2 changed files with 21 additions and 20 deletions

View File

@ -51,7 +51,7 @@ sched: *Scheduler,
pub fn init(self: *Self, allocator: Allocator, sched: *Scheduler, cpu: *Arm7tdmi, paths: FilePaths) !void { pub fn init(self: *Self, allocator: Allocator, sched: *Scheduler, cpu: *Arm7tdmi, paths: FilePaths) !void {
self.* = .{ 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), .bios = try Bios.init(allocator, paths.bios),
.ppu = try Ppu.init(allocator, sched), .ppu = try Ppu.init(allocator, sched),
.apu = Apu.init(sched), .apu = Apu.init(sched),

View File

@ -1,5 +1,6 @@
const std = @import("std"); const std = @import("std");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const Bit = @import("bitfield").Bit; const Bit = @import("bitfield").Bit;
const Bitfield = @import("bitfield").Bitfield; const Bitfield = @import("bitfield").Bitfield;
const Backup = @import("backup.zig").Backup; const Backup = @import("backup.zig").Backup;
@ -14,7 +15,7 @@ allocator: Allocator,
backup: Backup, backup: Backup,
gpio: *Gpio, 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, .{}); const file = try std.fs.cwd().openFile(rom_path, .{});
defer file.close(); defer file.close();
@ -28,7 +29,7 @@ pub fn init(allocator: Allocator, rom_path: []const u8, save_path: ?[]const u8)
.allocator = allocator, .allocator = allocator,
.title = title, .title = title,
.backup = try Backup.init(allocator, kind, title, save_path), .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) { switch (self.kind) {
.Rtc => { .Rtc => {
const clock = @ptrCast(*Clock, @alignCast(@alignOf(*Clock), self.ptr.?)); const clock = @ptrCast(*Clock, @alignCast(@alignOf(*Clock), self.ptr.?));
clock.step(Clock.Data{ .raw = value });
clock.step(Clock.GpioData{ .raw = value });
}, },
.None => {}, .None => {},
} }
@ -260,7 +260,7 @@ const Gpio = struct {
Control, 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); const self = try allocator.create(This);
self.* = .{ self.* = .{
@ -271,7 +271,7 @@ const Gpio = struct {
.device = switch (kind) { .device = switch (kind) {
.Rtc => blk: { .Rtc => blk: {
const clock = try allocator.create(Clock); const clock = try allocator.create(Clock);
clock.init(self); clock.init(cpu, self);
break :blk Device{ .kind = kind, .ptr = clock }; break :blk Device{ .kind = kind, .ptr = clock };
}, },
@ -339,6 +339,7 @@ const Clock = struct {
minute: u7, minute: u7,
second: u7, second: u7,
cpu: *Arm7tdmi,
gpio: *const Gpio, gpio: *const Gpio,
const Register = enum { const Register = enum {
@ -418,8 +419,8 @@ const Clock = struct {
} }
fn handleCommand(self: *const Command, rtc: *Clock) State { 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(); 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 is_write = command & 1 == 0;
const rtc_register = @intCast(u3, command >> 1 & 0x7); // TODO: Make Truncate 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), sck: Bit(u8, 0),
sio: Bit(u8, 1), sio: Bit(u8, 1),
cs: Bit(u8, 2), cs: Bit(u8, 2),
@ -473,7 +474,7 @@ const Clock = struct {
raw: u8, raw: u8,
}; };
fn init(ptr: *This, gpio: *const Gpio) void { fn init(ptr: *This, cpu: *Arm7tdmi, gpio: *const Gpio) void {
ptr.* = .{ ptr.* = .{
.cmd = .{ .buf = 0, .i = 0 }, .cmd = .{ .buf = 0, .i = 0 },
.writer = .{ .buf = 0, .i = 0, .count = 0 }, .writer = .{ .buf = 0, .i = 0, .count = 0 },
@ -486,16 +487,13 @@ const Clock = struct {
.hour = 0, .hour = 0,
.minute = 0, .minute = 0,
.second = 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 { fn step(self: *This, value: Data) void {
self.gpio = gpio; const cache: Data = .{ .raw = self.gpio.data };
}
fn step(self: *This, value: GpioData) void {
const cache: GpioData = .{ .raw = self.gpio.data };
switch (self.state) { switch (self.state) {
.Idle => { .Idle => {
@ -558,8 +556,11 @@ const Clock = struct {
log.info("RTC: Reset executed (control register was zeroed)", .{}); log.info("RTC: Reset executed (control register was zeroed)", .{});
} }
fn irq(_: *const This) void { fn irq(self: *This) void {
// TODO: Force GamePak IRQ // TODO: Confirm that this is the right behaviour
log.err("RTC: TODO: Force GamePak IRQ", .{});
log.debug("RTC: Force GamePak IRQ", .{});
self.cpu.bus.io.irq.game_pak.set();
self.cpu.handleInterrupt();
} }
}; };