diff --git a/src/bus.rs b/src/bus.rs index 8e67482..60de4d2 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -11,15 +11,15 @@ use std::{ /// Creates a new bus, instantiating BusConnectable devices /// # Examples /// ```rust -/// # use chumpulator::prelude::*; +/// # use chirp::prelude::*; /// let mut bus = bus! { -/// "RAM" [0x0000..0x8000], -/// "ROM" [0x8000..0xFFFF], +/// Stack [0x0000..0x0800] = b"ABCDEF", +/// Program [0x0800..0x1000] = include_bytes!("bus.rs"), /// }; /// ``` #[macro_export] macro_rules! bus { - ($($name:literal $(:)? [$range:expr] $(= $data:expr)?) ,* $(,)?) => { + ($($name:path $(:)? [$range:expr] $(= $data:expr)?) ,* $(,)?) => { $crate::bus::Bus::new() $( .add_region($name, $range) @@ -43,14 +43,30 @@ pub trait Write { fn write(&mut self, addr: impl Into, data: T); } -#[derive(Clone, Copy, Debug)] -pub enum Region {} +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Region { + Charset, + Program, + Screen, + Stack, +} + +impl Display for Region { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", match self { + Region::Charset => "charset", + Region::Program => "program", + Region::Screen => "screen", + Region::Stack => "stack", + }) + } +} /// Store memory in a series of named regions with ranges -#[derive(Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq)] pub struct Bus { memory: Vec, - region: HashMap<&'static str, Range>, + region: HashMap>, } impl Bus { @@ -66,25 +82,25 @@ impl Bus { pub fn is_empty(&self) -> bool { self.memory.is_empty() } - /// Grows the NewBus backing memory to at least size bytes, but does not truncate + /// Grows the Bus backing memory to at least size bytes, but does not truncate pub fn with_size(&mut self, size: usize) { if self.len() < size { self.memory.resize(size, 0); } } - pub fn add_region(mut self, name: &'static str, range: Range) -> Self { + pub fn add_region(mut self, name: Region, range: Range) -> Self { self.with_size(range.end); self.region.insert(name, range); self } - pub fn load_region(mut self, name: &str, data: &[u8]) -> Self { + pub fn load_region(mut self, name: Region, data: &[u8]) -> Self { use std::io::Write; if let Some(mut region) = self.get_region_mut(name) { - dbg!(region.write(data)).ok(); // TODO: THIS SUCKS + region.write(data).ok(); // TODO: THIS SUCKS } self } - pub fn clear_region(&mut self, name: &str) -> &mut Self { + pub fn clear_region(&mut self, name: Region) -> &mut Self { if let Some(region) = self.get_region_mut(name) { region.fill(0) } @@ -105,15 +121,15 @@ impl Bus { self.memory.get_mut(index) } /// Gets a slice of a named region of memory - pub fn get_region(&self, name: &str) -> Option<&[u8]> { - self.get(self.region.get(name)?.clone()) + pub fn get_region(&self, name: Region) -> Option<&[u8]> { + self.get(self.region.get(&name)?.clone()) } /// Gets a mutable slice to a named region of memory - pub fn get_region_mut(&mut self, name: &str) -> Option<&mut [u8]> { - self.get_mut(self.region.get(name)?.clone()) + pub fn get_region_mut(&mut self, name: Region) -> Option<&mut [u8]> { + self.get_mut(self.region.get(&name)?.clone()) } pub fn print_screen(&self) -> Result<()> { - const REGION: &str = "screen"; + const REGION: Region = Region::Screen; if let Some(screen) = self.get_region(REGION) { for (index, byte) in screen.iter().enumerate() { if index % 8 == 0 { diff --git a/src/cpu.rs b/src/cpu.rs index faf000f..d711c14 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -3,7 +3,7 @@ pub mod disassemble; use self::disassemble::Disassemble; -use crate::bus::{Bus, Read, Write}; +use crate::bus::{Bus, Read, Region, Write}; use owo_colors::OwoColorize; use rand::random; use std::time::Instant; @@ -99,6 +99,7 @@ impl CPU { /// ```rust /// # use chumpulator::prelude::*; /// let mut cpu = CPU::new(0xf00, 0x50, 0x200, 0xefe, Disassemble::default()); + /// let mut cpu = CPU::new(0xf00, 0x50, 0x200, 0xefe, Disassemble::default(), vec![], ControlFlags::default()); /// ``` pub fn new(screen: Adr, font: Adr, pc: Adr, sp: Adr, disassembler: Disassemble) -> Self { CPU { @@ -383,7 +384,7 @@ impl CPU { /// 00e0: Clears the screen memory to 0 #[inline] fn clear_screen(&mut self, bus: &mut Bus) { - if let Some(screen) = bus.get_region_mut("screen") { + if let Some(screen) = bus.get_region_mut(Region::Screen) { for byte in screen { *byte = 0; } diff --git a/src/io.rs b/src/io.rs index 0bfb863..d62dc47 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,6 +1,6 @@ //! -use crate::{bus::Bus, cpu::CPU, error::Result}; +use crate::{bus::{Bus, Region}, cpu::CPU, error::Result}; use minifb::*; #[derive(Clone, Copy, Debug)] @@ -75,7 +75,7 @@ impl FrameBuffer { } } pub fn render(&mut self, window: &mut Window, bus: &Bus) { - if let Some(screen) = bus.get_region("screen") { + if let Some(screen) = bus.get_region(Region::Screen) { for (idx, byte) in screen.iter().enumerate() { for bit in 0..8 { self.buffer[8 * idx + bit] = if byte & (1 << 7 - bit) as u8 != 0 { diff --git a/src/lib.rs b/src/lib.rs index 7c10aa9..eaf9868 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,17 +9,17 @@ Hopefully, though, you'll find some use in it. pub mod bus; pub mod cpu; +pub mod error; pub mod io; pub mod dump; -pub mod error; /// Common imports for chumpulator pub mod prelude { use super::*; pub use crate::bus; - pub use bus::{Bus, Read, Write}; pub use cpu::{disassemble::Disassemble, CPU}; pub use dump::{BinDumpable, Dumpable}; pub use io::{*, WindowBuilder}; + pub use bus::{Bus, Read, Region::*, Write}; }