Implement address decoding

feature/trap-handlers
Able 2023-04-22 17:17:49 -05:00
parent 35b2baf0a4
commit 7d8b0bae78
6 changed files with 109 additions and 57 deletions

33
Cargo.lock generated
View File

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

View File

@ -7,3 +7,4 @@ edition = "2021"
[dependencies]
log = "*"
hashbrown = "0.13.2"

View File

@ -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<Registers, u64>;
pub fn empty_enviroment_call(reg: Registers) -> Result<(), ()> {
Err(())
pub fn empty_enviroment_call(reg: Registers) -> Result<Registers, u64> {
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<fn() -> u32>,
memory: Vec<Page>,
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;
}

View File

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

View File

@ -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<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];
#[rustfmt::skip]
let prog: Vec<u8> = 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<Registers, u64> {
println!("{:?}", reg);
Ok(())
Ok(reg)
}

View File

@ -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<u64, Page>,
}
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<u8>) {}
}
impl Memory {
pub fn read_addr8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
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)
}