Finally find (& fix) bug in BIT instructions
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 26s
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 26s
- BIT not longer ANDs the A register - I now a pretty good debug view for debugging the CPU - I wrote a number_input element for iced - I upgraded to iced 0.14 - I added images for play and pause - The debug log now displays in the debug view
This commit is contained in:
106
src/main.rs
106
src/main.rs
@@ -1,15 +1,12 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
io::{Read, stdin},
|
||||
};
|
||||
|
||||
use iced::{
|
||||
Color, Element, Font,
|
||||
Length::Fill,
|
||||
Point, Renderer, Size, Subscription, Task, Theme, Vector,
|
||||
futures::io::Window,
|
||||
mouse,
|
||||
Point, Renderer, Size, Subscription, Task, Theme, mouse,
|
||||
widget::{
|
||||
Canvas, button,
|
||||
canvas::{Frame, Program},
|
||||
@@ -18,13 +15,13 @@ use iced::{
|
||||
window::{self, Id, Settings},
|
||||
};
|
||||
use nes_emu::{
|
||||
NES, PPU, RenderBuffer,
|
||||
header_menu::header_menu,
|
||||
hex_view::{self, HexEvent, HexView},
|
||||
debugger::{DebuggerMessage, DebuggerState}, header_menu::header_menu, hex_view::{HexEvent, HexView}, NES, PPU
|
||||
};
|
||||
use tracing::{debug, info};
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "basic_init_1.nes");
|
||||
// const ROM_FILE: &str = "./Super Mario Bros. (World).nes";
|
||||
|
||||
extern crate nes_emu;
|
||||
|
||||
fn main() -> Result<(), iced::Error> {
|
||||
@@ -32,16 +29,11 @@ fn main() -> Result<(), iced::Error> {
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.init();
|
||||
|
||||
iced::daemon(Emulator::title, Emulator::update, Emulator::view)
|
||||
iced::daemon(Emulator::new, Emulator::update, Emulator::view)
|
||||
.subscription(Emulator::subscriptions)
|
||||
.theme(|_, _| Theme::Dark)
|
||||
.run_with(Emulator::new)
|
||||
|
||||
// iced::application(title, Emulator::update, Emulator::view)
|
||||
// .subscription(Emulator::subscriptions)
|
||||
// .theme(|_| Theme::Dark)
|
||||
// .centered()
|
||||
// .run()
|
||||
.theme(Theme::Dark)
|
||||
.title(Emulator::title)
|
||||
.run()
|
||||
}
|
||||
|
||||
enum MemoryTy {
|
||||
@@ -53,6 +45,7 @@ enum WindowType {
|
||||
Memory(MemoryTy, HexView),
|
||||
TileMap,
|
||||
TileViewer,
|
||||
Debugger,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -60,6 +53,7 @@ enum HeaderButton {
|
||||
OpenMemory,
|
||||
OpenTileMap,
|
||||
OpenTileViewer,
|
||||
OpenDebugger,
|
||||
Reset,
|
||||
PowerCycle,
|
||||
}
|
||||
@@ -70,6 +64,7 @@ impl fmt::Display for HeaderButton {
|
||||
Self::OpenMemory => write!(f, "Open Memory Viewer"),
|
||||
Self::OpenTileMap => write!(f, "Open TileMap Viewer"),
|
||||
Self::OpenTileViewer => write!(f, "Open Tile Viewer"),
|
||||
Self::OpenDebugger => write!(f, "Open Debugger"),
|
||||
Self::Reset => write!(f, "Reset"),
|
||||
Self::PowerCycle => write!(f, "Power Cycle"),
|
||||
}
|
||||
@@ -79,6 +74,7 @@ impl fmt::Display for HeaderButton {
|
||||
struct Emulator {
|
||||
nes: NES,
|
||||
windows: HashMap<Id, WindowType>,
|
||||
debugger: DebuggerState,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -92,13 +88,12 @@ enum Message {
|
||||
WindowClosed(Id),
|
||||
Header(HeaderButton),
|
||||
Hex(Id, HexEvent),
|
||||
Debugger(DebuggerMessage),
|
||||
}
|
||||
|
||||
impl Emulator {
|
||||
fn new() -> (Self, Task<Message>) {
|
||||
let rom_file = concat!(env!("ROM_DIR"), "/", "basic_init_1.nes");
|
||||
// let rom_file = "./Super Mario Bros. (World).nes";
|
||||
let mut nes = nes_emu::NES::load_nes_file(rom_file)
|
||||
let mut nes = nes_emu::NES::load_nes_file(ROM_FILE)
|
||||
.expect("Failed to load nes file");
|
||||
nes.reset();
|
||||
let (win, task) = iced::window::open(Settings::default());
|
||||
@@ -106,6 +101,7 @@ impl Emulator {
|
||||
Self {
|
||||
nes,
|
||||
windows: HashMap::from_iter([(win, WindowType::Main)]),
|
||||
debugger: DebuggerState::new(),
|
||||
},
|
||||
task.map(Message::WindowOpened),
|
||||
)
|
||||
@@ -116,6 +112,7 @@ impl Emulator {
|
||||
Some(WindowType::Memory(_, _)) => "NES MemoryView".into(),
|
||||
Some(WindowType::TileMap) => "NES TileMap".into(),
|
||||
Some(WindowType::TileViewer) => "NES Tile Viewer".into(),
|
||||
Some(WindowType::Debugger) => "NES Debugger".into(),
|
||||
None => todo!(),
|
||||
}
|
||||
}
|
||||
@@ -129,38 +126,42 @@ impl Emulator {
|
||||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Tick(count) => {
|
||||
for _ in 0..count {
|
||||
self.nes.run_one_clock_cycle();
|
||||
}
|
||||
}
|
||||
for _ in 0..count {
|
||||
self.nes.run_one_clock_cycle();
|
||||
}
|
||||
}
|
||||
Message::Frame => while !self.nes.run_one_clock_cycle().ppu_frame {},
|
||||
Message::DMA => while !self.nes.run_one_clock_cycle().dma {},
|
||||
Message::CPU => while !self.nes.run_one_clock_cycle().cpu_exec {},
|
||||
Message::DebugInt => while !self.nes.run_one_clock_cycle().dbg_int {},
|
||||
Message::WindowOpened(id) => {
|
||||
// Window
|
||||
}
|
||||
Message::WindowOpened(_id) => {
|
||||
// Window
|
||||
}
|
||||
Message::WindowClosed(id) => {
|
||||
if let Some(WindowType::Main) = self.windows.remove(&id) {
|
||||
return iced::exit();
|
||||
}
|
||||
}
|
||||
if let Some(WindowType::Main) = self.windows.remove(&id) {
|
||||
return iced::exit();
|
||||
}
|
||||
}
|
||||
Message::Header(HeaderButton::OpenMemory) => {
|
||||
return self.open(WindowType::Memory(MemoryTy::Cpu, HexView::new()));
|
||||
}
|
||||
return self.open(WindowType::Memory(MemoryTy::Cpu, HexView::new()));
|
||||
}
|
||||
Message::Header(HeaderButton::OpenTileMap) => {
|
||||
return self.open(WindowType::TileMap);
|
||||
}
|
||||
return self.open(WindowType::TileMap);
|
||||
}
|
||||
Message::Header(HeaderButton::OpenTileViewer) => {
|
||||
return self.open(WindowType::TileViewer);
|
||||
}
|
||||
return self.open(WindowType::TileViewer);
|
||||
}
|
||||
Message::Header(HeaderButton::OpenDebugger) => {
|
||||
return self.open(WindowType::Debugger);
|
||||
}
|
||||
Message::Hex(id, val) => {
|
||||
if let Some(WindowType::Memory(_, view)) = self.windows.get_mut(&id) {
|
||||
return view.update(val).map(move |e| Message::Hex(id, e));
|
||||
}
|
||||
}
|
||||
if let Some(WindowType::Memory(_, view)) = self.windows.get_mut(&id) {
|
||||
return view.update(val).map(move |e| Message::Hex(id, e));
|
||||
}
|
||||
}
|
||||
Message::Header(HeaderButton::Reset) => { self.nes.reset(); }
|
||||
Message::Header(HeaderButton::PowerCycle) => { self.nes.power_cycle(); }
|
||||
Message::Debugger(debugger_message) => self.debugger.update(debugger_message, &mut self.nes),
|
||||
}
|
||||
// self.image.0.clone_from(self.nes.image());
|
||||
Task::none()
|
||||
@@ -197,7 +198,11 @@ impl Emulator {
|
||||
Some(WindowType::TileViewer) => {
|
||||
container(Canvas::new(DbgImage::NameTable(self.nes.ppu()))).width(Fill).height(Fill).into()
|
||||
}
|
||||
_ => todo!(),
|
||||
Some(WindowType::Debugger) => {
|
||||
container(self.debugger.view(&self.nes).map(Message::Debugger)).width(Fill).height(Fill).into()
|
||||
}
|
||||
None => panic!("Window not found"),
|
||||
// _ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,6 +240,7 @@ impl Emulator {
|
||||
header_menu(
|
||||
"Debugging",
|
||||
[
|
||||
HeaderButton::OpenDebugger,
|
||||
HeaderButton::OpenMemory,
|
||||
HeaderButton::OpenTileMap,
|
||||
HeaderButton::OpenTileViewer,
|
||||
@@ -252,13 +258,13 @@ impl Program<Message> for Emulator {
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
_state: &Self::State,
|
||||
renderer: &Renderer,
|
||||
theme: &Theme,
|
||||
bounds: iced::Rectangle,
|
||||
_theme: &Theme,
|
||||
_bounds: iced::Rectangle,
|
||||
_cursor: mouse::Cursor,
|
||||
) -> Vec<iced::widget::canvas::Geometry<Renderer>> {
|
||||
const SIZE: f32 = 2.;
|
||||
// const SIZE: f32 = 2.;
|
||||
let mut frame = Frame::new(
|
||||
renderer,
|
||||
iced::Size {
|
||||
@@ -291,13 +297,13 @@ impl Program<Message> for DbgImage<'_> {
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
_state: &Self::State,
|
||||
renderer: &Renderer,
|
||||
theme: &Theme,
|
||||
bounds: iced::Rectangle,
|
||||
_theme: &Theme,
|
||||
_bounds: iced::Rectangle,
|
||||
_cursor: mouse::Cursor,
|
||||
) -> Vec<iced::widget::canvas::Geometry<Renderer>> {
|
||||
const SIZE: f32 = 2.;
|
||||
// const SIZE: f32 = 2.;
|
||||
let mut name_table_frame =
|
||||
Frame::new(renderer, Size::new(256. * 4. + 260. * 2., 256. * 4.));
|
||||
name_table_frame.scale(2.);
|
||||
|
||||
Reference in New Issue
Block a user