diff --git a/Cargo.lock b/Cargo.lock index ba1a6b48..9e910c8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "holey_bytes" version = "0.1.0" +dependencies = [ + "log", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] diff --git a/Cargo.toml b/Cargo.toml index 5d242e48..362d93ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +log = "*" diff --git a/src/bytecode/ops.rs b/src/bytecode/ops.rs index 510aae88..8551b567 100644 --- a/src/bytecode/ops.rs +++ b/src/bytecode/ops.rs @@ -11,6 +11,8 @@ pub enum Operations { // STOREs a register/constant into a memory address STORE = 6, + EnviromentCall = 10, + JUMP = 100, JumpCond = 101, RET = 103, diff --git a/src/engine/call_stack.rs b/src/engine/call_stack.rs index c69db8b0..39fee04e 100644 --- a/src/engine/call_stack.rs +++ b/src/engine/call_stack.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + pub type CallStack = Vec; pub struct FnCall { pub ret: usize, diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 861b0eb0..523eb9f5 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -9,7 +9,9 @@ use crate::bytecode::types::*; use crate::engine::call_stack::FnCall; use crate::HaltStatus; use crate::RuntimeErrors; +use alloc::vec::Vec; use config::EngineConfig; +use log::trace; use regs::Registers; use self::call_stack::CallStack; @@ -17,6 +19,11 @@ use self::call_stack::CallStack; pub struct Page { pub data: [u8; 4096 * 2], } +pub type EnviromentCall = fn(Registers) -> Result<(), ()>; + +pub fn empty_enviroment_call(reg: Registers) -> Result<(), ()> { + Err(()) +} pub struct Engine { pub index: usize, @@ -28,6 +35,7 @@ pub struct Engine { last_timer_count: u32, timer_callback: Option u32>, memory: Vec, + pub enviroment_call_table: [EnviromentCall; 256], call_stack: CallStack, } @@ -36,6 +44,9 @@ impl Engine { // println!("{}", address); 255 } + pub fn set_timer_callback(&mut self, func: fn() -> u32) { + self.timer_callback = Some(func); + } } impl Engine { @@ -47,13 +58,15 @@ impl Engine { config: EngineConfig::default(), last_timer_count: 0, timer_callback: None, - memory: vec![], - call_stack: vec![], + enviroment_call_table: [empty_enviroment_call; 256], + memory: Vec::new(), + call_stack: Vec::new(), } } + pub fn dump(&self) { - println!("Registers"); - println!( + trace!("Registers"); + trace!( "A {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", self.registers.a0, self.registers.a1, @@ -66,7 +79,7 @@ impl Engine { self.registers.a8, self.registers.a9, ); - println!( + trace!( "B {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", self.registers.b0, self.registers.b1, @@ -79,7 +92,7 @@ impl Engine { self.registers.b8, self.registers.b9, ); - println!( + trace!( "C {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", self.registers.c0, self.registers.c1, @@ -92,8 +105,7 @@ impl Engine { self.registers.c8, self.registers.c9, ); - - println!( + trace!( "D0-D4 {:016X} {:016X} {:016X} {:016X} {:016X} D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.d0, @@ -107,7 +119,7 @@ D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.d8, self.registers.d9, ); - println!( + trace!( "E0-E4 {:016X} {:016X} {:016X} {:016X} {:016X} E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.e0, @@ -121,7 +133,7 @@ E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.e8, self.registers.e9, ); - println!( + trace!( "F0-F4 {:016X} {:016X} {:016X} {:016X} {:016X} F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.registers.f0, @@ -148,7 +160,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", // println!("OP {} INDEX {}", op.0, self.index); match op { (0, _) => { - println!("NO OP"); + trace!("NO OP"); self.index += 1; } // Add a 8 bit num @@ -305,18 +317,25 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", } let addr = u64::from_be_bytes(addr_array); - println!("addr {}", addr); + trace!("addr {}", addr); let ret = self.read_mem_addr(addr); let reg = self.program[self.index + 10]; - println!("reg {}", reg); + trace!("reg {}", reg); self.set_register_8(reg, ret); self.index += 9; } + (10, int) => { + println!("Enviroment Call {}", int); + self.enviroment_call_table[int as usize](self.registers); + self.index += 2; + } + (100, _) => { if self.call_stack.len() > self.config.call_stack_depth { - panic!("Callstack {}", self.call_stack.len()); + trace!("Callstack {}", self.call_stack.len()); + break; } let mut addr_array = [0; 8]; @@ -325,7 +344,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", .into_iter() .enumerate() { - println!("byte {}", byte); + trace!("byte {}", byte); addr_array[index] = *byte; } let addr = usize::from_be_bytes(addr_array); @@ -336,7 +355,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.call_stack.push(call); self.index = addr; - println!("Jumping to {}", addr); + trace!("Jumping to {}", addr); self.dump(); // panic!(); diff --git a/src/engine/regs.rs b/src/engine/regs.rs index 27fc413c..b18dcf63 100644 --- a/src/engine/regs.rs +++ b/src/engine/regs.rs @@ -1,4 +1,5 @@ #[rustfmt::skip] +#[derive(Debug, Clone, Copy)] 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, diff --git a/src/lib.rs b/src/lib.rs index f2aea92a..2a1867aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,14 @@ +// #![no_std] +extern crate alloc; + pub mod bytecode; pub mod engine; +pub mod memory; use bytecode::ops::*; use bytecode::types::{CONST_F64, CONST_U8}; use engine::Engine; -pub fn time() -> u32 { - 9 -} #[derive(Debug)] pub enum RuntimeErrors { InvalidOpcode(u8), diff --git a/src/main.rs b/src/main.rs index 3e3d6a01..b4c9a3c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,60 @@ +use std::{result, time::Duration}; + use holey_bytes::{ - bytecode::{ - ops::{Operations::*, RWSubTypes, RWSubTypes::*, SubTypes::*}, - types::*, - }, - engine::Engine, + bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*}, + engine::{regs::Registers, Engine}, RuntimeErrors, }; fn main() -> Result<(), RuntimeErrors> { - #[rustfmt::skip] - let prog: Vec = vec![ - // NOP as u8, NOP as u8, - ADD as u8, EightBit as u8, 100, 20, 0xA7, - ADD as u8, - EightBit as u8, 1, 0, 0xB0, - ADD as u8, - SixtyFourBit as u8, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 0xD0, - SUB as u8, EightBit as u8, 255, 0, 0xA7, - ADD as u8, Register8 as u8, 0xA7, 0xB0, 0xA7, - 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, - ]; - let mut eng = Engine::new(prog); - // eng.timer_callback = Some(time); - eng.run()?; - eng.dump(); + let mut results: Vec = vec![]; + let iters = 1; + for _ in 0..iters { + // #[rustfmt::skip] + // let prog: Vec = vec![ + // // NOP as u8, NOP as u8, + // ADD as u8, EightBit as u8, 100, 20, 0xA7, + // ADD as u8, + // EightBit as u8, 1, 0, 0xB0, + // ADD as u8, + // SixtyFourBit as u8, + // 0, 0, 0, 0, 0, 0, 0, 0, + // 0, 0, 0, 0, 0, 0, 0, 2, 0xD0, + // SUB as u8, EightBit as u8, 255, 0, 0xA7, + // ADD as u8, Register8 as u8, 0xA7, 0xB0, 0xA7, + // LOAD as u8, AddrToReg as u8, + // 0, 0, 0, 0, 0, 0, 0, 2, + // 0xA0, + // 10, 10, + // JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 5, + // ]; + let prog = vec![10, 10]; + + use std::time::Instant; + let now = Instant::now(); + + let mut eng = Engine::new(prog); + + eng.set_timer_callback(time); + eng.enviroment_call_table[10] = print_fn; + eng.run()?; + eng.dump(); + let elapsed = now.elapsed(); + // println!("Elapsed: {:.2?}", elapsed); + results.push(elapsed); + } + let mut val = 0; + for x in results { + val = val + x.as_micros(); + } + println!("micro seconds {}", val / iters); + Ok(()) +} + +pub fn time() -> u32 { + 9 +} +pub fn print_fn(reg: Registers) -> Result<(), ()> { + println!("{:?}", reg); Ok(()) } diff --git a/src/memory.rs b/src/memory.rs new file mode 100644 index 00000000..8e6fd433 --- /dev/null +++ b/src/memory.rs @@ -0,0 +1,18 @@ +pub struct Memory { + //TODO: hashmap with the start bytes as key and end bytes as offset +} +impl Memory { + pub fn read_addr8(&mut self, address: u64) -> u8 { + 0 + } + pub fn read_addr64(&mut self, address: u64) -> u64 { + 0 + } + + pub fn set_addr8(&mut self, address: u64, value: u8) -> u8 { + 0 + } + pub fn set_addr64(&mut self, address: u64, value: u64) -> u64 { + 0 + } +}