Compare commits
3 Commits
e96be7b18a
...
ed72427c71
Author | SHA1 | Date |
---|---|---|
Rekai Nyangadzayi Musuka | ed72427c71 | |
Rekai Nyangadzayi Musuka | 7f98f4cc26 | |
Rekai Nyangadzayi Musuka | 51076597e8 |
|
@ -7,3 +7,6 @@
|
|||
[submodule "lib/arm32"]
|
||||
path = lib/arm32
|
||||
url = https://git.musuka.dev/paoda/arm32.git
|
||||
[submodule "lib/zba-gdbstub"]
|
||||
path = lib/zba-gdbstub
|
||||
url = https://git.musuka.dev/paoda/zba-gdbstub
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
const std = @import("std");
|
||||
|
||||
const Sdk = @import("lib/SDL.zig/Sdk.zig");
|
||||
const Sdk = @import("lib/SDL.zig/build.zig");
|
||||
const zgui = @import("lib/zgui/build.zig");
|
||||
const arm32 = @import("lib/arm32/build.zig");
|
||||
const gdbstub = @import("lib/zba-gdbstub/build.zig");
|
||||
|
||||
// Although this function looks imperative, note that its job is to
|
||||
// declaratively construct a build graph that will be executed by an external
|
||||
|
@ -29,6 +30,7 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
|
||||
exe.addModule("arm32", arm32.module(b));
|
||||
exe.addModule("gdbstub", gdbstub.module(b));
|
||||
exe.addModule("zig-clap", b.dependency("zig-clap", .{}).module("clap"));
|
||||
|
||||
exe.addAnonymousModule("bitfield", .{ .source_file = .{ .path = "lib/bitfield.zig" } }); // https://github.com/FlorenceOS/
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit aad3bdc9ea44792906a6cff9e28c15cd4e143389
|
||||
Subproject commit 580e7baca962dd73815bb4717db05b83d55fd58e
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 479319e7cad78c3fd38b6865c56e9fe9e78d495c
|
|
@ -368,3 +368,38 @@ pub fn handleInterrupt(comptime proc: System.Process, cpu: *System.Cpu(proc)) vo
|
|||
cpu.r[15] = if (proc == .nds9) 0xFFFF_0018 else 0x0000_0018;
|
||||
cpu.pipe.reload(cpu);
|
||||
}
|
||||
|
||||
pub fn fastBoot(system: System) void {
|
||||
{
|
||||
const Bank = System.Arm946es.Bank;
|
||||
|
||||
const cpu = system.arm946es;
|
||||
|
||||
// from advanDS
|
||||
cpu.spsr = .{ .raw = 0x0000_000DF };
|
||||
|
||||
@memset(cpu.r[0..12], 0x0000_0000); // r0 -> r11 are zeroed
|
||||
// TODO: r12, r14, and r15 are set to the entrypoint?
|
||||
cpu.r[13] = 0x0300_2F7C; // FIXME: Why is there (!) in GBATEK?
|
||||
cpu.bank.r[Bank.regIdx(.Irq, .R13)] = 0x0300_3F80;
|
||||
cpu.bank.r[Bank.regIdx(.Supervisor, .R13)] = 0x0300_3FC0;
|
||||
cpu.bank.spsr[Bank.spsrIdx(.Irq)] = .{ .raw = 0x0000_0000 };
|
||||
cpu.bank.spsr[Bank.spsrIdx(.Supervisor)] = .{ .raw = 0x0000_0000 };
|
||||
}
|
||||
{
|
||||
const Bank = System.Arm7tdmi.Bank;
|
||||
|
||||
const cpu = system.arm7tdmi;
|
||||
|
||||
// from advanDS
|
||||
cpu.spsr = .{ .raw = 0x0000_000D3 };
|
||||
|
||||
@memset(cpu.r[0..12], 0x0000_0000); // r0 -> r11 are zeroed
|
||||
// TODO: r12, r14, and r15 are set to the entrypoint?
|
||||
cpu.r[13] = 0x0380_FD80;
|
||||
cpu.bank.r[Bank.regIdx(.Irq, .R13)] = 0x0380_FF80;
|
||||
cpu.bank.r[Bank.regIdx(.Supervisor, .R13)] = 0x0380_FFC0;
|
||||
cpu.bank.spsr[Bank.spsrIdx(.Irq)] = .{ .raw = 0x0000_0000 };
|
||||
cpu.bank.spsr[Bank.spsrIdx(.Supervisor)] = .{ .raw = 0x0000_0000 };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
0x0400_0214 => bus.io.irq.raw,
|
||||
|
||||
0x0410_0000 => bus.io.shr.ipc.recv(.nds7),
|
||||
else => 0, // warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
else => warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
},
|
||||
u16 => switch (address) {
|
||||
0x0400_0004 => bus.io.ppu.?.nds7.dispstat.raw,
|
||||
|
@ -78,7 +78,7 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
0x0400_0130 => bus.io.shr.keyinput.load(.Monotonic),
|
||||
0x0400_0180 => @truncate(bus.io.shr.ipc._nds7.sync.raw),
|
||||
0x0400_0184 => @truncate(bus.io.shr.ipc._nds7.cnt.raw),
|
||||
else => 0, // warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
else => warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
},
|
||||
u8 => switch (address) {
|
||||
// DMA Transfers
|
||||
|
@ -87,11 +87,14 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
// Timers
|
||||
0x0400_0100...0x0400_010F => warn("TODO: impl timer", .{}),
|
||||
|
||||
// RTC
|
||||
0x0400_0138 => warn("TODO: RTC read", .{}),
|
||||
|
||||
0x0400_0240 => bus.vram.stat().raw,
|
||||
0x0400_0241 => bus.io.shr.wramcnt.raw,
|
||||
|
||||
0x0400_0300 => @intFromEnum(bus.io.postflg),
|
||||
else => 0, // warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
else => warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
},
|
||||
else => @compileError(T ++ " is an unsupported bus read type"),
|
||||
};
|
||||
|
@ -112,9 +115,11 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
0x0400_0214 => bus.io.irq.raw &= ~value,
|
||||
|
||||
0x0400_0188 => bus.io.shr.ipc.send(.nds7, value),
|
||||
else => {}, // log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }),
|
||||
else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }),
|
||||
},
|
||||
u16 => switch (address) {
|
||||
0x0400_0004 => bus.io.ppu.?.nds7.dispstat.raw = value,
|
||||
|
||||
// DMA Transfers
|
||||
0x0400_00B0...0x0400_00DE => dma.write(T, &bus.dma, address, value),
|
||||
|
||||
|
@ -125,7 +130,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
0x0400_0184 => bus.io.shr.ipc.setIpcFifoCnt(.nds7, value),
|
||||
|
||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||
else => {}, // log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>4})", .{ T, address, value }),
|
||||
else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>4})", .{ T, address, value }),
|
||||
},
|
||||
u8 => switch (address) {
|
||||
// DMA Transfers
|
||||
|
@ -134,6 +139,9 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
// Timers
|
||||
0x0400_0100...0x0400_010F => log.warn("TODO: impl timer", .{}),
|
||||
|
||||
// RTC
|
||||
0x0400_0138 => log.warn("TODO: RTC write", .{}),
|
||||
|
||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||
|
||||
0x0400_0301 => switch ((value >> 6) & 0b11) {
|
||||
|
@ -144,7 +152,7 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
log.err("TODO: Implement {}", .{tag});
|
||||
},
|
||||
},
|
||||
else => {}, // log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>2})", .{ T, address, value }),
|
||||
else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>2})", .{ T, address, value }),
|
||||
},
|
||||
else => @compileError(T ++ " is an unsupported bus write type"),
|
||||
}
|
||||
|
|
|
@ -77,11 +77,12 @@ fn _read(self: *@This(), comptime T: type, comptime mode: Mode, address: u32) T
|
|||
}
|
||||
|
||||
return switch (aligned_addr) {
|
||||
0x0200_0000...0x02FF_FFFF => readInt(T, self.main[aligned_addr & 0x003F_FFFF ..][0..byte_count]),
|
||||
0x0200_0000...0x02FF_FFFF => readInt(T, self.main[aligned_addr & (4 * MiB - 1) ..][0..byte_count]),
|
||||
0x0300_0000...0x03FF_FFFF => self.wram.read(T, .nds9, aligned_addr),
|
||||
0x0400_0000...0x04FF_FFFF => io.read(self, T, aligned_addr),
|
||||
0x0500_0000...0x05FF_FFFF => readInt(T, self.makeshift_palram[aligned_addr & (2 * KiB - 1) ..][0..@sizeOf(T)]),
|
||||
0x0600_0000...0x06FF_FFFF => self.ppu.vram.read(T, .nds9, aligned_addr),
|
||||
0x0700_0000...0x07FF_FFFF => readInt(T, self.ppu.oam.buf[aligned_addr & (2 * KiB - 1) ..][0..byte_count]),
|
||||
0xFFFF_0000...0xFFFF_FFFF => self.bios.read(T, address),
|
||||
else => warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
};
|
||||
|
@ -108,11 +109,12 @@ fn _write(self: *@This(), comptime T: type, comptime mode: Mode, address: u32, v
|
|||
}
|
||||
|
||||
switch (aligned_addr) {
|
||||
0x0200_0000...0x02FF_FFFF => writeInt(T, self.main[aligned_addr & 0x003F_FFFF ..][0..byte_count], value),
|
||||
0x0200_0000...0x02FF_FFFF => writeInt(T, self.main[aligned_addr & (4 * MiB - 1) ..][0..byte_count], value),
|
||||
0x0300_0000...0x03FF_FFFF => self.wram.write(T, .nds9, aligned_addr, value),
|
||||
0x0400_0000...0x04FF_FFFF => io.write(self, T, aligned_addr, value),
|
||||
0x0500_0000...0x05FF_FFFF => writeInt(T, self.makeshift_palram[aligned_addr & (2 * KiB - 1) ..][0..@sizeOf(T)], value),
|
||||
0x0600_0000...0x06FF_FFFF => self.ppu.vram.write(T, .nds9, aligned_addr, value),
|
||||
0x0700_0000...0x07FF_FFFF => writeInt(T, self.ppu.oam.buf[aligned_addr & (2 * KiB - 1) ..][0..@sizeOf(T)], value),
|
||||
0xFFFF_0000...0xFFFF_FFFF => self.bios.write(T, address, value),
|
||||
else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }),
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ const log = std.log.scoped(.cp15);
|
|||
|
||||
const panic_on_unimplemented: bool = false;
|
||||
|
||||
control: u32 = 0x0005_2078,
|
||||
control: u32 = 0x0001_2078,
|
||||
dtcm_size_base: u32 = 0x0300_000A,
|
||||
itcm_size_base: u32 = 0x0000_0020,
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ fn Controller(comptime id: u2) type {
|
|||
const start_timing: Kind = @enumFromInt(new.start_timing.read());
|
||||
|
||||
switch (start_timing) {
|
||||
.immediate, .vblank => {},
|
||||
.immediate, .vblank, .hblank => {},
|
||||
else => log.err("TODO: Implement DMA({}) {s} mode", .{ id, @tagName(start_timing) }),
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,14 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
0x0400_0210 => bus.io.ie.raw,
|
||||
0x0400_0214 => bus.io.irq.raw,
|
||||
|
||||
// zig fmt: off
|
||||
0x0400_0240 => @as(u32, bus.ppu.vram.io.cnt_d.raw) << 24
|
||||
| @as(u32, bus.ppu.vram.io.cnt_c.raw) << 16
|
||||
| @as(u32, bus.ppu.vram.io.cnt_b.raw) << 8
|
||||
| bus.ppu.vram.io.cnt_a.raw << 0,
|
||||
// zig fmt: on
|
||||
|
||||
0x0400_0280 => bus.io.div.cnt.raw,
|
||||
0x0400_02A0, 0x0400_02A4 => @truncate(bus.io.div.result >> shift(u64, address)),
|
||||
0x0400_02A8, 0x0400_02AC => @truncate(bus.io.div.remainder >> shift(u64, address)),
|
||||
0x0400_02B4 => @truncate(bus.io.sqrt.result),
|
||||
|
@ -77,6 +85,8 @@ pub fn read(bus: *const Bus, comptime T: type, address: u32) T {
|
|||
else => warn("unexpected: read(T: {}, addr: 0x{X:0>8}) {} ", .{ T, address, T }),
|
||||
},
|
||||
u16 => switch (address) {
|
||||
0x0400_0006 => bus.ppu.io.nds9.vcount.raw,
|
||||
|
||||
// DMA Transfers
|
||||
0x0400_00B0...0x0400_00DE => dma.read(T, &bus.dma, address) orelse 0x0000,
|
||||
0x0400_00E0...0x0400_00EE => std.mem.readIntLittle(T, bus.io.dma_fill[address & 0xF ..][0..@sizeOf(T)]),
|
||||
|
@ -131,6 +141,32 @@ const subset = @import("../../util.zig").subset;
|
|||
pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
||||
switch (T) {
|
||||
u32 => switch (address) {
|
||||
0x0400_0000 => bus.ppu.engines[0].dispcnt.raw = value,
|
||||
0x0400_0004 => bus.ppu.io.nds9.dispstat.raw = @truncate(value),
|
||||
0x0400_0008 => {
|
||||
bus.ppu.engines[0].bg[0].cnt.raw = @truncate(value >> 0); // 0x0400_0008
|
||||
bus.ppu.engines[0].bg[1].cnt.raw = @truncate(value >> 16); // 0x0400_000A
|
||||
},
|
||||
0x0400_000C => {
|
||||
bus.ppu.engines[0].bg[2].cnt.raw = @truncate(value >> 0); // 0x0400_000A
|
||||
bus.ppu.engines[0].bg[3].cnt.raw = @truncate(value >> 16); // 0x0400_000C
|
||||
},
|
||||
0x00400_0010 => {
|
||||
bus.ppu.engines[0].bg[0].hofs.raw = @truncate(value >> 0); // 0x0400_0010
|
||||
bus.ppu.engines[0].bg[0].vofs.raw = @truncate(value >> 16); // 0x0400_0012
|
||||
},
|
||||
0x00400_0014 => {
|
||||
bus.ppu.engines[0].bg[1].hofs.raw = @truncate(value >> 0); // 0x0400_0014
|
||||
bus.ppu.engines[0].bg[1].vofs.raw = @truncate(value >> 16); // 0x0400_0016
|
||||
},
|
||||
0x00400_0018 => {
|
||||
bus.ppu.engines[0].bg[2].hofs.raw = @truncate(value >> 0); // 0x0400_0018
|
||||
bus.ppu.engines[0].bg[2].vofs.raw = @truncate(value >> 16); // 0x0400_001A
|
||||
},
|
||||
0x00400_001C => {
|
||||
bus.ppu.engines[0].bg[3].hofs.raw = @truncate(value >> 0); // 0x0400_001C
|
||||
bus.ppu.engines[0].bg[3].vofs.raw = @truncate(value >> 16); // 0x0400_001E
|
||||
},
|
||||
|
||||
// DMA Transfers
|
||||
0x0400_00B0...0x0400_00DC => dma.write(T, &bus.dma, address, value),
|
||||
|
@ -139,21 +175,36 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
// Timers
|
||||
0x0400_0100...0x0400_010C => log.warn("TODO: impl timer", .{}),
|
||||
|
||||
0x0400_0000 => bus.ppu.engines[0].dispcnt.raw = value,
|
||||
0x0400_0180 => bus.io.shr.ipc.setIpcSync(.nds9, value),
|
||||
0x0400_0184 => bus.io.shr.ipc.setIpcFifoCnt(.nds9, value),
|
||||
0x0400_0188 => bus.io.shr.ipc.send(.nds9, value),
|
||||
|
||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||
0x0400_0210 => bus.io.ie.raw = value,
|
||||
0x0400_0214 => bus.io.irq.raw &= ~value,
|
||||
|
||||
0x0400_0240 => {
|
||||
bus.ppu.vram.io.cnt_a.raw = @truncate(value >> 0); // 0x0400_0240
|
||||
bus.ppu.vram.io.cnt_b.raw = @truncate(value >> 8); // 0x0400_0241
|
||||
bus.ppu.vram.io.cnt_c.raw = @truncate(value >> 16); // 0x0400_0242
|
||||
bus.ppu.vram.io.cnt_d.raw = @truncate(value >> 24); // 0x0400_0243
|
||||
|
||||
bus.ppu.vram.update();
|
||||
},
|
||||
0x0400_0244 => {
|
||||
bus.ppu.vram.io.cnt_e.raw = @truncate(value >> 0); // 0x0400_0244
|
||||
bus.ppu.vram.io.cnt_f.raw = @truncate(value >> 8); // 0x0400_0245
|
||||
bus.ppu.vram.io.cnt_g.raw = @truncate(value >> 16); // 0x0400_0246
|
||||
bus.io.shr.wramcnt.raw = @truncate(value >> 24); // 0x0400_0247
|
||||
|
||||
bus.ppu.vram.update();
|
||||
bus.wram.update(bus.io.shr.wramcnt);
|
||||
},
|
||||
|
||||
0x0400_0208 => bus.io.ime = value & 1 == 1,
|
||||
0x0400_0210 => bus.io.ie.raw = value,
|
||||
0x0400_0214 => bus.io.irq.raw &= ~value,
|
||||
0x0400_0280 => {
|
||||
bus.io.div.cnt.raw = value;
|
||||
bus.io.div.schedule(bus.scheduler);
|
||||
},
|
||||
|
||||
0x0400_0290, 0x0400_0294 => {
|
||||
bus.io.div.numerator = subset(u64, u32, address, bus.io.div.numerator, value);
|
||||
|
@ -165,6 +216,11 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
bus.io.div.schedule(bus.scheduler);
|
||||
},
|
||||
|
||||
0x0400_02B0 => {
|
||||
bus.io.sqrt.cnt.raw = value;
|
||||
bus.io.sqrt.schedule(bus.scheduler);
|
||||
},
|
||||
|
||||
0x0400_02B8, 0x0400_02BC => {
|
||||
bus.io.sqrt.param = subset(u64, u32, address, bus.io.sqrt.param, value);
|
||||
bus.io.sqrt.schedule(bus.scheduler);
|
||||
|
@ -174,6 +230,30 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void {
|
|||
0x0400_0304 => bus.ppu.io.powcnt.raw = value,
|
||||
|
||||
0x0400_1000 => bus.ppu.engines[1].dispcnt.raw = value,
|
||||
0x0400_1008 => {
|
||||
bus.ppu.engines[1].bg[0].cnt.raw = @truncate(value >> 0); // 0x0400_1008
|
||||
bus.ppu.engines[1].bg[1].cnt.raw = @truncate(value >> 16); // 0x0400_100A
|
||||
},
|
||||
0x0400_100C => {
|
||||
bus.ppu.engines[1].bg[2].cnt.raw = @truncate(value >> 0); // 0x0400_100A
|
||||
bus.ppu.engines[1].bg[3].cnt.raw = @truncate(value >> 16); // 0x0400_100C
|
||||
},
|
||||
0x00400_1010 => {
|
||||
bus.ppu.engines[1].bg[0].hofs.raw = @truncate(value >> 0); // 0x0400_1010
|
||||
bus.ppu.engines[1].bg[0].vofs.raw = @truncate(value >> 16); // 0x0400_1012
|
||||
},
|
||||
0x00400_1014 => {
|
||||
bus.ppu.engines[1].bg[1].hofs.raw = @truncate(value >> 0); // 0x0400_1014
|
||||
bus.ppu.engines[1].bg[1].vofs.raw = @truncate(value >> 16); // 0x0400_1016
|
||||
},
|
||||
0x00400_1018 => {
|
||||
bus.ppu.engines[1].bg[2].hofs.raw = @truncate(value >> 0); // 0x0400_1018
|
||||
bus.ppu.engines[1].bg[2].vofs.raw = @truncate(value >> 16); // 0x0400_101A
|
||||
},
|
||||
0x00400_101C => {
|
||||
bus.ppu.engines[1].bg[3].hofs.raw = @truncate(value >> 0); // 0x0400_101C
|
||||
bus.ppu.engines[1].bg[3].vofs.raw = @truncate(value >> 16); // 0x0400_101E
|
||||
},
|
||||
|
||||
else => log.warn("unexpected: write(T: {}, addr: 0x{X:0>8}, value: 0x{X:0>8})", .{ T, address, value }),
|
||||
},
|
||||
|
|
|
@ -5,6 +5,8 @@ const Scheduler = @import("Scheduler.zig");
|
|||
const System = @import("emu.zig").System;
|
||||
|
||||
const Vram = @import("ppu/Vram.zig");
|
||||
const Oam = @import("ppu/Oam.zig");
|
||||
|
||||
const EngineA = @import("ppu/engine.zig").EngineA;
|
||||
const EngineB = @import("ppu/engine.zig").EngineB;
|
||||
|
||||
|
@ -24,6 +26,9 @@ pub const Ppu = struct {
|
|||
|
||||
vram: *Vram,
|
||||
|
||||
// FIXME: do I need a pointer here?
|
||||
oam: *Oam,
|
||||
|
||||
engines: struct { EngineA, EngineB },
|
||||
|
||||
io: Io = .{},
|
||||
|
@ -49,12 +54,19 @@ pub const Ppu = struct {
|
|||
.fb = try FrameBuffer.init(allocator),
|
||||
.engines = .{ try EngineA.init(allocator), try EngineB.init(allocator) },
|
||||
.vram = vram,
|
||||
.oam = blk: {
|
||||
var oam = try allocator.create(Oam);
|
||||
oam.init();
|
||||
|
||||
break :blk oam;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: @This(), allocator: Allocator) void {
|
||||
self.fb.deinit(allocator);
|
||||
inline for (self.engines) |eng| eng.deinit(allocator);
|
||||
allocator.destroy(self.oam);
|
||||
}
|
||||
|
||||
pub fn drawScanline(self: *@This(), bus: *System.Bus9) void {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
const KiB = 0x400;
|
||||
|
||||
buf: [2 * KiB]u8,
|
||||
|
||||
pub fn init(self: *@This()) void {
|
||||
@memset(self.buf[0..], 0);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
const std = @import("std");
|
||||
const Server = @import("gdbstub").Server;
|
||||
const Interface = @import("gdbstub").Emulator;
|
||||
const System = @import("core/emu.zig").System;
|
||||
const Scheduler = @import("core/Scheduler.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const TurboWrapper = struct {
|
||||
system: System,
|
||||
scheduler: *Scheduler,
|
||||
|
||||
pub fn init(system: System, scheduler: *Scheduler) @This() {
|
||||
return .{ .system = system, .scheduler = scheduler };
|
||||
}
|
||||
|
||||
pub fn interface(self: *@This(), allocator: Allocator) Interface {
|
||||
return Interface.init(allocator, self);
|
||||
}
|
||||
|
||||
pub fn read(self: *const @This(), addr: u32) u8 {
|
||||
return self.cpu.bus.dbgRead(u8, addr);
|
||||
}
|
||||
|
||||
pub fn write(self: *@This(), addr: u32, value: u8) void {
|
||||
self.cpu.bus.dbgWrite(u8, addr, value);
|
||||
}
|
||||
|
||||
pub fn registers(self: *const @This()) *[16]u32 {
|
||||
return &self.cpu.r;
|
||||
}
|
||||
|
||||
pub fn cpsr(self: *const @This()) u32 {
|
||||
return self.cpu.cpsr.raw;
|
||||
}
|
||||
|
||||
pub fn step(self: *@This()) void {
|
||||
_ = self;
|
||||
|
||||
@panic("TODO: Handle ARM7 and ARM9 lol");
|
||||
}
|
||||
};
|
|
@ -14,6 +14,7 @@ const ClapResult = clap.Result(clap.Help, &cli_params, clap.parsers.default);
|
|||
const cli_params = clap.parseParamsComptime(
|
||||
\\-h, --help Display this help and exit.
|
||||
\\-f, --firm <str> Path to NDS Firmware Directory
|
||||
\\--gdb Run Turbo in GDB Mode
|
||||
\\<str> Path to the NDS ROM
|
||||
\\
|
||||
);
|
||||
|
@ -65,6 +66,8 @@ pub fn main() !void {
|
|||
const rom_title = try emu.load(allocator, system, rom_path);
|
||||
if (firm_path) |path| try emu.loadFirm(allocator, system, path);
|
||||
|
||||
emu.fastBoot(system);
|
||||
|
||||
var ui = try Ui.init(allocator);
|
||||
defer ui.deinit(allocator);
|
||||
|
||||
|
|
Loading…
Reference in New Issue