feat(bus): emu is now able to read from user-provided BIOS
This commit is contained in:
parent
d50aff30c9
commit
f030889d6c
12
src/bus.zig
12
src/bus.zig
|
@ -1,21 +1,25 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const GamePak = @import("pak.zig").GamePak;
|
const Bios = @import("bus/bios.zig").Bios;
|
||||||
|
const GamePak = @import("bus/pak.zig").GamePak;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
pub const Bus = struct {
|
pub const Bus = struct {
|
||||||
pak: GamePak,
|
pak: GamePak,
|
||||||
|
bios: Bios,
|
||||||
|
|
||||||
pub fn withPak(alloc: Allocator, path: []const u8) !@This() {
|
pub fn withPak(alloc: Allocator, path: []const u8) !@This() {
|
||||||
return @This(){
|
return @This(){
|
||||||
.pak = try GamePak.fromPath(alloc, path),
|
.pak = try GamePak.fromPath(alloc, path),
|
||||||
|
// TODO: don't hardcode this + bundle open-sorce Boot ROM
|
||||||
|
.bios = try Bios.fromPath(alloc, "./bin/gba_bios.bin"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read32(self: *const @This(), addr: u32) u32 {
|
pub fn read32(self: *const @This(), addr: u32) u32 {
|
||||||
return switch (addr) {
|
return switch (addr) {
|
||||||
// General Internal Memory
|
// General Internal Memory
|
||||||
0x0000_0000...0x0000_3FFF => std.debug.panic("read32 from 0x{X:} in BIOS", .{addr}),
|
0x0000_0000...0x0000_3FFF => self.bios.get32(@as(usize, addr)),
|
||||||
0x0200_0000...0x0203FFFF => std.debug.panic("read32 from 0x{X:} in IWRAM", .{addr}),
|
0x0200_0000...0x0203FFFF => std.debug.panic("read32 from 0x{X:} in IWRAM", .{addr}),
|
||||||
0x0300_0000...0x0300_7FFF => std.debug.panic("read32 from 0x{X:} in EWRAM", .{addr}),
|
0x0300_0000...0x0300_7FFF => std.debug.panic("read32 from 0x{X:} in EWRAM", .{addr}),
|
||||||
0x0400_0000...0x0400_03FE => std.debug.panic("read32 from 0x{X:} in I/O", .{addr}),
|
0x0400_0000...0x0400_03FE => std.debug.panic("read32 from 0x{X:} in I/O", .{addr}),
|
||||||
|
@ -58,7 +62,7 @@ pub const Bus = struct {
|
||||||
pub fn read16(self: *const @This(), addr: u32) u16 {
|
pub fn read16(self: *const @This(), addr: u32) u16 {
|
||||||
return switch (addr) {
|
return switch (addr) {
|
||||||
// General Internal Memory
|
// General Internal Memory
|
||||||
0x0000_0000...0x0000_3FFF => std.debug.panic("read16 from 0x{X:} in BIOS", .{addr}),
|
0x0000_0000...0x0000_3FFF => self.bios.get16(@as(usize, addr)),
|
||||||
0x0200_0000...0x0203FFFF => std.debug.panic("read16 from 0x{X:} in IWRAM", .{addr}),
|
0x0200_0000...0x0203FFFF => std.debug.panic("read16 from 0x{X:} in IWRAM", .{addr}),
|
||||||
0x0300_0000...0x0300_7FFF => std.debug.panic("read16 from 0x{X:} in EWRAM", .{addr}),
|
0x0300_0000...0x0300_7FFF => std.debug.panic("read16 from 0x{X:} in EWRAM", .{addr}),
|
||||||
0x0400_0000...0x0400_03FE => std.debug.panic("read16 from 0x{X:} in I/O", .{addr}),
|
0x0400_0000...0x0400_03FE => std.debug.panic("read16 from 0x{X:} in I/O", .{addr}),
|
||||||
|
@ -101,7 +105,7 @@ pub const Bus = struct {
|
||||||
pub fn read8(self: *const @This(), addr: u32) u8 {
|
pub fn read8(self: *const @This(), addr: u32) u8 {
|
||||||
return switch (addr) {
|
return switch (addr) {
|
||||||
// General Internal Memory
|
// General Internal Memory
|
||||||
0x0000_0000...0x0000_3FFF => std.debug.panic("read8 from 0x{X:} in BIOS", .{addr}),
|
0x0000_0000...0x0000_3FFF => self.bios.get8(@as(usize, addr)),
|
||||||
0x0200_0000...0x0203FFFF => std.debug.panic("read8 from 0x{X:} in IWRAM", .{addr}),
|
0x0200_0000...0x0203FFFF => std.debug.panic("read8 from 0x{X:} in IWRAM", .{addr}),
|
||||||
0x0300_0000...0x0300_7FFF => std.debug.panic("read8 from 0x{X:} in EWRAM", .{addr}),
|
0x0300_0000...0x0300_7FFF => std.debug.panic("read8 from 0x{X:} in EWRAM", .{addr}),
|
||||||
0x0400_0000...0x0400_03FE => std.debug.panic("read8 from 0x{X:} in I/O", .{addr}),
|
0x0400_0000...0x0400_03FE => std.debug.panic("read8 from 0x{X:} in I/O", .{addr}),
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
pub const Bios = struct {
|
||||||
|
buf: []u8,
|
||||||
|
|
||||||
|
pub fn fromPath(alloc: Allocator, path: []const u8) !@This() {
|
||||||
|
const file = try std.fs.cwd().openFile(path, .{ .read = true });
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
const len = try file.getEndPos();
|
||||||
|
|
||||||
|
return @This(){
|
||||||
|
.buf = try file.readToEndAlloc(alloc, len),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn get32(self: *const @This(), idx: usize) u32 {
|
||||||
|
return (@as(u32, self.buf[idx + 3]) << 24) | (@as(u32, self.buf[idx + 2]) << 16) | (@as(u32, self.buf[idx + 1]) << 8) | (@as(u32, self.buf[idx]));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn get16(self: *const @This(), idx: usize) u16 {
|
||||||
|
return (@as(u16, self.buf[idx + 1]) << 8) | @as(u16, self.buf[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn get8(self: *const @This(), idx: usize) u8 {
|
||||||
|
return self.buf[idx];
|
||||||
|
}
|
||||||
|
};
|
|
@ -26,6 +26,7 @@ pub const Arm7tdmi = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn step(self: *@This()) u64 {
|
pub inline fn step(self: *@This()) u64 {
|
||||||
|
std.debug.print("PC: 0x{X:} ", .{self.r[15]});
|
||||||
const opcode = self.fetch();
|
const opcode = self.fetch();
|
||||||
std.debug.print("opcode: 0x{X:}\n", .{opcode}); // Debug
|
std.debug.print("opcode: 0x{X:}\n", .{opcode}); // Debug
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue