go to lunch
This commit is contained in:
parent
9d3fabe0c3
commit
ef1b6e70f7
@ -72,12 +72,8 @@ impl Chip8Computer {
|
|||||||
let high_byte = (self.memory.clone().peek(start_pc) as u16).rotate_left(8);
|
let high_byte = (self.memory.clone().peek(start_pc) as u16).rotate_left(8);
|
||||||
let low_byte = self.memory.clone().peek(start_pc + 1) as u16;
|
let low_byte = self.memory.clone().peek(start_pc + 1) as u16;
|
||||||
let result = high_byte | low_byte;
|
let result = high_byte | low_byte;
|
||||||
debug!("JOINED BYTES [{high_byte:2x}] and [{low_byte:2x}] to build [{result:4x}]");
|
|
||||||
let decoded_instruction =
|
let decoded_instruction =
|
||||||
Chip8CpuInstructions::decode(result);
|
Chip8CpuInstructions::decode(result);
|
||||||
debug!("PREPARING TO EXECUTE {:4x} as {:?}", result, decoded_instruction);
|
|
||||||
// println!("DECODED INSTRUCTION = {:?}", decoded_instruction);
|
|
||||||
// start by moving to the next instruction
|
|
||||||
// todo: THIS IS BAD AND IS A SIDE EFFECT
|
// todo: THIS IS BAD AND IS A SIDE EFFECT
|
||||||
decoded_instruction.execute(self);
|
decoded_instruction.execute(self);
|
||||||
|
|
||||||
|
|||||||
@ -367,8 +367,6 @@ impl Chip8CpuInstructions {
|
|||||||
0xE09E..=0xEFA1 => {
|
0xE09E..=0xEFA1 => {
|
||||||
match last_byte {
|
match last_byte {
|
||||||
0x9E => {
|
0x9E => {
|
||||||
println!("DECODING {:4x}", input);
|
|
||||||
println!("UBLN: {:4x}", ubln);
|
|
||||||
Chip8CpuInstructions::SkpVx(ubln)
|
Chip8CpuInstructions::SkpVx(ubln)
|
||||||
}
|
}
|
||||||
0xA1 => {
|
0xA1 => {
|
||||||
@ -380,7 +378,6 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xF007..=0xFF65 => {
|
0xF007..=0xFF65 => {
|
||||||
// println!("COMPARING LAST BYTE FROM TODECODE: {:2x} to {:4x} with {:2x}", last_byte, input, ubln);
|
|
||||||
match last_byte {
|
match last_byte {
|
||||||
0x07 => {
|
0x07 => {
|
||||||
Chip8CpuInstructions::LdVxDt(ubln)
|
Chip8CpuInstructions::LdVxDt(ubln)
|
||||||
@ -426,6 +423,7 @@ impl Chip8CpuInstructions {
|
|||||||
let _ = match self {
|
let _ = match self {
|
||||||
// 0x0nnn Exit to System Call
|
// 0x0nnn Exit to System Call
|
||||||
Chip8CpuInstructions::SysAddr(new_address) => {
|
Chip8CpuInstructions::SysAddr(new_address) => {
|
||||||
|
debug!("SysAddr [0x{new_address:3x}]");
|
||||||
// println!("SYS TO [{new_address}]");
|
// println!("SYS TO [{new_address}]");
|
||||||
input.registers.poke_pc(*new_address as u16);
|
input.registers.poke_pc(*new_address as u16);
|
||||||
}
|
}
|
||||||
@ -441,23 +439,26 @@ impl Chip8CpuInstructions {
|
|||||||
}
|
}
|
||||||
// 0x1nnn Jump to Address
|
// 0x1nnn Jump to Address
|
||||||
Chip8CpuInstructions::JpAddr(new_address) => {
|
Chip8CpuInstructions::JpAddr(new_address) => {
|
||||||
|
debug!("JpAddr [0x{new_address:3x}]");
|
||||||
input.registers.poke_pc(*new_address as u16);
|
input.registers.poke_pc(*new_address as u16);
|
||||||
}
|
}
|
||||||
// 0x2nnn Call Subroutine
|
// 0x2nnn Call Subroutine
|
||||||
Chip8CpuInstructions::CallAddr(new_address) => {
|
Chip8CpuInstructions::CallAddr(new_address) => {
|
||||||
debug!("CALL ADDR {new_address}");
|
debug!("CALL ADDR 0x{new_address:3x}");
|
||||||
}
|
}
|
||||||
// 0x3xkk Skip next instruction if Vx = kk.
|
// 0x3xkk Skip next instruction if Vx = kk.
|
||||||
Chip8CpuInstructions::SeVxByte(vx_register, byte) => {
|
Chip8CpuInstructions::SeVxByte(vx_register, byte) => {
|
||||||
if input.registers.peek(*vx_register as u8) == *byte as u8 {
|
if input.registers.peek(*vx_register as u8) == *byte as u8 {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
|
debug!("SeVxByte [0x{vx_register:1x}] [0x{byte:2x}]");
|
||||||
}
|
}
|
||||||
// 0x4xkk Skip next instruction if Vx != kk
|
// 0x4xkk Skip next instruction if Vx != kk
|
||||||
Chip8CpuInstructions::SneVxByte(x, byte) => {
|
Chip8CpuInstructions::SneVxByte(x, byte) => {
|
||||||
if input.registers.peek(*x as u8) != *byte as u8 {
|
if input.registers.peek(*x as u8) != *byte as u8 {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
|
debug!("SneVxByte [0x{x:1x}] [0x{byte:2x}");
|
||||||
}
|
}
|
||||||
// 0x5xy0 Skip next instruction if Vx == Vy
|
// 0x5xy0 Skip next instruction if Vx == Vy
|
||||||
Chip8CpuInstructions::SeVxVy(x, y) => {
|
Chip8CpuInstructions::SeVxVy(x, y) => {
|
||||||
@ -467,27 +468,33 @@ impl Chip8CpuInstructions {
|
|||||||
if lhs == rhs {
|
if lhs == rhs {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
|
debug!("SeVxVy [0x{x:1x}] [0x{y:1x}]");
|
||||||
}
|
}
|
||||||
// 0x6xkk Set Vx = kk
|
// 0x6xkk Set Vx = kk
|
||||||
Chip8CpuInstructions::LdVxByte(register, byte) => {
|
Chip8CpuInstructions::LdVxByte(register, byte) => {
|
||||||
let byte_value = *byte as u8;
|
let byte_value = *byte as u8;
|
||||||
input.registers.poke(*register as u8, byte_value);
|
input.registers.poke(*register as u8, byte_value);
|
||||||
|
debug!("LdVxByte [0x{register:1x}] [0x{byte:2.0x}]");
|
||||||
}
|
}
|
||||||
// 0x7xkk Set Vx = Vx + kk
|
// 0x7xkk Set Vx = Vx + kk
|
||||||
Chip8CpuInstructions::AddVxByte(vx_register, byte) => {
|
Chip8CpuInstructions::AddVxByte(vx_register, byte) => {
|
||||||
input.registers.poke(*vx_register as u8, (input.registers.peek(*vx_register as u8) + *byte as u8));
|
input.registers.poke(*vx_register as u8, (input.registers.peek(*vx_register as u8) + *byte as u8));
|
||||||
|
debug!("AddVxByte [0x{vx_register:1x}] [0x{byte:2x}]");
|
||||||
}
|
}
|
||||||
// 0x8xy0 Set value of Vy in Vx
|
// 0x8xy0 Set value of Vy in Vx
|
||||||
Chip8CpuInstructions::LdVxVy(x, y) => {
|
Chip8CpuInstructions::LdVxVy(x, y) => {
|
||||||
input.registers.poke(*x as u8, input.registers.peek(*y as u8));
|
input.registers.poke(*x as u8, input.registers.peek(*y as u8));
|
||||||
|
debug!("LdVxVy [0x{x:1x}] [0x{y:1x}]");
|
||||||
}
|
}
|
||||||
// 0x8xy1 Set Vx = Vx OR Vy
|
// 0x8xy1 Set Vx = Vx OR Vy
|
||||||
Chip8CpuInstructions::OrVxVy(x, y) => {
|
Chip8CpuInstructions::OrVxVy(x, y) => {
|
||||||
input.registers.poke(*x as u8, input.registers.peek(*x as u8) | input.registers.peek(*y as u8));
|
input.registers.poke(*x as u8, input.registers.peek(*x as u8) | input.registers.peek(*y as u8));
|
||||||
|
debug!("OrVxVy [0x{x:1x}] [0x{y:1x}]")
|
||||||
}
|
}
|
||||||
// 0x8xy2 Set Vx = Vx AND Vy
|
// 0x8xy2 Set Vx = Vx AND Vy
|
||||||
Chip8CpuInstructions::AndVxVy(x, y) => {
|
Chip8CpuInstructions::AndVxVy(x, y) => {
|
||||||
input.registers.poke(*x as u8, input.registers.peek(*x as u8) & input.registers.peek(*y as u8));
|
input.registers.poke(*x as u8, input.registers.peek(*x as u8) & input.registers.peek(*y as u8));
|
||||||
|
debug!("AndVxVy [0x{x:1x}] [0x{y:1x}]");
|
||||||
}
|
}
|
||||||
// 0x8xy3 Set Vx = Vx XOR Vy
|
// 0x8xy3 Set Vx = Vx XOR Vy
|
||||||
Chip8CpuInstructions::XorVxVy(x, y) => {
|
Chip8CpuInstructions::XorVxVy(x, y) => {
|
||||||
@ -510,7 +517,7 @@ impl Chip8CpuInstructions {
|
|||||||
// If Vx > Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, and the results stored in Vx.
|
// If Vx > Vy, then VF is set to 1, otherwise 0. Then Vy is subtracted from Vx, and the results stored in Vx.
|
||||||
input.registers.poke(*x as u8, input.registers.peek(*x as u8) - input.registers.peek(*y as u8));
|
input.registers.poke(*x as u8, input.registers.peek(*x as u8) - input.registers.peek(*y as u8));
|
||||||
}
|
}
|
||||||
Chip8CpuInstructions::ShrVxVy(x, y) => {
|
Chip8CpuInstructions::ShrVxVy(x, _) => {
|
||||||
// 8xy6 - SHR Vx {, Vy}
|
// 8xy6 - SHR Vx {, Vy}
|
||||||
// Set Vx = Vx SHR 1.
|
// Set Vx = Vx SHR 1.
|
||||||
//
|
//
|
||||||
@ -533,7 +540,7 @@ impl Chip8CpuInstructions {
|
|||||||
input.registers.poke(*x as u8, x_register - y_register);
|
input.registers.poke(*x as u8, x_register - y_register);
|
||||||
}
|
}
|
||||||
|
|
||||||
Chip8CpuInstructions::ShlVxVy(x, y) => {
|
Chip8CpuInstructions::ShlVxVy(x, _) => {
|
||||||
// 8xyE - SHL Vx {, Vy}
|
// 8xyE - SHL Vx {, Vy}
|
||||||
// Set Vx = Vx SHL 1.
|
// Set Vx = Vx SHL 1.
|
||||||
//
|
//
|
||||||
@ -561,7 +568,7 @@ impl Chip8CpuInstructions {
|
|||||||
// Set I = nnn.
|
// Set I = nnn.
|
||||||
//
|
//
|
||||||
// The value of register I is set to nnn.
|
// The value of register I is set to nnn.
|
||||||
println!("SETTING I to {new_index}");
|
debug!("LdiAddr [0x{new_index:3x}]");
|
||||||
input.registers.poke_i(*new_index);
|
input.registers.poke_i(*new_index);
|
||||||
}
|
}
|
||||||
// 0xBnnn Jump to nnn+V0
|
// 0xBnnn Jump to nnn+V0
|
||||||
@ -598,7 +605,7 @@ impl Chip8CpuInstructions {
|
|||||||
let num_bytes_to_read = *n;
|
let num_bytes_to_read = *n;
|
||||||
for i in start_position..start_position + num_bytes_to_read {
|
for i in start_position..start_position + num_bytes_to_read {
|
||||||
// let current_byte = input.memory[i as usize];
|
// let current_byte = input.memory[i as usize];
|
||||||
// println!("READ BYTE [{current_byte:8b}");
|
println!("READ BYTE [0x{i:2x}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut did_change: bool = false;
|
let mut did_change: bool = false;
|
||||||
@ -631,9 +638,8 @@ impl Chip8CpuInstructions {
|
|||||||
// and if the key corresponding to the value of Vx is currently in the up position,
|
// and if the key corresponding to the value of Vx is currently in the up position,
|
||||||
// PC is increased by 2.
|
// PC is increased by 2.
|
||||||
let target_key = input.registers.peek(*x as u8);
|
let target_key = input.registers.peek(*x as u8);
|
||||||
println!("TESTING REGISTER {x} -> READ {target_key}");
|
|
||||||
let is_pressed = input.keypad.pressed(target_key);
|
let is_pressed = input.keypad.pressed(target_key);
|
||||||
println!("KEY STATE = {is_pressed}");
|
debug!("SnKpVx [{x:1x}]");
|
||||||
if is_pressed {
|
if is_pressed {
|
||||||
input.registers.advance_pc();
|
input.registers.advance_pc();
|
||||||
}
|
}
|
||||||
@ -713,7 +719,6 @@ impl Chip8CpuInstructions {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use ratatui::crossterm::execute;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -836,7 +841,7 @@ mod test {
|
|||||||
|
|
||||||
// ** test moved up so it can be used later
|
// ** test moved up so it can be used later
|
||||||
#[test]
|
#[test]
|
||||||
fn LdVxByte_test() {
|
fn ld_vx_byte_test() {
|
||||||
// 0x6xkk Set Vx = kk
|
// 0x6xkk Set Vx = kk
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
Chip8CpuInstructions::LdVxByte(1, 0x12).execute(&mut x);
|
Chip8CpuInstructions::LdVxByte(1, 0x12).execute(&mut x);
|
||||||
@ -886,7 +891,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn SeVxVy_test() {
|
fn se_vx_vy_test() {
|
||||||
// 0x4xkk Skip next instruction if Vx != kk
|
// 0x4xkk Skip next instruction if Vx != kk
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
Chip8CpuInstructions::LdVxByte(0x01, 0x84).execute(&mut x);
|
Chip8CpuInstructions::LdVxByte(0x01, 0x84).execute(&mut x);
|
||||||
@ -908,7 +913,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn LdVxVy_test() {
|
fn ld_vx_vy_test() {
|
||||||
// 0x8xy0 Set value of Vy in Vx
|
// 0x8xy0 Set value of Vy in Vx
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
Chip8CpuInstructions::LdVxByte(0x01, 0x01).execute(&mut x);
|
Chip8CpuInstructions::LdVxByte(0x01, 0x01).execute(&mut x);
|
||||||
@ -921,7 +926,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn OrVxVy_test() {
|
fn or_vx_vy_test() {
|
||||||
// 0x8xy1 Set Vx = Vx OR Vy
|
// 0x8xy1 Set Vx = Vx OR Vy
|
||||||
// 0b0101 0000 (0x50)
|
// 0b0101 0000 (0x50)
|
||||||
// | 0b0000 1010 (0x0A)
|
// | 0b0000 1010 (0x0A)
|
||||||
@ -935,7 +940,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn AndVxVy_test() {
|
fn and_vx_vy_test() {
|
||||||
// 0x8xy2 Set Vx = Vx AND Vy
|
// 0x8xy2 Set Vx = Vx AND Vy
|
||||||
// 0b1111 1100 (0xFC)
|
// 0b1111 1100 (0xFC)
|
||||||
// & 0b1100 1010 (0xCA)
|
// & 0b1100 1010 (0xCA)
|
||||||
@ -949,7 +954,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn XorVxVy_test() {
|
fn xor_vx_vy_test() {
|
||||||
// 0x8xy3 Set Vx = Vx XOR Vy
|
// 0x8xy3 Set Vx = Vx XOR Vy
|
||||||
// 0b1111 1100 (0xFC)
|
// 0b1111 1100 (0xFC)
|
||||||
// ^ 0b1100 1010 (0xCA)
|
// ^ 0b1100 1010 (0xCA)
|
||||||
@ -963,7 +968,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn AddVxVy_test() {
|
fn add_vx_vy_test() {
|
||||||
// 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry)
|
// 0x8xy4 Set Vx = Vx + Vy (SET VF on Carry)
|
||||||
// T1 T2: Judgement Test
|
// T1 T2: Judgement Test
|
||||||
// 0x01 0xFF
|
// 0x01 0xFF
|
||||||
@ -991,7 +996,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ShrVxVy_test() {
|
fn shr_vx_vy_test() {
|
||||||
/*
|
/*
|
||||||
Set Vx = Vx SHR 1.
|
Set Vx = Vx SHR 1.
|
||||||
|
|
||||||
@ -1015,7 +1020,7 @@ mod test {
|
|||||||
assert_eq!(x.registers.peek_pc(), 0x206);
|
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn LdiAddr_test() {
|
fn ldi_addr_test() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
Chip8CpuInstructions::LdIAddr(0x123).execute(&mut x);
|
Chip8CpuInstructions::LdIAddr(0x123).execute(&mut x);
|
||||||
assert_eq!(x.registers.peek_i(), 0x123);
|
assert_eq!(x.registers.peek_i(), 0x123);
|
||||||
@ -1023,37 +1028,13 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn JpV0Addr_test() {
|
fn jp_v0addr_test() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
/// jump to I + nnn
|
/// jump to I + nnn
|
||||||
Chip8CpuInstructions::LdVxByte(0x0, 0xFF).execute(&mut x);
|
Chip8CpuInstructions::LdVxByte(0x0, 0xFF).execute(&mut x);
|
||||||
Chip8CpuInstructions::JpV0Addr(0x100).execute(&mut x);
|
Chip8CpuInstructions::JpV0Addr(0x100).execute(&mut x);
|
||||||
assert_eq!(x.registers.peek_pc(), 0x1FF);
|
assert_eq!(x.registers.peek_pc(), 0x1FF);
|
||||||
}
|
}
|
||||||
// #[test]
|
|
||||||
fn SnKpVx_test() {
|
|
||||||
// skip key not pressed
|
|
||||||
let mut x = Chip8Computer::new();
|
|
||||||
x.keypad.push_key(2);
|
|
||||||
Chip8CpuInstructions::LdVxByte(0x1, 0x02);
|
|
||||||
Chip8CpuInstructions::SnkpVx(2).execute(&mut x);
|
|
||||||
assert_eq!(x.registers.peek_pc(), 0x204);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn LdVxDt_test() {
|
|
||||||
// delay timer reading
|
|
||||||
let mut x = Chip8Computer::new();
|
|
||||||
|
|
||||||
// set the value we want in the timer to V0...
|
|
||||||
Chip8CpuInstructions::LdVxByte(0x1, 0x10).execute(&mut x);
|
|
||||||
Chip8CpuInstructions::LdDtVx(0x1).execute(&mut x);
|
|
||||||
// ...then tell the CPU to use that value for the timer.
|
|
||||||
Chip8CpuInstructions::LdVxDt(0x1).execute(&mut x);
|
|
||||||
|
|
||||||
let new_reg_value = x.registers.peek(0x1);
|
|
||||||
assert_eq!(new_reg_value, 0x1);
|
|
||||||
}
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cls_test() {
|
fn cls_test() {
|
||||||
let mut x = Chip8Computer::new();
|
let mut x = Chip8Computer::new();
|
||||||
@ -1074,15 +1055,6 @@ mod test {
|
|||||||
assert_eq!(x.registers.peek_pc(), 0x208);
|
assert_eq!(x.registers.peek_pc(), 0x208);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn lddtvx_test() {
|
|
||||||
let mut x = Chip8Computer::new();
|
|
||||||
Chip8CpuInstructions::LdDtVx(0x10).execute(&mut x);
|
|
||||||
assert_eq!(x.delay_timer.current(), 0x10);
|
|
||||||
x.delay_timer.tick();
|
|
||||||
x.delay_timer.tick();
|
|
||||||
assert_eq!(x.delay_timer.current(), 0x0E);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn addivx_test() {
|
fn addivx_test() {
|
||||||
@ -1126,4 +1098,63 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_vx_byte_test() {
|
||||||
|
let mut x = Chip8Computer::new();
|
||||||
|
// set a value in the register
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x1, 0xab).execute(&mut x);
|
||||||
|
// add 0x10 to register
|
||||||
|
Chip8CpuInstructions::AddVxByte(0x1, 0x10).execute(&mut x);
|
||||||
|
assert_eq!(x.registers.peek(1), 0xbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub_vx_vy_test() {
|
||||||
|
let mut x = Chip8Computer::new();
|
||||||
|
// load values in 2 registers
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x01, 0x10).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x02, 0x08).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::SubVxVy(0x1, 0x02).execute(&mut x);
|
||||||
|
assert_eq!(x.registers.peek(0xf), 0);
|
||||||
|
assert_eq!(x.registers.peek(0x1), 0x8);
|
||||||
|
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sne_vx_vy_test() {
|
||||||
|
let mut x = Chip8Computer::new();
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x1, 0x10).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x2, 0x10).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::SneVxVy(0x1, 0x2).execute(&mut x);
|
||||||
|
assert_eq!(x.registers.peek_pc(), 0x206);
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x2, 0x00).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::SneVxVy(0x01, 0x02).execute(&mut x);
|
||||||
|
assert_eq!(x.registers.peek_pc(), 0x20C)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ld_dt_vx_test() {
|
||||||
|
let mut x = Chip8Computer::new();
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x1, 0x10).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::LdDtVx(0x1).execute(&mut x);
|
||||||
|
assert_eq!(x.delay_timer.current(), 0x10);
|
||||||
|
for i in 0..0x20 {
|
||||||
|
x.delay_timer.tick();
|
||||||
|
}
|
||||||
|
assert_eq!(x.delay_timer.current(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ld_vx_dt_test() {
|
||||||
|
let mut x = Chip8Computer::new();
|
||||||
|
Chip8CpuInstructions::LdVxByte(0x1, 0xf0).execute(&mut x);
|
||||||
|
Chip8CpuInstructions::LdDtVx(0x1).execute(&mut x);
|
||||||
|
x.delay_timer.tick();
|
||||||
|
x.delay_timer.tick();
|
||||||
|
x.delay_timer.tick();
|
||||||
|
Chip8CpuInstructions::LdVxDt(0x1).execute(&mut x);
|
||||||
|
assert_eq!(x.registers.peek(0x1), 0xed);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,6 @@ impl Chip8Registers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn poke_i(&mut self, new_value: u16) {
|
pub fn poke_i(&mut self, new_value: u16) {
|
||||||
println!("REGISTER: Setting I to {new_value}");
|
|
||||||
self.i_register = new_value;
|
self.i_register = new_value;
|
||||||
}
|
}
|
||||||
pub fn peek(&self, register_number: u8) -> u8 {
|
pub fn peek(&self, register_number: u8) -> u8 {
|
||||||
@ -57,8 +56,24 @@ impl Chip8Registers {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use crate::chip8::registers::Chip8Registers;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn smoke() { assert!(true) }
|
fn smoke() { assert!(true) }
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn register_rw_test() {
|
||||||
|
let mut x = Chip8Registers::default();
|
||||||
|
x.poke(0x0, 0xff);
|
||||||
|
x.poke(0x1, 0xab);
|
||||||
|
assert_eq!(x.peek(0x0), 0xff);
|
||||||
|
assert_eq!(x.peek(0x1), 0xab);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn i_register_test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
use beep::beep;
|
use beep::beep;
|
||||||
|
use log::trace;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct SoundTimer {
|
pub struct SoundTimer {
|
||||||
@ -16,12 +17,12 @@ impl SoundTimer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_timer(&mut self, new_value: i32) {
|
pub fn set_timer(&mut self, new_value: i32) {
|
||||||
println!("SETTING SOUND TIMER TO {new_value}");
|
trace!("SETTING SOUND TIMER TO {new_value}");
|
||||||
self.counter = new_value
|
self.counter = new_value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
println!("TICKING SOUND FROM {} to {}", self.counter, self.counter - 1);
|
trace!("TICKING SOUND FROM {} to {}", self.counter, self.counter - 1);
|
||||||
if self.counter > 0 {
|
if self.counter > 0 {
|
||||||
self.counter -= 1;
|
self.counter -= 1;
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -122,6 +122,4 @@ mod test {
|
|||||||
assert_eq!(x.peek(0), 0x01);
|
assert_eq!(x.peek(0), 0x01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -160,6 +160,8 @@ mod test {
|
|||||||
}
|
}
|
||||||
assert_eq!(x.format_as_string(), expected);
|
assert_eq!(x.format_as_string(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
fn cls() {
|
fn cls() {
|
||||||
let mut initial_memory = [false; CHIP8_VIDEO_MEMORY];
|
let mut initial_memory = [false; CHIP8_VIDEO_MEMORY];
|
||||||
let mut ws = String::new();
|
let mut ws = String::new();
|
||||||
@ -178,4 +180,43 @@ mod test {
|
|||||||
set_x.cls();
|
set_x.cls();
|
||||||
assert_eq!(set_x.format_as_string(), ws);
|
assert_eq!(set_x.format_as_string(), ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn poke_byte_test() {
|
||||||
|
let to_poke = 0b10101010;
|
||||||
|
let mut v = Chip8Video::default();
|
||||||
|
v.poke_byte(0x00, to_poke);
|
||||||
|
assert!(v.peek(0x00));
|
||||||
|
assert!(v.peek(0x02));
|
||||||
|
assert!(v.peek(0x04));
|
||||||
|
assert!(v.peek(0x06));
|
||||||
|
assert!(!v.peek(0x01));
|
||||||
|
assert!(!v.peek(0x03));
|
||||||
|
assert!(!v.peek(0x05));
|
||||||
|
assert!(!v.peek(0x07));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn poke_multi_line_test() {
|
||||||
|
let mut v = Chip8Video::default();
|
||||||
|
let to_poke = [
|
||||||
|
0b00000000,
|
||||||
|
0b11111111,
|
||||||
|
0b10101010,
|
||||||
|
0b01010101
|
||||||
|
];
|
||||||
|
|
||||||
|
for to_poke_index in to_poke.iter() {
|
||||||
|
for current_to_poke_bit_index in 0..8 {
|
||||||
|
let right_shifted_bit = to_poke[*to_poke_index as usize] >> current_to_poke_bit_index;
|
||||||
|
let offset = to_poke_index * 8 + current_to_poke_bit_index;
|
||||||
|
v.poke(offset, is_bit_set(to_poke[*to_poke_index as usize] as u8, current_to_poke_bit_index as u8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_bit_set(to_check: u8, bit_index: u8) -> bool {
|
||||||
|
(to_check >> bit_index )& 0x1 == 0x1
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user