From bf8521eb5e61310c2362e079c4adc35a38f90152 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:12:47 -0300 Subject: [PATCH] chore: use stdlib endian-aware integer read/write functions --- src/apu.zig | 15 ++-------- src/bus/Bios.zig | 4 +-- src/bus/Ewram.zig | 16 ++--------- src/bus/GamePak.zig | 2 -- src/bus/Iwram.zig | 16 ++--------- src/bus/backup.zig | 29 ++----------------- src/cpu.zig | 6 ++-- src/ppu.zig | 69 +++++++++++---------------------------------- 8 files changed, 29 insertions(+), 128 deletions(-) diff --git a/src/apu.zig b/src/apu.zig index 5caf19e..e845355 100644 --- a/src/apu.zig +++ b/src/apu.zig @@ -1014,20 +1014,9 @@ const WaveDevice = struct { // TODO: Handle writes when Channel 3 is disabled const base = if (!cnt.bank.read()) @as(u32, 0x10) else 0; // Write to the Opposite Bank in Use + const i = base + addr - 0x0400_0090; switch (T) { - u32 => { - self.buf[base + addr - 0x0400_0090 + 3] = @truncate(u8, value >> 24); - self.buf[base + addr - 0x0400_0090 + 2] = @truncate(u8, value >> 16); - self.buf[base + addr - 0x0400_0090 + 1] = @truncate(u8, value >> 8); - self.buf[base + addr - 0x0400_0090] = @truncate(u8, value); - }, - u16 => { - self.buf[base + addr - 0x0400_0090 + 1] = @truncate(u8, value >> 8); - self.buf[base + addr - 0x0400_0090] = @truncate(u8, value); - }, - u8 => { - self.buf[base + addr - 0x0400_0090] = value; - }, + u32, u16, u8 => std.mem.writeIntSliceLittle(T, self.buf[i..][0..@sizeOf(T)], value), else => @compileError("Ch3 WAVERAM: Unsupported write width"), } } diff --git a/src/bus/Bios.zig b/src/bus/Bios.zig index aea7fbe..39f8e02 100644 --- a/src/bus/Bios.zig +++ b/src/bus/Bios.zig @@ -44,9 +44,7 @@ pub fn checkedRead(self: *Self, comptime T: type, r15: u32, addr: u32) T { fn read(self: *const Self, comptime T: type, addr: u32) T { if (self.buf) |buf| { return switch (T) { - u32 => (@as(u32, buf[addr + 3]) << 24) | (@as(u32, buf[addr + 2]) << 16) | (@as(u32, buf[addr + 1]) << 8) | (@as(u32, buf[addr])), - u16 => (@as(u16, buf[addr + 1]) << 8) | @as(u16, buf[addr]), - u8 => buf[addr], + u32, u16, u8 => std.mem.readIntSliceLittle(T, buf[addr..][0..@sizeOf(T)]), else => @compileError("BIOS: Unsupported read width"), }; } diff --git a/src/bus/Ewram.zig b/src/bus/Ewram.zig index 757a16d..80d493b 100644 --- a/src/bus/Ewram.zig +++ b/src/bus/Ewram.zig @@ -25,9 +25,7 @@ pub fn read(self: *const Self, comptime T: type, address: usize) T { const addr = address & 0x3FFFF; return switch (T) { - u32 => (@as(u32, self.buf[addr + 3]) << 24) | (@as(u32, self.buf[addr + 2]) << 16) | (@as(u32, self.buf[addr + 1]) << 8) | (@as(u32, self.buf[addr])), - u16 => (@as(u16, self.buf[addr + 1]) << 8) | @as(u16, self.buf[addr]), - u8 => self.buf[addr], + u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]), else => @compileError("EWRAM: Unsupported read width"), }; } @@ -36,17 +34,7 @@ pub fn write(self: *const Self, comptime T: type, address: usize, value: T) void const addr = address & 0x3FFFF; return switch (T) { - u32 => { - self.buf[addr + 3] = @truncate(u8, value >> 24); - self.buf[addr + 2] = @truncate(u8, value >> 16); - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u16 => { - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u8 => self.buf[addr] = value, + u32, u16, u8 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value), else => @compileError("EWRAM: Unsupported write width"), }; } diff --git a/src/bus/GamePak.zig b/src/bus/GamePak.zig index d5d31fb..00e380f 100644 --- a/src/bus/GamePak.zig +++ b/src/bus/GamePak.zig @@ -4,8 +4,6 @@ const Backup = @import("backup.zig").Backup; const Allocator = std.mem.Allocator; const log = std.log.scoped(.GamePak); -const intToBytes = @import("../util.zig").intToBytes; - const Self = @This(); title: [12]u8, diff --git a/src/bus/Iwram.zig b/src/bus/Iwram.zig index 9b5d699..40a83c9 100644 --- a/src/bus/Iwram.zig +++ b/src/bus/Iwram.zig @@ -25,9 +25,7 @@ pub fn read(self: *const Self, comptime T: type, address: usize) T { const addr = address & 0x7FFF; return switch (T) { - u32 => (@as(u32, self.buf[addr + 3]) << 24) | (@as(u32, self.buf[addr + 2]) << 16) | (@as(u32, self.buf[addr + 1]) << 8) | (@as(u32, self.buf[addr])), - u16 => (@as(u16, self.buf[addr + 1]) << 8) | @as(u16, self.buf[addr]), - u8 => self.buf[addr], + u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]), else => @compileError("IWRAM: Unsupported read width"), }; } @@ -36,17 +34,7 @@ pub fn write(self: *const Self, comptime T: type, address: usize, value: T) void const addr = address & 0x7FFF; return switch (T) { - u32 => { - self.buf[addr + 3] = @truncate(u8, value >> 24); - self.buf[addr + 2] = @truncate(u8, value >> 16); - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u16 => { - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u8 => self.buf[addr] = value, + u32, u16, u8 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value), else => @compileError("IWRAM: Unsupported write width"), }; } diff --git a/src/bus/backup.zig b/src/bus/backup.zig index 3ced172..5e62088 100644 --- a/src/bus/backup.zig +++ b/src/bus/backup.zig @@ -4,7 +4,6 @@ const log = std.log.scoped(.Backup); const escape = @import("../util.zig").escape; const asString = @import("../util.zig").asString; -const intToBytes = @import("../util.zig").intToBytes; const backup_kinds = [5]Needle{ .{ .str = "EEPROM_V", .kind = .Eeprom }, @@ -411,18 +410,7 @@ const Eeprom = struct { .Large => { if (self.writer.len() == 14) { const addr = @intCast(u10, self.writer.finish()); - const value_buf = buf[@as(u13, addr) * 8 ..][0..8]; - - // zig fmt: off - const value = @as(u64, value_buf[7]) << 56 - | @as(u64, value_buf[6]) << 48 - | @as(u64, value_buf[5]) << 40 - | @as(u64, value_buf[4]) << 32 - | @as(u64, value_buf[3]) << 24 - | @as(u64, value_buf[2]) << 16 - | @as(u64, value_buf[1]) << 8 - | @as(u64, value_buf[0]) << 0; - // zig fmt: on + const value = std.mem.readIntSliceLittle(u64, buf[@as(u13, addr) * 8 ..][0..8]); self.reader.configure(value); self.state = .RequestEnd; @@ -432,18 +420,7 @@ const Eeprom = struct { if (self.writer.len() == 6) { // FIXME: Duplicated code from above const addr = @intCast(u6, self.writer.finish()); - const value_buf = buf[@as(u13, addr) * 8 ..][0..8]; - - // zig fmt: off - const value = @as(u64, value_buf[7]) << 56 - | @as(u64, value_buf[6]) << 48 - | @as(u64, value_buf[5]) << 40 - | @as(u64, value_buf[4]) << 32 - | @as(u64, value_buf[3]) << 24 - | @as(u64, value_buf[2]) << 16 - | @as(u64, value_buf[1]) << 8 - | @as(u64, value_buf[0]) << 0; - // zig fmt: on + const value = std.mem.readIntSliceLittle(u64, buf[@as(u13, addr) * 8 ..][0..8]); self.reader.configure(value); self.state = .RequestEnd; @@ -471,7 +448,7 @@ const Eeprom = struct { }, .WriteTransfer => { if (self.writer.len() == 64) { - std.mem.copy(u8, buf[self.addr * 8 ..][0..8], &intToBytes(u64, self.writer.finish())); + std.mem.writeIntSliceLittle(u64, buf[self.addr * 8 ..][0..8], self.writer.finish()); self.state = .RequestEnd; } }, diff --git a/src/cpu.zig b/src/cpu.zig index b06462a..416868e 100644 --- a/src/cpu.zig +++ b/src/cpu.zig @@ -393,10 +393,8 @@ pub const Arm7tdmi = struct { } fn skyWrite(buf: []u8, i: usize, num: u32) void { - buf[(@sizeOf(u32) * i) + 3] = @truncate(u8, num >> 24 & 0xFF); - buf[(@sizeOf(u32) * i) + 2] = @truncate(u8, num >> 16 & 0xFF); - buf[(@sizeOf(u32) * i) + 1] = @truncate(u8, num >> 8 & 0xFF); - buf[(@sizeOf(u32) * i) + 0] = @truncate(u8, num >> 0 & 0xFF); + const j = @sizeOf(u32) * i; + std.mem.writeIntSliceNative(u32, buf[j..(j + @sizeOf(u32))], num); } fn mgbaLog(self: *const Self, file: *const File, opcode: u32) !void { diff --git a/src/ppu.zig b/src/ppu.zig index 5000a10..1bc7fd1 100644 --- a/src/ppu.zig +++ b/src/ppu.zig @@ -11,7 +11,6 @@ const Bitfield = @import("bitfield").Bitfield; const Allocator = std.mem.Allocator; const log = std.log.scoped(.PPU); const pollBlankingDma = @import("bus/dma.zig").pollBlankingDma; -const intToBytes = @import("util.zig").intToBytes; /// This is used to generate byuu / Talurabi's Color Correction algorithm const COLOUR_LUT = genColourLut(); @@ -289,7 +288,7 @@ pub const Ppu = struct { // If there are any nulls present in self.scanline_buf it means that no background drew a pixel there, so draw backdrop for (self.scanline_buf) |maybe_px, i| { const bgr555 = if (maybe_px) |px| px else self.palette.getBackdrop(); - std.mem.copy(u8, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..4], &intToBytes(u32, COLOUR_LUT[bgr555 & 0x7FFF])); + std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]); } // Reset Current Scanline Pixel Buffer and list of fetched sprites @@ -313,7 +312,7 @@ pub const Ppu = struct { // If there are any nulls present in self.scanline_buf it means that no background drew a pixel there, so draw backdrop for (self.scanline_buf) |maybe_px, i| { const bgr555 = if (maybe_px) |px| px else self.palette.getBackdrop(); - std.mem.copy(u8, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..4], &intToBytes(u32, COLOUR_LUT[bgr555 & 0x7FFF])); + std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]); } // Reset Current Scanline Pixel Buffer and list of fetched sprites @@ -335,7 +334,7 @@ pub const Ppu = struct { // If there are any nulls present in self.scanline_buf it means that no background drew a pixel there, so draw backdrop for (self.scanline_buf) |maybe_px, i| { const bgr555 = if (maybe_px) |px| px else self.palette.getBackdrop(); - std.mem.copy(u8, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..4], &intToBytes(u32, COLOUR_LUT[bgr555 & 0x7FFF])); + std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]); } // Reset Current Scanline Pixel Buffer and list of fetched sprites @@ -350,7 +349,7 @@ pub const Ppu = struct { var i: usize = 0; while (i < width) : (i += 1) { const bgr555 = self.vram.read(u16, vram_base + i * @sizeOf(u16)); - std.mem.copy(u8, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..4], &intToBytes(u32, COLOUR_LUT[bgr555 & 0x7FFF])); + std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]); } }, 0x4 => { @@ -361,7 +360,7 @@ pub const Ppu = struct { // Render Current Scanline for (self.vram.buf[vram_base .. vram_base + width]) |byte, i| { const bgr555 = self.palette.read(u16, @as(u16, byte) * @sizeOf(u16)); - std.mem.copy(u8, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..4], &intToBytes(u32, COLOUR_LUT[bgr555 & 0x7FFF])); + std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]); } }, 0x5 => { @@ -378,7 +377,7 @@ pub const Ppu = struct { const bgr555 = if (scanline < m5_height and i < m5_width) self.vram.read(u16, vram_base + i * @sizeOf(u16)) else self.palette.getBackdrop(); - std.mem.copy(u8, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..4], &intToBytes(u32, COLOUR_LUT[bgr555 & 0x7FFF])); + std.mem.writeIntNative(u32, self.framebuf.get(.Emulator)[fb_base + i * @sizeOf(u32) ..][0..@sizeOf(u32)], COLOUR_LUT[bgr555 & 0x7FFF]); } }, else => std.debug.panic("[PPU] TODO: Implement BG Mode {}", .{bg_mode}), @@ -494,9 +493,7 @@ const Palette = struct { const addr = address & 0x3FF; return switch (T) { - u32 => (@as(T, self.buf[addr + 3]) << 24) | (@as(T, self.buf[addr + 2]) << 16) | (@as(T, self.buf[addr + 1]) << 8) | (@as(T, self.buf[addr])), - u16 => (@as(T, self.buf[addr + 1]) << 8) | @as(T, self.buf[addr]), - u8 => self.buf[addr], + u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]), else => @compileError("PALRAM: Unsupported read width"), }; } @@ -505,22 +502,13 @@ const Palette = struct { const addr = address & 0x3FF; switch (T) { - u32 => { - self.buf[addr + 3] = @truncate(u8, value >> 24); - self.buf[addr + 2] = @truncate(u8, value >> 16); - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u16 => { - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, + u32, u16 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value), u8 => { const halfword: u16 = @as(u16, value) * 0x0101; - const real_addr = addr & ~@as(u32, 1); // *was* 8-bit read so address won't be aligned + // FIXME: I don't think my comment here makes sense? + const weird_addr = addr & ~@as(u32, 1); // *was* 8-bit read so address won't be aligned - self.buf[real_addr + 1] = @truncate(u8, halfword >> 8); - self.buf[real_addr + 0] = @truncate(u8, halfword >> 0); + std.mem.writeIntSliceLittle(u16, self.buf[weird_addr..(weird_addr + @sizeOf(u16))], halfword); }, else => @compileError("PALRAM: Unsupported write width"), } @@ -556,9 +544,7 @@ const Vram = struct { const addr = Self.mirror(address); return switch (T) { - u32 => (@as(T, self.buf[addr + 3]) << 24) | (@as(T, self.buf[addr + 2]) << 16) | (@as(T, self.buf[addr + 1]) << 8) | (@as(T, self.buf[addr])), - u16 => (@as(T, self.buf[addr + 1]) << 8) | @as(T, self.buf[addr]), - u8 => self.buf[addr], + u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]), else => @compileError("VRAM: Unsupported read width"), }; } @@ -568,16 +554,7 @@ const Vram = struct { const addr = Self.mirror(address); switch (T) { - u32 => { - self.buf[addr + 3] = @truncate(u8, value >> 24); - self.buf[addr + 2] = @truncate(u8, value >> 16); - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u16 => { - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, + u32, u16 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value), u8 => { // Ignore if write is in OBJ switch (mode) { @@ -586,10 +563,9 @@ const Vram = struct { } const halfword: u16 = @as(u16, value) * 0x0101; - const real_addr = addr & ~@as(u32, 1); + const weird_addr = addr & ~@as(u32, 1); - self.buf[real_addr + 1] = @truncate(u8, halfword >> 8); - self.buf[real_addr + 0] = @truncate(u8, halfword >> 0); + std.mem.writeIntSliceLittle(u16, self.buf[weird_addr..(weird_addr + @sizeOf(u16))], halfword); }, else => @compileError("VRAM: Unsupported write width"), } @@ -630,9 +606,7 @@ const Oam = struct { const addr = address & 0x3FF; return switch (T) { - u32 => (@as(T, self.buf[addr + 3]) << 24) | (@as(T, self.buf[addr + 2]) << 16) | (@as(T, self.buf[addr + 1]) << 8) | (@as(T, self.buf[addr])), - u16 => (@as(T, self.buf[addr + 1]) << 8) | @as(T, self.buf[addr]), - u8 => self.buf[addr], + u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]), else => @compileError("OAM: Unsupported read width"), }; } @@ -641,16 +615,7 @@ const Oam = struct { const addr = address & 0x3FF; switch (T) { - u32 => { - self.buf[addr + 3] = @truncate(u8, value >> 24); - self.buf[addr + 2] = @truncate(u8, value >> 16); - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, - u16 => { - self.buf[addr + 1] = @truncate(u8, value >> 8); - self.buf[addr + 0] = @truncate(u8, value >> 0); - }, + u32, u16 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value), u8 => return, // 8-bit writes are explicitly ignored else => @compileError("OAM: Unsupported write width"), }