Implement a stack for emulation
This commit is contained in:
parent
3c6aad798c
commit
e31c05ac9b
4 changed files with 85 additions and 11 deletions
|
@ -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],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<D> where D: Display {
|
||||
pub struct Emulator<D>
|
||||
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<D> 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<u16>,
|
||||
}
|
||||
|
||||
impl <D> Emulator<D> where D: Display {
|
||||
impl<D> Emulator<D>
|
||||
where
|
||||
D: Display,
|
||||
{
|
||||
/// Creates a new `Emulator` instance.
|
||||
///
|
||||
pub fn new(display: D) -> Emulator<D> {
|
||||
|
@ -60,6 +68,7 @@ impl <D> Emulator<D> where D: Display {
|
|||
delay_timer: 0,
|
||||
sound_timer: 0,
|
||||
stack_pointer: 0,
|
||||
stack: Stack::new(),
|
||||
};
|
||||
|
||||
emulator.load_font_data();
|
||||
|
@ -113,7 +122,7 @@ impl <D> Emulator<D> where D: Display {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::display::{TerminalDisplay};
|
||||
use crate::display::TerminalDisplay;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -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();
|
||||
|
|
65
src/stack.rs
Normal file
65
src/stack.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
/// Implements a simple stack based on a vector.
|
||||
#[derive(Debug)]
|
||||
pub struct Stack<T> {
|
||||
storage: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T: Debug> Stack<T> {
|
||||
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<T> {
|
||||
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::<u16>::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())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue