Continue implementing more opcode tests

This commit is contained in:
Rekai Musuka 2020-06-27 21:49:58 -05:00
parent 8ca64ec98d
commit 83b48cf27a
2 changed files with 170 additions and 20 deletions

View File

@ -370,26 +370,19 @@ impl Chip8 {
// if current key is the same as the on in Vx
// program counter is increased by 2
if let Some(key) = self.key.get_pressed() {
if self.v[x as usize] == key {
if self.key.is_pressed(self.v[x as usize]) {
self.pc += 2;
}
}
}
fn skip_not_pressed(&mut self, x: u8) {
// if current key is not the sameas the one in Vx
// increment the program counter by 2
match self.key.get_pressed() {
Some(key) => {
if self.v[x as usize] != key {
if !self.key.is_pressed(self.v[x as usize]) {
self.pc += 2;
}
}
None => self.pc += 2,
}
}
fn copy_delay_timer_val(&mut self, x: u8) {
// set Vx to be the value of the delay timer
@ -400,7 +393,7 @@ impl Chip8 {
// wait (blocking) until a key is pressed
// once pressed, store in Vx
match self.key.get_pressed() {
match self.key.get_any_pressed() {
Some(key) => self.v[x as usize] = key,
None => self.pc -= 2,
}
@ -413,7 +406,7 @@ impl Chip8 {
fn set_sound_to_vx(&mut self, x: u8) {
// set sound timer to be value of Vx
self.delay.set(self.v[x as usize]);
self.sound.set(self.v[x as usize]);
}
fn add_vx_to_i(&mut self, x: u8) {
@ -865,4 +858,141 @@ mod test {
assert_eq!(chip8.pc, 0x05D2 + 0xA2);
}
#[test]
fn opcode_rand_works() {
// Random Value so there's no real way to test it
// I don't think we can seed the RNG when we use rand::random()
// However, sine we bitwise AND the random byte with another byte,
// we can test that random_byte & 0x00 == 0x00
let mut chip8: Chip8 = Default::default();
chip8.v[0xE] = 0x77; // Make sure that VE is not 0x00
chip8.rand(0xE, 0x00);
assert_eq!(chip8.v[0xE], 0x00);
}
#[test]
#[ignore]
fn opcode_draw_works() {
// Will do this once I've rewritten the opcode for 0xDxyn
todo!("TODO: Write this Opcode Test")
}
#[test]
fn opcode_skip_on_press_works() {
let mut chip8: Chip8 = Default::default();
// Key and Vx are equal
chip8.pc = 0x200;
chip8.v[0xD] = 0xA;
chip8.key.set_key(0xA);
chip8.skip_on_press(0xD);
assert_eq!(chip8.pc, 0x202);
// Key and Vx are **not** equal
chip8.key.reset();
chip8.pc = 0x200;
chip8.v[0xD] = 0xA;
chip8.key.set_key(0x3);
chip8.skip_on_press(0xD);
assert_ne!(chip8.pc, 0x202);
}
#[test]
fn opcode_skip_not_pressed_works() {
let mut chip8: Chip8 = Default::default();
// Key and Vx are equal
chip8.pc = 0x200;
chip8.v[0xD] = 0xA;
chip8.key.set_key(0xA);
chip8.skip_not_pressed(0xD);
assert_ne!(chip8.pc, 0x202);
// Key and Vx are **not** equal
chip8.key.reset();
chip8.pc = 0x200;
chip8.v[0xD] = 0xA;
chip8.key.set_key(0x3);
chip8.skip_not_pressed(0xD);
assert_eq!(chip8.pc, 0x202);
}
#[test]
fn opcode_copy_delay_timer_works() {
let mut chip8: Chip8 = Default::default();
chip8.delay.set(0x0F);
chip8.v[0x2] = 0x00;
chip8.copy_delay_timer_val(0x2);
assert_eq!(chip8.v[0x2], 0x0F);
}
#[test]
fn opcode_loop_until_key_vx_works() {
let mut chip8: Chip8 = Default::default();
// Nothing Pressed
chip8.pc = 0x200;
chip8.v[0xC] = 0xFF; // Not a valid Key
chip8.loop_until_key_vx(0xC);
assert_eq!(chip8.v[0xC], 0xFF);
assert_eq!(chip8.pc, 0x1FE);
// Something Pressed
chip8.key.set_key(0x3);
chip8.pc = 0x200;
chip8.v[0xC] = 0xFF; // Not a valid Key
chip8.loop_until_key_vx(0xC);
assert_eq!(chip8.v[0xC], 0x3);
assert_eq!(chip8.pc, 0x200);
}
#[test]
fn opcode_set_delay_to_vx_works() {
let mut chip8: Chip8 = Default::default();
chip8.v[0x1] = 0x0F;
chip8.set_delay_to_vx(0x01);
assert_eq!(chip8.v[0x1], chip8.delay.get());
}
#[test]
fn opcode_set_sound_to_vx_works() {
let mut chip8: Chip8 = Default::default();
chip8.v[0x2] = 0x0F;
chip8.set_sound_to_vx(0x2);
assert_eq!(chip8.v[0x2], chip8.sound.get());
}
#[test]
fn opcode_add_vx_to_i_works() {
let mut chip8: Chip8 = Default::default();
chip8.i = 0x22;
chip8.v[0x6] = 0xC9;
chip8.add_vx_to_i(0x6);
assert_eq!(chip8.i, 0xEB);
}
#[test]
#[ignore]
fn opcode_set_i_to_hex_sprite_loc_works() {
todo!("Figure out how this instructin works")
}
}

View File

@ -68,16 +68,36 @@ impl Default for Keypad {
}
impl Keypad {
pub fn get_pressed(&self) -> Option<u8> {
let mut found: Option<u8> = None;
for (index, key) in self.keys.iter().enumerate() {
pub fn get_any_pressed(&self) -> Option<u8> {
for (i, key) in self.keys.iter().enumerate() {
if *key {
found = Some(index as u8);
break;
return Some(i as u8);
}
}
None
}
found
pub fn reset(&mut self) {
self.keys = [false; 16];
}
pub fn get_overview(&self) -> [bool; 16] {
self.keys
}
pub fn is_pressed(&self, key: u8) -> bool {
self.keys[key as usize]
}
pub fn set_all(&mut self, keys: [bool; 16]) {
self.keys = keys;
}
pub fn set_key(&mut self, index: usize) {
self.keys[index] = true;
}
pub fn unset_key(&mut self, index: usize) {
self.keys[index] = false;
}
}