Skip to content

Commit

Permalink
Merge branch 'bc/trace' into as/apple-iie
Browse files Browse the repository at this point in the history
  • Loading branch information
miakizz committed Dec 27, 2023
2 parents 1125127 + 7c62e39 commit d16aa00
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 3 deletions.
16 changes: 16 additions & 0 deletions src/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod execute;
mod fetch;
mod registers;
use crate::memory::{ActiveInterrupt, Memory, SystemInfo};
use crate::trace::{CpuTrace, TraceHandler};
use execute::Execute;
use fetch::Fetch;
use registers::{flags, Registers};
Expand All @@ -23,6 +24,7 @@ pub struct Mos6502 {
cycle_count: u64,
cycles_since_poll: u32,
variant: Mos6502Variant,
trace: Option<Box<dyn TraceHandler>>,
}

/// Read and write from the system's memory.
Expand Down Expand Up @@ -142,9 +144,14 @@ impl Mos6502 {
cycle_count: 0,
cycles_since_poll: 0,
variant,
trace: None,
}
}

pub fn attach_trace_handler(&mut self, trace: Box<dyn TraceHandler>) {
self.trace = Some(trace);
}

pub fn reset(&mut self) {
self.memory.reset();
self.registers.reset();
Expand All @@ -162,6 +169,15 @@ impl Mos6502 {
/// Execute a single instruction.
pub fn tick(&mut self) -> u8 {
let opcode = self.fetch();

if let Some(handler) = &mut self.trace {
let trace = CpuTrace {
opcode,
address: self.registers.pc.address() - 1,
};
handler.handle(&trace);
}

match self.execute(opcode) {
Ok(cycles) => {
self.cycle_count += cycles as u64;
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub mod roms;
/// Systems are created by a [`systems::SystemBuilder`]. A system is created with some roms, configuration, and platform. For instance, the `build` implementation on [`systems::pet::PetSystemBuilder`] takes in [`systems::pet::PetSystemRoms`], [`systems::pet::PetSystemConfig`], and an `Arc<dyn PlatformProvider>`.
pub mod systems;

/// Traces log the state of the system as it runs (e.g., to a file). This is useful for debugging.
pub mod trace;

mod time;

#[cfg(target_arch = "wasm32")]
Expand Down
13 changes: 11 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,16 @@ struct Args {

#[clap(short, long, value_parser, default_value = "symbolic")]
key_mapping: KeyMappingArg,

#[clap(short, long, value_parser, default_value = "false")]
trace: bool,
}

#[cfg(not(target_arch = "wasm32"))]
fn main() {
use libnoentiendo::{cpu::Mos6502Variant, systems::klaus::KlausSystemConfig};
use libnoentiendo::{
cpu::Mos6502Variant, systems::klaus::KlausSystemConfig, trace::file::FileTraceHandler,
};

let args = Args::parse();

Expand All @@ -85,7 +90,7 @@ fn main() {
KeyMappingArg::Physical => KeyMappingStrategy::Physical,
};

let system = match args.system {
let mut system = match args.system {
SystemArg::Basic => BasicSystemBuilder::build(romfile.unwrap(), (), platform.provider()),
SystemArg::Easy => Easy6502SystemBuilder::build(romfile.unwrap(), (), platform.provider()),
SystemArg::Klaus => KlausSystemBuilder::build(
Expand Down Expand Up @@ -121,5 +126,9 @@ fn main() {
),
};

if args.trace {
system.attach_trace_handler(Box::new(FileTraceHandler::new("./cpu.trace".to_owned())));
}

platform.run(system);
}
5 changes: 5 additions & 0 deletions src/systems/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::memory::{BlockMemory, BranchMemory};
use crate::platform::{PlatformProvider, WindowConfig};
use crate::roms::RomFile;
use crate::systems::{System, SystemBuilder};
use crate::trace::TraceHandler;
use std::io::Write;
use std::sync::Arc;

Expand Down Expand Up @@ -91,6 +92,10 @@ pub struct BasicSystem {
}

impl System for BasicSystem {
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>) {
self.cpu.attach_trace_handler(handler);
}

fn tick(&mut self) -> Duration {
Duration::from_secs_f64(1.0 / 20_000.0) * self.cpu.tick().into()
}
Expand Down
5 changes: 5 additions & 0 deletions src/systems/c64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
},
platform::{PlatformProvider, WindowConfig},
systems::System,
trace::TraceHandler,
};

mod keyboard;
Expand Down Expand Up @@ -320,6 +321,10 @@ pub struct C64System {
}

impl System for C64System {
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>) {
self.cpu.attach_trace_handler(handler);
}

fn tick(&mut self) -> Duration {
Duration::from_secs_f64(1.0 / 1_000_000.0) * self.cpu.tick() as u32
}
Expand Down
5 changes: 5 additions & 0 deletions src/systems/easy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::memory::{ActiveInterrupt, BlockMemory, BranchMemory, Memory, SystemIn
use crate::platform::{Color, PlatformProvider, WindowConfig};
use crate::roms::RomFile;
use crate::systems::{System, SystemBuilder};
use crate::trace::TraceHandler;
use std::sync::Arc;

const WIDTH: u32 = 32;
Expand Down Expand Up @@ -92,6 +93,10 @@ pub struct Easy6502System {
}

impl System for Easy6502System {
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>) {
self.cpu.attach_trace_handler(handler);
}

fn tick(&mut self) -> Duration {
Duration::from_secs_f64(1.0 / 20_000.0) * self.cpu.tick().into()
}
Expand Down
5 changes: 5 additions & 0 deletions src/systems/klaus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::memory::BlockMemory;
use crate::platform::{PlatformProvider, WindowConfig};
use crate::roms::RomFile;
use crate::systems::System;
use crate::trace::TraceHandler;
use std::cell::Cell;
use std::rc::Rc;
use std::sync::Arc;
Expand Down Expand Up @@ -44,6 +45,10 @@ pub struct KlausSystem {
}

impl System for KlausSystem {
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>) {
self.cpu.attach_trace_handler(handler);
}

fn tick(&mut self) -> Duration {
self.cpu.tick();
if let Some(pc) = &self.pc {
Expand Down
8 changes: 7 additions & 1 deletion src/systems/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::platform::{PlatformProvider, WindowConfig};
use crate::{
platform::{PlatformProvider, WindowConfig},
trace::TraceHandler,
};
use instant::Duration;
use std::sync::Arc;

Expand All @@ -22,6 +25,9 @@ pub trait SystemBuilder<SystemType, RomRegistry, SystemConfig> {

/// A representation of an emulated system.
pub trait System {
/// Attach a trace handler to the CPU in this sytem.
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>);

/// Advance the system by one tick.
fn tick(&mut self) -> Duration;

Expand Down
5 changes: 5 additions & 0 deletions src/systems/pet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::memory::mos652x::{Pia, Via};
use crate::memory::{BlockMemory, BranchMemory, NullMemory, NullPort, Port, SystemInfo};
use crate::platform::{Color, PlatformProvider, WindowConfig};
use crate::systems::{System, SystemBuilder};
use crate::trace::TraceHandler;
use instant::Instant;
use std::cell::Cell;
use std::rc::Rc;
Expand Down Expand Up @@ -210,6 +211,10 @@ pub struct PetSystem {
}

impl System for PetSystem {
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>) {
self.cpu.attach_trace_handler(handler);
}

fn tick(&mut self) -> Duration {
Duration::from_secs_f64(1.0 / 1_000_000.0) * self.cpu.tick() as u32
}
Expand Down
5 changes: 5 additions & 0 deletions src/systems/vic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::memory::{BlockMemory, BranchMemory, NullMemory, NullPort, Port, Syste
use crate::platform::{PlatformProvider, WindowConfig};
use crate::roms::RomFile;
use crate::systems::System;
use crate::trace::TraceHandler;
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use std::sync::Arc;
Expand Down Expand Up @@ -311,6 +312,10 @@ pub struct Vic20System {
}

impl System for Vic20System {
fn attach_trace_handler(&mut self, handler: Box<dyn TraceHandler>) {
self.cpu.attach_trace_handler(handler);
}

fn tick(&mut self) -> instant::Duration {
Duration::from_secs_f64(1.0 / 1_000_000.0) * self.cpu.tick() as u32
}
Expand Down
23 changes: 23 additions & 0 deletions src/trace/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::trace::{CpuTrace, TraceHandler};
use std::{fs::File, io::Write};

pub struct FileTraceHandler {
file: File,
}

impl FileTraceHandler {
pub fn new(filename: String) -> Self {
Self {
file: File::create(filename).expect("Invalid filename"),
}
}
}

impl TraceHandler for FileTraceHandler {
fn handle(&mut self, trace: &CpuTrace) {
self
.file
.write_all(format!("{:04X}: {:02X}\n", trace.address, trace.opcode).as_bytes())
.unwrap();
}
}
14 changes: 14 additions & 0 deletions src/trace/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#[cfg(not(target_arch = "wasm32"))]
pub mod file;

/// Trace information provided after each instruction by the CPU.
pub struct CpuTrace {
pub address: u16,
pub opcode: u8,
}

/// An item which can handle a CPU trace (e.g. logging to a file)
pub trait TraceHandler {
/// Handle a trace event.
fn handle(&mut self, trace: &CpuTrace);
}

0 comments on commit d16aa00

Please sign in to comment.