Compare commits

..

No commits in common. "f5e401a4ee9c1c4f8fc6dd6867e4724d74632bd5" and "35dba63b94a1b6d88cf8993c0727902488196078" have entirely different histories.

5 changed files with 27 additions and 44 deletions

View File

@ -64,6 +64,13 @@ pub fn attach(self: *Self, cpu: *Arm7tdmi) void {
self.cpu = cpu; self.cpu = cpu;
} }
pub inline fn isDmaRunning(self: *const Self) bool {
return self.dma[0].active or
self.dma[1].active or
self.dma[2].active or
self.dma[3].active;
}
pub fn debugRead(self: *const Self, comptime T: type, address: u32) T { pub fn debugRead(self: *const Self, comptime T: type, address: u32) T {
const cached = self.sched.tick; const cached = self.sched.tick;
defer self.sched.tick = cached; defer self.sched.tick = cached;

View File

@ -20,7 +20,7 @@ pub fn read(comptime T: type, dma: *const DmaTuple, addr: u32) T {
u32 => switch (byte) { u32 => switch (byte) {
0xB8 => @as(T, dma.*[0].cnt.raw) << 16, 0xB8 => @as(T, dma.*[0].cnt.raw) << 16,
0xC4 => @as(T, dma.*[1].cnt.raw) << 16, 0xC4 => @as(T, dma.*[1].cnt.raw) << 16,
0xD0 => @as(T, dma.*[2].cnt.raw) << 16, 0xD0 => @as(T, dma.*[1].cnt.raw) << 16,
0xDC => @as(T, dma.*[3].cnt.raw) << 16, 0xDC => @as(T, dma.*[3].cnt.raw) << 16,
else => readUndefined(log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, addr }), else => readUndefined(log, "Tried to perform a {} read to 0x{X:0>8}", .{ T, addr }),
}, },
@ -174,11 +174,13 @@ fn DmaController(comptime id: u2) type {
} }
pub fn setCnt(self: *Self, word: u32) void { pub fn setCnt(self: *Self, word: u32) void {
self.setCntL(@truncate(u16, word)); self.word_count = @truncate(@TypeOf(self.word_count), word);
self.setCntH(@truncate(u16, word >> 16)); self.setCntH(@truncate(u16, word >> 16));
} }
pub fn step(self: *Self, cpu: *Arm7tdmi) void { pub fn step(self: *Self, cpu: *Arm7tdmi) bool {
if (!self.active) return false;
const is_fifo = (self.id == 1 or self.id == 2) and self.cnt.start_timing.read() == 0b11; const is_fifo = (self.id == 1 or self.id == 2) and self.cnt.start_timing.read() == 0b11;
const sad_adj = Self.adjustment(self.cnt.sad_adj.read()); const sad_adj = Self.adjustment(self.cnt.sad_adj.read());
const dad_adj = if (is_fifo) .Fixed else Self.adjustment(self.cnt.dad_adj.read()); const dad_adj = if (is_fifo) .Fixed else Self.adjustment(self.cnt.dad_adj.read());
@ -230,6 +232,13 @@ fn DmaController(comptime id: u2) type {
// timing window // timing window
self.active = false; self.active = false;
} }
return true;
}
pub fn isBlocking(self: *const Self) bool {
// A DMA Transfer is Blocking if it is Immediate
return self.cnt.start_timing.read() == 0b00;
} }
pub fn pollBlankingDma(self: *Self, comptime kind: DmaKind) void { pub fn pollBlankingDma(self: *Self, comptime kind: DmaKind) void {

View File

@ -148,10 +148,6 @@ pub const Arm7tdmi = struct {
}; };
} }
pub inline fn isHalted(self: *const Self) bool {
return self.bus.io.haltcnt == .Halt;
}
pub fn setCpsr(self: *Self, value: u32) void { pub fn setCpsr(self: *Self, value: u32) void {
if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@truncate(u5, value & 0x1F)); if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@truncate(u5, value & 0x1F));
self.cpsr.raw = value; self.cpsr.raw = value;
@ -271,33 +267,13 @@ pub const Arm7tdmi = struct {
} }
} }
pub fn stepDmaTransfer(self: *Self) bool { pub fn handleDMATransfers(self: *Self) void {
const dma0 = &self.bus.dma[0]; while (self.bus.isDmaRunning()) {
const dma1 = &self.bus.dma[1]; if (self.bus.dma[0].step(self)) continue;
const dma2 = &self.bus.dma[2]; if (self.bus.dma[1].step(self)) continue;
const dma3 = &self.bus.dma[3]; if (self.bus.dma[2].step(self)) continue;
if (self.bus.dma[3].step(self)) continue;
if (dma0.active) {
dma0.step(self);
return true;
} }
if (dma1.active) {
dma1.step(self);
return true;
}
if (dma2.active) {
dma2.step(self);
return true;
}
if (dma3.active) {
dma3.step(self);
return true;
}
return false;
} }
pub fn handleInterrupt(self: *Self) void { pub fn handleInterrupt(self: *Self) void {

View File

@ -52,8 +52,8 @@ pub fn runFrame(sched: *Scheduler, cpu: *Arm7tdmi) void {
while (true) { while (true) {
while (sched.tick < std.math.min(frame_end, sched.nextTimestamp())) { while (sched.tick < std.math.min(frame_end, sched.nextTimestamp())) {
if (cpu.stepDmaTransfer()) continue; // DMA is blocking, ticks scheduler if (cpu.bus.io.haltcnt == .Execute) cpu.step() else sched.tick += 1;
if (!cpu.isHalted()) cpu.step() else sched.tick += 1; cpu.handleDMATransfers();
} }
if (sched.tick >= frame_end) break; if (sched.tick >= frame_end) break;

View File

@ -157,15 +157,6 @@ pub fn main() anyerror!void {
SDL.SDLK_RSHIFT => io.keyinput.select.set(), SDL.SDLK_RSHIFT => io.keyinput.select.set(),
SDL.SDLK_i => log.err("Sample Count: {}", .{@intCast(u32, SDL.SDL_AudioStreamAvailable(cpu.bus.apu.stream)) / (2 * @sizeOf(u16))}), SDL.SDLK_i => log.err("Sample Count: {}", .{@intCast(u32, SDL.SDL_AudioStreamAvailable(cpu.bus.apu.stream)) / (2 * @sizeOf(u16))}),
SDL.SDLK_j => log.err("Scheduler Capacity: {} | Scheduler Event Count: {}", .{ scheduler.queue.capacity(), scheduler.queue.count() }), SDL.SDLK_j => log.err("Scheduler Capacity: {} | Scheduler Event Count: {}", .{ scheduler.queue.capacity(), scheduler.queue.count() }),
SDL.SDLK_k => {
// Dump IWRAM to file
log.info("PC: 0x{X:0>8}", .{cpu.r[15]});
log.info("LR: 0x{X:0>8}", .{cpu.r[14]});
// const iwram_file = try std.fs.cwd().createFile("iwram.bin", .{});
// defer iwram_file.close();
// try iwram_file.writeAll(cpu.bus.iwram.buf);
},
else => {}, else => {},
} }
}, },