fix: reimplement DMA ticking
This commit is contained in:
		@@ -64,13 +64,6 @@ 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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -178,9 +178,7 @@ fn DmaController(comptime id: u2) type {
 | 
				
			|||||||
            self.setCntH(@truncate(u16, word >> 16));
 | 
					            self.setCntH(@truncate(u16, word >> 16));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pub fn step(self: *Self, cpu: *Arm7tdmi) bool {
 | 
					        pub fn step(self: *Self, cpu: *Arm7tdmi) void {
 | 
				
			||||||
            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());
 | 
				
			||||||
@@ -232,13 +230,6 @@ 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 {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								src/cpu.zig
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								src/cpu.zig
									
									
									
									
									
								
							@@ -271,13 +271,33 @@ pub const Arm7tdmi = struct {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn handleDMATransfers(self: *Self) void {
 | 
					    pub fn stepDmaTransfer(self: *Self) bool {
 | 
				
			||||||
        while (self.bus.isDmaRunning()) {
 | 
					        const dma0 = &self.bus.dma[0];
 | 
				
			||||||
            if (self.bus.dma[0].step(self)) continue;
 | 
					        const dma1 = &self.bus.dma[1];
 | 
				
			||||||
            if (self.bus.dma[1].step(self)) continue;
 | 
					        const dma2 = &self.bus.dma[2];
 | 
				
			||||||
            if (self.bus.dma[2].step(self)) continue;
 | 
					        const dma3 = &self.bus.dma[3];
 | 
				
			||||||
            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 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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.isHalted()) 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;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user