From 1fc1f5782bf9ec1108d30e2250d00a3bf49a5f34 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Tue, 5 Sep 2023 21:39:13 -0500 Subject: [PATCH] chore(bus): force align writes to NDS7/NDS9 Bus --- lib/arm32 | 2 +- src/core/emu.zig | 9 +++++++++ src/core/nds7/Bus.zig | 30 +++++++++++++++++------------- src/core/nds9/Bus.zig | 31 ++++++++++++++++++------------- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/lib/arm32 b/lib/arm32 index ada2a08..591352a 160000 --- a/lib/arm32 +++ b/lib/arm32 @@ -1 +1 @@ -Subproject commit ada2a08516d55a61bddd96f1c29e1547d0466049 +Subproject commit 591352a65b0ddbd5648f36910ae1ec899fed668d diff --git a/src/core/emu.zig b/src/core/emu.zig index a005c6d..7f553ab 100644 --- a/src/core/emu.zig +++ b/src/core/emu.zig @@ -131,3 +131,12 @@ pub const SharedContext = struct { allocator.destroy(self.main); } }; + +pub inline fn forceAlign(comptime T: type, address: u32) u32 { + return switch (T) { + u32 => address & ~@as(u32, 3), + u16 => address & ~@as(u32, 1), + u8 => address, + else => @compileError("Bus: Invalid read/write type"), + }; +} diff --git a/src/core/nds7/Bus.zig b/src/core/nds7/Bus.zig index 738dccf..69c681c 100644 --- a/src/core/nds7/Bus.zig +++ b/src/core/nds7/Bus.zig @@ -1,10 +1,10 @@ const std = @import("std"); - const io = @import("io.zig"); const Scheduler = @import("Scheduler.zig"); const SharedIo = @import("../io.zig").Io; const SharedContext = @import("../emu.zig").SharedContext; +const forceAlign = @import("../emu.zig").forceAlign; const Allocator = std.mem.Allocator; @@ -50,17 +50,19 @@ fn _read(self: *@This(), comptime T: type, comptime mode: Mode, address: u32) T const byte_count = @divExact(@typeInfo(T).Int.bits, 8); const readInt = std.mem.readIntLittle; + const aligned_addr = forceAlign(T, address); + switch (mode) { - // .debug => log.debug("read {} from 0x{X:0>8}", .{ T, address }), + // .debug => log.debug("read {} from 0x{X:0>8}", .{ T, aligned_addr }), .debug => {}, else => self.scheduler.tick += 1, } - return switch (address) { - 0x0200_0000...0x02FF_FFFF => readInt(T, self.main[address & 0x003F_FFFF ..][0..byte_count]), - 0x0380_0000...0x0380_FFFF => readInt(T, self.wram[address & 0x0000_FFFF ..][0..byte_count]), - 0x0400_0000...0x04FF_FFFF => io.read(self, T, address), - else => warn("unexpected read: 0x{x:0>8} -> {}", .{ address, T }), + return switch (aligned_addr) { + 0x0200_0000...0x02FF_FFFF => readInt(T, self.main[aligned_addr & 0x003F_FFFF ..][0..byte_count]), + 0x0380_0000...0x0380_FFFF => readInt(T, self.wram[aligned_addr & 0x0000_FFFF ..][0..byte_count]), + 0x0400_0000...0x04FF_FFFF => io.read(self, T, aligned_addr), + else => warn("unexpected read: 0x{x:0>8} -> {}", .{ aligned_addr, T }), }; } @@ -76,17 +78,19 @@ fn _write(self: *@This(), comptime T: type, comptime mode: Mode, address: u32, v const byte_count = @divExact(@typeInfo(T).Int.bits, 8); const writeInt = std.mem.writeIntLittle; + const aligned_addr = forceAlign(T, address); + switch (mode) { - // .debug => log.debug("wrote 0x{X:}{} to 0x{X:0>8}", .{ value, T, address }), + // .debug => log.debug("wrote 0x{X:}{} to 0x{X:0>8}", .{ value, T, aligned_addr }), .debug => {}, else => self.scheduler.tick += 1, } - switch (address) { - 0x0200_0000...0x02FF_FFFF => writeInt(T, self.main[address & 0x003F_FFFF ..][0..byte_count], value), - 0x0380_0000...0x0380_FFFF => writeInt(T, self.wram[address & 0x0000_FFFF ..][0..byte_count], value), - 0x0400_0000...0x04FF_FFFF => io.write(self, T, address, value), - else => log.warn("unexpected write: 0x{X:}{} -> 0x{X:0>8}", .{ value, T, address }), + switch (aligned_addr) { + 0x0200_0000...0x02FF_FFFF => writeInt(T, self.main[aligned_addr & 0x003F_FFFF ..][0..byte_count], value), + 0x0380_0000...0x0380_FFFF => writeInt(T, self.wram[aligned_addr & 0x0000_FFFF ..][0..byte_count], value), + 0x0400_0000...0x04FF_FFFF => io.write(self, T, aligned_addr, value), + else => log.warn("unexpected write: 0x{X:}{} -> 0x{X:0>8}", .{ value, T, aligned_addr }), } } diff --git a/src/core/nds9/Bus.zig b/src/core/nds9/Bus.zig index 803e35f..fdb2a67 100644 --- a/src/core/nds9/Bus.zig +++ b/src/core/nds9/Bus.zig @@ -1,9 +1,10 @@ const std = @import("std"); +const io = @import("io.zig"); const Ppu = @import("../ppu.zig").Ppu; const Scheduler = @import("Scheduler.zig"); const SharedContext = @import("../emu.zig").SharedContext; -const io = @import("io.zig"); +const forceAlign = @import("../emu.zig").forceAlign; const Allocator = std.mem.Allocator; @@ -60,17 +61,19 @@ fn _read(self: *@This(), comptime T: type, comptime mode: Mode, address: u32) T const byte_count = @divExact(@typeInfo(T).Int.bits, 8); const readInt = std.mem.readIntLittle; + const aligned_addr = forceAlign(T, address); + switch (mode) { - // .debug => log.debug("read {} from 0x{X:0>8}", .{ T, address }), + // .debug => log.debug("read {} from 0x{X:0>8}", .{ T, aligned_addr }), .debug => {}, else => self.scheduler.tick += 1, } - return switch (address) { - 0x0200_0000...0x02FF_FFFF => readInt(T, self.main[address & 0x003F_FFFF ..][0..byte_count]), - 0x0400_0000...0x04FF_FFFF => io.read(self, T, address), - 0x0600_0000...0x06FF_FFFF => readInt(T, self.vram1[address & 0x0007_FFFF ..][0..byte_count]), - else => warn("unexpected read: 0x{x:0>8} -> {}", .{ address, T }), + return switch (aligned_addr) { + 0x0200_0000...0x02FF_FFFF => readInt(T, self.main[aligned_addr & 0x003F_FFFF ..][0..byte_count]), + 0x0400_0000...0x04FF_FFFF => io.read(self, T, aligned_addr), + 0x0600_0000...0x06FF_FFFF => readInt(T, self.vram1[aligned_addr & 0x0007_FFFF ..][0..byte_count]), + else => warn("unexpected read: 0x{x:0>8} -> {}", .{ aligned_addr, T }), }; } @@ -86,17 +89,19 @@ fn _write(self: *@This(), comptime T: type, comptime mode: Mode, address: u32, v const byte_count = @divExact(@typeInfo(T).Int.bits, 8); const writeInt = std.mem.writeIntLittle; + const aligned_addr = forceAlign(T, address); + switch (mode) { - // .debug => log.debug("wrote 0x{X:}{} to 0x{X:0>8}", .{ value, T, address }), + // .debug => log.debug("wrote 0x{X:}{} to 0x{X:0>8}", .{ value, T, aligned_addr }), .debug => {}, else => self.scheduler.tick += 1, } - switch (address) { - 0x0200_0000...0x02FF_FFFF => writeInt(T, self.main[address & 0x003F_FFFF ..][0..byte_count], value), - 0x0400_0000...0x04FF_FFFF => io.write(self, T, address, value), - 0x0600_0000...0x06FF_FFFF => writeInt(T, self.vram1[address & 0x0007_FFFF ..][0..byte_count], value), - else => log.warn("unexpected write: 0x{X:}{} -> 0x{X:0>8}", .{ value, T, address }), + switch (aligned_addr) { + 0x0200_0000...0x02FF_FFFF => writeInt(T, self.main[aligned_addr & 0x003F_FFFF ..][0..byte_count], value), + 0x0400_0000...0x04FF_FFFF => io.write(self, T, aligned_addr, value), + 0x0600_0000...0x06FF_FFFF => writeInt(T, self.vram1[aligned_addr & 0x0007_FFFF ..][0..byte_count], value), + else => log.warn("unexpected write: 0x{X:}{} -> 0x{X:0>8}", .{ value, T, aligned_addr }), } }