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 anyhow::anyhow;
use log::{debug, info, trace, warn};
use rand::Rng;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::{thread, time};
use rand::Rng;
/// Represents the display's width in pixels.
const DISPLAY_WIDTH: usize = 64;
@ -279,7 +279,33 @@ where
ProcessorInstruction::GenerateRandomNumber(register, 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);
}
}

View file

@ -54,6 +54,14 @@ pub enum ProcessorInstruction {
JumpWithOffset(u16),
/// Generates a random number ANDed with the data and stores it in VX.
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
UnknownInstruction,
}
@ -172,15 +180,27 @@ impl Instruction {
Self::grab_first_nibble(data),
Self::grab_middle_nibble(data),
),
(0xB, _, _, _) => {
ProcessorInstruction::JumpWithOffset(Self::grab_inner_data(data))
}
(0xC, _, _, _) => {
ProcessorInstruction::GenerateRandomNumber(
(0xB, _, _, _) => ProcessorInstruction::JumpWithOffset(Self::grab_inner_data(data)),
(0xC, _, _, _) => ProcessorInstruction::GenerateRandomNumber(
Self::grab_first_nibble(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
_ => ProcessorInstruction::UnknownInstruction,
}