From f4a8840b91c5cf0441f262a8dd58e005ced2fab1 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Mon, 13 Jul 2020 21:39:38 -0500 Subject: [PATCH] Refactor several opcodes + remove opcode property --- src/emu.rs | 77 ++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/src/emu.rs b/src/emu.rs index 4c0a793..b346942 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -5,7 +5,6 @@ use std::path::Path; #[derive(Copy, Clone)] pub struct Chip8 { - opcode: u16, i: u16, pc: u16, sp: u8, @@ -21,7 +20,6 @@ pub struct Chip8 { impl Default for Chip8 { fn default() -> Self { let mut chip8 = Chip8 { - opcode: 0, i: 0, pc: 0x200, // Progrm counter starts at 0x200 sp: 0, @@ -60,16 +58,16 @@ impl Chip8 { ]; pub fn execute_cycle(&mut self) { - self.opcode = self.get_opcode(); - println!("{:#x}", self.opcode); - self.execute_opcode(); + let opcode = self.get_opcode(); + // println!("{:#x}", self.opcode); + self.execute_opcode(opcode); self.delay.tick(); self.sound.tick(); } pub fn load_font_set(&mut self) { - self.memory[0..0x50].copy_from_slice(&Self::FONT_SET); + self.memory[0x50..0xA0].copy_from_slice(&Self::FONT_SET); } pub fn load_rom>(&mut self, path: P) -> Result<(), io::Error> { @@ -98,11 +96,11 @@ impl Chip8 { ) } - fn execute_opcode(&mut self) { - let (nib_1, nib_2, nib_3, nib_4) = Self::get_nibs(self.opcode); + fn execute_opcode(&mut self, opcode: u16) { + let (nib_1, nib_2, nib_3, nib_4) = Self::get_nibs(opcode); - let nnn: u16 = self.opcode & 0x0FFF; - let kk: u8 = (self.opcode & 0x00FF) as u8; + let nnn: u16 = opcode & 0x0FFF; + let kk: u8 = (opcode & 0x00FF) as u8; let x = nib_2; let y = nib_3; let n = nib_4; @@ -114,6 +112,8 @@ impl Chip8 { (0x0, 0x0, 0xE, 0x0) => self.cls(), // 00EE (0x0, 0x0, 0xE, 0xE) => self.ret(), + // 0NNN + (0x0, _, _, _) => { /* Nothing to see here */ } // 1NNN (0x1, _, _, _) => self.jmp_addr(nnn), // 2NNN @@ -179,7 +179,7 @@ impl Chip8 { // Fx65 (0xF, _, 0x6, 0x5) => self.load_into_vx_from_i(x), // Otherwise... - _ => panic!("UNIMPLEMENTED OPCODE: {:#x}", self.opcode), + _ => panic!("UNIMPLEMENTED OPCODE: {:#x}", opcode), } } @@ -197,7 +197,7 @@ impl Chip8 { fn jmp_addr(&mut self, nnn: u16) { // sets the program counter to addr (nnn) - self.pc = nnn; + self.pc = nnn - 2; // We want to execute nnn so decrement pc by 2; } fn call_addr(&mut self, nnn: u16) { @@ -205,7 +205,7 @@ impl Chip8 { // pc is then set to addr self.sp += 1; self.stack[self.sp as usize] = self.pc; - self.pc = nnn; + self.pc = nnn - 2; // see Chip8#jmp_addr() } fn se_vx_byte(&mut self, x: u8, kk: u8) { @@ -236,6 +236,7 @@ impl Chip8 { fn add_vx_byte(&mut self, x: u8, kk: u8) { // calculate Vx + kk, then store it in Vx + // This does indeed overflow without setting VF self.v[x as usize] = self.v[x as usize].wrapping_add(kk); } @@ -265,22 +266,19 @@ impl Chip8 { // only the lowest 8 bits of result are stored in Vx let x = x as usize; - let (res, did_overflow) = self.v[x].overflowing_add(self.v[y as usize]); + let (sum, did_overflow) = self.v[x].overflowing_add(self.v[y as usize]); + self.v[x] = sum; self.v[0xF] = if did_overflow { 1 } else { 0 }; - self.v[x] = res; } fn sub_vx_vy(&mut self, x: u8, y: u8) { - // TODO: Confirm that the default behaviour - // for this opcode includes a wrapping subtraction - // subtract Vx and Vy, if Vx > Vy VF is set to 1, otherwise 0 // then set Vx to Vx - Vy - let vx = self.v[x as usize]; - let vy = self.v[y as usize]; + let x = x as usize; + let y = y as usize; - self.v[0xF] = if vx > vy { 1 } else { 0 }; - self.v[x as usize] = vx.wrapping_sub(vy); + self.v[0xF] = if self.v[x] > self.v[y] { 1 } else { 0 }; + self.v[x] = self.v[x].wrapping_sub(self.v[y]); } fn shr(&mut self, x: u8) { @@ -288,18 +286,18 @@ impl Chip8 { // then shift Vx one to the right let x = x as usize; - self.v[0xF] = if (self.v[x] & 1) == 1 { 1 } else { 0 }; + self.v[0xF] = if (self.v[x] & 0x01) == 0x01 { 1 } else { 0 }; self.v[x] >>= 1; } fn subn_vx_vy(&mut self, x: u8, y: u8) { // subtract Vy and Vx, if Vy > Vx VF is set to 1, otherwise 0 // then set Vx = Vy - Vx - let vx = self.v[x as usize]; - let vy = self.v[y as usize]; + let x = x as usize; + let y = y as usize; - self.v[0xF] = if vy > vx { 1 } else { 0 }; - self.v[x as usize] = vy.wrapping_sub(vx); + self.v[0xF] = if self.v[y] > self.v[x] { 1 } else { 0 }; + self.v[x as usize] = self.v[y].wrapping_sub(self.v[x]); } fn shl(&mut self, x: u8) { @@ -325,7 +323,7 @@ impl Chip8 { fn jmp_addr_with_offset(&mut self, nnn: u16) { // set program counter to addr + V0 - self.pc = nnn + self.v[0] as u16; + self.pc = nnn + self.v[0] as u16 - 2; // see Chip8#jmp_addr } fn rand(&mut self, x: u8, kk: u8) { @@ -347,7 +345,6 @@ impl Chip8 { fn skip_on_press(&mut self, x: u8) { // if current key is the same as the on in Vx // program counter is increased by 2 - if self.key.is_pressed(self.v[x as usize]) { self.pc += 2; } @@ -356,7 +353,6 @@ impl Chip8 { 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 - if !self.key.is_pressed(self.v[x as usize]) { self.pc += 2; } @@ -389,12 +385,16 @@ impl Chip8 { fn add_vx_to_i(&mut self, x: u8) { // set I to be I + Vx - self.i += self.v[x as usize] as u16; + // Althought not standard, we check for overflow as well here + // Memory is 4KB (12-bits) so anything mor than that "overflows" + let sum = self.i + self.v[x as usize] as u16; + self.v[0xF] = if sum > 0x0FFF { 1 } else { 0 }; + self.i = sum & 0x0FFF; } fn set_i_to_hex_sprite_loc(&mut self, x: u8) { // set I to location of hex sprite related to Vx - self.i = self.v[x as usize] as u16 * 5; + self.i = 0x50 + (5 * self.v[x as usize] as u16); } fn copy_digits_to_i(&mut self, x: u8) { @@ -402,11 +402,11 @@ impl Chip8 { // take tens digit and place it at I + 1 // take ones digit and place it at I + 2 let i = self.i as usize; - let mut iter = Self::digits(self.v[x as usize] as usize); + let mut digit = Self::digits(self.v[x as usize] as usize); - let ones = iter.next().unwrap(); // Ther has to at least be a ones lol - let tens = iter.next().unwrap_or(0); - let hundreds = iter.next().unwrap_or(0); + let ones = digit.next().unwrap(); // Ther has to at least be a ones lol + let tens = digit.next().unwrap_or(0); + let hundreds = digit.next().unwrap_or(0); self.memory[i] = hundreds as u8; self.memory[i + 1] = tens as u8; @@ -415,7 +415,6 @@ impl Chip8 { fn copy_from_vx_to_memory(&mut self, x: u8) { // copy values v0 -> Vx to memory starting at i - for n in 0..=(x as usize) { self.memory[self.i as usize + n] = self.v[n]; } @@ -423,9 +422,7 @@ impl Chip8 { fn load_into_vx_from_i(&mut self, x: u8) { // read what will be values of v0 -> vx from memory starting at i - let x = x as usize; - - for n in 0..=x { + for n in 0..=(x as usize) { self.v[n] = self.memory[self.i as usize + n]; } }