now passes the flags test rom

This commit is contained in:
Trevor Merritt 2024-10-10 16:12:48 -04:00
parent e176ee5638
commit 4fc0bfd3d8
2 changed files with 47 additions and 44 deletions

View File

@ -568,20 +568,16 @@ impl Chip8CpuInstructions {
// Set Vx = Vx SHR 1. // Set Vx = Vx SHR 1.
// SHIFT 1 Bit ----> // SHIFT 1 Bit ---->
// If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2. // If the least-significant bit of Vx is 1, then VF is set to 1, otherwise 0. Then Vx is divided by 2.
let initial_value = input.registers.peek(*x as u8); let initial_value = input.registers.peek(*x);
// overflow check // overflow check
let rotated = initial_value >> 1;
input.registers.poke(*x as u8, rotated);
if initial_value.bitand(0b1) == 1 { if initial_value.bitand(0b1) == 1 {
input.registers.poke(0x0f, 0x01); input.registers.poke(0x0f, 0x01);
} else { } else {
input.registers.poke(0x0f, 0x00); input.registers.poke(0x0f, 0x00);
} }
let rotated = initial_value >> 1;
println!("[{initial_value:80b}] / [{rotated:80b}]");
input.registers.poke(*x as u8, initial_value.shr(1));
} }
Chip8CpuInstructions::SubnVxVy(x, y) => { Chip8CpuInstructions::SubnVxVy(x, y) => {
// 8xy7 - SUBN Vx, Vy // 8xy7 - SUBN Vx, Vy
@ -592,15 +588,18 @@ impl Chip8CpuInstructions {
let x_register = input.registers.peek(*x as u8); let x_register = input.registers.peek(*x as u8);
let mut value_to_poke = 0; let mut value_to_poke = 0;
let new_value = if y_register <= x_register { let new_value = if y_register < x_register {
value_to_poke = (y_register as u16 + 256) - x_register as u16; value_to_poke = (y_register as u16 + 256) - x_register as u16;
1 } else {
value_to_poke = (y_register - x_register) as u16;
0 0
} else {
value_to_poke = (y_register - x_register) as u16;
1
}; };
println!("SUB CARRY -> REGISTER 1 = [0x{x:02x}] / [{x_register}] REGISTER 2 = [0x{y:02x}] / [{y_register}] SUB = {value_to_poke} CARRY = {new_value}");
input.registers.poke(*x, value_to_poke as u8);
input.registers.poke(0xf, new_value); input.registers.poke(0xf, new_value);
input.registers.poke(*x as u8, value_to_poke as u8);
} }
Chip8CpuInstructions::ShlVxVy(x, _) => { Chip8CpuInstructions::ShlVxVy(x, _) => {
@ -608,14 +607,16 @@ impl Chip8CpuInstructions {
// Set Vx = Vx SHL 1. // Set Vx = Vx SHL 1.
// //
// If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then Vx is multiplied by 2. // If the most-significant bit of Vx is 1, then VF is set to 1, otherwise to 0. Then Vx is multiplied by 2.
let initial_value = input.registers.peek(*x as u8); let initial_value = input.registers.peek(*x);
let rotated = initial_value.shl(1);
if 0b10000000 & initial_value == 0b10000000 { // overflow check
let rotated = initial_value << 1;
input.registers.poke(*x as u8, rotated);
if initial_value.bitand(0b10000000) == 0b10000000 {
input.registers.poke(0x0f, 0x01); input.registers.poke(0x0f, 0x01);
} else { } else {
input.registers.poke(0x0f, 0x00); input.registers.poke(0x0f, 0x00);
} }
input.registers.poke(*x as u8,rotated);
} }
Chip8CpuInstructions::SneVxVy(vx_register, vy_register) => { Chip8CpuInstructions::SneVxVy(vx_register, vy_register) => {
// 9xy0 - SNE Vx, Vy // 9xy0 - SNE Vx, Vy
@ -1371,7 +1372,6 @@ mod test {
for (idx, value) in to_load.iter().enumerate() { for (idx, value) in to_load.iter().enumerate() {
assert_eq!(x.registers.peek(idx as u8), *value); assert_eq!(x.registers.peek(idx as u8), *value);
} }
} }
#[test] #[test]
@ -1529,24 +1529,28 @@ mod test {
// If the least-significant bit of Vx is 1, then VF is set to 1, // If the least-significant bit of Vx is 1, then VF is set to 1,
// otherwise 0. Then Vx is divided by 2. // otherwise 0. Then Vx is divided by 2.
let mut x = Chip8Computer::new(); let mut x = Chip8Computer::new();
// 0b10000000 -> 0b01000000 // 0b10101010 -> 0b01010101
let start_value = 0b10000000; x.registers.poke(0x01, 0b10101010);
let end_value = 0b01000000; x.registers.poke(0x0f, 0x0);
x.registers.poke(0x01, start_value);
Chip8CpuInstructions::ShrVxVy(0x01, 0x00).execute(&mut x);
assert_eq!(x.registers.peek(0x01), end_value);
assert_eq!(x.registers.peek(0x0f), 0);
// 0b00000001 -> 0b00000000 Chip8CpuInstructions::ShlVxVy(0x01, 0x00).execute(&mut x);
let start_value = 0b00000001; assert_eq!(x.registers.peek(0x01), 0b01010100);
let end_value = 0b00000000;
let mut x = Chip8Computer::new();
let start_value = 1;
x.registers.poke(0x01, start_value);
Chip8CpuInstructions::ShrVxVy(0x01, 0x00).execute(&mut x);
assert_eq!(x.registers.peek(0x01), end_value);
assert_eq!(x.registers.peek(0x0f), 1); assert_eq!(x.registers.peek(0x0f), 1);
let end_value = start_value / 2;
assert_eq!(end_value, 0); Chip8CpuInstructions::ShlVxVy(0x01, 0x00).execute(&mut x);
assert_eq!(x.registers.peek(0x01), 0b10101000);
assert_eq!(x.registers.peek(0x0f), 0x00);
Chip8CpuInstructions::ShlVxVy(0x01, 0x00).execute(&mut x);
assert_eq!(x.registers.peek(0x01), 0b01010000);
assert_eq!(x.registers.peek(0x0f), 0x01);
Chip8CpuInstructions::ShlVxVy(0x01, 0x00).execute(&mut x);
assert_eq!(x.registers.peek(0x01), 0b10100000);
assert_eq!(x.registers.peek(0x0f), 0x00);
Chip8CpuInstructions::ShlVxVy(0x01, 0x00).execute(&mut x);
assert_eq!(x.registers.peek(0x01), 0b01000000);
assert_eq!(x.registers.peek(0x0f), 0x01);
} }
} }

View File

@ -6,5 +6,4 @@ fn smoke() { assert!(true) }
#[test] #[test]
fn test_rom_1_works() { fn test_rom_1_works() {
let mut x = Chip8Computer::new(); let mut x = Chip8Computer::new();
} }