From 43fa623da39c1e546dda685ec5c254cfea94281b Mon Sep 17 00:00:00 2001 From: John Breaux Date: Fri, 14 Apr 2023 22:20:30 -0500 Subject: [PATCH] Improve workflow and docs somewhat, make minifb optional --- Cargo.toml | 28 +++++++++++++++++++++++++--- justfile | 8 ++++---- readme.md | 1 + src/bin/chirp-disasm/main.rs | 34 +++++++++++++++++----------------- src/cpu.rs | 12 +++--------- src/cpu/disassembler.rs | 7 ++++++- src/cpu/flags.rs | 9 +++++++-- src/cpu/instruction.rs | 2 +- src/cpu/mode.rs | 3 +++ src/cpu/quirks.rs | 2 +- src/error.rs | 1 + src/lib.rs | 10 ++++++++-- 12 files changed, 77 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 05145dc..038b6f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,18 +1,40 @@ [package] name = "chirp" -version = "0.1.0" +version = "0.1.1" edition = "2021" +ignore = ["justfile", ".gitmodules", "chip8-test-suite", "chip8Archive"] +default-run = "chirp" authors = ["John Breaux"] license = "MIT" +publish = false + [features] -default = ["unstable", "drawille"] +default = ["unstable", "drawille", "minifb"] unstable = [] drawille = ["dep:drawille"] iced = ["dep:iced"] +minifb = ["dep:minifb"] rhexdump = ["dep:rhexdump"] serde = ["dep:serde"] +[[bin]] +name = "chirp" +path = "src/bin/chirp-minifb/main.rs" +required-features = ["minifb"] + +[[bin]] +name = "chirp-disasm" +required-features = ["default"] + +[[bin]] +name = "chirp-iced" +required-features = ["iced"] + +[[bin]] +name = "chirp-shot-viewer" +required-features = ["default", "drawille"] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [profile.release] opt-level = 3 @@ -31,10 +53,10 @@ drawille = {version = "0.3.0", optional = true} iced = {version = "0.8.0", optional = true} rhexdump = {version = "^0.1.1", optional = true } serde = { version = "^1.0", features = ["derive"], optional = true } +minifb = { version = "^0.24.0", optional = true } gumdrop = "^0.8.1" imperative-rs = "0.3.1" -minifb = { version = "^0.24.0" } owo-colors = "^3" rand = "^0.8.5" thiserror = "^1.0.39" diff --git a/justfile b/justfile index 496979f..ea37bb5 100644 --- a/justfile +++ b/justfile @@ -8,19 +8,19 @@ test: cargo nextest run run rom: - cargo run --bin chirp-minifb -- '{{rom}}' + cargo run -- '{{rom}}' debug rom: - cargo run --bin chirp-minifb -- -d '{{rom}}' + cargo run -- -d '{{rom}}' # Run at 2100000 instructions per frame, and output per-frame runtime statistics bench: - cargo run --bin chirp-minifb --release -- chip8Archive/roms/1dcell.ch8 -Ps10 -S2100000 -m xochip + cargo run --release -- chip8Archive/roms/1dcell.ch8 -Ps10 -S2100000 -m xochip flame rom: CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -F 15300 --open --bin chirp-minifb -- '{{rom}}' -s10 flamebench: - CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -F 15300 --open --bin chirp-minifb -- chip8Archive/roms/1dcell.ch8 -xPs10 -S2100000 + CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph -F 15300 --open --bin chirp-minifb -- chip8Archive/roms/1dcell.ch8 -Ps10 -S2100000 -m xochip cover: cargo llvm-cov --open --doctests diff --git a/readme.md b/readme.md index 0414ba4..791b83b 100644 --- a/readme.md +++ b/readme.md @@ -66,6 +66,7 @@ Optional arguments: ## TODO: +- [ ] Move the screen, stack, charset, and program memory into the CPU - [ ] Implement sound - [ ] Finish unit tests for "quirks" - [ ] Make pausing/unpausing the emulator less messy diff --git a/src/bin/chirp-disasm/main.rs b/src/bin/chirp-disasm/main.rs index fa0ac8f..8327581 100644 --- a/src/bin/chirp-disasm/main.rs +++ b/src/bin/chirp-disasm/main.rs @@ -1,24 +1,8 @@ -use chirp::{cpu::Disassembler, error::Result, *}; +use chirp::{error::Result, *}; use gumdrop::*; use owo_colors::OwoColorize; use std::{fs::read, path::PathBuf}; -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Options, Hash)] -struct Arguments { - #[options(help = "Show help text")] - help: bool, - #[options(help = "Load a ROM to run on Chirp", free, required)] - pub file: PathBuf, - #[options(help = "Load address (usually 200)", parse(try_from_str = "parse_hex"))] - pub loadaddr: u16, - #[options(help = "Start disassembling at offset...")] - pub offset: usize, -} - -fn parse_hex(value: &str) -> std::result::Result { - u16::from_str_radix(value, 16) -} - fn main() -> Result<()> { let options = Arguments::parse_args_default_or_exit(); let contents = &read(&options.file)?; @@ -40,3 +24,19 @@ fn main() -> Result<()> { } Ok(()) } + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Options, Hash)] +struct Arguments { + #[options(help = "Show help text")] + help: bool, + #[options(help = "Load a ROM to run on Chirp", free, required)] + pub file: PathBuf, + #[options(help = "Load address (usually 200)", parse(try_from_str = "parse_hex"))] + pub loadaddr: u16, + #[options(help = "Start disassembling at offset...")] + pub offset: usize, +} + +fn parse_hex(value: &str) -> std::result::Result { + u16::from_str_radix(value, 16) +} diff --git a/src/cpu.rs b/src/cpu.rs index bd0f905..23749ae 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -6,12 +6,6 @@ #[cfg(test)] mod tests; -/// Disassembles Chip-8 instructions -pub trait Disassembler { - /// Disassemble a single instruction - fn once(&self, insn: u16) -> String; -} - pub mod disassembler; pub mod flags; pub mod instruction; @@ -19,7 +13,7 @@ pub mod mode; pub mod quirks; use self::{ - disassembler::{Dis, Insn}, + disassembler::{Dis, Disassembler, Insn}, flags::Flags, mode::Mode, quirks::Quirks, @@ -57,7 +51,7 @@ impl Default for Timers { #[derive(Clone, Debug, PartialEq)] pub struct CPU { /// Flags that control how the CPU behaves, but which aren't inherent to the - /// implementation. Includes [Quirks], target IPF, etc. + /// chip-8. Includes [Quirks], target IPF, etc. pub flags: Flags, // memory map info screen: Adr, @@ -478,7 +472,7 @@ impl CPU { /// ``` pub fn tick(&mut self, bus: &mut Bus) -> Result<&mut Self> { // Do nothing if paused - if self.flags.pause || self.flags.draw_wait || self.flags.keypause { + if self.flags.is_paused() { // always tick in test mode if self.flags.monotonic.is_some() { self.cycle += 1; diff --git a/src/cpu/disassembler.rs b/src/cpu/disassembler.rs index e8b5092..94ec4ad 100644 --- a/src/cpu/disassembler.rs +++ b/src/cpu/disassembler.rs @@ -1,10 +1,15 @@ //! A disassembler for Chip-8 opcodes #![allow(clippy::bad_bit_mask)] -use super::Disassembler; use imperative_rs::InstructionSet; use owo_colors::{OwoColorize, Style}; use std::fmt::Display; +/// Disassembles Chip-8 instructions +pub trait Disassembler { + /// Disassemble a single instruction + fn once(&self, insn: u16) -> String; +} + #[allow(non_camel_case_types, non_snake_case, missing_docs)] #[derive(Clone, Copy, Debug, InstructionSet, PartialEq, Eq)] /// Implements a Disassembler using imperative_rs diff --git a/src/cpu/flags.rs b/src/cpu/flags.rs index 4acd8f0..b9c05b7 100644 --- a/src/cpu/flags.rs +++ b/src/cpu/flags.rs @@ -1,8 +1,8 @@ -//! Represents flags that aid in implementation but aren't a part of the Chip-8 spec +//! Represents [Flags] that aid in implementation but aren't a part of the Chip-8 spec use super::{Mode, Quirks}; -/// Represents flags that aid in operation, but aren't inherent to the CPU +/// Represents flags that aid in implementation but aren't a part of the Chip-8 spec #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Flags { /// Set when debug (live disassembly) mode enabled @@ -55,4 +55,9 @@ impl Flags { pub fn pause(&mut self) { self.pause = !self.pause } + + /// Gets whether the CPU is paused for any reason + pub fn is_paused(&self) -> bool { + self.pause || self.draw_wait || self.keypause + } } diff --git a/src/cpu/instruction.rs b/src/cpu/instruction.rs index 5db5019..99386fc 100644 --- a/src/cpu/instruction.rs +++ b/src/cpu/instruction.rs @@ -1,7 +1,7 @@ // (c) 2023 John A. Breaux // This code is licensed under MIT license (see LICENSE.txt for details) -//! Contains implementations for each instruction defined in [super::disassembler] +//! Contains implementations for each [Insn] as private member functions of [CPU] use super::*; diff --git a/src/cpu/mode.rs b/src/cpu/mode.rs index 5e42e87..3397d76 100644 --- a/src/cpu/mode.rs +++ b/src/cpu/mode.rs @@ -1,4 +1,7 @@ //! Selects the memory behavior of the [super::CPU] +//! +//! Since [super::Quirks] implements [From], +//! this can be used to select the appropriate quirk-set use crate::error::Error; use std::str::FromStr; diff --git a/src/cpu/quirks.rs b/src/cpu/quirks.rs index 90a5af2..4f2e283 100644 --- a/src/cpu/quirks.rs +++ b/src/cpu/quirks.rs @@ -1,4 +1,4 @@ -//! Controls the authenticity behavior of the CPU on a granular level. +//! Controls the [Quirks] behavior of the CPU on a granular level. use super::Mode; /// Controls the authenticity behavior of the CPU on a granular level. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/error.rs b/src/error.rs index fc3e995..2212e89 100644 --- a/src/error.rs +++ b/src/error.rs @@ -64,6 +64,7 @@ pub enum Error { /// Error originated in [std::array::TryFromSliceError] #[error(transparent)] TryFromSliceError(#[from] std::array::TryFromSliceError), + #[cfg(feature = "minifb")] /// Error originated in [minifb] #[error(transparent)] MinifbError(#[from] minifb::Error), diff --git a/src/lib.rs b/src/lib.rs index 3ef8738..ec24a46 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,8 +14,14 @@ pub mod error; // Common imports for Chirp pub use bus::{Bus, Read, Region::*, Write}; -pub use cpu::{disassembler::Dis, flags::Flags, mode::Mode, quirks::Quirks, CPU}; -pub use error::Result; +pub use cpu::{ + disassembler::{Dis, Disassembler}, + flags::Flags, + mode::Mode, + quirks::Quirks, + CPU, +}; +pub use error::{Error, Result}; /// Holds the state of a Chip-8 #[derive(Clone, Debug, Default, PartialEq)]