chore: contain DMA Controllers in a tuple rather than a struct

This commit is contained in:
Rekai Nyangadzayi Musuka 2022-05-05 19:53:12 -03:00
parent c0e026b9a8
commit f0ce39230b
4 changed files with 67 additions and 79 deletions

View File

@ -9,7 +9,7 @@ const Io = @import("bus/io.zig").Io;
const Iwram = @import("bus/Iwram.zig"); const Iwram = @import("bus/Iwram.zig");
const Ppu = @import("ppu.zig").Ppu; const Ppu = @import("ppu.zig").Ppu;
const Apu = @import("apu.zig").Apu; const Apu = @import("apu.zig").Apu;
const DmaControllers = @import("bus/dma.zig").DmaControllers; const DmaTuple = @import("bus/dma.zig").DmaTuple;
const Timers = @import("bus/timer.zig").Timers; const Timers = @import("bus/timer.zig").Timers;
const Scheduler = @import("scheduler.zig").Scheduler; const Scheduler = @import("scheduler.zig").Scheduler;
const FilePaths = @import("util.zig").FilePaths; const FilePaths = @import("util.zig").FilePaths;
@ -18,6 +18,7 @@ const io = @import("bus/io.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const log = std.log.scoped(.Bus); const log = std.log.scoped(.Bus);
const createDmaTuple = @import("bus/dma.zig").create;
const rotr = @import("util.zig").rotr; const rotr = @import("util.zig").rotr;
const Self = @This(); const Self = @This();
@ -25,7 +26,7 @@ pak: GamePak,
bios: Bios, bios: Bios,
ppu: Ppu, ppu: Ppu,
apu: Apu, apu: Apu,
dma: DmaControllers, dma: DmaTuple,
tim: Timers, tim: Timers,
iwram: Iwram, iwram: Iwram,
ewram: Ewram, ewram: Ewram,
@ -42,7 +43,7 @@ pub fn init(alloc: Allocator, sched: *Scheduler, paths: FilePaths) !Self {
.apu = Apu.init(sched), .apu = Apu.init(sched),
.iwram = try Iwram.init(alloc), .iwram = try Iwram.init(alloc),
.ewram = try Ewram.init(alloc), .ewram = try Ewram.init(alloc),
.dma = DmaControllers.init(), .dma = createDmaTuple(),
.tim = Timers.init(sched), .tim = Timers.init(sched),
.io = Io.init(), .io = Io.init(),
.cpu = null, .cpu = null,
@ -64,18 +65,18 @@ pub fn attach(self: *Self, cpu: *Arm7tdmi) void {
pub fn handleDMATransfers(self: *Self) void { pub fn handleDMATransfers(self: *Self) void {
while (self.isDmaRunning()) { while (self.isDmaRunning()) {
if (self.dma._1.step(self)) continue; if (self.dma[1].step(self)) continue;
if (self.dma._0.step(self)) continue; if (self.dma[0].step(self)) continue;
if (self.dma._2.step(self)) continue; if (self.dma[2].step(self)) continue;
if (self.dma._3.step(self)) continue; if (self.dma[3].step(self)) continue;
} }
} }
inline fn isDmaRunning(self: *const Self) bool { inline fn isDmaRunning(self: *const Self) bool {
return self.dma._0.active or return self.dma[0].active or
self.dma._1.active or self.dma[1].active or
self.dma._2.active or self.dma[2].active or
self.dma._3.active; 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 {
@ -173,7 +174,7 @@ pub fn write(self: *Self, comptime T: type, address: u32, value: T) void {
0x07 => self.ppu.oam.write(T, align_addr, value), 0x07 => self.ppu.oam.write(T, align_addr, value),
// External Memory (Game Pak) // External Memory (Game Pak)
0x08...0x0D => self.pak.write(T, self.dma._3.word_count, align_addr, value), 0x08...0x0D => self.pak.write(T, self.dma[3].word_count, align_addr, value),
0x0E...0x0F => { 0x0E...0x0F => {
const rotate_by = switch (T) { const rotate_by = switch (T) {
u32 => address & 3, u32 => address & 3,

View File

@ -263,12 +263,12 @@ pub const Apu = struct {
if (@boolToInt(self.dma_cnt.chA_timer.read()) == tim_id) { if (@boolToInt(self.dma_cnt.chA_timer.read()) == tim_id) {
self.chA.updateSample(); self.chA.updateSample();
if (self.chA.len() <= 15) cpu.bus.dma._1.enableSoundDma(0x0400_00A0); if (self.chA.len() <= 15) cpu.bus.dma[1].enableSoundDma(0x0400_00A0);
} }
if (@boolToInt(self.dma_cnt.chB_timer.read()) == tim_id) { if (@boolToInt(self.dma_cnt.chB_timer.read()) == tim_id) {
self.chB.updateSample(); self.chB.updateSample();
if (self.chB.len() <= 15) cpu.bus.dma._2.enableSoundDma(0x0400_00A4); if (self.chB.len() <= 15) cpu.bus.dma[2].enableSoundDma(0x0400_00A4);
} }
} }

View File

@ -3,25 +3,12 @@ const std = @import("std");
const DmaControl = @import("io.zig").DmaControl; const DmaControl = @import("io.zig").DmaControl;
const Bus = @import("../Bus.zig"); const Bus = @import("../Bus.zig");
pub const DmaTuple = std.meta.Tuple(&[_]type{ DmaController(0), DmaController(1), DmaController(2), DmaController(3) });
const log = std.log.scoped(.DmaTransfer); const log = std.log.scoped(.DmaTransfer);
pub const DmaControllers = struct { pub fn create() DmaTuple {
const Self = @This(); return .{ DmaController(0).init(), DmaController(1).init(), DmaController(2).init(), DmaController(3).init() };
_0: DmaController(0),
_1: DmaController(1),
_2: DmaController(2),
_3: DmaController(3),
pub fn init() Self {
return .{
._0 = DmaController(0).init(),
._1 = DmaController(1).init(),
._2 = DmaController(2).init(),
._3 = DmaController(3).init(),
};
} }
};
/// Function that creates a DMAController. Determines unique DMA Controller behaiour at compile-time /// Function that creates a DMAController. Determines unique DMA Controller behaiour at compile-time
fn DmaController(comptime id: u2) type { fn DmaController(comptime id: u2) type {
@ -228,10 +215,10 @@ fn DmaController(comptime id: u2) type {
} }
pub fn pollBlankingDma(bus: *Bus, comptime kind: DmaKind) void { pub fn pollBlankingDma(bus: *Bus, comptime kind: DmaKind) void {
bus.dma._0.pollBlankingDma(kind); bus.dma[0].pollBlankingDma(kind);
bus.dma._1.pollBlankingDma(kind); bus.dma[1].pollBlankingDma(kind);
bus.dma._2.pollBlankingDma(kind); bus.dma[2].pollBlankingDma(kind);
bus.dma._3.pollBlankingDma(kind); bus.dma[3].pollBlankingDma(kind);
} }
const Adjustment = enum(u2) { const Adjustment = enum(u2) {

View File

@ -46,10 +46,10 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
0x0400_0006 => @as(T, bus.ppu.bg[0].cnt.raw) << 16 | bus.ppu.vcount.raw, 0x0400_0006 => @as(T, bus.ppu.bg[0].cnt.raw) << 16 | bus.ppu.vcount.raw,
// DMA Transfers // DMA Transfers
0x0400_00B8 => @as(T, bus.dma._0.cnt.raw) << 16, 0x0400_00B8 => @as(T, bus.dma[0].cnt.raw) << 16,
0x0400_00C4 => @as(T, bus.dma._1.cnt.raw) << 16, 0x0400_00C4 => @as(T, bus.dma[1].cnt.raw) << 16,
0x0400_00D0 => @as(T, bus.dma._1.cnt.raw) << 16, 0x0400_00D0 => @as(T, bus.dma[1].cnt.raw) << 16,
0x0400_00DC => @as(T, bus.dma._3.cnt.raw) << 16, 0x0400_00DC => @as(T, bus.dma[3].cnt.raw) << 16,
// Timers // Timers
0x0400_0100 => @as(T, bus.tim._0.cnt.raw) << 16 | bus.tim._0.counter(), 0x0400_0100 => @as(T, bus.tim._0.cnt.raw) << 16 | bus.tim._0.counter(),
@ -86,10 +86,10 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
0x0400_0088 => bus.apu.bias.raw, 0x0400_0088 => bus.apu.bias.raw,
// DMA Transfers // DMA Transfers
0x0400_00BA => bus.dma._0.cnt.raw, 0x0400_00BA => bus.dma[0].cnt.raw,
0x0400_00C6 => bus.dma._1.cnt.raw, 0x0400_00C6 => bus.dma[1].cnt.raw,
0x0400_00D2 => bus.dma._2.cnt.raw, 0x0400_00D2 => bus.dma[2].cnt.raw,
0x0400_00DE => bus.dma._3.cnt.raw, 0x0400_00DE => bus.dma[3].cnt.raw,
// Timers // Timers
0x0400_0100 => bus.tim._0.counter(), 0x0400_0100 => bus.tim._0.counter(),
@ -199,18 +199,18 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
0x0400_00A8, 0x0400_00AC => {}, // Unused 0x0400_00A8, 0x0400_00AC => {}, // Unused
// DMA Transfers // DMA Transfers
0x0400_00B0 => bus.dma._0.writeSad(value), 0x0400_00B0 => bus.dma[0].writeSad(value),
0x0400_00B4 => bus.dma._0.writeDad(value), 0x0400_00B4 => bus.dma[0].writeDad(value),
0x0400_00B8 => bus.dma._0.writeCnt(value), 0x0400_00B8 => bus.dma[0].writeCnt(value),
0x0400_00BC => bus.dma._1.writeSad(value), 0x0400_00BC => bus.dma[1].writeSad(value),
0x0400_00C0 => bus.dma._1.writeDad(value), 0x0400_00C0 => bus.dma[1].writeDad(value),
0x0400_00C4 => bus.dma._1.writeCnt(value), 0x0400_00C4 => bus.dma[1].writeCnt(value),
0x0400_00C8 => bus.dma._2.writeSad(value), 0x0400_00C8 => bus.dma[2].writeSad(value),
0x0400_00CC => bus.dma._2.writeDad(value), 0x0400_00CC => bus.dma[2].writeDad(value),
0x0400_00D0 => bus.dma._2.writeCnt(value), 0x0400_00D0 => bus.dma[2].writeCnt(value),
0x0400_00D4 => bus.dma._3.writeSad(value), 0x0400_00D4 => bus.dma[3].writeSad(value),
0x0400_00D8 => bus.dma._3.writeDad(value), 0x0400_00D8 => bus.dma[3].writeDad(value),
0x0400_00DC => bus.dma._3.writeCnt(value), 0x0400_00DC => bus.dma[3].writeCnt(value),
0x0400_00E0...0x0400_00FC => {}, // Unused 0x0400_00E0...0x0400_00FC => {}, // Unused
// Timers // Timers
@ -310,33 +310,33 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
0x0400_0090...0x0400_009F => bus.apu.ch3.wave_dev.write(T, bus.apu.ch3.select, address, value), 0x0400_0090...0x0400_009F => bus.apu.ch3.wave_dev.write(T, bus.apu.ch3.select, address, value),
// Dma Transfers // Dma Transfers
0x0400_00B0 => bus.dma._0.writeSad(bus.dma._0.sad & 0xFFFF_0000 | value), 0x0400_00B0 => bus.dma[0].writeSad(bus.dma[0].sad & 0xFFFF_0000 | value),
0x0400_00B2 => bus.dma._0.writeSad(bus.dma._0.sad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00B2 => bus.dma[0].writeSad(bus.dma[0].sad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00B4 => bus.dma._0.writeDad(bus.dma._0.dad & 0xFFFF_0000 | value), 0x0400_00B4 => bus.dma[0].writeDad(bus.dma[0].dad & 0xFFFF_0000 | value),
0x0400_00B6 => bus.dma._0.writeDad(bus.dma._0.dad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00B6 => bus.dma[0].writeDad(bus.dma[0].dad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00B8 => bus.dma._0.writeWordCount(value), 0x0400_00B8 => bus.dma[0].writeWordCount(value),
0x0400_00BA => bus.dma._0.writeCntHigh(value), 0x0400_00BA => bus.dma[0].writeCntHigh(value),
0x0400_00BC => bus.dma._1.writeSad(bus.dma._1.sad & 0xFFFF_0000 | value), 0x0400_00BC => bus.dma[1].writeSad(bus.dma[1].sad & 0xFFFF_0000 | value),
0x0400_00BE => bus.dma._1.writeSad(bus.dma._1.sad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00BE => bus.dma[1].writeSad(bus.dma[1].sad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00C0 => bus.dma._1.writeDad(bus.dma._1.dad & 0xFFFF_0000 | value), 0x0400_00C0 => bus.dma[1].writeDad(bus.dma[1].dad & 0xFFFF_0000 | value),
0x0400_00C2 => bus.dma._1.writeDad(bus.dma._1.dad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00C2 => bus.dma[1].writeDad(bus.dma[1].dad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00C4 => bus.dma._1.writeWordCount(value), 0x0400_00C4 => bus.dma[1].writeWordCount(value),
0x0400_00C6 => bus.dma._1.writeCntHigh(value), 0x0400_00C6 => bus.dma[1].writeCntHigh(value),
0x0400_00C8 => bus.dma._2.writeSad(bus.dma._2.sad & 0xFFFF_0000 | value), 0x0400_00C8 => bus.dma[2].writeSad(bus.dma[2].sad & 0xFFFF_0000 | value),
0x0400_00CA => bus.dma._2.writeSad(bus.dma._2.sad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00CA => bus.dma[2].writeSad(bus.dma[2].sad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00CC => bus.dma._2.writeDad(bus.dma._2.dad & 0xFFFF_0000 | value), 0x0400_00CC => bus.dma[2].writeDad(bus.dma[2].dad & 0xFFFF_0000 | value),
0x0400_00CE => bus.dma._2.writeDad(bus.dma._2.dad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00CE => bus.dma[2].writeDad(bus.dma[2].dad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00D0 => bus.dma._2.writeWordCount(value), 0x0400_00D0 => bus.dma[2].writeWordCount(value),
0x0400_00D2 => bus.dma._2.writeCntHigh(value), 0x0400_00D2 => bus.dma[2].writeCntHigh(value),
0x0400_00D4 => bus.dma._3.writeSad(bus.dma._3.sad & 0xFFFF_0000 | value), 0x0400_00D4 => bus.dma[3].writeSad(bus.dma[3].sad & 0xFFFF_0000 | value),
0x0400_00D6 => bus.dma._3.writeSad(bus.dma._3.sad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00D6 => bus.dma[3].writeSad(bus.dma[3].sad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00D8 => bus.dma._3.writeDad(bus.dma._3.dad & 0xFFFF_0000 | value), 0x0400_00D8 => bus.dma[3].writeDad(bus.dma[3].dad & 0xFFFF_0000 | value),
0x0400_00DA => bus.dma._3.writeDad(bus.dma._3.dad & 0x0000_FFFF | (@as(u32, value) << 16)), 0x0400_00DA => bus.dma[3].writeDad(bus.dma[3].dad & 0x0000_FFFF | (@as(u32, value) << 16)),
0x0400_00DC => bus.dma._3.writeWordCount(value), 0x0400_00DC => bus.dma[3].writeWordCount(value),
0x0400_00DE => bus.dma._3.writeCntHigh(value), 0x0400_00DE => bus.dma[3].writeCntHigh(value),
// Timers // Timers
0x0400_0100 => bus.tim._0.setReload(value), 0x0400_0100 => bus.tim._0.setReload(value),