Commit Diff


commit - 7a1da51f6f97b298b9e252a0bcccff3b28805636
commit + 6a1ef6ce40bd2354eac59bd4cf402267f8f0add9
blob - 10b95dc48d8bb1ecddc9f258daf2e18207c1d479
blob + 5480c388fcc91b147019db698cfee3d85c210393
--- src/chip8.rs
+++ src/chip8.rs
@@ -47,8 +47,8 @@ impl Chip8 {
     pub fn execute(&mut self, instruction: u16) -> Result<(), String> {
         let nnn = instruction & 0x0FFF;
         let kk = (instruction & 0x00FF) as u8;
-        let x = (instruction & 0x0F00) >> 8;
-        let y = (instruction & 0x00F0) >> 4;
+        let x = ((instruction & 0x0F00) >> 8) as usize;
+        let y = ((instruction & 0x00F0) >> 4) as usize;
 
         match instruction & 0xF000 {
             0x0 => match nnn {
@@ -82,7 +82,7 @@ impl Chip8 {
             // SE Vx, byte
             0x3 => {
                 // skip next instruction if Vx == byte
-                if self.regs[x as usize] == kk {
+                if self.regs[x] == kk {
                     self.pc += 4;
                 } else {
                     self.pc += 2;
@@ -91,7 +91,7 @@ impl Chip8 {
             // SNE Vx, byte
             0x4 => {
                 // skip next instruction if Vx != byte
-                if self.regs[x as usize] != kk {
+                if self.regs[x] != kk {
                     self.pc += 4;
                 } else {
                     self.pc += 2;
@@ -100,7 +100,7 @@ impl Chip8 {
             // SE Vx, Vy
             0x5 => {
                 // skip next instruction if Vx == Vy
-                if self.regs[x as usize] == self.regs[y as usize] {
+                if self.regs[x] == self.regs[y] {
                     self.pc += 4;
                 } else {
                     self.pc += 2;
@@ -109,13 +109,71 @@ impl Chip8 {
             // LD
             0x6 => {
                 // save kk into Vx
-                self.regs[x as usize] = kk;
+                self.regs[x] = kk;
             },
             // ADD
             0x7 => {
                 // set Vx to Vx + kk
-                self.regs[x as usize] += kk;
+                self.regs[x] += kk;
             },
+            0x8 => match instruction & 0x000F {
+                // LD Vx, Vy
+                0x0 => {
+                    self.regs[x] = self.regs[y];
+                },
+                // OR Vx, Vy
+                0x1 => {
+                    self.regs[x] |= self.regs[y];
+                },
+                // AND Vx, Vy
+                0x2 => {
+                    self.regs[x] &= self.regs[y];
+                },
+                // XOR Vx, Vy
+                0x3 => {
+                    self.regs[x] ^= self.regs[y];
+                },
+                // ADD Vx, Vy
+                0x4 => {
+                    // set VF by checking if an overflow occured
+                    match self.regs[x].checked_add(self.regs[y]) {
+                        Some(_) => self.regs[0xF] = 0,
+                        None => self.regs[0xF] = 1,
+                    };
+                    self.regs[x] += self.regs[y];
+                },
+                // SUB Vx, Vy
+                0x5 => {
+                    if self.regs[x] > self.regs[y] {
+                        self.regs[0xF] = 1;
+                    } else {
+                        self.regs[0xF] = 0;
+                    }
+                    self.regs[x] -= self.regs[y];
+                },
+                // SHR Vx {, Vy}
+                0x6 => {
+                    self.regs[0xF] = self.regs[x] & 0x01;
+                    self.regs[x] /= 2;
+                },
+                // SUBN Vx, Vy
+                0x7 => {
+                    if self.regs[y] > self.regs[x] {
+                        self.regs[0xF] = 1;
+                    } else {
+                        self.regs[0xF] = 0;
+                    }
+                    self.regs[x] = self.regs[y] - self.regs[x];
+                },
+                // SHL Vx {, Vy}
+                0xE => {
+                    self.regs[0xF] = self.regs[x] & 0x70;
+                    self.regs[x] *= 2;
+                },
+                _ => {
+                    return Err(format!("{:#06x}: not an instruction", instruction));
+                }
+            },
             _ => {
                 return Err(format!("{:#06x}: not an instruction", instruction));
             }