Video reset now tests ok gemma egui interface now implements stupid workaround for video reset
105 lines
2.4 KiB
Rust
105 lines
2.4 KiB
Rust
#[derive(Clone)]
|
|
pub struct Chip8Stack {
|
|
items: Vec<u16>
|
|
}
|
|
|
|
impl Default for Chip8Stack {
|
|
fn default() -> Self {
|
|
Chip8Stack {
|
|
items: vec![],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Chip8Stack {
|
|
pub fn push(&mut self, new_value: &u16) {
|
|
if self.depth() == 16 {
|
|
// println!("Deep deep stack?");
|
|
panic!("Stack Overflow");
|
|
}
|
|
self.items.push(*new_value );
|
|
}
|
|
pub fn pop(&mut self) -> u16 {
|
|
if self.items.is_empty() {
|
|
panic!("Stack Underflow");
|
|
}
|
|
self.items.pop().unwrap()
|
|
}
|
|
pub fn depth(&self) -> u16 {
|
|
self.items.len() as u16
|
|
}
|
|
|
|
pub fn new() -> Self {
|
|
Chip8Stack {
|
|
items: vec![]
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use rand::random;
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn smoke() { assert!(true) }
|
|
|
|
#[test]
|
|
fn push_pop_test() {
|
|
let mut x = Chip8Stack::new();
|
|
|
|
// lets see if we can push and pop a bunch
|
|
x.push(&0xabcu16);
|
|
x.push(&0xcdeu16);
|
|
x.pop();
|
|
assert_eq!(x.depth(), 1);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic]
|
|
fn stack_overflow_test() {
|
|
let mut x = Chip8Stack::new();
|
|
for i in 0..17 {
|
|
x.push(&i);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic]
|
|
fn stack_underflow_test() {
|
|
let mut x = Chip8Stack::new();
|
|
x.pop();
|
|
}
|
|
|
|
#[test]
|
|
fn lots_of_subs() {
|
|
let mut x = Chip8Stack::new();
|
|
let stack_contents = [0x123, 0x321, 0xabc, 0xdef,
|
|
0xbad, 0xbef, 0xfed, 0xcab,
|
|
0xbed, 0xcad, 0xfeb, 0xcab,
|
|
0xfff, 0x000, 0x001];
|
|
for i in stack_contents {
|
|
x.push(&i);
|
|
}
|
|
|
|
assert_eq!(x.depth(), 15);
|
|
|
|
// up to 50 random loops
|
|
let num_loops: u8 = random::<u8>() % 50;
|
|
for i in 0..num_loops {
|
|
let start_count = x.depth();
|
|
let num_pop = random::<u8>() % x.depth() as u8;
|
|
for current_pop in 0..num_pop {
|
|
x.pop();
|
|
}
|
|
|
|
let post_pop_count = x.depth();
|
|
assert_eq!(post_pop_count as u8, start_count as u8 - num_pop);
|
|
for current_push in 0..num_pop {
|
|
x.push(&stack_contents[(current_push + post_pop_count as u8) as usize]);
|
|
}
|
|
assert_eq!(x.depth(), 15);
|
|
}
|
|
|
|
}
|
|
} |