chore: move cpu implementation to it's own module

There's a decent amount of Hacks and TODO:s that need revisiting
I should spend a bit of time cleaning up code 😔
This commit is contained in:
2023-06-25 18:56:37 -05:00
parent 5b6650ef34
commit 954fb279ad
33 changed files with 208 additions and 2129 deletions

View File

@@ -1,7 +1,7 @@
const std = @import("std");
const config = @import("../../config.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const Arm7tdmi = @import("arm32").Arm7tdmi;
const Backup = @import("backup.zig").Backup;
const Gpio = @import("gpio.zig").Gpio;
const Allocator = std.mem.Allocator;

View File

@@ -3,7 +3,7 @@ const util = @import("../../util.zig");
const DmaControl = @import("io.zig").DmaControl;
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const Arm7tdmi = @import("arm32").Arm7tdmi;
pub const DmaTuple = struct { DmaController(0), DmaController(1), DmaController(2), DmaController(3) };
const log = std.log.scoped(.DmaTransfer);
@@ -11,6 +11,7 @@ const log = std.log.scoped(.DmaTransfer);
const getHalf = util.getHalf;
const setHalf = util.setHalf;
const setQuart = util.setQuart;
const handleInterrupt = @import("../cpu_util.zig").handleInterrupt;
const rotr = @import("zba-util").rotr;
@@ -237,6 +238,8 @@ fn DmaController(comptime id: u2) type {
}
pub fn step(self: *Self, cpu: *Arm7tdmi) void {
const bus_ptr = @ptrCast(*Bus, @alignCast(@alignOf(Bus), cpu.bus.ptr));
const is_fifo = (id == 1 or id == 2) and self.cnt.start_timing.read() == 0b11;
const sad_adj = @intToEnum(Adjustment, self.cnt.sad_adj.read());
const dad_adj = if (is_fifo) .Fixed else @intToEnum(Adjustment, self.cnt.dad_adj.read());
@@ -283,13 +286,13 @@ fn DmaController(comptime id: u2) type {
if (self._word_count == 0) {
if (self.cnt.irq.read()) {
switch (id) {
0 => cpu.bus.io.irq.dma0.set(),
1 => cpu.bus.io.irq.dma1.set(),
2 => cpu.bus.io.irq.dma2.set(),
3 => cpu.bus.io.irq.dma3.set(),
0 => bus_ptr.io.irq.dma0.set(),
1 => bus_ptr.io.irq.dma1.set(),
2 => bus_ptr.io.irq.dma2.set(),
3 => bus_ptr.io.irq.dma3.set(),
}
cpu.handleInterrupt();
handleInterrupt(cpu);
}
// If we're not repeating, Fire the IRQs and disable the DMA

View File

@@ -2,9 +2,13 @@ const std = @import("std");
const Bit = @import("bitfield").Bit;
const DateTime = @import("datetime").datetime.Datetime;
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const Arm7tdmi = @import("arm32").Arm7tdmi;
const Bus = @import("../Bus.zig");
const Scheduler = @import("../scheduler.zig").Scheduler;
const Allocator = std.mem.Allocator;
const handleInterrupt = @import("../cpu_util.zig").handleInterrupt;
/// GPIO Register Implementation
pub const Gpio = struct {
const Self = @This();
@@ -286,11 +290,13 @@ pub const Clock = struct {
.gpio = gpio, // Can't use Arm7tdmi ptr b/c not initialized yet
};
cpu.sched.push(.RealTimeClock, 1 << 24); // Every Second
const sched_ptr = @ptrCast(*Scheduler, @alignCast(@alignOf(Scheduler), cpu.sched.ptr));
sched_ptr.push(.RealTimeClock, 1 << 24); // Every Second
}
pub fn onClockUpdate(self: *Self, late: u64) void {
self.cpu.sched.push(.RealTimeClock, (1 << 24) -| late); // Reschedule
const sched_ptr = @ptrCast(*Scheduler, @alignCast(@alignOf(Scheduler), self.cpu.sched.ptr));
sched_ptr.push(.RealTimeClock, (1 << 24) -| late); // Reschedule
const now = DateTime.now();
self.year = bcd(@intCast(u8, now.date.year - 2000));
@@ -397,11 +403,13 @@ pub const Clock = struct {
}
fn irq(self: *Self) void {
const bus_ptr = @ptrCast(*Bus, @alignCast(@alignOf(Bus), self.cpu.bus.ptr));
// TODO: Confirm that this is the right behaviour
log.debug("Force GamePak IRQ", .{});
self.cpu.bus.io.irq.game_pak.set();
self.cpu.handleInterrupt();
bus_ptr.io.irq.game_pak.set();
handleInterrupt(self.cpu);
}
fn processCommand(self: *Self, raw_command: u8) State {

View File

@@ -3,7 +3,10 @@ const util = @import("../../util.zig");
const TimerControl = @import("io.zig").TimerControl;
const Scheduler = @import("../scheduler.zig").Scheduler;
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const Arm7tdmi = @import("arm32").Arm7tdmi;
const Bus = @import("../Bus.zig");
const handleInterrupt = @import("../cpu_util.zig").handleInterrupt;
pub const TimerTuple = struct { Timer(0), Timer(1), Timer(2), Timer(3) };
const log = std.log.scoped(.Timer);
@@ -191,7 +194,9 @@ fn Timer(comptime id: u2) type {
pub fn onTimerExpire(self: *Self, cpu: *Arm7tdmi, late: u64) void {
// Fire IRQ if enabled
const io = &cpu.bus.io;
const bus_ptr = @ptrCast(*Bus, @alignCast(@alignOf(Bus), cpu.bus.ptr));
const io = &bus_ptr.io;
if (self.cnt.irq.read()) {
switch (id) {
@@ -201,12 +206,12 @@ fn Timer(comptime id: u2) type {
3 => io.irq.tim3.set(),
}
cpu.handleInterrupt();
handleInterrupt(cpu);
}
// DMA Sound Things
if (id == 0 or id == 1) {
cpu.bus.apu.onDmaAudioSampleRequest(cpu, id);
bus_ptr.apu.onDmaAudioSampleRequest(cpu, id);
}
// Perform Cascade Behaviour
@@ -214,9 +219,9 @@ fn Timer(comptime id: u2) type {
inline 0, 1, 2 => |idx| {
const next = idx + 1;
if (cpu.bus.tim[next].cnt.cascade.read()) {
cpu.bus.tim[next]._counter +%= 1;
if (cpu.bus.tim[next]._counter == 0) cpu.bus.tim[next].onTimerExpire(cpu, late);
if (bus_ptr.tim[next].cnt.cascade.read()) {
bus_ptr.tim[next]._counter +%= 1;
if (bus_ptr.tim[next]._counter == 0) bus_ptr.tim[next].onTimerExpire(cpu, late);
}
},
3 => {}, // THere is no timer for TIM3 to cascade to