pub mod call_stack; pub mod config; pub mod regs; use crate::bytecode::ops::*; use crate::bytecode::types::*; use crate::HaltStatus; use crate::Page; use crate::RuntimeErrors; use config::EngineConfig; use regs::Registers; use self::call_stack::CallStack; pub struct Engine { pub index: usize, program: Vec, registers: Registers, config: EngineConfig, /// BUG: This DOES NOT account for overflowing last_timer_count: u32, timer_callback: Option u32>, memory: Vec, call_stack: CallStack, } impl Engine { pub fn new(program: Vec) -> Self { Self { index: 0, program, registers: Registers::new(), config: EngineConfig::default(), last_timer_count: 0, timer_callback: None, memory: vec![], call_stack: vec![], } } pub fn dump(&self) { println!("Registers"); println!( "A {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", self.registers.a0, self.registers.a1, self.registers.a2, self.registers.a3, self.registers.a4, self.registers.a5, self.registers.a6, self.registers.a7, self.registers.a8, self.registers.a9, ); println!( "B {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", self.registers.b0, self.registers.b1, self.registers.b2, self.registers.b3, self.registers.b4, self.registers.b5, self.registers.b6, self.registers.b7, self.registers.b8, self.registers.b9, ); println!( "C {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", self.registers.c0, self.registers.c1, self.registers.c2, self.registers.c3, self.registers.c4, self.registers.c5, self.registers.c6, self.registers.c7, self.registers.c8, self.registers.c9, ); println!( "D0-D4 {:016X} {:016X} {:016X} {:016X} {:016X} D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.d0, self.registers.d1, self.registers.d2, self.registers.d3, self.registers.d4, self.registers.d5, self.registers.d6, self.registers.d7, self.registers.d8, self.registers.d9, ); println!( "E0-E4 {:016X} {:016X} {:016X} {:016X} {:016X} E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.e0, self.registers.e1, self.registers.e2, self.registers.e3, self.registers.e4, self.registers.e5, self.registers.e6, self.registers.e7, self.registers.e8, self.registers.e9, ); println!( "F0-F4 {:016X} {:016X} {:016X} {:016X} {:016X} F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.f0, self.registers.f1, self.registers.f2, self.registers.f3, self.registers.f4, self.registers.f5, self.registers.f6, self.registers.f7, self.registers.f8, self.registers.f9, ); } pub fn run(&mut self) -> Result { use HaltStatus::*; use RuntimeErrors::*; loop { // Break out of the loop if self.index == self.program.len() { break; } let op = self.program[self.index]; println!("OP {} INDEX {}", self.program[self.index], self.index); match op { NOP => self.index += 1, ADD => { print!("Add"); self.index += 1; let mut lhs: Vec = vec![]; let mut rhs: Vec = vec![]; let mut lhs_signed = false; let mut rhs_signed = false; match self.program[self.index] { CONST_U8 => { self.index += 1; lhs.push(self.program[self.index]); print!(" constant {:?}", lhs[0]); lhs_signed = false; self.index += 1; } CONST_U64 => { self.index += 1; lhs.push(self.program[self.index]); self.index += 1; lhs.push(self.program[self.index]); self.index += 1; lhs.push(self.program[self.index]); self.index += 1; lhs.push(self.program[self.index]); lhs_signed = false; self.index += 1; } 0xA0..=0xC9 => { println!("TRACE: 8 bit lhs"); } 0xD0..=0xFF => { println!("TRACE: 64 bit lhs"); } op => return Err(InvalidOpcode(op)), } match self.program[self.index] { CONST_U8 => { self.index += 1; rhs.push(self.program[self.index]); rhs_signed = false; print!(" constant {:?}", rhs[0]); self.index += 1; } CONST_U64 => { self.index += 1; rhs.push(self.program[self.index]); self.index += 1; rhs.push(self.program[self.index]); self.index += 1; rhs.push(self.program[self.index]); self.index += 1; rhs.push(self.program[self.index]); print!(" constant {:?}", rhs[0]); rhs_signed = false; self.index += 1; } 0xA0..=0xC9 => { println!("TRACE: 8 bit rhs"); } 0xD0..=0xFF => { println!("TRACE: 64 bit rhs"); } _ => { panic!() } } match self.program[self.index] { 0xA0 => { if lhs.len() > 1 { panic!("LHS is not an 8 bit number") } if rhs.len() > 1 { panic!("RHS is not an 8 bit number") } println!(" store in A0"); let sum = lhs[0] + rhs[0]; self.registers.a0 = sum; self.index += 1; } 0xB0 => { if lhs.len() > 1 { panic!("LHS is not an 8 bit number") } if rhs.len() > 1 { panic!("RHS is not an 8 bit number") } println!(" store in B0"); let sum = lhs[0] + rhs[0]; self.registers.b0 = sum; self.index += 1; } 0xC0 => { if lhs.len() > 1 { panic!("LHS is not an 8 bit number") } if rhs.len() > 1 { panic!("RHS is not an 8 bit number") } println!(" store in C0"); let sum = lhs[0] + rhs[0]; self.registers.c8 = sum; self.index += 1; } 0xD0 => { if lhs.len() > 4 { panic!("LHS is not an 8 bit number") } if rhs.len() > 4 { panic!("RHS is not an 8 bit number") } println!(" store in D0"); let lhs: u64 = Into::::into(lhs[3]) << 60; println!("{}", lhs); println!("{}", 2); // let rhs: u64 = (rhs[4] << 16).into(); let rhs: u64 = 0; let sum = lhs + rhs; self.registers.d0 = sum; self.index += 1; } op => { println!("{}", op) } } } SUB => { print!("Sub"); self.index += 1; let mut lhs: Vec = vec![]; let mut rhs: Vec = vec![]; let mut lhs_signed = false; let mut rhs_signed = false; match self.program[self.index] { 0xA0 => { lhs.push(self.registers.a8); lhs_signed = false; print!(" constant {:?}", self.registers.a8); self.index += 1; } 0xB0 => { lhs.push(self.registers.b8); lhs_signed = false; print!(" constant {:?}", self.registers.b8); self.index += 1; } CONST_U8 => { self.index += 1; lhs.push(self.program[self.index]); print!(" constant {:?}", lhs[0]); lhs_signed = false; self.index += 1; } op => return Err(InvalidOpcode(op)), } match self.program[self.index] { 0xB0 => { rhs.push(self.registers.b8); rhs_signed = false; print!(" constant {:?}", self.registers.b8); self.index += 1; } _ => { panic!() } } match self.program[self.index] { 0xA0 => { if lhs.len() > 1 { panic!("LHS is not an 8 bit number") } println!(" store in A8"); let sum = lhs[0] - rhs[0]; self.registers.a8 = sum; self.index += 1; } 0xB0 => { if lhs.len() > 1 { panic!("LHS is not an 8 bit number") } if rhs.len() > 1 { panic!("RHS is not an 8 bit number") } println!(" store in B8"); let sum = lhs[0] - rhs[0]; self.registers.b8 = sum; self.index += 1; } 0xC0 => { if lhs.len() > 1 { panic!("LHS is not an 8 bit number") } if rhs.len() > 1 { panic!("RHS is not an 8 bit number") } println!(" store in B8"); let sum = lhs[0] - rhs[0]; self.registers.c8 = sum; self.index += 1; } _ => { panic!() } } } op => { println!("INVALID OPCODE {}", op); self.index += 1; } } // Finish step if self.timer_callback.is_some() { let ret = self.timer_callback.unwrap()(); if (ret - self.last_timer_count) >= self.config.quantum { return Ok(Running); } } } Ok(Halted) } }