Compare commits

..

3 Commits

5 changed files with 43 additions and 60 deletions

View File

@ -335,10 +335,10 @@ fn DmaController(comptime id: u2) type {
} }
pub fn pollDmaOnBlank(bus: *Bus, comptime kind: DmaKind) void { pub fn pollDmaOnBlank(bus: *Bus, comptime kind: DmaKind) void {
bus.dma[0].poll(kind); comptime var i: usize = 0;
bus.dma[1].poll(kind); inline while (i < 4) : (i += 1) {
bus.dma[2].poll(kind); bus.dma[i].poll(kind);
bus.dma[3].poll(kind); }
} }
const Adjustment = enum(u2) { const Adjustment = enum(u2) {

View File

@ -72,7 +72,7 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) ?T {
0x0400_0200 => @as(u32, bus.io.irq.raw) << 16 | bus.io.ie.raw, 0x0400_0200 => @as(u32, bus.io.irq.raw) << 16 | bus.io.ie.raw,
0x0400_0204 => bus.io.waitcnt.raw, 0x0400_0204 => bus.io.waitcnt.raw,
0x0400_0208 => @boolToInt(bus.io.ime), 0x0400_0208 => @boolToInt(bus.io.ime),
0x0400_0300 => @enumToInt(bus.io.postflg),
else => util.io.read.undef(T, log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, address }), else => util.io.read.undef(T, log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, address }),
}, },
u16 => switch (address) { u16 => switch (address) {
@ -100,10 +100,11 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) ?T {
// Interrupts // Interrupts
0x0400_0200 => bus.io.ie.raw, 0x0400_0200 => bus.io.ie.raw,
0x0400_0202 => bus.io.irq.raw, 0x0400_0202 => bus.io.irq.raw,
0x0400_0204 => @truncate(T, bus.io.waitcnt.raw), 0x0400_0204 => bus.io.waitcnt.raw,
0x0400_0206 => null, 0x0400_0206 => null,
0x0400_0208 => @boolToInt(bus.io.ime), 0x0400_0208 => @boolToInt(bus.io.ime),
0x0400_020A => null, 0x0400_020A => null,
0x0400_0300 => @enumToInt(bus.io.postflg),
else => util.io.read.undef(T, log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, address }), else => util.io.read.undef(T, log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, address }),
}, },
u8 => return switch (address) { u8 => return switch (address) {
@ -135,7 +136,6 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) ?T {
0x0400_0206, 0x0400_0207 => null, 0x0400_0206, 0x0400_0207 => null,
0x0400_0208, 0x0400_0209 => @truncate(T, @as(u16, @boolToInt(bus.io.ime)) >> getHalf(@truncate(u8, address))), 0x0400_0208, 0x0400_0209 => @truncate(T, @as(u16, @boolToInt(bus.io.ime)) >> getHalf(@truncate(u8, address))),
0x0400_020A, 0x0400_020B => null, 0x0400_020A, 0x0400_020B => null,
0x0400_0300 => @enumToInt(bus.io.postflg), 0x0400_0300 => @enumToInt(bus.io.postflg),
else => util.io.read.undef(T, log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, address }), else => util.io.read.undef(T, log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, address }),
}, },
@ -183,8 +183,12 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
// Interrupts // Interrupts
0x0400_0200 => bus.io.setIrqs(value), 0x0400_0200 => bus.io.setIrqs(value),
0x0400_0204 => bus.io.waitcnt.raw = value, 0x0400_0204 => bus.io.waitcnt.raw = @truncate(u16, value),
0x0400_0208 => bus.io.ime = value & 1 == 1, 0x0400_0208 => bus.io.ime = value & 1 == 1,
0x0400_0300 => {
bus.io.postflg = @intToEnum(PostFlag, value & 1);
bus.io.haltcnt = if (value >> 15 & 1 == 0) .Halt else @panic("TODO: Implement STOP");
},
else => util.io.write.undef(log, "Tried to write 0x{X:0>8}{} to 0x{X:0>8}", .{ value, T, address }), else => util.io.write.undef(log, "Tried to write 0x{X:0>8}{} to 0x{X:0>8}", .{ value, T, address }),
}, },
u16 => switch (address) { u16 => switch (address) {
@ -228,7 +232,10 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
0x0400_0206 => {}, 0x0400_0206 => {},
0x0400_0208 => bus.io.ime = value & 1 == 1, 0x0400_0208 => bus.io.ime = value & 1 == 1,
0x0400_020A => {}, 0x0400_020A => {},
0x0400_0300 => {
bus.io.postflg = @intToEnum(PostFlag, value & 1);
bus.io.haltcnt = if (value >> 15 & 1 == 0) .Halt else @panic("TODO: Implement STOP");
},
else => util.io.write.undef(log, "Tried to write 0x{X:0>4}{} to 0x{X:0>8}", .{ value, T, address }), else => util.io.write.undef(log, "Tried to write 0x{X:0>4}{} to 0x{X:0>8}", .{ value, T, address }),
}, },
u8 => switch (address) { u8 => switch (address) {
@ -262,7 +269,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
0x0400_0209 => {}, 0x0400_0209 => {},
0x0400_020A, 0x0400_020B => {}, 0x0400_020A, 0x0400_020B => {},
0x0400_0300 => bus.io.postflg = std.meta.intToEnum(PostFlag, value & 1) catch unreachable, 0x0400_0300 => bus.io.postflg = @intToEnum(PostFlag, value & 1),
0x0400_0301 => bus.io.haltcnt = if (value >> 7 & 1 == 0) .Halt else std.debug.panic("TODO: Implement STOP", .{}), 0x0400_0301 => bus.io.haltcnt = if (value >> 7 & 1 == 0) .Halt else std.debug.panic("TODO: Implement STOP", .{}),
0x0400_0410 => log.debug("Wrote 0x{X:0>2} to the common yet undocumented 0x{X:0>8}", .{ value, address }), 0x0400_0410 => log.debug("Wrote 0x{X:0>2} to the common yet undocumented 0x{X:0>8}", .{ value, address }),
@ -602,16 +609,16 @@ pub const SoundBias = extern union {
/// Read / Write /// Read / Write
pub const WaitControl = extern union { pub const WaitControl = extern union {
sram_cnt: Bitfield(u32, 0, 2), sram_cnt: Bitfield(u16, 0, 2),
s0_first: Bitfield(u32, 2, 2), s0_first: Bitfield(u16, 2, 2),
s0_second: Bit(u32, 4), s0_second: Bit(u16, 4),
s1_first: Bitfield(u32, 5, 2), s1_first: Bitfield(u16, 5, 2),
s1_second: Bit(u32, 7), s1_second: Bit(u16, 7),
s2_first: Bitfield(u32, 8, 2), s2_first: Bitfield(u16, 8, 2),
s2_second: Bit(u32, 10), s2_second: Bit(u16, 10),
phi_out: Bitfield(u32, 11, 2), phi_out: Bitfield(u16, 11, 2),
prefetch_enable: Bit(u32, 14), prefetch_enable: Bit(u16, 14),
pak_kind: Bit(u32, 15), pak_kind: Bit(u16, 15),
raw: u32, raw: u16,
}; };

View File

@ -190,19 +190,15 @@ fn Timer(comptime id: u2) type {
// Perform Cascade Behaviour // Perform Cascade Behaviour
switch (id) { switch (id) {
0 => if (cpu.bus.tim[1].cnt.cascade.read()) { inline 0, 1, 2 => |idx| {
cpu.bus.tim[1]._counter +%= 1; const next = idx + 1;
if (cpu.bus.tim[1]._counter == 0) cpu.bus.tim[1].onTimerExpire(cpu, late);
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);
}
}, },
1 => if (cpu.bus.tim[2].cnt.cascade.read()) { 3 => {}, // THere is no timer for TIM3 to cascade to
cpu.bus.tim[2]._counter +%= 1;
if (cpu.bus.tim[2]._counter == 0) cpu.bus.tim[2].onTimerExpire(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].onTimerExpire(cpu, late);
},
3 => {}, // There is no Timer for TIM3 to "cascade" to,
} }
// Reschedule Timer if we're not cascading // Reschedule Timer if we're not cascading

View File

@ -455,29 +455,12 @@ pub const Arm7tdmi = struct {
} }
pub fn stepDmaTransfer(self: *Self) bool { pub fn stepDmaTransfer(self: *Self) bool {
const dma0 = &self.bus.dma[0]; comptime var i: usize = 0;
const dma1 = &self.bus.dma[1]; inline while (i < 4) : (i += 1) {
const dma2 = &self.bus.dma[2]; if (self.bus.dma[i].in_progress) {
const dma3 = &self.bus.dma[3]; self.bus.dma[i].step(self);
return true;
if (dma0.in_progress) { }
dma0.step(self);
return true;
}
if (dma1.in_progress) {
dma1.step(self);
return true;
}
if (dma2.in_progress) {
dma2.step(self);
return true;
}
if (dma3.in_progress) {
dma3.step(self);
return true;
} }
return false; return false;

View File

@ -46,10 +46,7 @@ pub const Scheduler = struct {
}, },
.TimerOverflow => |id| { .TimerOverflow => |id| {
switch (id) { switch (id) {
0 => cpu.bus.tim[0].onTimerExpire(cpu, late), inline 0...3 => |idx| cpu.bus.tim[idx].onTimerExpire(cpu, late),
1 => cpu.bus.tim[1].onTimerExpire(cpu, late),
2 => cpu.bus.tim[2].onTimerExpire(cpu, late),
3 => cpu.bus.tim[3].onTimerExpire(cpu, late),
} }
}, },
.ApuChannel => |id| { .ApuChannel => |id| {