rework architecture and add a "compiler"
This commit is contained in:
parent
b2870bf2b0
commit
15c3ce1f69
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -19,6 +19,10 @@ 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 = "compiler"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.13.2"
|
version = "0.13.2"
|
||||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -1,10 +1,2 @@
|
||||||
[package]
|
[workspace]
|
||||||
name = "holey_bytes"
|
members = ["hbvm", "compiler"]
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
log = "*"
|
|
||||||
hashbrown = "0.13.2"
|
|
||||||
|
|
8
compiler/Cargo.toml
Normal file
8
compiler/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "compiler"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
5
compiler/src/main.rs
Normal file
5
compiler/src/main.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fn main() {
|
||||||
|
let prog = "load 1, A0
|
||||||
|
jump 0";
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
10
hbvm/Cargo.toml
Normal file
10
hbvm/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "holey_bytes"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "*"
|
||||||
|
hashbrown = "0.13.2"
|
|
@ -30,6 +30,13 @@ pub enum Operations {
|
||||||
EnviromentCall = 255,
|
EnviromentCall = 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum PageMapTypes {
|
||||||
|
// Have the host make a new VMPage
|
||||||
|
VMPage = 0,
|
||||||
|
// Ask the host to map a RealPage into memory
|
||||||
|
RealPage = 1,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum SubTypes {
|
pub enum SubTypes {
|
||||||
EightBit = 1,
|
EightBit = 1,
|
||||||
SixtyFourBit = 2,
|
SixtyFourBit = 2,
|
|
@ -3,27 +3,32 @@ pub mod config;
|
||||||
pub mod enviroment_calls;
|
pub mod enviroment_calls;
|
||||||
pub mod regs;
|
pub mod regs;
|
||||||
|
|
||||||
use crate::bytecode::{
|
|
||||||
ops::{Operations::*, *},
|
|
||||||
types::*,
|
|
||||||
};
|
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{engine::call_stack::FnCall, memory, HaltStatus, RuntimeErrors},
|
self::call_stack::CallStack,
|
||||||
|
crate::{
|
||||||
|
bytecode::{
|
||||||
|
ops::{Operations::*, *},
|
||||||
|
types::*,
|
||||||
|
},
|
||||||
|
engine::call_stack::FnCall,
|
||||||
|
memory, HaltStatus, RuntimeErrors,
|
||||||
|
},
|
||||||
alloc::vec::Vec,
|
alloc::vec::Vec,
|
||||||
config::EngineConfig,
|
config::EngineConfig,
|
||||||
log::trace,
|
log::trace,
|
||||||
regs::Registers,
|
regs::Registers,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::call_stack::CallStack;
|
|
||||||
// pub const PAGE_SIZE: usize = 8192;
|
// pub const PAGE_SIZE: usize = 8192;
|
||||||
|
|
||||||
|
pub struct RealPage {
|
||||||
|
pub ptr: *mut u8,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Page {
|
pub struct VMPage {
|
||||||
pub data: [u8; 8192],
|
pub data: [u8; 8192],
|
||||||
}
|
}
|
||||||
impl Page {
|
impl VMPage {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
data: [0; 4096 * 2],
|
data: [0; 4096 * 2],
|
||||||
|
@ -31,23 +36,38 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Page {
|
||||||
|
VMPage(VMPage),
|
||||||
|
RealPage(RealPage),
|
||||||
|
}
|
||||||
|
impl Page {
|
||||||
|
pub fn data(&self) -> [u8; 4096 * 2] {
|
||||||
|
match self {
|
||||||
|
Page::VMPage(vmpage) => vmpage.data,
|
||||||
|
Page::RealPage(_) => {
|
||||||
|
unimplemented!("Memmapped hw page not yet supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn empty_enviroment_call(engine: &mut Engine) -> Result<&mut Engine, u64> {
|
pub fn empty_enviroment_call(engine: &mut Engine) -> Result<&mut Engine, u64> {
|
||||||
trace!("Registers {:?}", engine.registers);
|
trace!("Registers {:?}", engine.registers);
|
||||||
Err(0)
|
Err(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Engine {
|
pub struct Engine {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
program: Vec<u8>,
|
pub program: Vec<u8>,
|
||||||
registers: Registers,
|
pub registers: Registers,
|
||||||
config: EngineConfig,
|
pub config: EngineConfig,
|
||||||
|
|
||||||
/// BUG: This DOES NOT account for overflowing
|
/// BUG: This DOES NOT account for overflowing
|
||||||
last_timer_count: u32,
|
pub last_timer_count: u32,
|
||||||
timer_callback: Option<fn() -> u32>,
|
pub timer_callback: Option<fn() -> u32>,
|
||||||
memory: memory::Memory,
|
pub memory: memory::Memory,
|
||||||
pub enviroment_call_table: [EnviromentCall; 256],
|
pub enviroment_call_table: [EnviromentCall; 256],
|
||||||
call_stack: CallStack,
|
pub call_stack: CallStack,
|
||||||
}
|
}
|
||||||
use crate::engine::enviroment_calls::EnviromentCall;
|
use crate::engine::enviroment_calls::EnviromentCall;
|
||||||
impl Engine {
|
impl Engine {
|
||||||
|
@ -319,8 +339,49 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
||||||
// TODO: Implement 64 bit register to register subtraction
|
// TODO: Implement 64 bit register to register subtraction
|
||||||
(2, 4) => {
|
(2, 4) => {
|
||||||
// 64 bit
|
// 64 bit
|
||||||
self.index += 19;
|
|
||||||
|
let mut lhs_array = [0; 8];
|
||||||
|
let mut rhs_array = [0; 8];
|
||||||
|
|
||||||
|
for (index, byte) in self.program[self.index + 2..self.index + 10]
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
lhs_array[index] = *byte;
|
||||||
|
}
|
||||||
|
let lhs = u64::from_be_bytes(lhs_array);
|
||||||
|
|
||||||
|
for (index, byte) in self.program[self.index + 10..self.index + 18]
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
rhs_array[index] = *byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
let rhs = u64::from_be_bytes(rhs_array);
|
||||||
|
|
||||||
|
// println!("RHS 64BIT {}", rhs);
|
||||||
|
|
||||||
|
let ret = lhs - rhs;
|
||||||
|
|
||||||
|
let reg = self.program[self.index + 18];
|
||||||
|
// println!("Store {} in {:02X}", ret, reg);
|
||||||
|
|
||||||
|
match reg {
|
||||||
|
0xA0..=0xC9 => {
|
||||||
|
panic!("Register undersized")
|
||||||
|
}
|
||||||
|
0xD0..=0xF9 => {
|
||||||
|
self.set_register_64(reg, ret);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Not a register.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.index += 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from address to register
|
// Read from address to register
|
||||||
(5, 0) => {
|
(5, 0) => {
|
||||||
let mut addr_array = [0; 8];
|
let mut addr_array = [0; 8];
|
|
@ -1,14 +1,10 @@
|
||||||
// #![no_std]
|
#![no_std]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
pub mod bytecode;
|
pub mod bytecode;
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
|
||||||
use bytecode::ops::*;
|
|
||||||
use bytecode::types::{CONST_F64, CONST_U8};
|
|
||||||
use engine::Engine;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RuntimeErrors {
|
pub enum RuntimeErrors {
|
||||||
InvalidOpcode(u8),
|
InvalidOpcode(u8),
|
||||||
|
@ -22,10 +18,3 @@ pub enum HaltStatus {
|
||||||
Halted,
|
Halted,
|
||||||
Running,
|
Running,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HandSide {
|
|
||||||
signed: bool,
|
|
||||||
float: bool,
|
|
||||||
num8: Option<u8>,
|
|
||||||
num64: Option<u64>,
|
|
||||||
}
|
|
|
@ -31,6 +31,7 @@ fn main() -> Result<(), RuntimeErrors> {
|
||||||
eng.enviroment_call_table[10] = print_fn;
|
eng.enviroment_call_table[10] = print_fn;
|
||||||
eng.run()?;
|
eng.run()?;
|
||||||
eng.dump();
|
eng.dump();
|
||||||
|
println!("{:#?}", eng.registers);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
|
@ -1,10 +1,13 @@
|
||||||
use hashbrown::HashMap;
|
use crate::engine::VMPage;
|
||||||
use log::trace;
|
|
||||||
|
|
||||||
use crate::{engine::Page, RuntimeErrors};
|
use {
|
||||||
|
crate::{engine::Page, RuntimeErrors},
|
||||||
|
alloc::vec::Vec,
|
||||||
|
hashbrown::HashMap,
|
||||||
|
log::trace,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Memory {
|
pub struct Memory {
|
||||||
//TODO: hashmap with the start bytes as key and end bytes as offset
|
|
||||||
inner: HashMap<u64, Page>,
|
inner: HashMap<u64, Page>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +16,12 @@ impl Memory {
|
||||||
Self {
|
Self {
|
||||||
inner: HashMap::new(),
|
inner: HashMap::new(),
|
||||||
}
|
}
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_vec(&mut self, address: u64, vec: Vec<u8>) {}
|
pub fn map_vec(&mut self, address: u64, vec: Vec<u8>) {
|
||||||
|
panic!("Mapping vectors into pages is not supported yet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
|
@ -24,7 +30,7 @@ impl Memory {
|
||||||
trace!("page {} offset {}", page, offset);
|
trace!("page {} offset {}", page, offset);
|
||||||
match self.inner.get(&page) {
|
match self.inner.get(&page) {
|
||||||
Some(page) => {
|
Some(page) => {
|
||||||
let val = page.data[offset as usize];
|
let val = page.data()[offset as usize];
|
||||||
trace!("Value {}", val);
|
trace!("Value {}", val);
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
|
@ -43,13 +49,13 @@ impl Memory {
|
||||||
let ret: Option<(&u64, &mut Page)> = self.inner.get_key_value_mut(&page);
|
let ret: Option<(&u64, &mut Page)> = self.inner.get_key_value_mut(&page);
|
||||||
match ret {
|
match ret {
|
||||||
Some((_, page)) => {
|
Some((_, page)) => {
|
||||||
page.data[offset as usize] = value;
|
page.data()[offset as usize] = value;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut pg = Page::new();
|
let mut pg = VMPage::new();
|
||||||
pg.data[offset as usize] = value;
|
pg.data[offset as usize] = value;
|
||||||
self.inner.insert(page, pg);
|
self.inner.insert(page, Page::VMPage(pg));
|
||||||
println!("Mapped page {}", page);
|
trace!("Mapped page {}", page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
Loading…
Reference in a new issue