decode instruction using pattern matching

This commit is contained in:
Denis-Cosmin Nutiu 2024-12-04 00:07:33 +02:00
parent 7ecfff3e0d
commit 95b769d227
2 changed files with 44 additions and 15 deletions

View file

@ -1,5 +1,5 @@
use crate::display::Display;
use crate::instruction::Instruction;
use crate::instruction::{Instruction, ProcessorInstruction};
use crate::stack::Stack;
use anyhow::anyhow;
use log::{debug, info, warn};
@ -112,18 +112,15 @@ where
}
fn execute_instruction(&mut self, instruction: Instruction) -> Result<(), anyhow::Error> {
match instruction.raw() {
// Clear Display
0x00E0 => {
match instruction.processor_instruction() {
ProcessorInstruction::ClearScreen => {
info!("clear display");
self.display.clear()
}
// Jump
0x1000..=0x1FFF => {
info!("jump to {}", instruction);
ProcessorInstruction::Jump(address) => {
todo!("implement jump")
}
// Unknown instruction
_ => {
ProcessorInstruction::UnknownInstruction => {
warn!("Unknown instruction: {:04x}, skipping.", instruction);
}
}
@ -142,10 +139,6 @@ where
]))
}
fn decode_instruction(&mut self, _instruction: Instruction) -> Result<(), anyhow::Error> {
todo!("must implement");
}
/// Loads the ROM found at the rom path in the emulator's RAM memory.
fn load_rom<T>(&mut self, rom_file: T) -> Result<(), anyhow::Error>
where

View file

@ -1,23 +1,59 @@
use std::fmt;
use std::fmt::{Display, Formatter, LowerHex};
#[derive(Debug, Clone, Copy)]
pub enum ProcessorInstruction {
/// Clears the screen
ClearScreen,
/// Jumps to a given address
Jump(u16),
UnknownInstruction
}
#[derive(Debug)]
pub struct Instruction {
data: u16,
processor_instruction: ProcessorInstruction
}
impl Instruction {
/// Creates a new instruction instance.
pub(crate) fn new(data: [u8; 2]) -> Self {
let data = (data[0] as u16) << 8u8 | (data[1] as u16);
Instruction {
data: (data[0] as u16) << 8u8 | (data[1] as u16),
data,
processor_instruction: Instruction::decode_instruction(data),
}
}
/// raw returns the raw instruction data.
pub fn raw(&self) -> u16 {
self.data
}
/// Returns the processor instruction.
pub fn processor_instruction(&self) -> ProcessorInstruction {
self.processor_instruction
}
/// Decodes the raw instruction data into a processor instruction.
fn decode_instruction(data: u16) -> ProcessorInstruction {
match data {
// Clear Display
0x00E0 => {
ProcessorInstruction::ClearScreen
}
// Jump
0x1000..=0x1FFF => {
ProcessorInstruction::Jump(data & 0xFFF)
}
// Unknown instruction
_ => {
ProcessorInstruction::UnknownInstruction
}
}
}
}
impl Display for Instruction {