From d140f1e12262f2fbb52beff19b2119947aefae31 Mon Sep 17 00:00:00 2001 From: Matthew Pomes Date: Wed, 8 Apr 2026 21:15:15 -0500 Subject: [PATCH] Fix minor warnings and debug log --- src/bin/native/audio.rs | 11 +-- src/bin/native/debugger.rs | 24 +++--- src/bin/native/hex_view.rs | 162 +++++++++++++++++++------------------ src/bin/native/main.rs | 5 +- src/cpu.rs | 9 ++- src/debug.rs | 14 ++-- src/lib.rs | 32 ++++---- src/ppu.rs | 4 +- src/test_roms/mod.rs | 34 ++++---- 9 files changed, 153 insertions(+), 142 deletions(-) diff --git a/src/bin/native/audio.rs b/src/bin/native/audio.rs index f024497..016e230 100644 --- a/src/bin/native/audio.rs +++ b/src/bin/native/audio.rs @@ -1,12 +1,9 @@ -use std::{ - sync::{ - atomic::AtomicBool, mpsc::{channel, Sender, TryRecvError}, Arc - }, - time::Instant, -}; +use std::sync::{ + atomic::AtomicBool, Arc + }; use cpal::{ - Device, FrameCount, Host, SampleFormat, Stream, + Device, FrameCount, Host, Stream, traits::{DeviceTrait, HostTrait, StreamTrait}, }; use ringbuf::{ diff --git a/src/bin/native/debugger.rs b/src/bin/native/debugger.rs index c8517f3..a36b2b4 100644 --- a/src/bin/native/debugger.rs +++ b/src/bin/native/debugger.rs @@ -70,13 +70,13 @@ where { text(format!("{val:02X}")) } -pub fn bin8<'a, Theme, Renderer>(val: u8) -> Text<'a, Theme, Renderer> -where - Theme: text::Catalog + 'a, - Renderer: iced::advanced::text::Renderer, -{ - text(format!("{val:08b}")) -} +// pub fn bin8<'a, Theme, Renderer>(val: u8) -> Text<'a, Theme, Renderer> +// where +// Theme: text::Catalog + 'a, +// Renderer: iced::advanced::text::Renderer, +// { +// text(format!("{val:08b}")) +// } pub fn bin32<'a, Theme, Renderer>(val: u32) -> Text<'a, Theme, Renderer> where Theme: text::Catalog + 'a, @@ -408,7 +408,7 @@ pub fn labelled_box<'a, Message: 'a>(label: &'a str, value: bool) -> Element<'a, pub enum DbgImage<'a> { NameTable(&'a Mapped, &'a PPU), PatternTable(&'a Mapped, &'a PPU), - Palette(&'a Mapped, &'a PPU), + Palette(&'a PPU), } impl Program for DbgImage<'_> { @@ -432,7 +432,7 @@ impl Program for DbgImage<'_> { DbgImage::PatternTable(mem, ppu) => { ppu.render_pattern_tables(mem, &mut name_table_frame) } - DbgImage::Palette(_, ppu) => ppu.render_palette(&mut name_table_frame), + DbgImage::Palette(ppu) => ppu.render_palette(&mut name_table_frame), }; vec![name_table_frame.into_geometry()] } @@ -443,21 +443,21 @@ impl DbgImage<'_> { match self { DbgImage::NameTable(_, _) => Length::Fixed(512. * 2.), DbgImage::PatternTable(_, _) => Length::Fixed(16. * 8. * 2.), - DbgImage::Palette(_, _) => Length::Fixed(40. * 2.), + DbgImage::Palette(_) => Length::Fixed(40. * 2.), } } fn height(&self) -> Length { match self { DbgImage::NameTable(_, _) => Length::Fixed(512. * 2.), DbgImage::PatternTable(_, _) => Length::Fixed(16. * 8. * 2. * 2.), - DbgImage::Palette(_, _) => Length::Fixed(80. * 2.), + DbgImage::Palette(_) => Length::Fixed(80. * 2.), } } fn help(&self, cursor: Point) -> Option { match self { DbgImage::NameTable(mem, ppu) => ppu.name_cursor_info(mem, cursor), DbgImage::PatternTable(_, ppu) => ppu.pattern_cursor_info(cursor), - DbgImage::Palette(_, ppu) => ppu.palette_cursor_info(cursor), + DbgImage::Palette(ppu) => ppu.palette_cursor_info(cursor), } } } diff --git a/src/bin/native/hex_view.rs b/src/bin/native/hex_view.rs index 2019eb7..c50ec16 100644 --- a/src/bin/native/hex_view.rs +++ b/src/bin/native/hex_view.rs @@ -1,25 +1,25 @@ -use std::{ - fmt::{self, Display}, ops::Deref -}; +use std::fmt::{self, Display}; use iced::{ - advanced::{layout::{Limits, Node}, overlay, renderer::{Quad, Style}, text::Renderer, widget::{tree::{State, Tag}, Operation, Tree}, Clipboard, Layout, Shell, Text, Widget}, alignment::Vertical, keyboard::{key::Named, Key}, mouse::{Button, Cursor, Interaction, ScrollDelta}, widget::{column, lazy, text}, Color, Element, Event, Fill, Font, Length, Padding, Pixels, Point, Rectangle, Size, Task, Vector + Color, Element, Event, Font, Length, Padding, Pixels, Point, Rectangle, Size, Task, Vector, + advanced::{ + Clipboard, Layout, Shell, Text, Widget, + layout::{Limits, Node}, + overlay, + renderer::{Quad, Style}, + text::Renderer, + widget::{ + Operation, Tree, + tree::{State, Tag}, + }, + }, + alignment::Vertical, + keyboard::{Key, key::Named}, + mouse::{Button, Cursor, Interaction, ScrollDelta}, }; -// use iced_core::{ -// Clipboard, Color, Event, Layout, Length, Pixels, Point, Rectangle, Shell, Size, Text, Vector, -// Widget, -// layout::{Limits, Node}, -// mouse::{Cursor, Interaction}, -// overlay, -// renderer::{Quad, Style}, -// widget::{ -// Operation, Tree, -// tree::{State, Tag}, -// }, -// }; use nes_emu::Memory; -use nes_emu::{PPU, Mapped, PPUMMRegisters}; +use nes_emu::{Mapped, PPU, PPUMMRegisters}; #[derive(Debug, Clone, Copy)] struct Cpu<'a>(&'a Mapped); @@ -82,53 +82,53 @@ pub enum HexEvent {} #[derive(Debug, Clone, PartialEq, Eq)] pub struct HexView {} -struct Val(Option); -impl fmt::Display for Val { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(val) = self.0 { - write!(f, "{:02X}", val) - } else { - write!(f, "XX") - } - } -} +// struct Val(Option); +// impl fmt::Display for Val { +// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +// if let Some(val) = self.0 { +// write!(f, "{:02X}", val) +// } else { +// write!(f, "XX") +// } +// } +// } impl HexView { - pub fn new() -> Self { - Self {} - } + // pub fn new() -> Self { + // Self {} + // } - pub fn render_any<'a, M: Memory + Copy + 'a>(&self, mem: M) -> Element<'a, HexEvent> { - struct Row(usize, M); - impl<'a, M: Memory + 'a> fmt::Display for Row { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", Val(self.1.peek(self.0)))?; - for i in 1..16 { - write!(f, " {}", Val(self.1.peek(self.0 + i)))?; - } - Ok(()) - } - } - column![ - text!("Hex view"), - iced::widget::scrollable(lazy(mem.edit_ver(), move |_| column( - [ - text!(" | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F") - .font(Font::MONOSPACE) - .into() - ] - .into_iter() - .chain((0..mem.len()).step_by(16).map(|off| { - text!(" {off:04X} | {}", Row(off, mem)) - .font(Font::MONOSPACE) - .into() - })) - ))) - .width(Fill), - ] - .width(Fill) - .into() - } + // pub fn render_any<'a, M: Memory + Copy + 'a>(&self, mem: M) -> Element<'a, HexEvent> { + // struct Row(usize, M); + // impl<'a, M: Memory + 'a> fmt::Display for Row { + // fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // write!(f, "{}", Val(self.1.peek(self.0)))?; + // for i in 1..16 { + // write!(f, " {}", Val(self.1.peek(self.0 + i)))?; + // } + // Ok(()) + // } + // } + // column![ + // text!("Hex view"), + // iced::widget::scrollable(lazy(mem.edit_ver(), move |_| column( + // [ + // text!(" | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F") + // .font(Font::MONOSPACE) + // .into() + // ] + // .into_iter() + // .chain((0..mem.len()).step_by(16).map(|off| { + // text!(" {off:04X} | {}", Row(off, mem)) + // .font(Font::MONOSPACE) + // .into() + // })) + // ))) + // .width(Fill), + // ] + // .width(Fill) + // .into() + // } pub fn render_cpu<'a>(&self, mem: &'a Mapped) -> Element<'a, HexEvent> { // self.render_any(Cpu(mem)) Element::new( @@ -147,35 +147,35 @@ impl HexView { ) } - pub fn update(&mut self, ev: HexEvent) -> Task { + pub fn update(&mut self, _ev: HexEvent) -> Task { todo!() } } -pub struct BufferSlice<'a>(pub &'a [u8]); +// pub struct BufferSlice<'a>(pub &'a [u8]); -impl Deref for BufferSlice<'_> { - type Target = [u8]; +// impl Deref for BufferSlice<'_> { +// type Target = [u8]; - fn deref(&self) -> &Self::Target { - self.0 - } -} +// fn deref(&self) -> &Self::Target { +// self.0 +// } +// } pub trait Buffer { fn peek(&self, val: usize) -> Option; fn len(&self) -> usize; } -impl Buffer for BufferSlice<'_> { - fn peek(&self, val: usize) -> Option { - self.get(val).copied() - } +// impl Buffer for BufferSlice<'_> { +// fn peek(&self, val: usize) -> Option { +// self.get(val).copied() +// } - fn len(&self) -> usize { - self.iter().len() - } -} +// fn len(&self) -> usize { +// self.iter().len() +// } +// } impl Buffer for M { fn peek(&self, val: usize) -> Option { self.peek(val) @@ -202,6 +202,7 @@ pub struct HexEdit { new_value: u8, } +#[allow(dead_code)] pub struct HexEditor { val: B, font_size: Option, @@ -279,6 +280,7 @@ where } #[derive(Default)] +#[allow(dead_code)] struct HexEditorState { offset_y: f32, selected: usize, @@ -311,10 +313,10 @@ where &self, tree: &Tree, renderer: &mut R, - theme: &T, - style: &Style, + _theme: &T, + _style: &Style, layout: Layout<'_>, - cursor: Cursor, + _cursor: Cursor, viewport: &Rectangle, ) { let state: &HexEditorState = tree.state.downcast_ref(); diff --git a/src/bin/native/main.rs b/src/bin/native/main.rs index 349c256..8ac21f2 100644 --- a/src/bin/native/main.rs +++ b/src/bin/native/main.rs @@ -46,11 +46,12 @@ use audio::Audio; // const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "sprites.nes"); // const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "apu_pulse_channel_1.nes"); // const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "apu_pulse_channel_1_evelope.nes"); -const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "apu_pulse_1.nes"); +// const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "apu_pulse_1.nes"); // const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "apu_triangle.nes"); // const ROM_FILE: &str = "./Super Mario Bros. (World).nes"; // const ROM_FILE: &str = "./cpu_timing_test.nes"; // const ROM_FILE: &str = "../nes-test-roms/instr_test-v5/official_only.nes"; +const ROM_FILE: &str = "../Downloads/Legend of Zelda, The (USA).nes"; extern crate nes_emu; @@ -453,7 +454,7 @@ impl Emulator { dbg_image(DbgImage::PatternTable(self.nes.mem(), self.nes.ppu())).into() } Some(WindowType::Palette) => { - dbg_image(DbgImage::Palette(self.nes.mem(), self.nes.ppu())).into() + dbg_image(DbgImage::Palette(self.nes.ppu())).into() } Some(WindowType::Debugger) => column![ row![ diff --git a/src/cpu.rs b/src/cpu.rs index a47d04a..6e55c06 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -1729,7 +1729,12 @@ impl Cpu { 0xEA => inst!("NOP", 1, || { log!("{addr:04X}: NOP"); }), - _ => todo!("ins: 0x{:04X}: 0x{ins:X}, {params:X?}", self.pc - 1), + // _ => todo!("ins: 0x{:04X}: 0x{ins:X}, {params:X?}", self.pc - 1), + _ => { + println!("ins: 0x{:04X}: 0x{ins:X}, {params:X?}", self.pc - 1); + self.halt(); + ExecState::Done + } } } @@ -1936,7 +1941,9 @@ impl Cpu { } pub fn reset(&mut self, mem: &mut CpuMem<'_>) { + let debug_log = self.debug_log.enabled(); *self = Self::init(); + if debug_log { self.debug_log.enable(); } self.pc = u16::from_le_bytes([mem.read(0xFFFC), mem.read(0xFFFD)]); self.sp = 0xFD; self.status.set_interrupt_disable(true); diff --git a/src/debug.rs b/src/debug.rs index 5fc55e1..261ed0e 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,12 +1,12 @@ -use std::num::NonZeroUsize; +// use std::num::NonZeroUsize; #[derive(Debug, Clone)] pub struct DebugLog { enabled: bool, current: String, history: Vec, - max_history: Option, - pos: usize, + // max_history: Option, + // pos: usize, } impl DebugLog { @@ -15,8 +15,8 @@ impl DebugLog { enabled: false, current: String::new(), history: vec![], - max_history: None, - pos: 0, + // max_history: None, + // pos: 0, } } @@ -53,6 +53,10 @@ impl DebugLog { pub fn enable(&mut self) { self.enabled = true; } + + pub fn enabled(&self) -> bool { + self.enabled + } } impl std::fmt::Write for DebugLog { diff --git a/src/lib.rs b/src/lib.rs index a8c99ac..ad6389a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,10 +9,10 @@ mod mem; mod ppu; #[cfg(test)] mod test_roms; -pub use mem::{Memory, Mapped}; +pub use mem::{Mapped, Memory}; -pub use ppu::{Color, PPU, RenderBuffer, PPUMMRegisters}; -pub use cpu::{Cpu, CycleResult, CPUMMRegisters}; +pub use cpu::{CPUMMRegisters, Cpu, CycleResult}; +pub use ppu::{Color, PPU, PPUMMRegisters, RenderBuffer}; // #[cfg(not(target_arch = "wasm32"))] // use tokio::io::AsyncReadExt as _; @@ -260,16 +260,16 @@ impl NES { pub fn reset(&mut self) { self.clock_count = 0; - // dbg_int: false, + // dbg_int: false, - // clock_count: 0, - // mapped, - // cpu: Cpu::init(), - // dma: DmaState::Passive, - // // ppu: PPU::with_chr_rom(chr_rom, mapper), - // ppu: PPU::init(), - // apu: APU::init(), - // controller: Controllers::init(), + // clock_count: 0, + // mapped, + // cpu: Cpu::init(), + // dma: DmaState::Passive, + // // ppu: PPU::with_chr_rom(chr_rom, mapper), + // ppu: PPU::init(), + // apu: APU::init(), + // controller: Controllers::init(), self.cpu.reset(&mut CpuMem::new( &mut self.mapped, &mut self.ppu, @@ -284,11 +284,11 @@ impl NES { } pub fn power_cycle(&mut self) { - // self.memory.clear(); - // self.ppu.reset(); - // self.ppu.memory.clear(); + let debug_log = self.debug_log().enabled(); *self = Self::from_mem(self.mapped.power_cylce()); - // self.memory.power_cycle(); + if debug_log { + self.debug_log_mut().enable(); + } self.reset(); } diff --git a/src/ppu.rs b/src/ppu.rs index 8c76e66..08ee485 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -107,7 +107,7 @@ enum OamState { ReadTile, ReadAttrs, ReadX, - OverflowScan, + // OverflowScan, Wait, } @@ -194,7 +194,7 @@ impl OAM { self.state = OamState::Wait; // Should be Overflow scan... } } - OamState::OverflowScan => todo!(), + // OamState::OverflowScan => todo!(), OamState::Wait => (), } } diff --git a/src/test_roms/mod.rs b/src/test_roms/mod.rs index d2e6d48..6252082 100644 --- a/src/test_roms/mod.rs +++ b/src/test_roms/mod.rs @@ -10,28 +10,28 @@ macro_rules! rom_test { ($name:ident, $rom:literal, timeout = $timeout:expr, |$nes:ident| $eval:expr) => { #[test] fn $name() { - let rom_file = concat!(env!("ROM_DIR"), "/", $rom); - println!("{}: {}", stringify!($name), rom_file); - let mut $nes = crate::NES::load_nes_file(rom_file).expect("Failed to create nes object"); - $nes.reset_and_run_with_timeout($timeout); - println!("Final: {:?}", $nes); - $eval - } - }; - ($name:ident, . $rom:literal, |$nes:ident| $eval:expr) => { - rom_test!($name, . $rom, timeout = 10000000, |$nes| $eval); - }; - ($name:ident, . $rom:literal, timeout = $timeout:expr, |$nes:ident| $eval:expr) => { - #[test] - fn $name() { - let rom_file = $rom; - println!("{}: {}", stringify!($name), rom_file); - let mut $nes = crate::NES::load_nes_file(rom_file).expect("Failed to create nes object"); + let rom_file = include_bytes!(concat!(env!("ROM_DIR"), "/", $rom)); + println!("{}: {}", stringify!($name), concat!(env!("ROM_DIR"), "/", $rom)); + let mut $nes = crate::NES::load_nes_file_mem(rom_file).expect("Failed to create nes object"); $nes.reset_and_run_with_timeout($timeout); println!("Final: {:?}", $nes); $eval } }; + // ($name:ident, . $rom:literal, |$nes:ident| $eval:expr) => { + // rom_test!($name, . $rom, timeout = 10000000, |$nes| $eval); + // }; + // ($name:ident, . $rom:literal, timeout = $timeout:expr, |$nes:ident| $eval:expr) => { + // #[test] + // fn $name() { + // let rom_file = $rom; + // println!("{}: {}", stringify!($name), rom_file); + // let mut $nes = crate::NES::load_nes_file(rom_file).expect("Failed to create nes object"); + // $nes.reset_and_run_with_timeout($timeout); + // println!("Final: {:?}", $nes); + // $eval + // } + // }; } pub(crate) use rom_test;