commit 8660646dc4d56e97f36595433b5c5737b8fcedb4 from: Witcher01 date: Sun Aug 1 18:04:56 2021 UTC added instruction SNE for regs commit - 62fe7ccb10e71b355420d3fced24ad4d88998dc7 commit + 8660646dc4d56e97f36595433b5c5737b8fcedb4 blob - 5d06393b27541e3e57212e9d545981d5932699c5 blob + f8cdd4f86eb97f48254ef798d678cffcc6b3f0c3 --- src/chip8.rs +++ src/chip8.rs @@ -49,6 +49,8 @@ impl Chip8 { let kk = (instruction & 0x00FF) as u8; let x = ((instruction & 0x0F00) >> 8) as usize; let y = ((instruction & 0x00F0) >> 4) as usize; + // "least significant hex" + let lsh = instruction & 0x000F; match (instruction & 0xF000) >> 12 { 0x0 => match nnn { @@ -116,63 +118,78 @@ impl Chip8 { // set Vx to Vx + 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; + 0x8 => { + match lsh { + // 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)); } - 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; - }, - _ => { + }; + self.pc += 2; + }, + // SNE Vx, Vy + 0x9 => { + if lsh != 0 { return Err(format!("{:#06x}: not an instruction", instruction)); } + + if self.regs[x] != self.regs[y] { + self.pc += 4; + } else { + self.pc += 2; + } }, _ => { return Err(format!("{:#06x}: not an instruction", instruction));