diff --git a/src/emu.rs b/src/emu.rs index 696c721..8e50f47 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -236,8 +236,7 @@ impl Chip8 { fn add_vx_byte(&mut self, x: u8, kk: u8) { // calculate Vx + kk, then store it in Vx - let x = x as usize; - self.v[x] = self.v[x] + kk; + self.v[x as usize] += kk; } fn ld_vx_vy(&mut self, x: u8, y: u8) { @@ -247,8 +246,7 @@ impl Chip8 { fn or(&mut self, x: u8, y: u8) { // calc bitwise OR on Vx and Vy, then store in Vx - let x = x as usize; - self.v[x] = self.v[x] | self.v[y as usize]; + self.v[x as usize] |= self.v[y as usize]; } fn and_vx_vy(&mut self, x: u8, y: u8) { @@ -259,8 +257,7 @@ impl Chip8 { fn xor(&mut self, x: u8, y: u8) { // calc bitwise XOR on Vx and Vy, then store in Vx - let x = x as usize; - self.v[x] = self.v[x] ^ self.v[y as usize]; + self.v[x as usize] ^= self.v[y as usize]; } fn add_vx_vy(&mut self, x: u8, y: u8) { @@ -552,4 +549,177 @@ mod test { assert_eq!(chip8.sp, 0); assert_eq!(chip8.pc, 0x50D5); } + + #[test] + fn opcode_jmp_addr_works() { + let mut chip8: Chip8 = Default::default(); + + let opcode = 0x1ABC; + let nnn = opcode & 0x0FFF; + + chip8.jmp_addr(nnn); + + assert_eq!(chip8.pc, nnn); + } + + #[test] + fn opcode_call_addr_works() { + let mut chip8: Chip8 = Default::default(); + + let nnn = 0x0ABC; + chip8.call_addr(nnn); + + assert_eq!(chip8.sp, 1); + assert_eq!(chip8.stack[chip8.sp as usize], 0x200); + assert_eq!(chip8.pc, nnn); + } + + #[test] + fn opcode_se_vx_byte_works() { + let mut chip8: Chip8 = Default::default(); + + // Opcode: 0x32D5 + + // Test Vx == kk + chip8.pc = 0x200; + chip8.v[2] = 0xD5; + chip8.se_vx_byte(0x2, 0xD5); + + assert_eq!(chip8.pc, 0x202); + + // Test Vx != kk + chip8.pc = 0x200; + chip8.v[2] = 0xD6; + chip8.se_vx_byte(0x2, 0xD5); + + assert_ne!(chip8.pc, 0x202); + } + + #[test] + fn opcode_sne_vx_byte_works() { + let mut chip8: Chip8 = Default::default(); + + // Opcode: 0x32D6 + + // Test Vx != kk + chip8.pc = 0x200; + chip8.v[2] = 0xD5; + chip8.sne_vx_byte(0x2, 0xD6); + + assert_eq!(chip8.pc, 0x202); + + // Test Vx == kk + chip8.pc = 0x200; + chip8.v[2] = 0xD6; + chip8.sne_vx_byte(0x2, 0xD6); + + assert_ne!(chip8.pc, 0x202); + } + + #[test] + fn opcode_se_vx_vy_works() { + let mut chip8: Chip8 = Default::default(); + + // When Equal + chip8.pc = 0x200; + chip8.v[4] = 0xAB; + chip8.v[7] = 0xAB; + chip8.se_vx_vy(0x4, 0x7); + + assert_eq!(chip8.pc, 0x202); + + // When not Equal + chip8.pc = 0x200; + chip8.v[4] = 0xAC; + chip8.v[7] = 0xAB; + + chip8.se_vx_vy(0x4, 0x7); + assert_eq!(chip8.pc, 0x200); + } + + #[test] + fn opcode_ld_vx_byte_works() { + let mut chip8: Chip8 = Default::default(); + + assert_ne!(chip8.v[5], 0xAB); + chip8.ld_vx_byte(0x5, 0xAB); + assert_eq!(chip8.v[5], 0xAB); + } + + #[test] + fn opcode_add_vx_byte_works() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[3] = 0x0A; + chip8.add_vx_byte(0x3, 0x36); + assert_eq!(chip8.v[3], 0x40); + } + + #[test] + fn opcode_ld_vx_vy_works() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[1] = 0x64; + chip8.v[4] = 0x96; + + chip8.ld_vx_vy(0x1, 0x4); + assert_eq!(chip8.v[1], 0x96); + } + + #[test] + fn opcode_or_works() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[0xA] = 0xAB; + chip8.v[0x9] = 0xC6; + + chip8.or(0xA, 0x9); + assert_eq!(chip8.v[0xA], 0xAB | 0xC6); + } + + #[test] + fn opcode_and_vx_vy_works() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[0xC] = 0x58; + chip8.v[0x2] = 0x9a; + + chip8.and_vx_vy(0xC, 0x2); + assert_eq!(chip8.v[0xC], 0x58 & 0x9a); + } + + #[test] + fn opcode_xor_works() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[0x5] = 0x38; + chip8.v[0xB] = 0x4C; + + chip8.xor(0x5, 0xB); + assert_eq!(chip8.v[0x5], 0x38 ^ 0x4C); + } + + #[test] + fn opcode_add_vx_vy_works() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[0xA] = 0x01; + chip8.v[0x8] = 0xC8; + + chip8.add_vx_vy(0xA, 0x8); + assert_eq!(chip8.v[0xA], 0x01 + 0xC8); + } + + #[test] + fn opcode_add_vx_vy_overflows_as_expected() { + let mut chip8: Chip8 = Default::default(); + + chip8.v[0xE] = 0xFF; + chip8.v[0x7] = 0x01; + + chip8.add_vx_vy(0xE, 0x7); + + assert_eq!(chip8.v[0xA], (0xFF as u8).wrapping_add(0x01)); + assert_eq!(chip8.v[0xF], 1); + } }