From 7d8b0bae78509d1808548dd5dcf2abba56dce7cc Mon Sep 17 00:00:00 2001 From: Able Date: Sat, 22 Apr 2023 17:17:49 -0500 Subject: [PATCH] Implement address decoding --- Cargo.lock | 33 +++++++++++++++++++++++ Cargo.toml | 1 + src/engine/mod.rs | 22 ++++++++++----- src/lib.rs | 1 + src/main.rs | 69 +++++++++++++++++++---------------------------- src/memory.rs | 40 +++++++++++++++++++++------ 6 files changed, 109 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e910c8a..eadfaafe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,16 +2,37 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "holey_bytes" version = "0.1.0" dependencies = [ + "hashbrown", "log", ] @@ -23,3 +44,15 @@ checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/Cargo.toml b/Cargo.toml index 362d93ad..485cfc9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] log = "*" +hashbrown = "0.13.2" diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 523eb9f5..e2f631a1 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -7,6 +7,7 @@ use crate::bytecode::ops::*; use crate::bytecode::types::*; use crate::engine::call_stack::FnCall; +use crate::memory; use crate::HaltStatus; use crate::RuntimeErrors; use alloc::vec::Vec; @@ -15,14 +16,15 @@ use log::trace; use regs::Registers; use self::call_stack::CallStack; - +#[derive(Debug, Clone, Copy)] pub struct Page { pub data: [u8; 4096 * 2], } -pub type EnviromentCall = fn(Registers) -> Result<(), ()>; +pub type EnviromentCall = fn(Registers) -> Result; -pub fn empty_enviroment_call(reg: Registers) -> Result<(), ()> { - Err(()) +pub fn empty_enviroment_call(reg: Registers) -> Result { + trace!("Registers {:?}", reg); + Err(0) } pub struct Engine { @@ -34,7 +36,7 @@ pub struct Engine { /// BUG: This DOES NOT account for overflowing last_timer_count: u32, timer_callback: Option u32>, - memory: Vec, + memory: memory::Memory, pub enviroment_call_table: [EnviromentCall; 256], call_stack: CallStack, } @@ -59,7 +61,7 @@ impl Engine { last_timer_count: 0, timer_callback: None, enviroment_call_table: [empty_enviroment_call; 256], - memory: Vec::new(), + memory: memory::Memory::new(), call_stack: Vec::new(), } } @@ -328,7 +330,13 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", (10, int) => { println!("Enviroment Call {}", int); - self.enviroment_call_table[int as usize](self.registers); + let ret = self.enviroment_call_table[int as usize](self.registers); + match ret { + Ok(_) => {} + Err(err) => { + return Err(HostError(err)); + } + } self.index += 2; } diff --git a/src/lib.rs b/src/lib.rs index 2a1867aa..2dcb84e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ use engine::Engine; pub enum RuntimeErrors { InvalidOpcode(u8), RegisterTooSmall, + HostError(u64), } // If you solve the halting problem feel free to remove this diff --git a/src/main.rs b/src/main.rs index b4c9a3c4..ec894c95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -use std::{result, time::Duration}; - use holey_bytes::{ bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*}, engine::{regs::Registers, Engine}, @@ -7,54 +5,41 @@ use holey_bytes::{ }; fn main() -> Result<(), RuntimeErrors> { - 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]; + #[rustfmt::skip] + let prog: Vec = vec![ + // NOP as u8, NOP as u8, + // 10, 10, - use std::time::Instant; - let now = Instant::now(); + 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); + let mut eng = Engine::new(prog); + + // eng.set_timer_callback(time); + eng.enviroment_call_table[10] = print_fn; + eng.run()?; + eng.dump(); - 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<(), ()> { +pub fn print_fn(mut reg: Registers) -> Result { println!("{:?}", reg); - Ok(()) + + Ok(reg) } diff --git a/src/memory.rs b/src/memory.rs index 8e6fd433..05422e1e 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,18 +1,42 @@ +use hashbrown::HashMap; +use log::trace; + +use crate::{engine::Page, RuntimeErrors}; + pub struct Memory { //TODO: hashmap with the start bytes as key and end bytes as offset + inner: HashMap, } + impl Memory { - pub fn read_addr8(&mut self, address: u64) -> u8 { - 0 - } - pub fn read_addr64(&mut self, address: u64) -> u64 { - 0 + pub fn new() -> Self { + Self { + inner: HashMap::new(), + } } - pub fn set_addr8(&mut self, address: u64, value: u8) -> u8 { - 0 + pub fn map_vec(&mut self, address: u64, vec: Vec) {} +} + +impl Memory { + pub fn read_addr8(&mut self, address: u64) -> Result { + let (page, offset) = addr_to_page(address); + let val: u8 = self.inner.get(&page).unwrap().data[offset as usize]; + trace!("Value read {} from page {} offset {}", val, page, offset); + Ok(val) + } + pub fn read_addr64(&mut self, address: u64) -> u64 { + unimplemented!() + } + + pub fn set_addr8(&self, address: u64, value: u8) -> Result<(), RuntimeErrors> { + unimplemented!() } pub fn set_addr64(&mut self, address: u64, value: u64) -> u64 { - 0 + unimplemented!() } } + +fn addr_to_page(addr: u64) -> (u64, u64) { + (addr / 8192, addr % 8192) +}