Fix minor warnings and debug log
This commit is contained in:
@@ -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::{
|
||||
|
||||
@@ -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<Message, T> Program<Message, T> for DbgImage<'_> {
|
||||
@@ -432,7 +432,7 @@ impl<Message, T> Program<Message, T> 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<String> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<u8>);
|
||||
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<u8>);
|
||||
// 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<M: Memory>(usize, M);
|
||||
impl<'a, M: Memory + 'a> fmt::Display for Row<M> {
|
||||
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<M: Memory>(usize, M);
|
||||
// impl<'a, M: Memory + 'a> fmt::Display for Row<M> {
|
||||
// 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<HexEvent> {
|
||||
pub fn update(&mut self, _ev: HexEvent) -> Task<HexEvent> {
|
||||
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<u8>;
|
||||
fn len(&self) -> usize;
|
||||
}
|
||||
|
||||
impl Buffer for BufferSlice<'_> {
|
||||
fn peek(&self, val: usize) -> Option<u8> {
|
||||
self.get(val).copied()
|
||||
}
|
||||
// impl Buffer for BufferSlice<'_> {
|
||||
// fn peek(&self, val: usize) -> Option<u8> {
|
||||
// self.get(val).copied()
|
||||
// }
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.iter().len()
|
||||
}
|
||||
}
|
||||
// fn len(&self) -> usize {
|
||||
// self.iter().len()
|
||||
// }
|
||||
// }
|
||||
impl<M: Memory> Buffer for M {
|
||||
fn peek(&self, val: usize) -> Option<u8> {
|
||||
self.peek(val)
|
||||
@@ -202,6 +202,7 @@ pub struct HexEdit {
|
||||
new_value: u8,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct HexEditor<B, M, R: Renderer> {
|
||||
val: B,
|
||||
font_size: Option<Pixels>,
|
||||
@@ -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();
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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);
|
||||
|
||||
14
src/debug.rs
14
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<String>,
|
||||
max_history: Option<NonZeroUsize>,
|
||||
pos: usize,
|
||||
// max_history: Option<NonZeroUsize>,
|
||||
// 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 {
|
||||
|
||||
32
src/lib.rs
32
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 => (),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user