implement fetch from pipeline stage

This commit is contained in:
Denis-Cosmin NUTIU 2024-12-01 13:37:38 +02:00
parent e31c05ac9b
commit fba4c9e5e7
3 changed files with 58 additions and 1 deletions

View file

@ -1,4 +1,5 @@
use crate::display::Display; use crate::display::Display;
use crate::instruction::Instruction;
use crate::stack::Stack; use crate::stack::Stack;
use anyhow::anyhow; use anyhow::anyhow;
use log::{debug, info}; use log::{debug, info};
@ -92,10 +93,37 @@ where
T: AsRef<Path> + std::fmt::Display, T: AsRef<Path> + std::fmt::Display,
{ {
self.load_rom(path)?; self.load_rom(path)?;
self.emulation_loop::<T>()?;
Ok(()) Ok(())
} }
/// Emulation loop executes the fetch -> decode -> execute pipeline
fn emulation_loop<T>(&mut self) -> Result<(), anyhow::Error> {
loop {
// fetch instruction
let instruction = self.fetch_instruction();
self.program_counter += 2;
// decode opcode
// let decode = self.decode_instruction(instruction);
// execute
}
Ok(())
}
/// Fetches the current instruction from the memory without incrementing the program counter.
fn fetch_instruction(&self) -> Instruction {
Instruction::new([
self.memory[self.program_counter as usize],
self.memory[self.program_counter as usize + 1],
])
}
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
@ -114,6 +142,9 @@ where
} }
file.read(&mut self.memory[0x200..])?; file.read(&mut self.memory[0x200..])?;
// Set program counter to start of memory
self.program_counter = 0x200;
debug!("Memory:\n{}\n", format!("{:?}", self.memory)); debug!("Memory:\n{}\n", format!("{:?}", self.memory));
Ok(()) Ok(())
} }

25
src/instruction.rs Normal file
View file

@ -0,0 +1,25 @@
use std::fmt::{Display, Formatter, Write};
#[derive(Debug)]
pub struct Instruction {
data: u16,
}
impl Instruction {
/// Creates a new instruction instance.
pub(crate) fn new(data: [u8; 2]) -> Self {
Instruction {
data: (data[1] as u16) << 8u8 | (data[0] as u16),
}
}
}
impl Display for Instruction {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&format!(
"Instruction: [{:02x}, {:02x}]",
((self.data & 0xFF00) >> 8u8) as u8,
(self.data & 0x00FF) as u8
))
}
}

View file

@ -4,6 +4,7 @@ use env_logger;
mod display; mod display;
mod emulator; mod emulator;
mod instruction;
mod stack; mod stack;
fn main() -> Result<(), anyhow::Error> { fn main() -> Result<(), anyhow::Error> {