diff --git a/src/display.rs b/src/display.rs index 9a29593..bfed099 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,4 +1,3 @@ - /// Represents the display's width in pixels. const DISPLAY_WIDTH: usize = 64; @@ -22,7 +21,7 @@ pub struct TerminalDisplay { impl TerminalDisplay { pub fn new() -> TerminalDisplay { TerminalDisplay { - display_data: [false; DISPLAY_WIDTH * DISPLAY_HEIGHT] + display_data: [false; DISPLAY_WIDTH * DISPLAY_HEIGHT], } } } @@ -47,4 +46,4 @@ impl Display for TerminalDisplay { print!("\n") } } -} \ No newline at end of file +} diff --git a/src/emulator.rs b/src/emulator.rs index 6e04525..99c2e90 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -1,9 +1,10 @@ +use crate::display::Display; +use crate::stack::Stack; use anyhow::anyhow; use log::{debug, info}; use std::fs::File; use std::io::Read; -use std::path::{Path}; -use crate::display::{Display}; +use std::path::Path; const MEMORY_SIZE: usize = 4096; const NUMBER_OF_REGISTERS: usize = 16; @@ -27,7 +28,10 @@ const FONT_SPRITES: [u8; 80] = [ ]; /// Emulator emulates the Chip8 CPU. -pub struct Emulator where D: Display { +pub struct Emulator +where + D: Display, +{ /// Memory represents the emulator's memory. memory: [u8; MEMORY_SIZE], /// Registers holds the general purpose registers. @@ -44,10 +48,14 @@ pub struct Emulator where D: Display { /// The stack pointer register. stack_pointer: u8, /// The display_data holds all the data associated with the display - display: D + display: D, + stack: Stack, } -impl Emulator where D: Display { +impl Emulator +where + D: Display, +{ /// Creates a new `Emulator` instance. /// pub fn new(display: D) -> Emulator { @@ -60,6 +68,7 @@ impl Emulator where D: Display { delay_timer: 0, sound_timer: 0, stack_pointer: 0, + stack: Stack::new(), }; emulator.load_font_data(); @@ -113,7 +122,7 @@ impl Emulator where D: Display { #[cfg(test)] mod tests { use super::*; - use crate::display::{TerminalDisplay}; + use crate::display::TerminalDisplay; use pretty_assertions::assert_eq; #[test] diff --git a/src/main.rs b/src/main.rs index fc617f4..e69ff50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ +use crate::display::TerminalDisplay; use crate::emulator::Emulator; use env_logger; -use crate::display::TerminalDisplay; -mod emulator; mod display; +mod emulator; +mod stack; fn main() -> Result<(), anyhow::Error> { env_logger::init(); diff --git a/src/stack.rs b/src/stack.rs new file mode 100644 index 0000000..72c8ffd --- /dev/null +++ b/src/stack.rs @@ -0,0 +1,65 @@ +use std::fmt::Debug; + +/// Implements a simple stack based on a vector. +#[derive(Debug)] +pub struct Stack { + storage: Vec, +} + +impl Stack { + pub fn new() -> Self { + Stack { + storage: Vec::new(), + } + } + + /// Pushes an element on the top of the stack + pub fn push(&mut self, element: T) { + self.storage.push(element) + } + + /// Returns the top element from the stack. + pub fn pop(&mut self) -> Option { + self.storage.pop() + } + + // + pub fn peek(&self) -> Option<&T> { + self.storage.last() + } + + /// Size returns the size of the stack. + pub fn size(&self) -> usize { + self.storage.len() + } + + /// Is Empty returns true if the stack is empty. + pub fn is_empty(&self) -> bool { + self.storage.len() == 0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn basic_operations() { + // Given + let mut stack = Stack::::new(); + + // Then + stack.push(15); + + assert_eq!(1, stack.size()); + assert_eq!(15u16, *stack.peek().unwrap()); + + let element = stack.pop(); + assert_eq!(15u16, element.unwrap()); + assert_eq!(0, stack.size()); + assert_eq!(true, stack.is_empty()); + + let element = stack.pop(); + assert_eq!(true, element.is_none()) + } +}