implement skip conditional instructions set

This commit is contained in:
Denis-Cosmin Nutiu 2024-12-07 12:37:01 +02:00
parent f9a81e200c
commit d6ef37daf9
2 changed files with 57 additions and 11 deletions

View file

@ -3,11 +3,11 @@ use crate::instruction::{Instruction, ProcessorInstruction};
use crate::stack::Stack; use crate::stack::Stack;
use anyhow::anyhow; use anyhow::anyhow;
use log::{debug, info, trace, warn}; use log::{debug, info, trace, warn};
use rand::Rng;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
use std::{thread, time}; use std::{thread, time};
use rand::Rng;
/// Represents the display's width in pixels. /// Represents the display's width in pixels.
const DISPLAY_WIDTH: usize = 64; const DISPLAY_WIDTH: usize = 64;
@ -279,7 +279,33 @@ where
ProcessorInstruction::GenerateRandomNumber(register, data) => { ProcessorInstruction::GenerateRandomNumber(register, data) => {
self.registers[register as usize] = rand::thread_rng().gen_range(0x00..0xFF) & data self.registers[register as usize] = rand::thread_rng().gen_range(0x00..0xFF) & data
} }
ProcessorInstruction::UnknownInstruction => { ProcessorInstruction::SkipEqualVXData(vx, data) => {
let vx_data = self.registers[vx as usize];
if vx_data == data {
self.program_counter += 2
}
}
ProcessorInstruction::SkipNotEqualVXData(vx, data) => {
let vx_data = self.registers[vx as usize];
if vx_data != data {
self.program_counter += 2
}
}
ProcessorInstruction::SkipEqualVXVY(vx, vy) => {
let vx_data = self.registers[vx as usize];
let vy_data = self.registers[vy as usize];
if vx_data == vy_data {
self.program_counter += 2
}
}
ProcessorInstruction::SkipNotEqualVXVY(vx, vy) => {
let vx_data = self.registers[vx as usize];
let vy_data = self.registers[vy as usize];
if vx_data != vy_data {
self.program_counter += 2
}
}
_ => {
warn!("Unknown instruction: {:04x}, skipping.", instruction); warn!("Unknown instruction: {:04x}, skipping.", instruction);
} }
} }

View file

@ -54,6 +54,14 @@ pub enum ProcessorInstruction {
JumpWithOffset(u16), JumpWithOffset(u16),
/// Generates a random number ANDed with the data and stores it in VX. /// Generates a random number ANDed with the data and stores it in VX.
GenerateRandomNumber(u8, u8), GenerateRandomNumber(u8, u8),
/// Skips the next instruction if VX is equal to data.
SkipEqualVXData(u8, u8),
/// Skip the next instruction if VX is not equal to data.
SkipNotEqualVXData(u8, u8),
/// Skips the next instruction if VX is equal to VY.
SkipEqualVXVY(u8, u8),
/// Skip the next instruction if VX is not equal to VY.
SkipNotEqualVXVY(u8, u8),
/// Unknown instruction /// Unknown instruction
UnknownInstruction, UnknownInstruction,
} }
@ -172,15 +180,27 @@ impl Instruction {
Self::grab_first_nibble(data), Self::grab_first_nibble(data),
Self::grab_middle_nibble(data), Self::grab_middle_nibble(data),
), ),
(0xB, _, _, _) => { (0xB, _, _, _) => ProcessorInstruction::JumpWithOffset(Self::grab_inner_data(data)),
ProcessorInstruction::JumpWithOffset(Self::grab_inner_data(data)) (0xC, _, _, _) => ProcessorInstruction::GenerateRandomNumber(
}
(0xC, _, _, _) => {
ProcessorInstruction::GenerateRandomNumber(
Self::grab_first_nibble(data), Self::grab_first_nibble(data),
Self::grab_last_byte(data), Self::grab_last_byte(data),
) ),
} (0x3, _, _, _) => ProcessorInstruction::SkipEqualVXData(
Self::grab_first_nibble(data),
Self::grab_last_byte(data),
),
(0x4, _, _, _) => ProcessorInstruction::SkipNotEqualVXData(
Self::grab_first_nibble(data),
Self::grab_last_byte(data),
),
(0x5, _, _, 0x0) => ProcessorInstruction::SkipEqualVXVY(
Self::grab_first_nibble(data),
Self::grab_middle_nibble(data),
),
(0x9, _, _, 0x0) => ProcessorInstruction::SkipNotEqualVXVY(
Self::grab_first_nibble(data),
Self::grab_middle_nibble(data),
),
// Unknown instruction // Unknown instruction
_ => ProcessorInstruction::UnknownInstruction, _ => ProcessorInstruction::UnknownInstruction,
} }