diff --git a/src/bytecode/ops.rs b/src/bytecode/ops.rs index 8551b567..325b6c9e 100644 --- a/src/bytecode/ops.rs +++ b/src/bytecode/ops.rs @@ -5,17 +5,29 @@ pub enum Operations { SUB = 2, MUL = 3, DIV = 4, + MOD = 5, + + And = 6, + Or = 7, + Xor = 8, + Not = 9, // LOADs a memory address/constant into a register - LOAD = 5, + LOAD = 15, // STOREs a register/constant into a memory address - STORE = 6, + STORE = 16, - EnviromentCall = 10, + MapPage = 17, + UnmapPage = 18, + + // SHIFT LEFT 16 A0 + Shift = 20, JUMP = 100, JumpCond = 101, RET = 103, + + EnviromentCall = 255, } pub enum SubTypes { @@ -41,5 +53,7 @@ pub enum JumpConditionals { Equal = 0, NotEqual = 1, LessThan = 2, - GreaterThan = 3, + LessThanOrEqualTo = 3, + GreaterThan = 4, + GreaterThanOrEqualTo = 5, } diff --git a/src/engine/enviroment_calls.rs b/src/engine/enviroment_calls.rs new file mode 100644 index 00000000..27289d6b --- /dev/null +++ b/src/engine/enviroment_calls.rs @@ -0,0 +1,3 @@ +use super::Engine; + +pub type EnviromentCall = fn(&mut Engine) -> Result<&mut Engine, u64>; diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 27e2c0a3..99c85b1a 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -1,24 +1,27 @@ pub mod call_stack; pub mod config; +pub mod enviroment_calls; pub mod regs; -use crate::bytecode::ops::Operations::*; -use crate::bytecode::ops::*; -use crate::bytecode::types::*; +use crate::bytecode::{ + ops::{Operations::*, *}, + types::*, +}; -use crate::engine::call_stack::FnCall; -use crate::memory; -use crate::HaltStatus; -use crate::RuntimeErrors; -use alloc::vec::Vec; -use config::EngineConfig; -use log::trace; -use regs::Registers; +use { + crate::{engine::call_stack::FnCall, memory, HaltStatus, RuntimeErrors}, + alloc::vec::Vec, + config::EngineConfig, + log::trace, + regs::Registers, +}; use self::call_stack::CallStack; +// pub const PAGE_SIZE: usize = 8192; + #[derive(Debug, Clone, Copy)] pub struct Page { - pub data: [u8; 4096 * 2], + pub data: [u8; 8192], } impl Page { pub fn new() -> Self { @@ -27,18 +30,17 @@ impl Page { } } } -pub type EnviromentCall = fn(Registers) -> Result; -pub fn empty_enviroment_call(reg: Registers) -> Result { - trace!("Registers {:?}", reg); +pub fn empty_enviroment_call(engine: &mut Engine) -> Result<&mut Engine, u64> { + trace!("Registers {:?}", engine.registers); Err(0) } pub struct Engine { pub index: usize, - program: Vec, + program: Vec, registers: Registers, - config: EngineConfig, + config: EngineConfig, /// BUG: This DOES NOT account for overflowing last_timer_count: u32, @@ -47,7 +49,7 @@ pub struct Engine { pub enviroment_call_table: [EnviromentCall; 256], call_stack: CallStack, } - +use crate::engine::enviroment_calls::EnviromentCall; impl Engine { pub fn read_mem_addr_8(&mut self, address: u64) -> Result { // println!("{}", address); @@ -62,10 +64,9 @@ impl Engine { pub fn new(program: Vec) -> Self { let mut mem = memory::Memory::new(); for (addr, byte) in program.clone().into_iter().enumerate() { - let ret = mem.set_addr8(addr as u64, byte); - println!("{:?}", ret); + let _ = mem.set_addr8(addr as u64, byte); } - println!("{:?}", mem.read_addr8(0)); + trace!("{:?}", mem.read_addr8(0)); Self { index: 0, @@ -75,7 +76,7 @@ impl Engine { last_timer_count: 0, timer_callback: None, enviroment_call_table: [empty_enviroment_call; 256], - memory: memory::Memory::new(), + memory: mem, call_stack: Vec::new(), } } @@ -165,8 +166,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", ); } pub fn run(&mut self) -> Result { - use HaltStatus::*; - use RuntimeErrors::*; + use {HaltStatus::*, RuntimeErrors::*}; loop { // Break out of the loop if self.index + 1 == self.program.len() { @@ -245,7 +245,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", } } - self.index += 19; + self.index += 18; } (2, 1) => { let lhs = self.program[self.index + 2]; @@ -335,18 +335,25 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", trace!("addr {}", addr); - let ret = self.read_mem_addr_8(addr)?; - let reg = self.program[self.index + 10]; - trace!("reg {}", reg); - self.set_register_8(reg, ret); - self.index += 9; + let ret = self.read_mem_addr_8(addr); + match ret { + Ok(ret) => { + let reg = self.program[self.index + 10]; + trace!("reg {}", reg); + self.set_register_8(reg, ret); + self.index += 10; + } + Err(err) => trace!("{:?}", err), + } } (10, int) => { - println!("Enviroment Call {}", int); - let ret = self.enviroment_call_table[int as usize](self.registers); + trace!("Enviroment Call {}", int); + let ret = self.enviroment_call_table[int as usize](self); match ret { - Ok(_) => {} + Ok(eng) => { + trace!("Resuming execution at {}", eng.index); + } Err(err) => { return Err(HostError(err)); } @@ -366,9 +373,9 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", .into_iter() .enumerate() { - trace!("byte {}", byte); addr_array[index] = *byte; } + let addr = usize::from_be_bytes(addr_array); if addr > self.program.len() { panic!("Invalid jump address {}", addr) diff --git a/src/engine/regs.rs b/src/engine/regs.rs index b18dcf63..84427dd0 100644 --- a/src/engine/regs.rs +++ b/src/engine/regs.rs @@ -1,6 +1,6 @@ #[rustfmt::skip] #[derive(Debug, Clone, Copy)] -pub struct Registers{ +pub struct Registers { pub a0: u8, pub b0: u8, pub c0: u8, pub d0: u64, pub e0: u64, pub f0: u64, pub a1: u8, pub b1: u8, pub c1: u8, pub d1: u64, pub e1: u64, pub f1: u64, pub a2: u8, pub b2: u8, pub c2: u8, pub d2: u64, pub e2: u64, pub f2: u64, diff --git a/src/lib.rs b/src/lib.rs index 8926402a..71969c74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ pub enum RuntimeErrors { InvalidOpcode(u8), RegisterTooSmall, HostError(u64), - PageUnmapped(u64), + PageNotMapped(u64), } // If you solve the halting problem feel free to remove this diff --git a/src/main.rs b/src/main.rs index d063aba7..32e7534a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use holey_bytes::{ bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*}, - engine::{regs::Registers, Engine}, + engine::Engine, RuntimeErrors, }; @@ -8,8 +8,7 @@ fn main() -> Result<(), RuntimeErrors> { #[rustfmt::skip] let prog: Vec = vec![ NOP as u8, NOP as u8, - // 10, 10, - + 10, 10, ADD as u8, EightBit as u8, 100, 20, 0xA7, ADD as u8, EightBit as u8, 1, 0, 0xB0, @@ -22,15 +21,16 @@ fn main() -> Result<(), RuntimeErrors> { LOAD as u8, AddrToReg as u8, 0, 0, 0, 0, 0, 0, 0, 2, 0xA0, - JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 5, + // JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0, + JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0, + ]; let mut eng = Engine::new(prog); - println!("{:?}", eng.read_mem_addr_8(4)); // eng.set_timer_callback(time); - // eng.enviroment_call_table[10] = print_fn; - // eng.run()?; - // eng.dump(); + eng.enviroment_call_table[10] = print_fn; + eng.run()?; + eng.dump(); Ok(()) } @@ -38,8 +38,7 @@ fn main() -> Result<(), RuntimeErrors> { pub fn time() -> u32 { 9 } -pub fn print_fn(mut reg: Registers) -> Result { - println!("{:?}", reg); - - Ok(reg) +pub fn print_fn(engine: &mut Engine) -> Result<&mut Engine, u64> { + println!("hello"); + Ok(engine) } diff --git a/src/memory.rs b/src/memory.rs index bcb5a58b..1b97c4a5 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -21,15 +21,18 @@ impl Memory { impl Memory { pub fn read_addr8(&mut self, address: u64) -> Result { let (page, offset) = addr_to_page(address); - println!("page {} offset {}", page, offset); + trace!("page {} offset {}", page, offset); match self.inner.get(&page) { Some(page) => { let val = page.data[offset as usize]; + trace!("Value {}", val); Ok(val) } - None => Err(RuntimeErrors::PageUnmapped(page)), + None => { + trace!("page not mapped"); + Err(RuntimeErrors::PageNotMapped(page)) + } } - // trace!("Value read {} from page {} offset {}", val, page, offset); } pub fn read_addr64(&mut self, address: u64) -> u64 { unimplemented!()