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::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
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 display;
|
||||||
mod emulator;
|
mod emulator;
|
||||||
|
mod instruction;
|
||||||
mod stack;
|
mod stack;
|
||||||
|
|
||||||
fn main() -> Result<(), anyhow::Error> {
|
fn main() -> Result<(), anyhow::Error> {
|
||||||
|
|
Loading…
Reference in a new issue