chore: use stdlib endian-aware integer read/write functions
This commit is contained in:
parent
deff74d804
commit
2dc3864dca
15
src/apu.zig
15
src/apu.zig
|
@ -1014,20 +1014,9 @@ const WaveDevice = struct {
|
||||||
// TODO: Handle writes when Channel 3 is disabled
|
// 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 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) {
|
switch (T) {
|
||||||
u32 => {
|
u32, u16, u8 => std.mem.writeIntSliceLittle(T, self.buf[i..][0..@sizeOf(T)], value),
|
||||||
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;
|
|
||||||
},
|
|
||||||
else => @compileError("Ch3 WAVERAM: Unsupported write width"),
|
else => @compileError("Ch3 WAVERAM: Unsupported write width"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
fn read(self: *const Self, comptime T: type, addr: u32) T {
|
||||||
if (self.buf) |buf| {
|
if (self.buf) |buf| {
|
||||||
return switch (T) {
|
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])),
|
u32, u16, u8 => std.mem.readIntSliceLittle(T, buf[addr..][0..@sizeOf(T)]),
|
||||||
u16 => (@as(u16, buf[addr + 1]) << 8) | @as(u16, buf[addr]),
|
|
||||||
u8 => buf[addr],
|
|
||||||
else => @compileError("BIOS: Unsupported read width"),
|
else => @compileError("BIOS: Unsupported read width"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,7 @@ pub fn read(self: *const Self, comptime T: type, address: usize) T {
|
||||||
const addr = address & 0x3FFFF;
|
const addr = address & 0x3FFFF;
|
||||||
|
|
||||||
return switch (T) {
|
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])),
|
u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]),
|
||||||
u16 => (@as(u16, self.buf[addr + 1]) << 8) | @as(u16, self.buf[addr]),
|
|
||||||
u8 => self.buf[addr],
|
|
||||||
else => @compileError("EWRAM: Unsupported read width"),
|
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;
|
const addr = address & 0x3FFFF;
|
||||||
|
|
||||||
return switch (T) {
|
return switch (T) {
|
||||||
u32 => {
|
u32, u16, u8 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value),
|
||||||
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,
|
|
||||||
else => @compileError("EWRAM: Unsupported write width"),
|
else => @compileError("EWRAM: Unsupported write width"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ const Backup = @import("backup.zig").Backup;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const log = std.log.scoped(.GamePak);
|
const log = std.log.scoped(.GamePak);
|
||||||
|
|
||||||
const intToBytes = @import("../util.zig").intToBytes;
|
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
title: [12]u8,
|
title: [12]u8,
|
||||||
|
|
|
@ -25,9 +25,7 @@ pub fn read(self: *const Self, comptime T: type, address: usize) T {
|
||||||
const addr = address & 0x7FFF;
|
const addr = address & 0x7FFF;
|
||||||
|
|
||||||
return switch (T) {
|
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])),
|
u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]),
|
||||||
u16 => (@as(u16, self.buf[addr + 1]) << 8) | @as(u16, self.buf[addr]),
|
|
||||||
u8 => self.buf[addr],
|
|
||||||
else => @compileError("IWRAM: Unsupported read width"),
|
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;
|
const addr = address & 0x7FFF;
|
||||||
|
|
||||||
return switch (T) {
|
return switch (T) {
|
||||||
u32 => {
|
u32, u16, u8 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value),
|
||||||
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,
|
|
||||||
else => @compileError("IWRAM: Unsupported write width"),
|
else => @compileError("IWRAM: Unsupported write width"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ const log = std.log.scoped(.Backup);
|
||||||
|
|
||||||
const escape = @import("../util.zig").escape;
|
const escape = @import("../util.zig").escape;
|
||||||
const asString = @import("../util.zig").asString;
|
const asString = @import("../util.zig").asString;
|
||||||
const intToBytes = @import("../util.zig").intToBytes;
|
|
||||||
|
|
||||||
const backup_kinds = [5]Needle{
|
const backup_kinds = [5]Needle{
|
||||||
.{ .str = "EEPROM_V", .kind = .Eeprom },
|
.{ .str = "EEPROM_V", .kind = .Eeprom },
|
||||||
|
@ -411,18 +410,7 @@ const Eeprom = struct {
|
||||||
.Large => {
|
.Large => {
|
||||||
if (self.writer.len() == 14) {
|
if (self.writer.len() == 14) {
|
||||||
const addr = @intCast(u10, self.writer.finish());
|
const addr = @intCast(u10, self.writer.finish());
|
||||||
const value_buf = buf[@as(u13, addr) * 8 ..][0..8];
|
const value = std.mem.readIntSliceLittle(u64, 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
|
|
||||||
|
|
||||||
self.reader.configure(value);
|
self.reader.configure(value);
|
||||||
self.state = .RequestEnd;
|
self.state = .RequestEnd;
|
||||||
|
@ -432,18 +420,7 @@ const Eeprom = struct {
|
||||||
if (self.writer.len() == 6) {
|
if (self.writer.len() == 6) {
|
||||||
// FIXME: Duplicated code from above
|
// FIXME: Duplicated code from above
|
||||||
const addr = @intCast(u6, self.writer.finish());
|
const addr = @intCast(u6, self.writer.finish());
|
||||||
const value_buf = buf[@as(u13, addr) * 8 ..][0..8];
|
const value = std.mem.readIntSliceLittle(u64, 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
|
|
||||||
|
|
||||||
self.reader.configure(value);
|
self.reader.configure(value);
|
||||||
self.state = .RequestEnd;
|
self.state = .RequestEnd;
|
||||||
|
@ -471,7 +448,7 @@ const Eeprom = struct {
|
||||||
},
|
},
|
||||||
.WriteTransfer => {
|
.WriteTransfer => {
|
||||||
if (self.writer.len() == 64) {
|
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;
|
self.state = .RequestEnd;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -393,10 +393,8 @@ pub const Arm7tdmi = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skyWrite(buf: []u8, i: usize, num: u32) void {
|
fn skyWrite(buf: []u8, i: usize, num: u32) void {
|
||||||
buf[(@sizeOf(u32) * i) + 3] = @truncate(u8, num >> 24 & 0xFF);
|
const j = @sizeOf(u32) * i;
|
||||||
buf[(@sizeOf(u32) * i) + 2] = @truncate(u8, num >> 16 & 0xFF);
|
std.mem.writeIntSliceNative(u32, buf[j..(j + @sizeOf(u32))], num);
|
||||||
buf[(@sizeOf(u32) * i) + 1] = @truncate(u8, num >> 8 & 0xFF);
|
|
||||||
buf[(@sizeOf(u32) * i) + 0] = @truncate(u8, num >> 0 & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mgbaLog(self: *const Self, file: *const File, opcode: u32) !void {
|
fn mgbaLog(self: *const Self, file: *const File, opcode: u32) !void {
|
||||||
|
|
69
src/ppu.zig
69
src/ppu.zig
|
@ -11,7 +11,6 @@ const Bitfield = @import("bitfield").Bitfield;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const log = std.log.scoped(.PPU);
|
const log = std.log.scoped(.PPU);
|
||||||
const pollBlankingDma = @import("bus/dma.zig").pollBlankingDma;
|
const pollBlankingDma = @import("bus/dma.zig").pollBlankingDma;
|
||||||
const intToBytes = @import("util.zig").intToBytes;
|
|
||||||
|
|
||||||
/// This is used to generate byuu / Talurabi's Color Correction algorithm
|
/// This is used to generate byuu / Talurabi's Color Correction algorithm
|
||||||
const COLOUR_LUT = genColourLut();
|
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
|
// 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| {
|
for (self.scanline_buf) |maybe_px, i| {
|
||||||
const bgr555 = if (maybe_px) |px| px else self.palette.getBackdrop();
|
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
|
// 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
|
// 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| {
|
for (self.scanline_buf) |maybe_px, i| {
|
||||||
const bgr555 = if (maybe_px) |px| px else self.palette.getBackdrop();
|
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
|
// 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
|
// 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| {
|
for (self.scanline_buf) |maybe_px, i| {
|
||||||
const bgr555 = if (maybe_px) |px| px else self.palette.getBackdrop();
|
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
|
// Reset Current Scanline Pixel Buffer and list of fetched sprites
|
||||||
|
@ -350,7 +349,7 @@ pub const Ppu = struct {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < width) : (i += 1) {
|
while (i < width) : (i += 1) {
|
||||||
const bgr555 = self.vram.read(u16, vram_base + i * @sizeOf(u16));
|
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 => {
|
0x4 => {
|
||||||
|
@ -361,7 +360,7 @@ pub const Ppu = struct {
|
||||||
// Render Current Scanline
|
// Render Current Scanline
|
||||||
for (self.vram.buf[vram_base .. vram_base + width]) |byte, i| {
|
for (self.vram.buf[vram_base .. vram_base + width]) |byte, i| {
|
||||||
const bgr555 = self.palette.read(u16, @as(u16, byte) * @sizeOf(u16));
|
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 => {
|
0x5 => {
|
||||||
|
@ -378,7 +377,7 @@ pub const Ppu = struct {
|
||||||
const bgr555 =
|
const bgr555 =
|
||||||
if (scanline < m5_height and i < m5_width) self.vram.read(u16, vram_base + i * @sizeOf(u16)) else self.palette.getBackdrop();
|
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}),
|
else => std.debug.panic("[PPU] TODO: Implement BG Mode {}", .{bg_mode}),
|
||||||
|
@ -494,9 +493,7 @@ const Palette = struct {
|
||||||
const addr = address & 0x3FF;
|
const addr = address & 0x3FF;
|
||||||
|
|
||||||
return switch (T) {
|
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])),
|
u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]),
|
||||||
u16 => (@as(T, self.buf[addr + 1]) << 8) | @as(T, self.buf[addr]),
|
|
||||||
u8 => self.buf[addr],
|
|
||||||
else => @compileError("PALRAM: Unsupported read width"),
|
else => @compileError("PALRAM: Unsupported read width"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -505,22 +502,13 @@ const Palette = struct {
|
||||||
const addr = address & 0x3FF;
|
const addr = address & 0x3FF;
|
||||||
|
|
||||||
switch (T) {
|
switch (T) {
|
||||||
u32 => {
|
u32, u16 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value),
|
||||||
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 => {
|
u8 => {
|
||||||
const halfword: u16 = @as(u16, value) * 0x0101;
|
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);
|
std.mem.writeIntSliceLittle(u16, self.buf[weird_addr..(weird_addr + @sizeOf(u16))], halfword);
|
||||||
self.buf[real_addr + 0] = @truncate(u8, halfword >> 0);
|
|
||||||
},
|
},
|
||||||
else => @compileError("PALRAM: Unsupported write width"),
|
else => @compileError("PALRAM: Unsupported write width"),
|
||||||
}
|
}
|
||||||
|
@ -556,9 +544,7 @@ const Vram = struct {
|
||||||
const addr = Self.mirror(address);
|
const addr = Self.mirror(address);
|
||||||
|
|
||||||
return switch (T) {
|
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])),
|
u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]),
|
||||||
u16 => (@as(T, self.buf[addr + 1]) << 8) | @as(T, self.buf[addr]),
|
|
||||||
u8 => self.buf[addr],
|
|
||||||
else => @compileError("VRAM: Unsupported read width"),
|
else => @compileError("VRAM: Unsupported read width"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -568,16 +554,7 @@ const Vram = struct {
|
||||||
const addr = Self.mirror(address);
|
const addr = Self.mirror(address);
|
||||||
|
|
||||||
switch (T) {
|
switch (T) {
|
||||||
u32 => {
|
u32, u16 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value),
|
||||||
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 => {
|
u8 => {
|
||||||
// Ignore if write is in OBJ
|
// Ignore if write is in OBJ
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
@ -586,10 +563,9 @@ const Vram = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const halfword: u16 = @as(u16, value) * 0x0101;
|
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);
|
std.mem.writeIntSliceLittle(u16, self.buf[weird_addr..(weird_addr + @sizeOf(u16))], halfword);
|
||||||
self.buf[real_addr + 0] = @truncate(u8, halfword >> 0);
|
|
||||||
},
|
},
|
||||||
else => @compileError("VRAM: Unsupported write width"),
|
else => @compileError("VRAM: Unsupported write width"),
|
||||||
}
|
}
|
||||||
|
@ -630,9 +606,7 @@ const Oam = struct {
|
||||||
const addr = address & 0x3FF;
|
const addr = address & 0x3FF;
|
||||||
|
|
||||||
return switch (T) {
|
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])),
|
u32, u16, u8 => std.mem.readIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)]),
|
||||||
u16 => (@as(T, self.buf[addr + 1]) << 8) | @as(T, self.buf[addr]),
|
|
||||||
u8 => self.buf[addr],
|
|
||||||
else => @compileError("OAM: Unsupported read width"),
|
else => @compileError("OAM: Unsupported read width"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -641,16 +615,7 @@ const Oam = struct {
|
||||||
const addr = address & 0x3FF;
|
const addr = address & 0x3FF;
|
||||||
|
|
||||||
switch (T) {
|
switch (T) {
|
||||||
u32 => {
|
u32, u16 => std.mem.writeIntSliceLittle(T, self.buf[addr..][0..@sizeOf(T)], value),
|
||||||
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 => return, // 8-bit writes are explicitly ignored
|
u8 => return, // 8-bit writes are explicitly ignored
|
||||||
else => @compileError("OAM: Unsupported write width"),
|
else => @compileError("OAM: Unsupported write width"),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue