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 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue