Compare commits
	
		
			3 Commits
		
	
	
		
			35dba63b94
			...
			f5e401a4ee
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f5e401a4ee | |||
| dba8873f76 | |||
| db08edbdb9 | 
@@ -64,13 +64,6 @@ pub fn attach(self: *Self, cpu: *Arm7tdmi) void {
 | 
			
		||||
    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 {
 | 
			
		||||
    const cached = self.sched.tick;
 | 
			
		||||
    defer self.sched.tick = cached;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ pub fn read(comptime T: type, dma: *const DmaTuple, addr: u32) T {
 | 
			
		||||
        u32 => switch (byte) {
 | 
			
		||||
            0xB8 => @as(T, dma.*[0].cnt.raw) << 16,
 | 
			
		||||
            0xC4 => @as(T, dma.*[1].cnt.raw) << 16,
 | 
			
		||||
            0xD0 => @as(T, dma.*[1].cnt.raw) << 16,
 | 
			
		||||
            0xD0 => @as(T, dma.*[2].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 }),
 | 
			
		||||
        },
 | 
			
		||||
@@ -174,13 +174,11 @@ fn DmaController(comptime id: u2) type {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn setCnt(self: *Self, word: u32) void {
 | 
			
		||||
            self.word_count = @truncate(@TypeOf(self.word_count), word);
 | 
			
		||||
            self.setCntL(@truncate(u16, word));
 | 
			
		||||
            self.setCntH(@truncate(u16, word >> 16));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn step(self: *Self, cpu: *Arm7tdmi) bool {
 | 
			
		||||
            if (!self.active) return false;
 | 
			
		||||
 | 
			
		||||
        pub fn step(self: *Self, cpu: *Arm7tdmi) void {
 | 
			
		||||
            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 dad_adj = if (is_fifo) .Fixed else Self.adjustment(self.cnt.dad_adj.read());
 | 
			
		||||
@@ -232,13 +230,6 @@ fn DmaController(comptime id: u2) type {
 | 
			
		||||
                // timing window
 | 
			
		||||
                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 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								src/cpu.zig
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								src/cpu.zig
									
									
									
									
									
								
							@@ -148,6 +148,10 @@ 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 {
 | 
			
		||||
        if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@truncate(u5, value & 0x1F));
 | 
			
		||||
        self.cpsr.raw = value;
 | 
			
		||||
@@ -267,13 +271,33 @@ pub const Arm7tdmi = struct {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn handleDMATransfers(self: *Self) void {
 | 
			
		||||
        while (self.bus.isDmaRunning()) {
 | 
			
		||||
            if (self.bus.dma[0].step(self)) continue;
 | 
			
		||||
            if (self.bus.dma[1].step(self)) continue;
 | 
			
		||||
            if (self.bus.dma[2].step(self)) continue;
 | 
			
		||||
            if (self.bus.dma[3].step(self)) continue;
 | 
			
		||||
    pub fn stepDmaTransfer(self: *Self) bool {
 | 
			
		||||
        const dma0 = &self.bus.dma[0];
 | 
			
		||||
        const dma1 = &self.bus.dma[1];
 | 
			
		||||
        const dma2 = &self.bus.dma[2];
 | 
			
		||||
        const dma3 = &self.bus.dma[3];
 | 
			
		||||
 | 
			
		||||
        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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -52,8 +52,8 @@ pub fn runFrame(sched: *Scheduler, cpu: *Arm7tdmi) void {
 | 
			
		||||
 | 
			
		||||
    while (true) {
 | 
			
		||||
        while (sched.tick < std.math.min(frame_end, sched.nextTimestamp())) {
 | 
			
		||||
            if (cpu.bus.io.haltcnt == .Execute) cpu.step() else sched.tick += 1;
 | 
			
		||||
            cpu.handleDMATransfers();
 | 
			
		||||
            if (cpu.stepDmaTransfer()) continue; // DMA is blocking, ticks scheduler
 | 
			
		||||
            if (!cpu.isHalted()) cpu.step() else sched.tick += 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sched.tick >= frame_end) break;
 | 
			
		||||
 
 | 
			
		||||
@@ -157,6 +157,15 @@ pub fn main() anyerror!void {
 | 
			
		||||
                        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_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 => {},
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user