Minor refactors and bug fixes
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Has been cancelled

- Bit instruction now sets Z flag correctly
- DMA is no longer handled by cpu.rs
This commit is contained in:
2026-01-26 01:21:37 -06:00
parent f861f75b21
commit 148ab2004d
10 changed files with 371 additions and 166 deletions

View File

@@ -24,7 +24,7 @@ use iced::{
},
};
use crate::{CycleResult, NES, PPU, mem::Mapped};
use crate::{Break, CycleResult, NES, PPU, mem::Mapped};
#[derive(Debug, Clone)]
pub struct DebuggerState {
@@ -254,23 +254,41 @@ impl DebuggerState {
fn run_n_clock_cycles(nes: &mut NES, n: usize) {
for _ in 0..n {
if nes.run_one_clock_cycle().dbg_int || nes.halted() {
if nes.run_one_clock_cycle(&Break::default()).dbg_int || nes.halted() {
break;
}
}
}
fn run_until(nes: &mut NES, mut f: impl FnMut(CycleResult, &NES) -> bool, mut count: usize) {
loop {
let res = nes.run_one_clock_cycle();
if res.dbg_int || f(res, nes) {
count -= 1;
if count <= 0 {
break;
}
}
if nes.halted() {
break;
}
fn run_until(
nes: &mut NES,
br: &Break,
mut f: impl FnMut(CycleResult, &NES) -> bool,
// mut count: usize,
) {
// Always run at least 1 cycle
let mut res = nes.run_one_clock_cycle(&Break::default());
while !nes.halted() && !res.dbg_int && !f(res, nes) {
// if res.dbg_int || f(res, nes) {
// count -= 1;
// if count <= 0 {
// break;
// }
// }
// if nes.halted() {
// break;
// }
res = nes.run_one_clock_cycle(br);
}
}
fn run_until_n(
nes: &mut NES,
br: &Break,
mut f: impl FnMut(CycleResult, &NES) -> bool,
mut count: usize,
) {
while count > 0 {
Self::run_until(nes, br, &mut f);
count -= 1;
}
}
@@ -280,23 +298,49 @@ impl DebuggerState {
DebuggerMessage::SetCPUCycles(n) => self.cpu_cycles = n,
DebuggerMessage::SetInstructions(n) => self.instructions = n,
DebuggerMessage::SetScanLines(n) => self.scan_lines = n,
DebuggerMessage::SetToScanLine(n) => self.to_scan_line = n,
DebuggerMessage::SetToScanLine(n) => self.to_scan_line = n.min(261), // Max scanline is 261
DebuggerMessage::SetFrames(n) => self.frames = n,
DebuggerMessage::SetBreakpoint(n) => self.breakpoint = n,
DebuggerMessage::RunPPUCycles => Self::run_n_clock_cycles(nes, self.ppu_cycles),
DebuggerMessage::RunCPUCycles => Self::run_n_clock_cycles(nes, self.cpu_cycles * 3),
DebuggerMessage::RunInstructions => {
Self::run_until(nes, |c, _| c.cpu_exec, self.instructions)
}
// DebuggerMessage::RunInstructions => Self::run_until_n(
// nes,
// &Break {
// cpu_exec: true,
// ..Break::default()
// },
// |_, _| false,
// self.instructions,
// ),
DebuggerMessage::RunInstructions => Self::run_until_n(
nes,
&Break {
..Break::default()
},
|res, _| res.cpu_exec,
self.instructions,
),
DebuggerMessage::RunScanLines => Self::run_n_clock_cycles(nes, self.scan_lines * 341),
DebuggerMessage::RunToScanLine => {
Self::run_until(nes, |_, n| n.ppu.scanline == self.to_scan_line, 1)
}
DebuggerMessage::RunToScanLine => Self::run_until(
nes,
&Break {
ppu_scanline: true,
..Break::default()
},
|_, n| n.ppu.scanline == self.to_scan_line,
),
DebuggerMessage::RunFrames => Self::run_n_clock_cycles(nes, self.frames * 341 * 262),
DebuggerMessage::RunBreakpoint => {
Self::run_until(nes, |_, nes| nes.cpu.pc as usize == self.breakpoint, 1)
DebuggerMessage::RunBreakpoint => Self::run_until(
nes,
&Break {
break_points: vec![self.breakpoint as u16],
..Break::default()
},
|_, nes| nes.cpu.pc as usize == self.breakpoint,
),
DebuggerMessage::Run => {
Self::run_until(nes, &Break { ..Break::default() }, |_, nes| nes.halted())
}
DebuggerMessage::Run => Self::run_until(nes, |_, nes| nes.halted(), 1),
DebuggerMessage::Pause => todo!(),
}
}