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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user