adding in environ calls

feature/trap-handlers
Able 2023-04-22 16:06:33 -05:00
parent 685ddbbe74
commit 35b2baf0a4
9 changed files with 134 additions and 45 deletions

18
Cargo.lock generated
View File

@ -2,6 +2,24 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "holey_bytes" name = "holey_bytes"
version = "0.1.0" 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",
]

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "*"

View File

@ -11,6 +11,8 @@ pub enum Operations {
// STOREs a register/constant into a memory address // STOREs a register/constant into a memory address
STORE = 6, STORE = 6,
EnviromentCall = 10,
JUMP = 100, JUMP = 100,
JumpCond = 101, JumpCond = 101,
RET = 103, RET = 103,

View File

@ -1,3 +1,5 @@
use alloc::vec::Vec;
pub type CallStack = Vec<FnCall>; pub type CallStack = Vec<FnCall>;
pub struct FnCall { pub struct FnCall {
pub ret: usize, pub ret: usize,

View File

@ -9,7 +9,9 @@ use crate::bytecode::types::*;
use crate::engine::call_stack::FnCall; use crate::engine::call_stack::FnCall;
use crate::HaltStatus; use crate::HaltStatus;
use crate::RuntimeErrors; use crate::RuntimeErrors;
use alloc::vec::Vec;
use config::EngineConfig; use config::EngineConfig;
use log::trace;
use regs::Registers; use regs::Registers;
use self::call_stack::CallStack; use self::call_stack::CallStack;
@ -17,6 +19,11 @@ use self::call_stack::CallStack;
pub struct Page { pub struct Page {
pub data: [u8; 4096 * 2], pub data: [u8; 4096 * 2],
} }
pub type EnviromentCall = fn(Registers) -> Result<(), ()>;
pub fn empty_enviroment_call(reg: Registers) -> Result<(), ()> {
Err(())
}
pub struct Engine { pub struct Engine {
pub index: usize, pub index: usize,
@ -28,6 +35,7 @@ pub struct Engine {
last_timer_count: u32, last_timer_count: u32,
timer_callback: Option<fn() -> u32>, timer_callback: Option<fn() -> u32>,
memory: Vec<Page>, memory: Vec<Page>,
pub enviroment_call_table: [EnviromentCall; 256],
call_stack: CallStack, call_stack: CallStack,
} }
@ -36,6 +44,9 @@ impl Engine {
// println!("{}", address); // println!("{}", address);
255 255
} }
pub fn set_timer_callback(&mut self, func: fn() -> u32) {
self.timer_callback = Some(func);
}
} }
impl Engine { impl Engine {
@ -47,13 +58,15 @@ impl Engine {
config: EngineConfig::default(), config: EngineConfig::default(),
last_timer_count: 0, last_timer_count: 0,
timer_callback: None, timer_callback: None,
memory: vec![], enviroment_call_table: [empty_enviroment_call; 256],
call_stack: vec![], memory: Vec::new(),
call_stack: Vec::new(),
} }
} }
pub fn dump(&self) { pub fn dump(&self) {
println!("Registers"); trace!("Registers");
println!( trace!(
"A {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", "A {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}",
self.registers.a0, self.registers.a0,
self.registers.a1, self.registers.a1,
@ -66,7 +79,7 @@ impl Engine {
self.registers.a8, self.registers.a8,
self.registers.a9, self.registers.a9,
); );
println!( trace!(
"B {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", "B {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}",
self.registers.b0, self.registers.b0,
self.registers.b1, self.registers.b1,
@ -79,7 +92,7 @@ impl Engine {
self.registers.b8, self.registers.b8,
self.registers.b9, self.registers.b9,
); );
println!( trace!(
"C {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", "C {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}",
self.registers.c0, self.registers.c0,
self.registers.c1, self.registers.c1,
@ -92,8 +105,7 @@ impl Engine {
self.registers.c8, self.registers.c8,
self.registers.c9, self.registers.c9,
); );
trace!(
println!(
"D0-D4 {:016X} {:016X} {:016X} {:016X} {:016X} "D0-D4 {:016X} {:016X} {:016X} {:016X} {:016X}
D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}", D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}",
self.registers.d0, self.registers.d0,
@ -107,7 +119,7 @@ D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}",
self.registers.d8, self.registers.d8,
self.registers.d9, self.registers.d9,
); );
println!( trace!(
"E0-E4 {:016X} {:016X} {:016X} {:016X} {:016X} "E0-E4 {:016X} {:016X} {:016X} {:016X} {:016X}
E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}", E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}",
self.registers.e0, self.registers.e0,
@ -121,7 +133,7 @@ E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}",
self.registers.e8, self.registers.e8,
self.registers.e9, self.registers.e9,
); );
println!( trace!(
"F0-F4 {:016X} {:016X} {:016X} {:016X} {:016X} "F0-F4 {:016X} {:016X} {:016X} {:016X} {:016X}
F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
self.registers.f0, self.registers.f0,
@ -148,7 +160,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
// println!("OP {} INDEX {}", op.0, self.index); // println!("OP {} INDEX {}", op.0, self.index);
match op { match op {
(0, _) => { (0, _) => {
println!("NO OP"); trace!("NO OP");
self.index += 1; self.index += 1;
} }
// Add a 8 bit num // Add a 8 bit num
@ -305,18 +317,25 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
} }
let addr = u64::from_be_bytes(addr_array); let addr = u64::from_be_bytes(addr_array);
println!("addr {}", addr); trace!("addr {}", addr);
let ret = self.read_mem_addr(addr); let ret = self.read_mem_addr(addr);
let reg = self.program[self.index + 10]; let reg = self.program[self.index + 10];
println!("reg {}", reg); trace!("reg {}", reg);
self.set_register_8(reg, ret); self.set_register_8(reg, ret);
self.index += 9; self.index += 9;
} }
(10, int) => {
println!("Enviroment Call {}", int);
self.enviroment_call_table[int as usize](self.registers);
self.index += 2;
}
(100, _) => { (100, _) => {
if self.call_stack.len() > self.config.call_stack_depth { 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]; let mut addr_array = [0; 8];
@ -325,7 +344,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
.into_iter() .into_iter()
.enumerate() .enumerate()
{ {
println!("byte {}", byte); trace!("byte {}", byte);
addr_array[index] = *byte; addr_array[index] = *byte;
} }
let addr = usize::from_be_bytes(addr_array); 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.call_stack.push(call);
self.index = addr; self.index = addr;
println!("Jumping to {}", addr); trace!("Jumping to {}", addr);
self.dump(); self.dump();
// panic!(); // panic!();

View File

@ -1,4 +1,5 @@
#[rustfmt::skip] #[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 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 a1: u8, pub b1: u8, pub c1: u8, pub d1: u64, pub e1: u64, pub f1: u64,

View File

@ -1,13 +1,14 @@
// #![no_std]
extern crate alloc;
pub mod bytecode; pub mod bytecode;
pub mod engine; pub mod engine;
pub mod memory;
use bytecode::ops::*; use bytecode::ops::*;
use bytecode::types::{CONST_F64, CONST_U8}; use bytecode::types::{CONST_F64, CONST_U8};
use engine::Engine; use engine::Engine;
pub fn time() -> u32 {
9
}
#[derive(Debug)] #[derive(Debug)]
pub enum RuntimeErrors { pub enum RuntimeErrors {
InvalidOpcode(u8), InvalidOpcode(u8),

View File

@ -1,33 +1,60 @@
use std::{result, time::Duration};
use holey_bytes::{ use holey_bytes::{
bytecode::{ bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
ops::{Operations::*, RWSubTypes, RWSubTypes::*, SubTypes::*}, engine::{regs::Registers, Engine},
types::*,
},
engine::Engine,
RuntimeErrors, RuntimeErrors,
}; };
fn main() -> Result<(), RuntimeErrors> { fn main() -> Result<(), RuntimeErrors> {
#[rustfmt::skip] let mut results: Vec<Duration> = vec![];
let prog: Vec<u8> = vec![ let iters = 1;
// NOP as u8, NOP as u8, for _ in 0..iters {
ADD as u8, EightBit as u8, 100, 20, 0xA7, // #[rustfmt::skip]
ADD as u8, // let prog: Vec<u8> = vec![
EightBit as u8, 1, 0, 0xB0, // // NOP as u8, NOP as u8,
ADD as u8, // ADD as u8, EightBit as u8, 100, 20, 0xA7,
SixtyFourBit as u8, // ADD as u8,
0, 0, 0, 0, 0, 0, 0, 0, // EightBit as u8, 1, 0, 0xB0,
0, 0, 0, 0, 0, 0, 0, 2, 0xD0, // ADD as u8,
SUB as u8, EightBit as u8, 255, 0, 0xA7, // SixtyFourBit as u8,
ADD as u8, Register8 as u8, 0xA7, 0xB0, 0xA7, // 0, 0, 0, 0, 0, 0, 0, 0,
LOAD as u8, AddrToReg as u8, // 0, 0, 0, 0, 0, 0, 0, 2, 0xD0,
0, 0, 0, 0, 0, 0, 0, 2, // SUB as u8, EightBit as u8, 255, 0, 0xA7,
0xA0, // ADD as u8, Register8 as u8, 0xA7, 0xB0, 0xA7,
JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 5, // LOAD as u8, AddrToReg as u8,
]; // 0, 0, 0, 0, 0, 0, 0, 2,
let mut eng = Engine::new(prog); // 0xA0,
// eng.timer_callback = Some(time); // 10, 10,
eng.run()?; // JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 5,
eng.dump(); // ];
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(()) Ok(())
} }

18
src/memory.rs Normal file
View File

@ -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
}
}