Implement address decoding
This commit is contained in:
parent
35b2baf0a4
commit
7d8b0bae78
33
Cargo.lock
generated
33
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -7,3 +7,4 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
log = "*"
|
||||
hashbrown = "0.13.2"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
59
src/main.rs
59
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<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,
|
||||
#[rustfmt::skip]
|
||||
let prog: Vec<u8> = vec![
|
||||
// NOP as u8, NOP as u8,
|
||||
// 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();
|
||||
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.set_timer_callback(time);
|
||||
// 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)
|
||||
}
|
||||
|
|
|
@ -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 new() -> Self {
|
||||
Self {
|
||||
inner: HashMap::new(),
|
||||
}
|
||||
pub fn read_addr64(&mut self, address: u64) -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue