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.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
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]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "holey_bytes"
|
name = "holey_bytes"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -23,3 +44,15 @@ checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"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]
|
[dependencies]
|
||||||
log = "*"
|
log = "*"
|
||||||
|
hashbrown = "0.13.2"
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::bytecode::ops::*;
|
||||||
use crate::bytecode::types::*;
|
use crate::bytecode::types::*;
|
||||||
|
|
||||||
use crate::engine::call_stack::FnCall;
|
use crate::engine::call_stack::FnCall;
|
||||||
|
use crate::memory;
|
||||||
use crate::HaltStatus;
|
use crate::HaltStatus;
|
||||||
use crate::RuntimeErrors;
|
use crate::RuntimeErrors;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
@ -15,14 +16,15 @@ use log::trace;
|
||||||
use regs::Registers;
|
use regs::Registers;
|
||||||
|
|
||||||
use self::call_stack::CallStack;
|
use self::call_stack::CallStack;
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
pub data: [u8; 4096 * 2],
|
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<(), ()> {
|
pub fn empty_enviroment_call(reg: Registers) -> Result<Registers, u64> {
|
||||||
Err(())
|
trace!("Registers {:?}", reg);
|
||||||
|
Err(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
|
@ -34,7 +36,7 @@ pub struct Engine {
|
||||||
/// BUG: This DOES NOT account for overflowing
|
/// BUG: This DOES NOT account for overflowing
|
||||||
last_timer_count: u32,
|
last_timer_count: u32,
|
||||||
timer_callback: Option<fn() -> u32>,
|
timer_callback: Option<fn() -> u32>,
|
||||||
memory: Vec<Page>,
|
memory: memory::Memory,
|
||||||
pub enviroment_call_table: [EnviromentCall; 256],
|
pub enviroment_call_table: [EnviromentCall; 256],
|
||||||
call_stack: CallStack,
|
call_stack: CallStack,
|
||||||
}
|
}
|
||||||
|
@ -59,7 +61,7 @@ impl Engine {
|
||||||
last_timer_count: 0,
|
last_timer_count: 0,
|
||||||
timer_callback: None,
|
timer_callback: None,
|
||||||
enviroment_call_table: [empty_enviroment_call; 256],
|
enviroment_call_table: [empty_enviroment_call; 256],
|
||||||
memory: Vec::new(),
|
memory: memory::Memory::new(),
|
||||||
call_stack: Vec::new(),
|
call_stack: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +330,13 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
||||||
|
|
||||||
(10, int) => {
|
(10, int) => {
|
||||||
println!("Enviroment Call {}", 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;
|
self.index += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ use engine::Engine;
|
||||||
pub enum RuntimeErrors {
|
pub enum RuntimeErrors {
|
||||||
InvalidOpcode(u8),
|
InvalidOpcode(u8),
|
||||||
RegisterTooSmall,
|
RegisterTooSmall,
|
||||||
|
HostError(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you solve the halting problem feel free to remove this
|
// 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::{
|
use holey_bytes::{
|
||||||
bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
|
bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
|
||||||
engine::{regs::Registers, Engine},
|
engine::{regs::Registers, Engine},
|
||||||
|
@ -7,54 +5,41 @@ use holey_bytes::{
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() -> Result<(), RuntimeErrors> {
|
fn main() -> Result<(), RuntimeErrors> {
|
||||||
let mut results: Vec<Duration> = vec![];
|
#[rustfmt::skip]
|
||||||
let iters = 1;
|
let prog: Vec<u8> = vec![
|
||||||
for _ in 0..iters {
|
// NOP as u8, NOP as u8,
|
||||||
// #[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,
|
// 10, 10,
|
||||||
// JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 5,
|
|
||||||
// ];
|
|
||||||
let prog = vec![10, 10];
|
|
||||||
|
|
||||||
use std::time::Instant;
|
ADD as u8, EightBit as u8, 100, 20, 0xA7,
|
||||||
let now = Instant::now();
|
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.set_timer_callback(time);
|
||||||
eng.enviroment_call_table[10] = print_fn;
|
eng.enviroment_call_table[10] = print_fn;
|
||||||
eng.run()?;
|
eng.run()?;
|
||||||
eng.dump();
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn time() -> u32 {
|
pub fn time() -> u32 {
|
||||||
9
|
9
|
||||||
}
|
}
|
||||||
pub fn print_fn(reg: Registers) -> Result<(), ()> {
|
pub fn print_fn(mut reg: Registers) -> Result<Registers, u64> {
|
||||||
println!("{:?}", reg);
|
println!("{:?}", reg);
|
||||||
Ok(())
|
|
||||||
|
Ok(reg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,42 @@
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use log::trace;
|
||||||
|
|
||||||
|
use crate::{engine::Page, RuntimeErrors};
|
||||||
|
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
//TODO: hashmap with the start bytes as key and end bytes as offset
|
//TODO: hashmap with the start bytes as key and end bytes as offset
|
||||||
|
inner: HashMap<u64, Page>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn read_addr8(&mut self, address: u64) -> u8 {
|
pub fn new() -> Self {
|
||||||
0
|
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 {
|
pub fn map_vec(&mut self, address: u64, vec: Vec<u8>) {}
|
||||||
0
|
}
|
||||||
|
|
||||||
|
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 {
|
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