chore: contain Timers in a tuple rather than a struct
This commit is contained in:
parent
f0ce39230b
commit
d5443d9c2f
|
@ -10,7 +10,7 @@ const Iwram = @import("bus/Iwram.zig");
|
|||
const Ppu = @import("ppu.zig").Ppu;
|
||||
const Apu = @import("apu.zig").Apu;
|
||||
const DmaTuple = @import("bus/dma.zig").DmaTuple;
|
||||
const Timers = @import("bus/timer.zig").Timers;
|
||||
const TimerTuple = @import("bus/timer.zig").TimerTuple;
|
||||
const Scheduler = @import("scheduler.zig").Scheduler;
|
||||
const FilePaths = @import("util.zig").FilePaths;
|
||||
|
||||
|
@ -19,6 +19,7 @@ const Allocator = std.mem.Allocator;
|
|||
const log = std.log.scoped(.Bus);
|
||||
|
||||
const createDmaTuple = @import("bus/dma.zig").create;
|
||||
const createTimerTuple = @import("bus/timer.zig").create;
|
||||
const rotr = @import("util.zig").rotr;
|
||||
const Self = @This();
|
||||
|
||||
|
@ -27,7 +28,7 @@ bios: Bios,
|
|||
ppu: Ppu,
|
||||
apu: Apu,
|
||||
dma: DmaTuple,
|
||||
tim: Timers,
|
||||
tim: TimerTuple,
|
||||
iwram: Iwram,
|
||||
ewram: Ewram,
|
||||
io: Io,
|
||||
|
@ -44,7 +45,7 @@ pub fn init(alloc: Allocator, sched: *Scheduler, paths: FilePaths) !Self {
|
|||
.iwram = try Iwram.init(alloc),
|
||||
.ewram = try Ewram.init(alloc),
|
||||
.dma = createDmaTuple(),
|
||||
.tim = Timers.init(sched),
|
||||
.tim = createTimerTuple(sched),
|
||||
.io = Io.init(),
|
||||
.cpu = null,
|
||||
.sched = sched,
|
||||
|
|
|
@ -52,10 +52,10 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
0x0400_00DC => @as(T, bus.dma[3].cnt.raw) << 16,
|
||||
|
||||
// Timers
|
||||
0x0400_0100 => @as(T, bus.tim._0.cnt.raw) << 16 | bus.tim._0.counter(),
|
||||
0x0400_0104 => @as(T, bus.tim._1.cnt.raw) << 16 | bus.tim._1.counter(),
|
||||
0x0400_0108 => @as(T, bus.tim._2.cnt.raw) << 16 | bus.tim._2.counter(),
|
||||
0x0400_010C => @as(T, bus.tim._3.cnt.raw) << 16 | bus.tim._3.counter(),
|
||||
0x0400_0100 => @as(T, bus.tim[0].cnt.raw) << 16 | bus.tim[0].counter(),
|
||||
0x0400_0104 => @as(T, bus.tim[1].cnt.raw) << 16 | bus.tim[1].counter(),
|
||||
0x0400_0108 => @as(T, bus.tim[2].cnt.raw) << 16 | bus.tim[2].counter(),
|
||||
0x0400_010C => @as(T, bus.tim[3].cnt.raw) << 16 | bus.tim[3].counter(),
|
||||
|
||||
// Serial Communication 1
|
||||
0x0400_0128 => unimplementedRead("Read {} from SIOCNT and SIOMLT_SEND", .{T}),
|
||||
|
@ -92,14 +92,14 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
0x0400_00DE => bus.dma[3].cnt.raw,
|
||||
|
||||
// Timers
|
||||
0x0400_0100 => bus.tim._0.counter(),
|
||||
0x0400_0102 => bus.tim._0.cnt.raw,
|
||||
0x0400_0104 => bus.tim._1.counter(),
|
||||
0x0400_0106 => bus.tim._1.cnt.raw,
|
||||
0x0400_0108 => bus.tim._2.counter(),
|
||||
0x0400_010A => bus.tim._2.cnt.raw,
|
||||
0x0400_010C => bus.tim._3.counter(),
|
||||
0x0400_010E => bus.tim._3.cnt.raw,
|
||||
0x0400_0100 => bus.tim[0].counter(),
|
||||
0x0400_0102 => bus.tim[0].cnt.raw,
|
||||
0x0400_0104 => bus.tim[1].counter(),
|
||||
0x0400_0106 => bus.tim[1].cnt.raw,
|
||||
0x0400_0108 => bus.tim[2].counter(),
|
||||
0x0400_010A => bus.tim[2].cnt.raw,
|
||||
0x0400_010C => bus.tim[3].counter(),
|
||||
0x0400_010E => bus.tim[3].cnt.raw,
|
||||
|
||||
// Serial Communication 1
|
||||
0x0400_0128 => unimplementedRead("Read {} from SIOCNT", .{T}),
|
||||
|
@ -214,10 +214,10 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
0x0400_00E0...0x0400_00FC => {}, // Unused
|
||||
|
||||
// Timers
|
||||
0x0400_0100 => bus.tim._0.writeCnt(value),
|
||||
0x0400_0104 => bus.tim._1.writeCnt(value),
|
||||
0x0400_0108 => bus.tim._2.writeCnt(value),
|
||||
0x0400_010C => bus.tim._3.writeCnt(value),
|
||||
0x0400_0100 => bus.tim[0].writeCnt(value),
|
||||
0x0400_0104 => bus.tim[1].writeCnt(value),
|
||||
0x0400_0108 => bus.tim[2].writeCnt(value),
|
||||
0x0400_010C => bus.tim[3].writeCnt(value),
|
||||
0x0400_0110...0x0400_011C => {}, // Unused
|
||||
|
||||
// Serial Communication 1
|
||||
|
@ -339,14 +339,14 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
0x0400_00DE => bus.dma[3].writeCntHigh(value),
|
||||
|
||||
// Timers
|
||||
0x0400_0100 => bus.tim._0.setReload(value),
|
||||
0x0400_0102 => bus.tim._0.writeCntHigh(value),
|
||||
0x0400_0104 => bus.tim._1.setReload(value),
|
||||
0x0400_0106 => bus.tim._1.writeCntHigh(value),
|
||||
0x0400_0108 => bus.tim._2.setReload(value),
|
||||
0x0400_010A => bus.tim._2.writeCntHigh(value),
|
||||
0x0400_010C => bus.tim._3.setReload(value),
|
||||
0x0400_010E => bus.tim._3.writeCntHigh(value),
|
||||
0x0400_0100 => bus.tim[0].setReload(value),
|
||||
0x0400_0102 => bus.tim[0].writeCntHigh(value),
|
||||
0x0400_0104 => bus.tim[1].setReload(value),
|
||||
0x0400_0106 => bus.tim[1].writeCntHigh(value),
|
||||
0x0400_0108 => bus.tim[2].setReload(value),
|
||||
0x0400_010A => bus.tim[2].writeCntHigh(value),
|
||||
0x0400_010C => bus.tim[3].setReload(value),
|
||||
0x0400_010E => bus.tim[3].writeCntHigh(value),
|
||||
0x0400_0114 => {}, // TODO: Gyakuten Saiban writes 0x8000 to 0x0400_0114
|
||||
0x0400_0110 => {}, // Not Used,
|
||||
|
||||
|
|
|
@ -6,25 +6,12 @@ const Scheduler = @import("../scheduler.zig").Scheduler;
|
|||
const Event = @import("../scheduler.zig").Event;
|
||||
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
|
||||
|
||||
pub const TimerTuple = std.meta.Tuple(&[_]type{ Timer(0), Timer(1), Timer(2), Timer(3) });
|
||||
const log = std.log.scoped(.Timer);
|
||||
|
||||
pub const Timers = struct {
|
||||
const Self = @This();
|
||||
|
||||
_0: Timer(0),
|
||||
_1: Timer(1),
|
||||
_2: Timer(2),
|
||||
_3: Timer(3),
|
||||
|
||||
pub fn init(sched: *Scheduler) Self {
|
||||
return .{
|
||||
._0 = Timer(0).init(sched),
|
||||
._1 = Timer(1).init(sched),
|
||||
._2 = Timer(2).init(sched),
|
||||
._3 = Timer(3).init(sched),
|
||||
};
|
||||
pub fn create(sched: *Scheduler) TimerTuple {
|
||||
return .{ Timer(0).init(sched), Timer(1).init(sched), Timer(2).init(sched), Timer(3).init(sched) };
|
||||
}
|
||||
};
|
||||
|
||||
fn Timer(comptime id: u2) type {
|
||||
return struct {
|
||||
|
@ -94,7 +81,6 @@ fn Timer(comptime id: u2) type {
|
|||
pub fn handleOverflow(self: *Self, cpu: *Arm7tdmi, late: u64) void {
|
||||
// Fire IRQ if enabled
|
||||
const io = &cpu.bus.io;
|
||||
const tim = &cpu.bus.tim;
|
||||
|
||||
if (self.cnt.irq.read()) {
|
||||
switch (id) {
|
||||
|
@ -114,17 +100,17 @@ fn Timer(comptime id: u2) type {
|
|||
|
||||
// Perform Cascade Behaviour
|
||||
switch (id) {
|
||||
0 => if (tim._1.cnt.cascade.read()) {
|
||||
tim._1._counter +%= 1;
|
||||
if (tim._1._counter == 0) tim._1.handleOverflow(cpu, late);
|
||||
0 => if (cpu.bus.tim[1].cnt.cascade.read()) {
|
||||
cpu.bus.tim[1]._counter +%= 1;
|
||||
if (cpu.bus.tim[1]._counter == 0) cpu.bus.tim[1].handleOverflow(cpu, late);
|
||||
},
|
||||
1 => if (tim._2.cnt.cascade.read()) {
|
||||
tim._2._counter +%= 1;
|
||||
if (tim._2._counter == 0) tim._2.handleOverflow(cpu, late);
|
||||
1 => if (cpu.bus.tim[2].cnt.cascade.read()) {
|
||||
cpu.bus.tim[2]._counter +%= 1;
|
||||
if (cpu.bus.tim[2]._counter == 0) cpu.bus.tim[2].handleOverflow(cpu, late);
|
||||
},
|
||||
2 => if (tim._3.cnt.cascade.read()) {
|
||||
tim._3._counter +%= 1;
|
||||
if (tim._3._counter == 0) tim._3.handleOverflow(cpu, late);
|
||||
2 => if (cpu.bus.tim[3].cnt.cascade.read()) {
|
||||
cpu.bus.tim[3]._counter +%= 1;
|
||||
if (cpu.bus.tim[3]._counter == 0) cpu.bus.tim[3].handleOverflow(cpu, late);
|
||||
},
|
||||
3 => {}, // There is no Timer for TIM3 to "cascade" to,
|
||||
}
|
||||
|
|
|
@ -45,10 +45,10 @@ pub const Scheduler = struct {
|
|||
},
|
||||
.TimerOverflow => |id| {
|
||||
switch (id) {
|
||||
0 => cpu.bus.tim._0.handleOverflow(cpu, late),
|
||||
1 => cpu.bus.tim._1.handleOverflow(cpu, late),
|
||||
2 => cpu.bus.tim._2.handleOverflow(cpu, late),
|
||||
3 => cpu.bus.tim._3.handleOverflow(cpu, late),
|
||||
0 => cpu.bus.tim[0].handleOverflow(cpu, late),
|
||||
1 => cpu.bus.tim[1].handleOverflow(cpu, late),
|
||||
2 => cpu.bus.tim[2].handleOverflow(cpu, late),
|
||||
3 => cpu.bus.tim[3].handleOverflow(cpu, late),
|
||||
}
|
||||
},
|
||||
.ApuChannel => |id| {
|
||||
|
|
Loading…
Reference in New Issue