[ins] Fix shift instructions

This commit is contained in:
2024-03-06 07:26:11 +05:30
parent 2d6557e770
commit 5fc961a155
2 changed files with 27 additions and 12 deletions

View File

@@ -26,4 +26,5 @@ Chip 8 emulator/interpreter.
### More information on CHIP-8 ### More information on CHIP-8
- [Guide to making a CHIP-8 emulator - Tobias V. Langhoff](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#specifications) - [Guide to making a CHIP-8 emulator - Tobias V. Langhoff](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#specifications)
- [CHIP-8 Test Suite](https://github.com/Timendus/chip8-test-suite)
- [Awesome CHIP-8](https://chip-8.github.io/links/) - [Awesome CHIP-8](https://chip-8.github.io/links/)

View File

@@ -180,31 +180,34 @@ impl Device {
} }
Instruction::Sub(x, y) => { Instruction::Sub(x, y) => {
let left = self.registers.v[x]; let left = self.registers.v[x];
let (wrapped_subtraction_result, is_overflow) = left.overflowing_sub(self.registers.v[y]); let right = self.registers.v[y];
let (wrapped_subtraction_result, is_overflow) = left.overflowing_sub(right);
self.registers.v[x] = wrapped_subtraction_result; self.registers.v[x] = wrapped_subtraction_result;
self.set_flag_register(is_overflow); self.set_flag_register(!is_overflow);
} }
Instruction::RSub(x, y) => { Instruction::RSub(x, y) => {
let left = self.registers.v[y]; let left = self.registers.v[y];
let (wrapped_subtraction_result, is_overflow) = left.overflowing_sub(self.registers.v[x]); let (wrapped_subtraction_result, is_overflow) = left.overflowing_sub(self.registers.v[x]);
self.registers.v[x] = wrapped_subtraction_result; self.registers.v[x] = wrapped_subtraction_result;
self.set_flag_register(is_overflow); self.set_flag_register(!is_overflow);
} }
Instruction::RShift(x, y) => { Instruction::RShift(x, y) => {
if (self.new_chip8_mode) { if !self.new_chip8_mode {
self.registers.v[x] = self.registers.v[y]; self.registers.v[x] = self.registers.v[y];
} }
let (shift_res, did_overflow) = self.registers.v[x].overflowing_shr(1); let val = self.registers.v[x];
let (shift_res, bit_carry) = Self::shr_1(val);
self.registers.v[x] = shift_res; self.registers.v[x] = shift_res;
self.set_flag_register(did_overflow); self.set_flag_register(bit_carry);
} }
Instruction::LShift(x, y) => { Instruction::LShift(x, y) => {
if (self.new_chip8_mode) { if !self.new_chip8_mode {
self.registers.v[x] = self.registers.v[y]; self.registers.v[x] = self.registers.v[y];
} }
let (shift_res, did_overflow) = self.registers.v[x].overflowing_shl(1); let left = self.registers.v[x];
self.registers.v[x] = shift_res; let (res, bit_carry) = Self::shl_1(left);
self.set_flag_register(did_overflow); self.registers.v[x] = res;
self.set_flag_register(bit_carry);
} }
Instruction::FetchDelayTimer(x) => { Instruction::FetchDelayTimer(x) => {
@@ -291,13 +294,13 @@ impl Device {
let index = Self::get_framebuffer_index(x, y + i); let index = Self::get_framebuffer_index(x, y + i);
let slice_from_memory = self.memory[self.registers.i as usize + i]; let slice_from_memory = self.memory[self.registers.i as usize + i];
// if we are drawing below the screen // if we are drawing below the screen
if (y+i)>=Self::FRAME_BUFFER_HEIGHT { if (y + i) >= Self::FRAME_BUFFER_HEIGHT {
log::trace!("Overdraw detected, skipping"); log::trace!("Overdraw detected, skipping");
continue; continue;
} }
for bit_index in (0..8).rev() { for bit_index in (0..8).rev() {
// if going out of the screen, stop // if going out of the screen, stop
if Self::get_framebuffer_index(0, y+i + 1) <= (index + (7 - bit_index)) { if Self::get_framebuffer_index(0, y + i + 1) <= (index + (7 - bit_index)) {
break; break;
} }
let bit_is_true = (slice_from_memory & (1 << bit_index)) == (1 << bit_index); let bit_is_true = (slice_from_memory & (1 << bit_index)) == (1 << bit_index);
@@ -322,6 +325,17 @@ impl Device {
log::info!("Loaded ROM from memory"); log::info!("Loaded ROM from memory");
self.memory[Self::ROM_START..].copy_from_slice(rom); self.memory[Self::ROM_START..].copy_from_slice(rom);
} }
/// Shift right and get carried out bit
fn shr_1(left: u8) -> (u8, bool) {
let bit_carry = (left & 0x1) == 0x1;
return ((left) >> 1, bit_carry);
}
/// Shift left, and get carried out bit
fn shl_1(left: u8) -> (u8, bool) {
let bit_carry = (left & 0x80) == 0x80;
let left = left & 0x7f;
return ((left & 0x7f) << 1, bit_carry);
}
} }
impl Drop for Device { impl Drop for Device {