use crate::core::{ cpu::{Cpu, CpuType::*}, mem::Memory, registers::Registers, }; use utils::{ error::{Error, Severity, Type::UnhandledInstruction}, instruction::Instruction, }; pub struct Interpreter { regs: Registers, delay_slot: bool, prev_delay_slot: bool, } impl Cpu for Interpreter { fn get_type() -> super::cpu::CpuType { Interpreter } fn get_regs(&mut self) -> &mut Registers { &mut self.regs } fn should_service_interrupt(&self) -> bool { false } fn update_compare_interrupt(&mut self) { todo!("update_compare_interrupt") } fn fetch(&self, _mem: &Memory, _vaddr: u64) -> Option { todo!("translate vaddr to paddr and if it fails, throw the exception and return None"); // Some(mem.read(paddr).into()) } fn fetch_then_advance(&mut self, mem: &Memory) -> Option { self.update_compare_interrupt(); self.prev_delay_slot = self.delay_slot; self.delay_slot = false; todo!("is_address_error ? then throw exception and return None"); let instr = self.fetch(mem, self.regs.curr_pc as u64)?; if self.should_service_interrupt() { todo!("should_service_interrupt ? then throw exception and return None"); } self.regs.old_pc = self.regs.curr_pc; self.regs.curr_pc = self.regs.next_pc; self.regs.next_pc += 4; Some(instr) } fn step(&mut self, mem: &Memory) -> Result { if let Some(instr) = self.fetch_then_advance(mem) { self.decode_execute(instr)?; } Ok(1) } fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error> { match instr.opcode() { _ => Err(Error { severity: Severity::Error, err_type: UnhandledInstruction(instr), }), } } fn reset(&mut self) { todo!("reset") } }