lib.rs: Remove crate::prelude, re-export in lib.rs
This commit is contained in:
parent
bb8015f33c
commit
a4c548d0ec
@ -1,4 +1,4 @@
|
||||
use chirp::{cpu::Disassembler, error::Result, prelude::*};
|
||||
use chirp::{cpu::Disassembler, error::Result, *};
|
||||
use gumdrop::*;
|
||||
use owo_colors::OwoColorize;
|
||||
use std::{fs::read, path::PathBuf};
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![allow(unused_imports)]
|
||||
use chirp::prelude::*;
|
||||
use chirp::*;
|
||||
#[cfg(features = "iced")]
|
||||
use iced::{
|
||||
executor, time, window, Alignment, Application, Command, Element, Length, Settings,
|
||||
|
@ -4,19 +4,20 @@
|
||||
//! Chirp: A chip-8 interpreter in Rust
|
||||
//! Hello, world!
|
||||
|
||||
mod io;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod ui;
|
||||
|
||||
use chirp::{error::Result, prelude::*};
|
||||
use chirp::error::Error::BreakpointHit;
|
||||
use chirp::{error::Result, *};
|
||||
use gumdrop::*;
|
||||
use io::*;
|
||||
use owo_colors::OwoColorize;
|
||||
use std::fs::read;
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use ui::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Options, Hash)]
|
||||
struct Arguments {
|
||||
@ -136,10 +137,10 @@ impl State {
|
||||
state.ch8.bus.write(0x1feu16, options.data);
|
||||
Ok(state)
|
||||
}
|
||||
fn keys(&mut self) -> Result<Option<()>> {
|
||||
fn keys(&mut self) -> Result<bool> {
|
||||
self.ui.keys(&mut self.ch8)
|
||||
}
|
||||
fn frame(&mut self) -> Option<()> {
|
||||
fn frame(&mut self) -> Result<bool> {
|
||||
self.ui.frame(&mut self.ch8)
|
||||
}
|
||||
fn tick_cpu(&mut self) -> Result<()> {
|
||||
@ -180,14 +181,23 @@ impl Iterator for State {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.wait_for_next_frame();
|
||||
match self.keys() {
|
||||
Ok(opt) => opt?,
|
||||
Err(e) => return Some(Err(e)), // summary
|
||||
Ok(opt) if !opt => return None,
|
||||
Err(e) => return Some(Err(e)), // summary lol
|
||||
_ => (),
|
||||
}
|
||||
self.keys().unwrap_or(None)?;
|
||||
if let Err(e) = self.tick_cpu() {
|
||||
return Some(Err(e));
|
||||
// Allow breakpoint hit messages
|
||||
match self.tick_cpu() {
|
||||
Err(BreakpointHit { addr, next }) => {
|
||||
eprintln!("Breakpoint hit: {:3x} ({:4x})", addr, next);
|
||||
}
|
||||
Err(e) => return Some(Err(e)),
|
||||
_ => (),
|
||||
}
|
||||
match self.frame() {
|
||||
Ok(opt) if !opt => return None,
|
||||
Err(e) => return Some(Err(e)),
|
||||
_ => (),
|
||||
}
|
||||
self.frame()?;
|
||||
Some(Ok(()))
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Tests for chirp-minifb
|
||||
|
||||
use super::io::*;
|
||||
use chirp::prelude::*;
|
||||
use super::ui::*;
|
||||
use chirp::*;
|
||||
use std::{collections::hash_map::DefaultHasher, hash::Hash};
|
||||
|
||||
mod ui_builder {
|
||||
|
@ -104,7 +104,7 @@ impl FrameBuffer {
|
||||
format: Default::default(),
|
||||
}
|
||||
}
|
||||
pub fn render(&mut self, window: &mut Window, bus: &Bus) {
|
||||
pub fn render(&mut self, window: &mut Window, bus: &Bus) -> Result<()> {
|
||||
if let Some(screen) = bus.get_region(Region::Screen) {
|
||||
for (idx, byte) in screen.iter().enumerate() {
|
||||
for bit in 0..8 {
|
||||
@ -116,10 +116,8 @@ impl FrameBuffer {
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: NOT THIS
|
||||
window
|
||||
.update_with_buffer(&self.buffer, self.width, self.height)
|
||||
.expect("The window manager should update the buffer.");
|
||||
window.update_with_buffer(&self.buffer, self.width, self.height)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,8 +137,7 @@ pub struct UI {
|
||||
}
|
||||
|
||||
impl UI {
|
||||
pub fn frame(&mut self, ch8: &mut Chip8) -> Option<()> {
|
||||
{
|
||||
pub fn frame(&mut self, ch8: &mut Chip8) -> Result<bool> {
|
||||
if ch8.cpu.flags.pause {
|
||||
self.window.set_title("Chirp ⏸")
|
||||
} else {
|
||||
@ -150,16 +147,15 @@ impl UI {
|
||||
));
|
||||
}
|
||||
if !self.window.is_open() {
|
||||
std::process::exit(0);
|
||||
return Ok(false);
|
||||
}
|
||||
self.time = Instant::now();
|
||||
// update framebuffer
|
||||
self.fb.render(&mut self.window, &ch8.bus);
|
||||
}
|
||||
Some(())
|
||||
self.fb.render(&mut self.window, &ch8.bus)?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn keys(&mut self, ch8: &mut Chip8) -> Result<Option<()>> {
|
||||
pub fn keys(&mut self, ch8: &mut Chip8) -> Result<bool> {
|
||||
// TODO: Remove this hacky workaround for minifb's broken get_keys_* functions.
|
||||
let get_keys_pressed = || {
|
||||
self.window
|
||||
@ -173,7 +169,7 @@ impl UI {
|
||||
.into_iter()
|
||||
.filter(|key| !self.window.get_keys().contains(key))
|
||||
};
|
||||
use crate::io::Region::*;
|
||||
use crate::ui::Region::*;
|
||||
for key in get_keys_released() {
|
||||
if let Some(key) = identify_key(key) {
|
||||
ch8.cpu.release(key)?;
|
||||
@ -184,10 +180,7 @@ impl UI {
|
||||
use Key::*;
|
||||
match key {
|
||||
F1 | Comma => ch8.cpu.dump(),
|
||||
F2 | Period => ch8
|
||||
.bus
|
||||
.print_screen()
|
||||
.expect("The 'screen' memory region should exist"),
|
||||
F2 | Period => ch8.bus.print_screen()?,
|
||||
F3 => {
|
||||
debug_dump_screen(ch8, &self.rom).expect("Unable to write debug screen dump");
|
||||
}
|
||||
@ -226,7 +219,7 @@ impl UI {
|
||||
ch8.cpu.soft_reset();
|
||||
ch8.bus.clear_region(Screen);
|
||||
}
|
||||
Escape => return Ok(None),
|
||||
Escape => return Ok(false),
|
||||
key => {
|
||||
if let Some(key) = identify_key(key) {
|
||||
ch8.cpu.press(key)?;
|
||||
@ -235,7 +228,7 @@ impl UI {
|
||||
}
|
||||
}
|
||||
self.keyboard = self.window.get_keys();
|
||||
Ok(Some(()))
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use chirp::{error::Result, prelude::*};
|
||||
use chirp::{error::Result, *};
|
||||
use std::{env::args, fs::read};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
30
src/bus.rs
30
src/bus.rs
@ -15,7 +15,7 @@ use std::{
|
||||
/// Creates a new bus, growing the backing memory as needed
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut bus = bus! {
|
||||
/// Stack [0x0000..0x0800] = b"ABCDEF",
|
||||
/// Program [0x0800..0x1000] = include_bytes!("bus.rs"),
|
||||
@ -92,7 +92,7 @@ impl Bus {
|
||||
/// Constructs a new bus
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new();
|
||||
/// assert!(bus.is_empty());
|
||||
@ -106,7 +106,7 @@ impl Bus {
|
||||
/// Gets the length of the bus' backing memory
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Program, 0..1234);
|
||||
@ -121,7 +121,7 @@ impl Bus {
|
||||
/// Returns true if the backing memory contains no elements
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new();
|
||||
/// assert!(bus.is_empty());
|
||||
@ -134,7 +134,7 @@ impl Bus {
|
||||
/// Grows the Bus backing memory to at least size bytes, but does not truncate
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let mut bus = Bus::new();
|
||||
/// bus.with_size(1234);
|
||||
@ -152,7 +152,7 @@ impl Bus {
|
||||
/// Adds a new named range (Region) to the bus
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new().add_region(Program, 0..1234);
|
||||
/// assert_eq!(1234, bus.len());
|
||||
@ -169,7 +169,7 @@ impl Bus {
|
||||
/// Loads data into a named region
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Program, 0..1234)
|
||||
@ -188,7 +188,7 @@ impl Bus {
|
||||
/// Fills a named region with zeroes
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Program, 0..1234)
|
||||
@ -199,7 +199,7 @@ impl Bus {
|
||||
/// ```
|
||||
/// If the region doesn't exist, that's okay.
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Program, 0..1234)
|
||||
@ -218,7 +218,7 @@ impl Bus {
|
||||
/// Gets a slice of bus memory
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Program, 0..10);
|
||||
@ -236,7 +236,7 @@ impl Bus {
|
||||
/// Gets a mutable slice of bus memory
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let mut bus = Bus::new()
|
||||
/// .add_region(Program, 0..10);
|
||||
@ -254,7 +254,7 @@ impl Bus {
|
||||
/// Gets a slice of a named region of memory
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Program, 0..10);
|
||||
@ -269,7 +269,7 @@ impl Bus {
|
||||
/// Gets a mutable slice of a named region of memory
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let mut bus = Bus::new()
|
||||
/// .add_region(Program, 0..10);
|
||||
@ -286,7 +286,7 @@ impl Bus {
|
||||
///
|
||||
/// [Bus::print_screen] will print the screen
|
||||
/// ```rust
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let bus = Bus::new()
|
||||
/// .add_region(Screen, 0x000..0x100);
|
||||
@ -296,7 +296,7 @@ impl Bus {
|
||||
/// ```
|
||||
/// If there is no Screen region, it will return Err([MissingRegion])
|
||||
/// ```rust,should_panic
|
||||
///# use chirp::prelude::*;
|
||||
///# use chirp::*;
|
||||
///# fn main() -> Result<()> {
|
||||
/// let mut bus = Bus::new()
|
||||
/// .add_region(Program, 0..10);
|
||||
|
46
src/cpu.rs
46
src/cpu.rs
@ -95,7 +95,7 @@ impl ControlFlags {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(true, cpu.flags.debug);
|
||||
/// // Toggle debug mode
|
||||
@ -110,7 +110,7 @@ impl ControlFlags {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(false, cpu.flags.pause);
|
||||
/// // Pause the cpu
|
||||
@ -169,7 +169,7 @@ impl CPU {
|
||||
/// Constructs a new CPU, taking all configurable parameters
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let cpu = CPU::new(
|
||||
/// 0xf00, // screen location
|
||||
/// 0x50, // font location
|
||||
@ -207,7 +207,7 @@ impl CPU {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
///
|
||||
/// // press key `7`
|
||||
@ -238,7 +238,7 @@ impl CPU {
|
||||
/// and the [ControlFlags::lastkey] is recorded.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// // press key `7`
|
||||
/// cpu.press(0x7).unwrap();
|
||||
@ -269,7 +269,7 @@ impl CPU {
|
||||
/// If the register doesn't exist, returns [Error::InvalidRegister]
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// // Create a new CPU, and set v4 to 0x41
|
||||
/// let mut cpu = CPU::default();
|
||||
/// cpu.set_v(0x4, 0x41).unwrap();
|
||||
@ -288,7 +288,7 @@ impl CPU {
|
||||
/// Gets a slice of the entire general purpose registers
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// // Create a new CPU, and set v4 to 0x41
|
||||
/// let mut cpu = CPU::default();
|
||||
/// cpu.set_v(0x0, 0x41);
|
||||
@ -304,7 +304,7 @@ impl CPU {
|
||||
/// Gets the program counter
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(0x200, cpu.pc());
|
||||
/// ```
|
||||
@ -315,7 +315,7 @@ impl CPU {
|
||||
/// Gets the I register
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(0, cpu.i());
|
||||
/// ```
|
||||
@ -326,7 +326,7 @@ impl CPU {
|
||||
/// Gets the value in the Sound Timer register
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(0, cpu.sound());
|
||||
/// ```
|
||||
@ -337,7 +337,7 @@ impl CPU {
|
||||
/// Gets the value in the Delay Timer register
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(0, cpu.delay());
|
||||
/// ```
|
||||
@ -351,7 +351,7 @@ impl CPU {
|
||||
/// updated even when the CPU is in drawpause or keypause
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(0x0, cpu.cycle());
|
||||
/// ```
|
||||
@ -363,7 +363,7 @@ impl CPU {
|
||||
/// reinitializing the program counter to 0x200
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::new(
|
||||
/// 0xf00,
|
||||
/// 0x50,
|
||||
@ -416,7 +416,7 @@ impl CPU {
|
||||
/// Gets a slice of breakpoints
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// assert_eq!(cpu.breakpoints(), &[]);
|
||||
/// ```
|
||||
@ -433,7 +433,7 @@ impl CPU {
|
||||
/// NOTE: does not synchronize with delay timers
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// let mut bus = bus!{
|
||||
/// Program [0x0200..0x0f00] = &[
|
||||
@ -459,7 +459,7 @@ impl CPU {
|
||||
/// Ticks the timers every `rate` ticks
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// let mut bus = bus!{
|
||||
/// Program [0x0200..0x0f00] = &[
|
||||
@ -524,7 +524,7 @@ impl CPU {
|
||||
/// Executes a single instruction
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// let mut bus = bus!{
|
||||
/// Program [0x0200..0x0f00] = &[
|
||||
@ -540,7 +540,7 @@ impl CPU {
|
||||
/// ```
|
||||
/// Returns [Error::UnimplementedInstruction] if the instruction is not implemented.
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// # use chirp::error::Error;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// # cpu.flags.debug = true; // enable live disassembly
|
||||
@ -610,7 +610,7 @@ impl CPU {
|
||||
/// Dumps the current state of all CPU registers, and the cycle count
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use chirp::prelude::*;
|
||||
/// # use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// cpu.dump();
|
||||
/// ```
|
||||
@ -663,7 +663,7 @@ impl Default for CPU {
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// use chirp::prelude::*;
|
||||
/// use chirp::*;
|
||||
/// let mut cpu = CPU::default();
|
||||
/// ```
|
||||
fn default() -> Self {
|
||||
@ -689,9 +689,6 @@ impl Default for CPU {
|
||||
}
|
||||
}
|
||||
|
||||
// Below this point, comments may be duplicated per impl' block,
|
||||
// since some opcodes handle multiple instructions.
|
||||
|
||||
impl CPU {
|
||||
/// Executes a single [Insn]
|
||||
#[inline(always)]
|
||||
@ -736,6 +733,9 @@ impl CPU {
|
||||
}
|
||||
}
|
||||
|
||||
// Below this point, comments may be duplicated per impl' block,
|
||||
// since some opcodes handle multiple instructions.
|
||||
|
||||
// |`0aaa`| Issues a "System call" (ML routine)
|
||||
//
|
||||
// |opcode| effect |
|
||||
|
13
src/lib.rs
13
src/lib.rs
@ -12,15 +12,10 @@ pub mod bus;
|
||||
pub mod cpu;
|
||||
pub mod error;
|
||||
|
||||
/// Common imports for Chirp
|
||||
pub mod prelude {
|
||||
pub use super::Chip8;
|
||||
use super::*;
|
||||
pub use crate::bus;
|
||||
pub use bus::{Bus, Read, Region::*, Write};
|
||||
pub use cpu::{disassembler::Dis, ControlFlags, CPU};
|
||||
pub use error::Result;
|
||||
}
|
||||
// Common imports for Chirp
|
||||
pub use bus::{Bus, Read, Region::*, Write};
|
||||
pub use cpu::{disassembler::Dis, ControlFlags, CPU};
|
||||
pub use error::Result;
|
||||
|
||||
/// Holds the state of a Chip-8
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! These are a series of interpreter tests using Timendus's incredible test suite
|
||||
|
||||
pub use chirp::prelude::*;
|
||||
pub use chirp::*;
|
||||
|
||||
fn setup_environment() -> (CPU, Bus) {
|
||||
let mut cpu = CPU::default();
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Testing methods on Chirp's public API
|
||||
use chirp::prelude::*;
|
||||
use chirp::*;
|
||||
use std::{collections::hash_map::DefaultHasher, hash::Hash};
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user