implement skip conditional instructions set
This commit is contained in:
parent
f9a81e200c
commit
d6ef37daf9
2 changed files with 57 additions and 11 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue