chore: refactor scheduler + nds7/nds9 group structs

This commit is contained in:
Rekai Nyangadzayi Musuka 2023-09-26 23:25:36 -05:00
parent 2f06f178e2
commit d90cd699b6
12 changed files with 128 additions and 221 deletions

@ -1 +1 @@
Subproject commit 106820b444cf394f2887b44a2afbfb2c01b182ca Subproject commit 481271ba2abcaab82b0930a10d424134099143c8

View File

@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const Bus = @import("Bus.zig"); const Bus9 = @import("nds9/Bus.zig");
const Bus7 = @import("nds7/Bus.zig");
const PriorityQueue = std.PriorityQueue(Event, void, Event.lessThan); const PriorityQueue = std.PriorityQueue(Event, void, Event.lessThan);
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@ -27,22 +28,30 @@ pub fn now(self: @This()) u64 {
return self.tick; return self.tick;
} }
pub fn next(self: @This()) u64 {
@setRuntimeSafety(false);
return self.queue.items[0].tick;
}
pub fn reset(self: *@This()) void { pub fn reset(self: *@This()) void {
self.tick = 0; self.tick = 0;
} }
pub fn handle(self: *@This(), bus: *Bus) void { pub inline fn check(self: *@This()) ?Event {
const event = self.queue.remove(); @setRuntimeSafety(false);
const late = self.tick - event.tick; if (self.tick < self.queue.items[0].tick) return null;
return self.queue.remove();
}
pub fn handle(self: *@This(), bus_ptr: ?*anyopaque, event: Event, late: u64) void {
switch (event.kind) { switch (event.kind) {
.heat_death => unreachable, .heat_death => unreachable,
.nds7 => |ev| {
const bus: *Bus7 = @ptrCast(@alignCast(bus_ptr));
_ = bus;
switch (ev) {}
},
.nds9 => |ev| {
const bus: *Bus9 = @ptrCast(@alignCast(bus_ptr));
switch (ev) {
.draw => { .draw => {
bus.ppu.drawScanline(bus); bus.ppu.drawScanline(bus);
bus.ppu.onHdrawEnd(self, late); bus.ppu.onHdrawEnd(self, late);
@ -50,17 +59,21 @@ pub fn handle(self: *@This(), bus: *Bus) void {
.hblank => bus.ppu.onHblankEnd(self, late), .hblank => bus.ppu.onHblankEnd(self, late),
.vblank => bus.ppu.onHblankEnd(self, late), .vblank => bus.ppu.onHblankEnd(self, late),
} }
},
}
} }
pub const Event = struct { pub const Event = struct {
tick: u64, tick: u64,
kind: Kind, kind: Kind,
pub const Kind = enum { const Kind7 = enum {};
heat_death, const Kind9 = enum { draw, hblank, vblank };
draw,
hblank, pub const Kind = union(enum) {
vblank, nds7: Kind7,
nds9: Kind9,
heat_death: void,
}; };
fn lessThan(_: void, left: @This(), right: @This()) std.math.Order { fn lessThan(_: void, left: @This(), right: @This()) std.math.Order {

View File

@ -1,17 +1,15 @@
const std = @import("std"); const std = @import("std");
const nds9 = @import("nds9.zig");
const nds7 = @import("nds7.zig");
const Header = @import("cartridge.zig").Header; const Header = @import("cartridge.zig").Header;
const SharedIo = @import("io.zig").Io; const SharedIo = @import("io.zig").Io;
const Arm946es = nds9.Arm946es; const Scheduler = @import("Scheduler.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
/// Load a NDS Cartridge /// Load a NDS Cartridge
/// ///
/// intended to be used immediately after Emulator initialization /// intended to be used immediately after Emulator initialization
pub fn load(allocator: Allocator, nds7_group: nds7.Group, nds9_group: nds9.Group, rom_file: std.fs.File) ![12]u8 { pub fn load(allocator: Allocator, system: System, rom_file: std.fs.File) ![12]u8 {
const log = std.log.scoped(.load_rom); const log = std.log.scoped(.load_rom);
const rom_buf = try rom_file.readToEndAlloc(allocator, try rom_file.getEndPos()); const rom_buf = try rom_file.readToEndAlloc(allocator, try rom_file.getEndPos());
@ -26,8 +24,6 @@ pub fn load(allocator: Allocator, nds7_group: nds7.Group, nds9_group: nds9.Group
// Dealing with the ARM946E-S // Dealing with the ARM946E-S
{ {
const arm946es = nds9_group.cpu;
log.debug("ARM9 ROM Offset: 0x{X:0>8}", .{header.arm9_rom_offset}); log.debug("ARM9 ROM Offset: 0x{X:0>8}", .{header.arm9_rom_offset});
log.debug("ARM9 Entry Address: 0x{X:0>8}", .{header.arm9_entry_address}); log.debug("ARM9 Entry Address: 0x{X:0>8}", .{header.arm9_entry_address});
log.debug("ARM9 RAM Address: 0x{X:0>8}", .{header.arm9_ram_address}); log.debug("ARM9 RAM Address: 0x{X:0>8}", .{header.arm9_ram_address});
@ -36,16 +32,14 @@ pub fn load(allocator: Allocator, nds7_group: nds7.Group, nds9_group: nds9.Group
// Copy ARM9 Code into Main Memory // Copy ARM9 Code into Main Memory
for (rom_buf[header.arm9_rom_offset..][0..header.arm9_size], 0..) |value, i| { for (rom_buf[header.arm9_rom_offset..][0..header.arm9_size], 0..) |value, i| {
const address = header.arm9_ram_address + @as(u32, @intCast(i)); const address = header.arm9_ram_address + @as(u32, @intCast(i));
nds9_group.bus.dbgWrite(u8, address, value); system.bus9.dbgWrite(u8, address, value);
} }
arm946es.r[15] = header.arm9_entry_address; system.arm946es.r[15] = header.arm9_entry_address;
} }
// Dealing with the ARM7TDMI // Dealing with the ARM7TDMI
{ {
const arm7tdmi = nds7_group.cpu;
log.debug("ARM7 ROM Offset: 0x{X:0>8}", .{header.arm7_rom_offset}); log.debug("ARM7 ROM Offset: 0x{X:0>8}", .{header.arm7_rom_offset});
log.debug("ARM7 Entry Address: 0x{X:0>8}", .{header.arm7_entry_address}); log.debug("ARM7 Entry Address: 0x{X:0>8}", .{header.arm7_entry_address});
log.debug("ARM7 RAM Address: 0x{X:0>8}", .{header.arm7_ram_address}); log.debug("ARM7 RAM Address: 0x{X:0>8}", .{header.arm7_ram_address});
@ -54,10 +48,10 @@ pub fn load(allocator: Allocator, nds7_group: nds7.Group, nds9_group: nds9.Group
// Copy ARM7 Code into Main Memory // Copy ARM7 Code into Main Memory
for (rom_buf[header.arm7_rom_offset..][0..header.arm7_size], 0..) |value, i| { for (rom_buf[header.arm7_rom_offset..][0..header.arm7_size], 0..) |value, i| {
const address = header.arm7_ram_address + @as(u32, @intCast(i)); const address = header.arm7_ram_address + @as(u32, @intCast(i));
nds7_group.bus.dbgWrite(u8, address, value); system.bus7.dbgWrite(u8, address, value);
} }
arm7tdmi.r[15] = header.arm7_entry_address; system.arm7tdmi.r[15] = header.arm7_entry_address;
} }
return header.title; return header.title;
@ -68,43 +62,29 @@ const dot_clock = 5585664; // 5.585664 Hz
const arm7_clock = bus_clock; const arm7_clock = bus_clock;
const arm9_clock = bus_clock * 2; const arm9_clock = bus_clock * 2;
pub fn runFrame(nds7_group: nds7.Group, nds9_group: nds9.Group) void { pub fn runFrame(scheduler: *Scheduler, system: System) void {
// TODO: might be more efficient to run them both in the same loop?
{
const scheduler = nds9_group.scheduler;
const cycles_per_dot = arm9_clock / dot_clock + 1; const cycles_per_dot = arm9_clock / dot_clock + 1;
comptime std.debug.assert(cycles_per_dot == 12); comptime std.debug.assert(cycles_per_dot == 12);
const cycles_per_frame = 355 * 263 * cycles_per_dot; const cycles_per_frame = 355 * 263 * cycles_per_dot;
const frame_end = scheduler.tick + cycles_per_frame; const frame_end = scheduler.tick + cycles_per_frame;
const cpu = nds9_group.cpu;
const bus = nds9_group.bus;
while (scheduler.tick < frame_end) { while (scheduler.tick < frame_end) {
cpu.step(); system.arm7tdmi.step();
system.arm946es.step();
system.arm946es.step();
if (scheduler.tick >= scheduler.next()) scheduler.handle(bus); if (scheduler.check()) |ev| {
} const late = scheduler.tick - ev.tick;
}
{ // this is kinda really jank lol
const scheduler = nds7_group.scheduler; const bus_ptr: ?*anyopaque = switch (ev.kind) {
.heat_death => null,
.nds7 => system.bus7,
.nds9 => system.bus9,
};
const cycles_per_dot = arm7_clock / dot_clock + 1; scheduler.handle(bus_ptr, ev, late);
comptime std.debug.assert(cycles_per_dot == 6);
const cycles_per_frame = 355 * 263 * cycles_per_dot;
const frame_end = scheduler.tick + cycles_per_frame;
const cpu = nds7_group.cpu;
const bus = nds7_group.bus;
while (scheduler.tick < frame_end) {
cpu.step();
if (scheduler.tick >= scheduler.next()) scheduler.handle(bus);
} }
} }
} }
@ -140,3 +120,25 @@ pub inline fn forceAlign(comptime T: type, address: u32) u32 {
else => @compileError("Bus: Invalid read/write type"), else => @compileError("Bus: Invalid read/write type"),
}; };
} }
pub const System = struct {
pub const Bus7 = @import("nds7/Bus.zig");
pub const Bus9 = @import("nds9/Bus.zig");
pub const Cp15 = @import("nds9/Cp15.zig");
pub const Arm7tdmi = @import("arm32").Arm7tdmi;
pub const Arm946es = @import("arm32").Arm946es;
arm7tdmi: *Arm7tdmi,
arm946es: *Arm946es,
bus7: *Bus7,
bus9: *Bus9,
cp15: *Cp15,
pub fn deinit(self: @This(), allocator: Allocator) void {
self.bus7.deinit(allocator);
self.bus9.deinit(allocator);
}
};

View File

@ -1,21 +0,0 @@
const std = @import("std");
pub const Bus = @import("nds7/Bus.zig");
pub const io = @import("nds7/io.zig");
pub const Scheduler = @import("nds7/Scheduler.zig");
pub const Arm7tdmi = @import("arm32").Arm7tdmi;
const Allocator = std.mem.Allocator;
// TODO: Rename (maybe Devices?)
pub const Group = struct {
cpu: *Arm7tdmi,
bus: *Bus,
scheduler: *Scheduler,
/// Responsible for deallocated the ARM7 CPU, Bus and Scheduler
pub fn deinit(self: @This(), allocator: Allocator) void {
self.bus.deinit(allocator);
self.scheduler.deinit();
}
};

View File

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const io = @import("io.zig"); const io = @import("io.zig");
const Scheduler = @import("Scheduler.zig"); const Scheduler = @import("../Scheduler.zig");
const SharedIo = @import("../io.zig").Io; const SharedIo = @import("../io.zig").Io;
const SharedContext = @import("../emu.zig").SharedContext; const SharedContext = @import("../emu.zig").SharedContext;
const forceAlign = @import("../emu.zig").forceAlign; const forceAlign = @import("../emu.zig").forceAlign;

View File

@ -1,59 +0,0 @@
const std = @import("std");
const Bus = @import("Bus.zig");
const PriorityQueue = std.PriorityQueue(Event, void, Event.lessThan);
const Allocator = std.mem.Allocator;
tick: u64 = 0,
queue: PriorityQueue,
pub fn init(allocator: Allocator) !@This() {
var queue = PriorityQueue.init(allocator, {});
try queue.add(.{ .tick = std.math.maxInt(u64), .kind = .heat_death });
return .{ .queue = queue };
}
pub fn push(self: *@This(), kind: Event.Kind, offset: u64) void {
self.queue.add(.{ .kind = kind, .tick = self.tick + offset }) catch unreachable;
}
pub fn deinit(self: @This()) void {
self.queue.deinit();
}
pub fn now(self: @This()) u64 {
return self.tick;
}
pub fn next(self: @This()) u64 {
@setRuntimeSafety(false);
return self.queue.items[0].tick;
}
pub fn reset(self: *@This()) void {
self.tick = 0;
}
pub fn handle(self: *@This(), bus: *Bus) void {
_ = bus;
const event = self.queue.remove();
const late = self.tick - event.tick;
_ = late;
switch (event.kind) {
.heat_death => unreachable,
}
}
pub const Event = struct {
tick: u64,
kind: Kind,
pub const Kind = enum { heat_death };
fn lessThan(_: void, left: @This(), right: @This()) std.math.Order {
return std.math.order(left.tick, right.tick);
}
};

View File

@ -1,22 +0,0 @@
const std = @import("std");
pub const Bus = @import("nds9/Bus.zig");
pub const Cp15 = @import("nds9/Cp15.zig");
pub const io = @import("nds9/io.zig");
pub const Scheduler = @import("nds9/Scheduler.zig");
pub const Arm946es = @import("arm32").Arm946es;
const Allocator = std.mem.Allocator;
// TODO: Rename
pub const Group = struct {
cpu: *Arm946es,
bus: *Bus,
scheduler: *Scheduler,
/// Responsible for deallocating the ARM9 CPU, Bus and Scheduler
pub fn deinit(self: @This(), allocator: Allocator) void {
self.bus.deinit(allocator);
self.scheduler.deinit();
}
};

View File

@ -2,7 +2,7 @@ const std = @import("std");
const io = @import("io.zig"); const io = @import("io.zig");
const Ppu = @import("../ppu.zig").Ppu; const Ppu = @import("../ppu.zig").Ppu;
const Scheduler = @import("Scheduler.zig"); const Scheduler = @import("../Scheduler.zig");
const SharedContext = @import("../emu.zig").SharedContext; const SharedContext = @import("../emu.zig").SharedContext;
const forceAlign = @import("../emu.zig").forceAlign; const forceAlign = @import("../emu.zig").forceAlign;
@ -27,7 +27,7 @@ pub fn init(allocator: Allocator, scheduler: *Scheduler, shared_ctx: SharedConte
@memset(vram1_mem, 0); @memset(vram1_mem, 0);
const dots_per_cycle = 3; // ARM946E-S runs twice as fast as the ARM7TDMI const dots_per_cycle = 3; // ARM946E-S runs twice as fast as the ARM7TDMI
scheduler.push(.draw, 256 * dots_per_cycle); scheduler.push(.{ .nds9 = .draw }, 256 * dots_per_cycle);
return .{ return .{
.main = shared_ctx.main, .main = shared_ctx.main,

View File

@ -1,7 +1,8 @@
const std = @import("std"); const std = @import("std");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const nds9 = @import("nds9.zig"); const Scheduler = @import("Scheduler.zig");
const System = @import("emu.zig").System;
pub const screen_width = 256; pub const screen_width = 256;
pub const screen_height = 192; pub const screen_height = 192;
@ -14,16 +15,14 @@ pub const Ppu = struct {
io: io = .{}, io: io = .{},
pub fn init(allocator: Allocator) !@This() { pub fn init(allocator: Allocator) !@This() {
return .{ return .{ .fb = try FrameBuffer.init(allocator) };
.fb = try FrameBuffer.init(allocator),
};
} }
pub fn deinit(self: @This(), allocator: Allocator) void { pub fn deinit(self: @This(), allocator: Allocator) void {
self.fb.deinit(allocator); self.fb.deinit(allocator);
} }
pub fn drawScanline(self: *@This(), nds9_bus: *nds9.Bus) void { pub fn drawScanline(self: *@This(), bus: *System.Bus9) void {
const bg_mode = self.io.dispcnt_a.display_mode.read(); const bg_mode = self.io.dispcnt_a.display_mode.read();
const scanline = self.io.vcount.scanline.read(); const scanline = self.io.vcount.scanline.read();
@ -45,7 +44,7 @@ pub const Ppu = struct {
for (scanline_ptr, 0..) |*rgba, i| { for (scanline_ptr, 0..) |*rgba, i| {
const addr = base_addr + @as(u32, @intCast(i)) * @sizeOf(u16); const addr = base_addr + @as(u32, @intCast(i)) * @sizeOf(u16);
rgba.* = rgba888(nds9_bus.dbgRead(u16, addr)); rgba.* = rgba888(bus.dbgRead(u16, addr));
} }
} }
}, },
@ -54,7 +53,7 @@ pub const Ppu = struct {
} }
/// HDraw -> HBlank /// HDraw -> HBlank
pub fn onHdrawEnd(self: *@This(), nds9_scheduler: *nds9.Scheduler, late: u64) void { pub fn onHdrawEnd(self: *@This(), scheduler: *Scheduler, late: u64) void {
const dots_in_hblank = 99; const dots_in_hblank = 99;
std.debug.assert(self.io.dispstat.hblank.read() == false); std.debug.assert(self.io.dispstat.hblank.read() == false);
std.debug.assert(self.io.dispstat.vblank.read() == false); std.debug.assert(self.io.dispstat.vblank.read() == false);
@ -62,10 +61,10 @@ pub const Ppu = struct {
// TODO: Signal HBlank IRQ // TODO: Signal HBlank IRQ
self.io.dispstat.hblank.set(); self.io.dispstat.hblank.set();
nds9_scheduler.push(.hblank, dots_in_hblank * cycles_per_dot -| late); scheduler.push(.{ .nds9 = .hblank }, dots_in_hblank * cycles_per_dot -| late);
} }
pub fn onHblankEnd(self: *@This(), nds9_scheduler: *nds9.Scheduler, late: u64) void { pub fn onHblankEnd(self: *@This(), scheduler: *Scheduler, late: u64) void {
const scanline_count = 192 + 71; const scanline_count = 192 + 71;
const prev_scanline = self.io.vcount.scanline.read(); const prev_scanline = self.io.vcount.scanline.read();
@ -85,7 +84,7 @@ pub const Ppu = struct {
// Draw Another Scanline // Draw Another Scanline
const dots_in_hdraw = 256; const dots_in_hdraw = 256;
return nds9_scheduler.push(.draw, dots_in_hdraw * cycles_per_dot -| late); return scheduler.push(.{ .nds9 = .draw }, dots_in_hdraw * cycles_per_dot -| late);
} }
if (scanline == 192) { if (scanline == 192) {
@ -100,7 +99,7 @@ pub const Ppu = struct {
std.debug.assert(self.io.dispstat.vblank.read() == (scanline != 262)); std.debug.assert(self.io.dispstat.vblank.read() == (scanline != 262));
const dots_in_scanline = 256 + 99; const dots_in_scanline = 256 + 99;
nds9_scheduler.push(.hblank, dots_in_scanline * cycles_per_dot -| late); scheduler.push(.{ .nds9 = .hblank }, dots_in_scanline * cycles_per_dot -| late);
} }
}; };

View File

@ -1,16 +1,12 @@
const std = @import("std"); const std = @import("std");
const clap = @import("zig-clap"); const clap = @import("zig-clap");
const nds9 = @import("core/nds9.zig");
const nds7 = @import("core/nds7.zig");
const emu = @import("core/emu.zig"); const emu = @import("core/emu.zig");
const IBus = @import("arm32").Bus;
const IScheduler = @import("arm32").Scheduler;
const ICoprocessor = @import("arm32").Coprocessor;
const Ui = @import("platform.zig").Ui; const Ui = @import("platform.zig").Ui;
const SharedContext = @import("core/emu.zig").SharedContext; const SharedContext = @import("core/emu.zig").SharedContext;
const System = @import("core/emu.zig").System;
const Scheduler = @import("core/Scheduler.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const ClapResult = clap.Result(clap.Help, &cli_params, clap.parsers.default); const ClapResult = clap.Result(clap.Help, &cli_params, clap.parsers.default);
@ -41,33 +37,32 @@ pub fn main() !void {
const shared_ctx = try SharedContext.init(allocator); const shared_ctx = try SharedContext.init(allocator);
defer shared_ctx.deinit(allocator); defer shared_ctx.deinit(allocator);
const nds9_group: nds9.Group = blk: { var scheduler = try Scheduler.init(allocator);
var scheduler = try nds9.Scheduler.init(allocator); defer scheduler.deinit();
var bus = try nds9.Bus.init(allocator, &scheduler, shared_ctx);
var cp15 = nds9.Cp15{};
var arm946es = nds9.Arm946es.init(IScheduler.init(&scheduler), IBus.init(&bus), ICoprocessor.init(&cp15)); const system: System = blk: {
const IBus = @import("arm32").Bus;
const IScheduler = @import("arm32").Scheduler;
const ICoprocessor = @import("arm32").Coprocessor;
break :blk .{ .cpu = &arm946es, .bus = &bus, .scheduler = &scheduler }; var cp15 = System.Cp15{};
var bus7 = try System.Bus7.init(allocator, &scheduler, shared_ctx);
var bus9 = try System.Bus9.init(allocator, &scheduler, shared_ctx);
var arm7tdmi = System.Arm7tdmi.init(IScheduler.init(&scheduler), IBus.init(&bus7));
var arm946es = System.Arm946es.init(IScheduler.init(&scheduler), IBus.init(&bus9), ICoprocessor.init(&cp15));
break :blk .{ .arm7tdmi = &arm7tdmi, .arm946es = &arm946es, .bus7 = &bus7, .bus9 = &bus9, .cp15 = &cp15 };
}; };
defer nds9_group.deinit(allocator); defer system.deinit(allocator);
const rom_title = try emu.load(allocator, system, rom_file);
const nds7_group: nds7.Group = blk: {
var scheduler = try nds7.Scheduler.init(allocator);
var bus = try nds7.Bus.init(allocator, &scheduler, shared_ctx);
var arm7tdmi = nds7.Arm7tdmi.init(IScheduler.init(&scheduler), IBus.init(&bus));
break :blk .{ .cpu = &arm7tdmi, .bus = &bus, .scheduler = &scheduler };
};
defer nds7_group.deinit(allocator);
const rom_title = try emu.load(allocator, nds7_group, nds9_group, rom_file);
var ui = try Ui.init(allocator); var ui = try Ui.init(allocator);
defer ui.deinit(allocator); defer ui.deinit(allocator);
ui.setTitle(rom_title); ui.setTitle(rom_title);
try ui.run(nds7_group, nds9_group); try ui.run(&scheduler, system);
} }
fn handlePositional(result: ClapResult) ![]const u8 { fn handlePositional(result: ClapResult) ![]const u8 {

View File

@ -3,14 +3,13 @@ const SDL = @import("sdl2");
const gl = @import("gl"); const gl = @import("gl");
const zgui = @import("zgui"); const zgui = @import("zgui");
const nds9 = @import("core/nds9.zig");
const nds7 = @import("core/nds7.zig");
const ppu = @import("core/ppu.zig"); const ppu = @import("core/ppu.zig");
const imgui = @import("ui/imgui.zig"); const imgui = @import("ui/imgui.zig");
const emu = @import("core/emu.zig"); const emu = @import("core/emu.zig");
const System = @import("core/emu.zig").System;
const KeyInput = @import("core/nds9/io.zig").KeyInput; const KeyInput = @import("core/nds9/io.zig").KeyInput;
const Scheduler = @import("core/Scheduler.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@ -86,14 +85,14 @@ pub const Ui = struct {
return SDL.SDL_GL_GetProcAddress(proc.ptr); return SDL.SDL_GL_GetProcAddress(proc.ptr);
} }
pub fn run(self: *Self, nds7_group: nds7.Group, nds9_group: nds9.Group) !void { pub fn run(self: *Self, scheduler: *Scheduler, system: System) !void {
// TODO: Sort this out please // TODO: Sort this out please
const vao_id = opengl_impl.vao(); const vao_id = opengl_impl.vao();
defer gl.deleteVertexArrays(1, &[_]GLuint{vao_id}); defer gl.deleteVertexArrays(1, &[_]GLuint{vao_id});
const top_tex = opengl_impl.screenTex(nds9_group.bus.ppu.fb.top(.front)); const top_tex = opengl_impl.screenTex(system.bus9.ppu.fb.top(.front));
const btm_tex = opengl_impl.screenTex(nds9_group.bus.ppu.fb.btm(.front)); const btm_tex = opengl_impl.screenTex(system.bus9.ppu.fb.btm(.front));
const top_out_tex = opengl_impl.outTex(); const top_out_tex = opengl_impl.outTex();
const btm_out_tex = opengl_impl.outTex(); const btm_out_tex = opengl_impl.outTex();
defer gl.deleteTextures(4, &[_]GLuint{ top_tex, top_out_tex, btm_tex, btm_out_tex }); defer gl.deleteTextures(4, &[_]GLuint{ top_tex, top_out_tex, btm_tex, btm_out_tex });
@ -108,7 +107,7 @@ pub const Ui = struct {
var event: SDL.SDL_Event = undefined; var event: SDL.SDL_Event = undefined;
emu_loop: while (true) { emu_loop: while (true) {
emu.runFrame(nds7_group, nds9_group); emu.runFrame(scheduler, system);
while (SDL.SDL_PollEvent(&event) != 0) { while (SDL.SDL_PollEvent(&event) != 0) {
_ = zgui.backend.processEvent(&event); _ = zgui.backend.processEvent(&event);
@ -142,7 +141,7 @@ pub const Ui = struct {
else => {}, else => {},
} }
nds9_group.bus.io.keyinput.fetchAnd(~keyinput.raw, .Monotonic); system.bus9.io.keyinput.fetchAnd(~keyinput.raw, .Monotonic);
}, },
SDL.SDL_KEYUP => { SDL.SDL_KEYUP => {
// TODO: Make use of compare_and_xor? // TODO: Make use of compare_and_xor?
@ -163,7 +162,7 @@ pub const Ui = struct {
else => {}, else => {},
} }
nds9_group.bus.io.keyinput.fetchOr(keyinput.raw, .Monotonic); system.bus9.io.keyinput.fetchOr(keyinput.raw, .Monotonic);
}, },
else => {}, else => {},
} }
@ -174,7 +173,7 @@ pub const Ui = struct {
defer gl.bindFramebuffer(gl.FRAMEBUFFER, 0); defer gl.bindFramebuffer(gl.FRAMEBUFFER, 0);
gl.viewport(0, 0, nds_width, nds_height); gl.viewport(0, 0, nds_width, nds_height);
opengl_impl.drawScreen(top_tex, prog_id, vao_id, nds9_group.bus.ppu.fb.top(.front)); opengl_impl.drawScreen(top_tex, prog_id, vao_id, system.bus9.ppu.fb.top(.front));
} }
{ {
@ -182,10 +181,10 @@ pub const Ui = struct {
defer gl.bindFramebuffer(gl.FRAMEBUFFER, 0); defer gl.bindFramebuffer(gl.FRAMEBUFFER, 0);
gl.viewport(0, 0, nds_width, nds_height); gl.viewport(0, 0, nds_width, nds_height);
opengl_impl.drawScreen(btm_tex, prog_id, vao_id, nds9_group.bus.ppu.fb.btm(.front)); opengl_impl.drawScreen(btm_tex, prog_id, vao_id, system.bus9.ppu.fb.btm(.front));
} }
const zgui_redraw = imgui.draw(&self.state, top_out_tex, btm_out_tex, nds9_group.cpu); const zgui_redraw = imgui.draw(&self.state, top_out_tex, btm_out_tex, system);
if (zgui_redraw) { if (zgui_redraw) {
// Background Colour // Background Colour

View File

@ -3,7 +3,7 @@ const zgui = @import("zgui");
const platform = @import("../platform.zig"); const platform = @import("../platform.zig");
const Arm946es = @import("../core/nds9.zig").Arm946es; const System = @import("../core/emu.zig").System;
const Dimensions = platform.Dimensions; const Dimensions = platform.Dimensions;
const nds_height = @import("../core/ppu.zig").screen_height; const nds_height = @import("../core/ppu.zig").screen_height;
@ -18,8 +18,9 @@ pub const State = struct {
dim: Dimensions = .{ .width = 1600, .height = 900 }, dim: Dimensions = .{ .width = 1600, .height = 900 },
}; };
pub fn draw(state: *const State, top_tex: GLuint, btm_tex: GLuint, arm946es: *Arm946es) bool { pub fn draw(state: *const State, top_tex: GLuint, btm_tex: GLuint, system: System) bool {
_ = arm946es; _ = system;
zgui.backend.newFrame(@floatFromInt(state.dim.width), @floatFromInt(state.dim.height)); zgui.backend.newFrame(@floatFromInt(state.dim.width), @floatFromInt(state.dim.height));
{ {