use crate::{ consts::{Addr, RegId, RegValue}, decode::Instruction, instructions::find_runner, mem::MemConfig, }; // placeholder - change when exception system is in place pub(crate) type Exception = (); pub(crate) enum InstructionResult { Normal, Exception(Exception), Pause, } pub struct Core { x_regs: [RegValue; 32], pc: Addr, mem: MemConfig, } impl Core { pub fn new(mem: MemConfig) -> Self { Self { x_regs: [0; 32], pc: 0, mem, } } pub fn run(&mut self) { loop { let page = (self.pc / 4096) as usize; let offset = (self.pc / 4) as u16; if !self.pc.is_multiple_of(4) { //replace eprint with logging, replace break with exception eprintln!("PC not aligned"); break; } let instr = match self.mem.read_word(page, offset) { Ok(i) => i, Err(_) => { eprintln!("Memory access fault while fetching instruction"); break; } }; let instr = Instruction(instr); let runner = find_runner(instr); if let Some(runner) = runner { let res = runner(self, instr); match res { InstructionResult::Normal => {} InstructionResult::Exception(_e) => { eprintln!("Exception from instruction"); break; } InstructionResult::Pause => { eprintln!("Instruction asked for pause"); break; } } } } } pub fn reset(&mut self, pc: Addr) { self.pc = pc; } fn reg_read(&self, id: RegId) -> RegValue { self.x_regs[id as usize] } fn reg_write(&mut self, id: RegId, value: RegValue) { if id == 0 { return; } self.x_regs[id as usize] = value; } }