forked from koniifer/ableos
beetp
This commit is contained in:
parent
46eb4c17a0
commit
5909b8e520
|
@ -5,17 +5,29 @@ pub enum Operations {
|
|||
SUB = 2,
|
||||
MUL = 3,
|
||||
DIV = 4,
|
||||
MOD = 5,
|
||||
|
||||
And = 6,
|
||||
Or = 7,
|
||||
Xor = 8,
|
||||
Not = 9,
|
||||
|
||||
// LOADs a memory address/constant into a register
|
||||
LOAD = 5,
|
||||
LOAD = 15,
|
||||
// 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,
|
||||
JumpCond = 101,
|
||||
RET = 103,
|
||||
|
||||
EnviromentCall = 255,
|
||||
}
|
||||
|
||||
pub enum SubTypes {
|
||||
|
@ -41,5 +53,7 @@ pub enum JumpConditionals {
|
|||
Equal = 0,
|
||||
NotEqual = 1,
|
||||
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 config;
|
||||
pub mod enviroment_calls;
|
||||
pub mod regs;
|
||||
|
||||
use crate::bytecode::ops::Operations::*;
|
||||
use crate::bytecode::ops::*;
|
||||
use crate::bytecode::types::*;
|
||||
use crate::bytecode::{
|
||||
ops::{Operations::*, *},
|
||||
types::*,
|
||||
};
|
||||
|
||||
use crate::engine::call_stack::FnCall;
|
||||
use crate::memory;
|
||||
use crate::HaltStatus;
|
||||
use crate::RuntimeErrors;
|
||||
use alloc::vec::Vec;
|
||||
use config::EngineConfig;
|
||||
use log::trace;
|
||||
use regs::Registers;
|
||||
use {
|
||||
crate::{engine::call_stack::FnCall, memory, HaltStatus, RuntimeErrors},
|
||||
alloc::vec::Vec,
|
||||
config::EngineConfig,
|
||||
log::trace,
|
||||
regs::Registers,
|
||||
};
|
||||
|
||||
use self::call_stack::CallStack;
|
||||
// pub const PAGE_SIZE: usize = 8192;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Page {
|
||||
pub data: [u8; 4096 * 2],
|
||||
pub data: [u8; 8192],
|
||||
}
|
||||
impl Page {
|
||||
pub fn new() -> Self {
|
||||
|
@ -27,18 +30,17 @@ impl Page {
|
|||
}
|
||||
}
|
||||
}
|
||||
pub type EnviromentCall = fn(Registers) -> Result<Registers, u64>;
|
||||
|
||||
pub fn empty_enviroment_call(reg: Registers) -> Result<Registers, u64> {
|
||||
trace!("Registers {:?}", reg);
|
||||
pub fn empty_enviroment_call(engine: &mut Engine) -> Result<&mut Engine, u64> {
|
||||
trace!("Registers {:?}", engine.registers);
|
||||
Err(0)
|
||||
}
|
||||
|
||||
pub struct Engine {
|
||||
pub index: usize,
|
||||
program: Vec<u8>,
|
||||
program: Vec<u8>,
|
||||
registers: Registers,
|
||||
config: EngineConfig,
|
||||
config: EngineConfig,
|
||||
|
||||
/// BUG: This DOES NOT account for overflowing
|
||||
last_timer_count: u32,
|
||||
|
@ -47,7 +49,7 @@ pub struct Engine {
|
|||
pub enviroment_call_table: [EnviromentCall; 256],
|
||||
call_stack: CallStack,
|
||||
}
|
||||
|
||||
use crate::engine::enviroment_calls::EnviromentCall;
|
||||
impl Engine {
|
||||
pub fn read_mem_addr_8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
||||
// println!("{}", address);
|
||||
|
@ -62,10 +64,9 @@ impl Engine {
|
|||
pub fn new(program: Vec<u8>) -> Self {
|
||||
let mut mem = memory::Memory::new();
|
||||
for (addr, byte) in program.clone().into_iter().enumerate() {
|
||||
let ret = mem.set_addr8(addr as u64, byte);
|
||||
println!("{:?}", ret);
|
||||
let _ = mem.set_addr8(addr as u64, byte);
|
||||
}
|
||||
println!("{:?}", mem.read_addr8(0));
|
||||
trace!("{:?}", mem.read_addr8(0));
|
||||
|
||||
Self {
|
||||
index: 0,
|
||||
|
@ -75,7 +76,7 @@ impl Engine {
|
|||
last_timer_count: 0,
|
||||
timer_callback: None,
|
||||
enviroment_call_table: [empty_enviroment_call; 256],
|
||||
memory: memory::Memory::new(),
|
||||
memory: mem,
|
||||
call_stack: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -165,8 +166,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
|||
);
|
||||
}
|
||||
pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> {
|
||||
use HaltStatus::*;
|
||||
use RuntimeErrors::*;
|
||||
use {HaltStatus::*, RuntimeErrors::*};
|
||||
loop {
|
||||
// Break out of the loop
|
||||
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) => {
|
||||
let lhs = self.program[self.index + 2];
|
||||
|
@ -335,18 +335,25 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
|||
|
||||
trace!("addr {}", addr);
|
||||
|
||||
let ret = self.read_mem_addr_8(addr)?;
|
||||
let reg = self.program[self.index + 10];
|
||||
trace!("reg {}", reg);
|
||||
self.set_register_8(reg, ret);
|
||||
self.index += 9;
|
||||
let ret = self.read_mem_addr_8(addr);
|
||||
match ret {
|
||||
Ok(ret) => {
|
||||
let reg = self.program[self.index + 10];
|
||||
trace!("reg {}", reg);
|
||||
self.set_register_8(reg, ret);
|
||||
self.index += 10;
|
||||
}
|
||||
Err(err) => trace!("{:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
(10, int) => {
|
||||
println!("Enviroment Call {}", int);
|
||||
let ret = self.enviroment_call_table[int as usize](self.registers);
|
||||
trace!("Enviroment Call {}", int);
|
||||
let ret = self.enviroment_call_table[int as usize](self);
|
||||
match ret {
|
||||
Ok(_) => {}
|
||||
Ok(eng) => {
|
||||
trace!("Resuming execution at {}", eng.index);
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(HostError(err));
|
||||
}
|
||||
|
@ -366,9 +373,9 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
|
|||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
trace!("byte {}", byte);
|
||||
addr_array[index] = *byte;
|
||||
}
|
||||
|
||||
let addr = usize::from_be_bytes(addr_array);
|
||||
if addr > self.program.len() {
|
||||
panic!("Invalid jump address {}", addr)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#[rustfmt::skip]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Registers{
|
||||
pub struct Registers {
|
||||
pub a0: u8, pub b0: u8, pub c0: u8, pub d0: u64, pub e0: u64, pub f0: u64,
|
||||
pub a1: u8, pub b1: u8, pub c1: u8, pub d1: u64, pub e1: u64, pub f1: u64,
|
||||
pub a2: u8, pub b2: u8, pub c2: u8, pub d2: u64, pub e2: u64, pub f2: u64,
|
||||
|
|
|
@ -14,7 +14,7 @@ pub enum RuntimeErrors {
|
|||
InvalidOpcode(u8),
|
||||
RegisterTooSmall,
|
||||
HostError(u64),
|
||||
PageUnmapped(u64),
|
||||
PageNotMapped(u64),
|
||||
}
|
||||
|
||||
// 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::{
|
||||
bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
|
||||
engine::{regs::Registers, Engine},
|
||||
engine::Engine,
|
||||
RuntimeErrors,
|
||||
};
|
||||
|
||||
|
@ -8,8 +8,7 @@ fn main() -> Result<(), RuntimeErrors> {
|
|||
#[rustfmt::skip]
|
||||
let prog: Vec<u8> = vec![
|
||||
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, 1, 0, 0xB0,
|
||||
|
@ -22,15 +21,16 @@ fn main() -> Result<(), RuntimeErrors> {
|
|||
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,
|
||||
// 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);
|
||||
println!("{:?}", eng.read_mem_addr_8(4));
|
||||
// eng.set_timer_callback(time);
|
||||
// eng.enviroment_call_table[10] = print_fn;
|
||||
// eng.run()?;
|
||||
// eng.dump();
|
||||
eng.enviroment_call_table[10] = print_fn;
|
||||
eng.run()?;
|
||||
eng.dump();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -38,8 +38,7 @@ fn main() -> Result<(), RuntimeErrors> {
|
|||
pub fn time() -> u32 {
|
||||
9
|
||||
}
|
||||
pub fn print_fn(mut reg: Registers) -> Result<Registers, u64> {
|
||||
println!("{:?}", reg);
|
||||
|
||||
Ok(reg)
|
||||
pub fn print_fn(engine: &mut Engine) -> Result<&mut Engine, u64> {
|
||||
println!("hello");
|
||||
Ok(engine)
|
||||
}
|
||||
|
|
|
@ -21,15 +21,18 @@ impl Memory {
|
|||
impl Memory {
|
||||
pub fn read_addr8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
||||
let (page, offset) = addr_to_page(address);
|
||||
println!("page {} offset {}", page, offset);
|
||||
trace!("page {} offset {}", page, offset);
|
||||
match self.inner.get(&page) {
|
||||
Some(page) => {
|
||||
let val = page.data[offset as usize];
|
||||
trace!("Value {}", 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 {
|
||||
unimplemented!()
|
||||
|
|
Loading…
Reference in a new issue