forked from AbleOS/holey-bytes
beetp
This commit is contained in:
parent
46eb4c17a0
commit
5909b8e520
|
@ -5,17 +5,29 @@ pub enum Operations {
|
||||||
SUB = 2,
|
SUB = 2,
|
||||||
MUL = 3,
|
MUL = 3,
|
||||||
DIV = 4,
|
DIV = 4,
|
||||||
|
MOD = 5,
|
||||||
|
|
||||||
|
And = 6,
|
||||||
|
Or = 7,
|
||||||
|
Xor = 8,
|
||||||
|
Not = 9,
|
||||||
|
|
||||||
// LOADs a memory address/constant into a register
|
// LOADs a memory address/constant into a register
|
||||||
LOAD = 5,
|
LOAD = 15,
|
||||||
// STOREs a register/constant into a memory address
|
// STOREs a register/constant into a memory address
|
||||||
STORE = 6,
|
STORE = 16,
|
||||||
|
|
||||||
EnviromentCall = 10,
|
MapPage = 17,
|
||||||
|
UnmapPage = 18,
|
||||||
|
|
||||||
|
// SHIFT LEFT 16 A0
|
||||||
|
Shift = 20,
|
||||||
|
|
||||||
JUMP = 100,
|
JUMP = 100,
|
||||||
JumpCond = 101,
|
JumpCond = 101,
|
||||||
RET = 103,
|
RET = 103,
|
||||||
|
|
||||||
|
EnviromentCall = 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum SubTypes {
|
pub enum SubTypes {
|
||||||
|
@ -41,5 +53,7 @@ pub enum JumpConditionals {
|
||||||
Equal = 0,
|
Equal = 0,
|
||||||
NotEqual = 1,
|
NotEqual = 1,
|
||||||
LessThan = 2,
|
LessThan = 2,
|
||||||
GreaterThan = 3,
|
LessThanOrEqualTo = 3,
|
||||||
|
GreaterThan = 4,
|
||||||
|
GreaterThanOrEqualTo = 5,
|
||||||
}
|
}
|
||||||
|
|
3
src/engine/enviroment_calls.rs
Normal file
3
src/engine/enviroment_calls.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
use super::Engine;
|
||||||
|
|
||||||
|
pub type EnviromentCall = fn(&mut Engine) -> Result<&mut Engine, u64>;
|
|
@ -1,24 +1,27 @@
|
||||||
pub mod call_stack;
|
pub mod call_stack;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod enviroment_calls;
|
||||||
pub mod regs;
|
pub mod regs;
|
||||||
|
|
||||||
use crate::bytecode::ops::Operations::*;
|
use crate::bytecode::{
|
||||||
use crate::bytecode::ops::*;
|
ops::{Operations::*, *},
|
||||||
use crate::bytecode::types::*;
|
types::*,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::engine::call_stack::FnCall;
|
use {
|
||||||
use crate::memory;
|
crate::{engine::call_stack::FnCall, memory, HaltStatus, RuntimeErrors},
|
||||||
use crate::HaltStatus;
|
alloc::vec::Vec,
|
||||||
use crate::RuntimeErrors;
|
config::EngineConfig,
|
||||||
use alloc::vec::Vec;
|
log::trace,
|
||||||
use config::EngineConfig;
|
regs::Registers,
|
||||||
use log::trace;
|
};
|
||||||
use regs::Registers;
|
|
||||||
|
|
||||||
use self::call_stack::CallStack;
|
use self::call_stack::CallStack;
|
||||||
|
// pub const PAGE_SIZE: usize = 8192;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
pub data: [u8; 4096 * 2],
|
pub data: [u8; 8192],
|
||||||
}
|
}
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -27,10 +30,9 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub type EnviromentCall = fn(Registers) -> Result<Registers, u64>;
|
|
||||||
|
|
||||||
pub fn empty_enviroment_call(reg: Registers) -> Result<Registers, u64> {
|
pub fn empty_enviroment_call(engine: &mut Engine) -> Result<&mut Engine, u64> {
|
||||||
trace!("Registers {:?}", reg);
|
trace!("Registers {:?}", engine.registers);
|
||||||
Err(0)
|
Err(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@ pub struct Engine {
|
||||||
pub enviroment_call_table: [EnviromentCall; 256],
|
pub enviroment_call_table: [EnviromentCall; 256],
|
||||||
call_stack: CallStack,
|
call_stack: CallStack,
|
||||||
}
|
}
|
||||||
|
use crate::engine::enviroment_calls::EnviromentCall;
|
||||||
impl Engine {
|
impl Engine {
|
||||||
pub fn read_mem_addr_8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
pub fn read_mem_addr_8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
||||||
// println!("{}", address);
|
// println!("{}", address);
|
||||||
|
@ -62,10 +64,9 @@ impl Engine {
|
||||||
pub fn new(program: Vec<u8>) -> Self {
|
pub fn new(program: Vec<u8>) -> Self {
|
||||||
let mut mem = memory::Memory::new();
|
let mut mem = memory::Memory::new();
|
||||||
for (addr, byte) in program.clone().into_iter().enumerate() {
|
for (addr, byte) in program.clone().into_iter().enumerate() {
|
||||||
let ret = mem.set_addr8(addr as u64, byte);
|
let _ = mem.set_addr8(addr as u64, byte);
|
||||||
println!("{:?}", ret);
|
|
||||||
}
|
}
|
||||||
println!("{:?}", mem.read_addr8(0));
|
trace!("{:?}", mem.read_addr8(0));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
index: 0,
|
index: 0,
|
||||||
|
@ -75,7 +76,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: memory::Memory::new(),
|
memory: mem,
|
||||||
call_stack: Vec::new(),
|
call_stack: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,8 +166,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> {
|
pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> {
|
||||||
use HaltStatus::*;
|
use {HaltStatus::*, RuntimeErrors::*};
|
||||||
use RuntimeErrors::*;
|
|
||||||
loop {
|
loop {
|
||||||
// Break out of the loop
|
// Break out of the loop
|
||||||
if self.index + 1 == self.program.len() {
|
if self.index + 1 == self.program.len() {
|
||||||
|
@ -245,7 +245,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.index += 19;
|
self.index += 18;
|
||||||
}
|
}
|
||||||
(2, 1) => {
|
(2, 1) => {
|
||||||
let lhs = self.program[self.index + 2];
|
let lhs = self.program[self.index + 2];
|
||||||
|
@ -335,18 +335,25 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
||||||
|
|
||||||
trace!("addr {}", addr);
|
trace!("addr {}", addr);
|
||||||
|
|
||||||
let ret = self.read_mem_addr_8(addr)?;
|
let ret = self.read_mem_addr_8(addr);
|
||||||
|
match ret {
|
||||||
|
Ok(ret) => {
|
||||||
let reg = self.program[self.index + 10];
|
let reg = self.program[self.index + 10];
|
||||||
trace!("reg {}", reg);
|
trace!("reg {}", reg);
|
||||||
self.set_register_8(reg, ret);
|
self.set_register_8(reg, ret);
|
||||||
self.index += 9;
|
self.index += 10;
|
||||||
|
}
|
||||||
|
Err(err) => trace!("{:?}", err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(10, int) => {
|
(10, int) => {
|
||||||
println!("Enviroment Call {}", int);
|
trace!("Enviroment Call {}", int);
|
||||||
let ret = self.enviroment_call_table[int as usize](self.registers);
|
let ret = self.enviroment_call_table[int as usize](self);
|
||||||
match ret {
|
match ret {
|
||||||
Ok(_) => {}
|
Ok(eng) => {
|
||||||
|
trace!("Resuming execution at {}", eng.index);
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(HostError(err));
|
return Err(HostError(err));
|
||||||
}
|
}
|
||||||
|
@ -366,9 +373,9 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
trace!("byte {}", byte);
|
|
||||||
addr_array[index] = *byte;
|
addr_array[index] = *byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
let addr = usize::from_be_bytes(addr_array);
|
let addr = usize::from_be_bytes(addr_array);
|
||||||
if addr > self.program.len() {
|
if addr > self.program.len() {
|
||||||
panic!("Invalid jump address {}", addr)
|
panic!("Invalid jump address {}", addr)
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub enum RuntimeErrors {
|
||||||
InvalidOpcode(u8),
|
InvalidOpcode(u8),
|
||||||
RegisterTooSmall,
|
RegisterTooSmall,
|
||||||
HostError(u64),
|
HostError(u64),
|
||||||
PageUnmapped(u64),
|
PageNotMapped(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you solve the halting problem feel free to remove this
|
// If you solve the halting problem feel free to remove this
|
||||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,6 +1,6 @@
|
||||||
use holey_bytes::{
|
use holey_bytes::{
|
||||||
bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
|
bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
|
||||||
engine::{regs::Registers, Engine},
|
engine::Engine,
|
||||||
RuntimeErrors,
|
RuntimeErrors,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,8 +8,7 @@ fn main() -> Result<(), RuntimeErrors> {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let prog: Vec<u8> = vec![
|
let prog: Vec<u8> = vec![
|
||||||
NOP as u8, NOP as u8,
|
NOP as u8, NOP as u8,
|
||||||
// 10, 10,
|
10, 10,
|
||||||
|
|
||||||
ADD as u8, EightBit as u8, 100, 20, 0xA7,
|
ADD as u8, EightBit as u8, 100, 20, 0xA7,
|
||||||
ADD as u8,
|
ADD as u8,
|
||||||
EightBit as u8, 1, 0, 0xB0,
|
EightBit as u8, 1, 0, 0xB0,
|
||||||
|
@ -22,15 +21,16 @@ fn main() -> Result<(), RuntimeErrors> {
|
||||||
LOAD as u8, AddrToReg as u8,
|
LOAD as u8, AddrToReg as u8,
|
||||||
0, 0, 0, 0, 0, 0, 0, 2,
|
0, 0, 0, 0, 0, 0, 0, 2,
|
||||||
0xA0,
|
0xA0,
|
||||||
JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 5,
|
// JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut eng = Engine::new(prog);
|
let mut eng = Engine::new(prog);
|
||||||
println!("{:?}", eng.read_mem_addr_8(4));
|
|
||||||
// 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();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,7 @@ fn main() -> Result<(), RuntimeErrors> {
|
||||||
pub fn time() -> u32 {
|
pub fn time() -> u32 {
|
||||||
9
|
9
|
||||||
}
|
}
|
||||||
pub fn print_fn(mut reg: Registers) -> Result<Registers, u64> {
|
pub fn print_fn(engine: &mut Engine) -> Result<&mut Engine, u64> {
|
||||||
println!("{:?}", reg);
|
println!("hello");
|
||||||
|
Ok(engine)
|
||||||
Ok(reg)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,18 @@ impl Memory {
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn read_addr8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
pub fn read_addr8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
||||||
let (page, offset) = addr_to_page(address);
|
let (page, offset) = addr_to_page(address);
|
||||||
println!("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);
|
||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
None => Err(RuntimeErrors::PageUnmapped(page)),
|
None => {
|
||||||
|
trace!("page not mapped");
|
||||||
|
Err(RuntimeErrors::PageNotMapped(page))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// trace!("Value read {} from page {} offset {}", val, page, offset);
|
|
||||||
}
|
}
|
||||||
pub fn read_addr64(&mut self, address: u64) -> u64 {
|
pub fn read_addr64(&mut self, address: u64) -> u64 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
|
Loading…
Reference in a new issue