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::display::Display;
use crate::instruction::Instruction; use crate::instruction::{Instruction, ProcessorInstruction};
use crate::stack::Stack; use crate::stack::Stack;
use anyhow::anyhow; use anyhow::anyhow;
use log::{debug, info, warn}; use log::{debug, info, warn};
@ -112,18 +112,15 @@ where
} }
fn execute_instruction(&mut self, instruction: Instruction) -> Result<(), anyhow::Error> { fn execute_instruction(&mut self, instruction: Instruction) -> Result<(), anyhow::Error> {
match instruction.raw() { match instruction.processor_instruction() {
// Clear Display ProcessorInstruction::ClearScreen => {
0x00E0 => {
info!("clear display"); info!("clear display");
self.display.clear() self.display.clear()
} }
// Jump ProcessorInstruction::Jump(address) => {
0x1000..=0x1FFF => { todo!("implement jump")
info!("jump to {}", instruction);
} }
// Unknown instruction ProcessorInstruction::UnknownInstruction => {
_ => {
warn!("Unknown instruction: {:04x}, skipping.", instruction); 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. /// 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> fn load_rom<T>(&mut self, rom_file: T) -> Result<(), anyhow::Error>
where where

View file

@ -1,23 +1,59 @@
use std::fmt; use std::fmt;
use std::fmt::{Display, Formatter, LowerHex}; 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)] #[derive(Debug)]
pub struct Instruction { pub struct Instruction {
data: u16, data: u16,
processor_instruction: ProcessorInstruction
} }
impl Instruction { impl Instruction {
/// Creates a new instruction instance. /// Creates a new instruction instance.
pub(crate) fn new(data: [u8; 2]) -> Self { pub(crate) fn new(data: [u8; 2]) -> Self {
let data = (data[0] as u16) << 8u8 | (data[1] as u16);
Instruction { Instruction {
data: (data[0] as u16) << 8u8 | (data[1] as u16), data,
processor_instruction: Instruction::decode_instruction(data),
} }
} }
/// raw returns the raw instruction data. /// raw returns the raw instruction data.
pub fn raw(&self) -> u16 { pub fn raw(&self) -> u16 {
self.data 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 { impl Display for Instruction {