diff --git a/src/emulator.rs b/src/emulator.rs index 99c2e90..6a1a0a1 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -1,4 +1,5 @@ use crate::display::Display; +use crate::instruction::Instruction; use crate::stack::Stack; use anyhow::anyhow; use log::{debug, info}; @@ -92,10 +93,37 @@ where T: AsRef + std::fmt::Display, { self.load_rom(path)?; - + self.emulation_loop::()?; Ok(()) } + /// Emulation loop executes the fetch -> decode -> execute pipeline + fn emulation_loop(&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. fn load_rom(&mut self, rom_file: T) -> Result<(), anyhow::Error> where @@ -114,6 +142,9 @@ where } file.read(&mut self.memory[0x200..])?; + // Set program counter to start of memory + self.program_counter = 0x200; + debug!("Memory:\n{}\n", format!("{:?}", self.memory)); Ok(()) } diff --git a/src/instruction.rs b/src/instruction.rs new file mode 100644 index 0000000..ab5bb0d --- /dev/null +++ b/src/instruction.rs @@ -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 + )) + } +} diff --git a/src/main.rs b/src/main.rs index e69ff50..b46c8bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use env_logger; mod display; mod emulator; +mod instruction; mod stack; fn main() -> Result<(), anyhow::Error> {