implement fetch from pipeline stage
This commit is contained in:
parent
e31c05ac9b
commit
fba4c9e5e7
3 changed files with 58 additions and 1 deletions
|
@ -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<Path> + std::fmt::Display,
|
||||
{
|
||||
self.load_rom(path)?;
|
||||
|
||||
self.emulation_loop::<T>()?;
|
||||
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.
|
||||
fn load_rom<T>(&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(())
|
||||
}
|
||||
|
|
25
src/instruction.rs
Normal file
25
src/instruction.rs
Normal 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
|
||||
))
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ use env_logger;
|
|||
|
||||
mod display;
|
||||
mod emulator;
|
||||
mod instruction;
|
||||
mod stack;
|
||||
|
||||
fn main() -> Result<(), anyhow::Error> {
|
||||
|
|
Loading…
Reference in a new issue