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.
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",
]

View File

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

View File

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

View File

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

View File

@ -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<fn() -> u32>,
memory: Vec<Page>,
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!();

View File

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

View File

@ -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),

View File

@ -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<u8> = 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<Duration> = vec![];
let iters = 1;
for _ in 0..iters {
// #[rustfmt::skip]
// let prog: Vec<u8> = 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(())
}

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