feat: implement force irqs for GPIO/RTC
This commit is contained in:
parent
92417025e9
commit
c977f3f965
|
@ -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),
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue