Add stack

This commit is contained in:
Michael Kohl 2021-03-29 17:31:39 +07:00
parent 8e84056a1c
commit 5c77429374
1 changed files with 33 additions and 1 deletions

View File

@ -2,6 +2,7 @@ const MEMORY_SIZE: usize = 4096;
const WIDTH: u32 = 64;
const HEIGHT: u32 = 32;
const DATA_REGISTERS: usize = 16;
const STACK_DEPTH: usize = 16;
pub const SCALE_FACTOR: u32 = 10;
pub const WINDOW_WIDTH: u32 = WIDTH * SCALE_FACTOR;
@ -42,9 +43,12 @@ struct Registers {
sp: u8,
}
type Stack = [u16; STACK_DEPTH];
pub struct Chip8 {
memory: Memory,
registers: Registers,
stack: Stack,
}
fn data_register_to_index(register: Register) -> usize {
@ -81,6 +85,7 @@ impl Chip8 {
pc: 0,
sp: 0,
},
stack: [0; STACK_DEPTH],
}
}
@ -103,7 +108,7 @@ impl Chip8 {
}
}
pub fn register_get(&mut self, register: Register) -> u16 {
pub fn register_get(&self, register: Register) -> u16 {
match register {
Register::I => self.registers.i,
Register::DT => self.registers.delay_timer as u16,
@ -113,6 +118,19 @@ impl Chip8 {
_ => self.registers.data[data_register_to_index(register)] as u16,
}
}
pub fn stack_push(&mut self, value: u16) -> () {
assert!((self.registers.sp as usize) < STACK_DEPTH, "stack overflow");
self.stack[self.registers.sp as usize] = value;
self.registers.sp += 1;
}
pub fn stack_pop(&mut self) -> u16 {
assert!(self.registers.sp > 0, "stack underflow");
self.registers.sp -= 1;
assert!((self.registers.sp as usize) < STACK_DEPTH, "stack overflow");
self.stack[self.registers.sp as usize]
}
}
#[cfg(test)]
@ -170,4 +188,18 @@ mod tests {
chip8.register_set(Register::PC, 42);
assert_eq!(chip8.register_get(Register::PC), 42);
}
#[test]
fn it_can_push_to_and_pop_from_the_stack() {
let mut chip8 = Chip8::new();
assert_eq!(chip8.register_get(Register::SP), 0);
chip8.stack_push(0xff);
assert_eq!(chip8.register_get(Register::SP), 1);
chip8.stack_push(0xaa);
assert_eq!(chip8.register_get(Register::SP), 2);
assert_eq!(chip8.stack_pop(), 170);
assert_eq!(chip8.register_get(Register::SP), 1);
assert_eq!(chip8.stack_pop(), 255);
assert_eq!(chip8.register_get(Register::SP), 0);
}
}