From fb2c859db14aed40ac3538fb40b936cbb3f6b502 Mon Sep 17 00:00:00 2001 From: Able Date: Tue, 18 Apr 2023 18:08:30 -0500 Subject: [PATCH] commit --- DESIGN_DOC.md | 37 +++- src/bytecode.rs | 49 ------ src/bytecode/mod.rs | 2 + src/bytecode/ops.rs | 32 ++++ src/bytecode/types.rs | 9 + src/engine/call_stack.rs | 4 + src/engine/config.rs | 13 ++ src/engine/mod.rs | 370 +++++++++++++++++++++++++++++++++++++++ src/engine/regs.rs | 30 ++++ src/lib.rs | 324 +--------------------------------- src/main.rs | 20 +++ 11 files changed, 523 insertions(+), 367 deletions(-) delete mode 100644 src/bytecode.rs create mode 100644 src/bytecode/mod.rs create mode 100644 src/bytecode/ops.rs create mode 100644 src/bytecode/types.rs create mode 100644 src/engine/call_stack.rs create mode 100644 src/engine/config.rs create mode 100644 src/engine/mod.rs create mode 100644 src/engine/regs.rs create mode 100644 src/main.rs diff --git a/DESIGN_DOC.md b/DESIGN_DOC.md index 898cf6d5..5a101893 100644 --- a/DESIGN_DOC.md +++ b/DESIGN_DOC.md @@ -1,2 +1,37 @@ Holey Bytes has two bit widths -8 bit to help with byte level manipulation and 64 bit numbers because nothing else should ever be used. \ No newline at end of file +8 bit to help with byte level manipulation and 64 bit numbers because nothing else should ever be used in a modern setting + +this leaves us with an amount of registers that should be defined +I'd like to use a letter and a number to represent registers +like `a0` or `d0` the first of which would be reserved for 8 bit numbers and the later of which 64 bit. + +instructions +### NOP +`0` + +### ADD_8 TYPE LHS RHS LOCATION +`1` +### SUB TYPE LHS RHS LOCATION +`2` +### MUL TYPE LHS RHS LOCATION +`3` +### MUL TYPE LHS RHS LOCATION +`4` +### DIV TYPE LHS RHS LOCATION +`5` + +### JUMP ADDR +`100` +an unconditional jump to an address + +### JUMP_EQ LHS RHS ADDR +`101` +A conditional jump +if LHS is equal to RHS then jump to address +### JUMP_NEQ LHS RHS ADDR +`102` +A conditional jump +if LHS is not equal to RHS then jump to address + +### RET +pop off the callstack \ No newline at end of file diff --git a/src/bytecode.rs b/src/bytecode.rs deleted file mode 100644 index 5cc4ab21..00000000 --- a/src/bytecode.rs +++ /dev/null @@ -1,49 +0,0 @@ -pub const NOP: u8 = 0; -pub const ADD: u8 = 1; -pub const SUB: u8 = 2; -pub const MML: u8 = 3; -pub const DIV: u8 = 4; - -pub const CONST_U8: u8 = 0x00; -pub const CONST_I8: i8 = 0x01; - -pub const CONST_U16: u8 = 0x02; -pub const CONST_I16: u8 = 0x03; - -pub const CONST_U32: u8 = 0x04; -pub const CONST_I32: u8 = 0x05; -pub const CONST_F32: u8 = 0x06; - -pub const CONST_U64: u8 = 0x07; -pub const CONST_I64: u8 = 0x08; -pub const CONST_F64: u8 = 0x09; - -pub const ADDRESS: u8 = 0x10; - -pub const RegisterA8: u8 = 0xA0; -pub const RegisterB8: u8 = 0xB0; -pub const RegisterC8: u8 = 0xC0; -pub const RegisterD8: u8 = 0xD0; -pub const RegisterE8: u8 = 0xE0; -pub const RegisterF8: u8 = 0xF0; - -pub const RegisterA16: u8 = 0xA1; -pub const RegisterB16: u8 = 0xB1; -pub const RegisterC16: u8 = 0xC1; -pub const RegisterD16: u8 = 0xD1; -pub const RegisterE16: u8 = 0xE1; -pub const RegisterF16: u8 = 0xF1; - -pub const RegisterA32: u8 = 0xA2; -pub const RegisterB32: u8 = 0xB2; -pub const RegisterC32: u8 = 0xC2; -pub const RegisterD32: u8 = 0xD2; -pub const RegisterE32: u8 = 0xE2; -pub const RegisterF32: u8 = 0xF2; - -pub const RegisterA64: u8 = 0xA3; -pub const RegisterB64: u8 = 0xB3; -pub const RegisterC64: u8 = 0xC3; -pub const RegisterD64: u8 = 0xD3; -pub const RegisterE64: u8 = 0xE3; -pub const RegisterF64: u8 = 0xF3; diff --git a/src/bytecode/mod.rs b/src/bytecode/mod.rs new file mode 100644 index 00000000..414c60d2 --- /dev/null +++ b/src/bytecode/mod.rs @@ -0,0 +1,2 @@ +pub mod ops; +pub mod types; diff --git a/src/bytecode/ops.rs b/src/bytecode/ops.rs new file mode 100644 index 00000000..c8a22f1d --- /dev/null +++ b/src/bytecode/ops.rs @@ -0,0 +1,32 @@ +#[repr(u8)] +pub enum Operations { + NOP = 0, + ADD = 1, + SUB = 2, + MUL = 3, + DIV = 4, + + // READs a register/memory address/constant into a register + READ = 5, + // WRITEs a register/memory address/constant into a memory address + WRITE = 6, + + JUMP = 100, + JumpEq = 101, + JumpNeq = 102, + RET = 103, +} + +pub enum MathTypes { + EightBit = 1, + SixtyFourBit = 2, +} + +pub enum RWTypes { + RegisterToAddress = 0, + RegisterToRegister = 1, + ConstantToAddress = 2, + ConstantToRegister = 3, + AddressToRegister = 4, + AddressToAddress = 5, +} diff --git a/src/bytecode/types.rs b/src/bytecode/types.rs new file mode 100644 index 00000000..1e98c23b --- /dev/null +++ b/src/bytecode/types.rs @@ -0,0 +1,9 @@ + +pub const CONST_U8: u8 = 0x00; +pub const CONST_I8: i8 = 0x01; + +pub const CONST_U64: u8 = 0x02; +pub const CONST_I64: u8 = 0x03; +pub const CONST_F64: u8 = 0x04; + +pub const ADDRESS: u8 = 0x05; diff --git a/src/engine/call_stack.rs b/src/engine/call_stack.rs new file mode 100644 index 00000000..00739a38 --- /dev/null +++ b/src/engine/call_stack.rs @@ -0,0 +1,4 @@ +pub type CallStack = Vec; +pub struct FnCall { + ret: usize, +} diff --git a/src/engine/config.rs b/src/engine/config.rs new file mode 100644 index 00000000..504d6631 --- /dev/null +++ b/src/engine/config.rs @@ -0,0 +1,13 @@ +pub struct EngineConfig { + pub call_stack_depth: usize, + pub quantum: u32, +} + +impl EngineConfig { + pub fn default() -> Self { + Self { + call_stack_depth: 32, + quantum: 0, + } + } +} diff --git a/src/engine/mod.rs b/src/engine/mod.rs new file mode 100644 index 00000000..332605f7 --- /dev/null +++ b/src/engine/mod.rs @@ -0,0 +1,370 @@ +pub mod call_stack; +pub mod config; +pub mod regs; + +use crate::bytecode::ops::*; +use crate::bytecode::types::*; + +use crate::HaltStatus; +use crate::Page; +use crate::RuntimeErrors; +use config::EngineConfig; +use regs::Registers; + +use self::call_stack::CallStack; + +pub struct Engine { + pub index: usize, + program: Vec, + registers: Registers, + config: EngineConfig, + + /// BUG: This DOES NOT account for overflowing + last_timer_count: u32, + timer_callback: Option u32>, + memory: Vec, + call_stack: CallStack, +} + +impl Engine { + pub fn new(program: Vec) -> Self { + Self { + index: 0, + program, + registers: Registers::new(), + config: EngineConfig::default(), + last_timer_count: 0, + timer_callback: None, + memory: vec![], + call_stack: vec![], + } + } + pub fn dump(&self) { + println!("Registers"); + println!( + "A {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", + self.registers.a0, + self.registers.a1, + self.registers.a2, + self.registers.a3, + self.registers.a4, + self.registers.a5, + self.registers.a6, + self.registers.a7, + self.registers.a8, + self.registers.a9, + ); + println!( + "B {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", + self.registers.b0, + self.registers.b1, + self.registers.b2, + self.registers.b3, + self.registers.b4, + self.registers.b5, + self.registers.b6, + self.registers.b7, + self.registers.b8, + self.registers.b9, + ); + println!( + "C {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X} {:02X}", + self.registers.c0, + self.registers.c1, + self.registers.c2, + self.registers.c3, + self.registers.c4, + self.registers.c5, + self.registers.c6, + self.registers.c7, + self.registers.c8, + self.registers.c9, + ); + + println!( + "D0-D4 {:016X} {:016X} {:016X} {:016X} {:016X} +D5-D9 {:016X} {:016X} {:016X} {:016X} {:016X}", + self.registers.d0, + self.registers.d1, + self.registers.d2, + self.registers.d3, + self.registers.d4, + self.registers.d5, + self.registers.d6, + self.registers.d7, + self.registers.d8, + self.registers.d9, + ); + println!( + "E0-E4 {:016X} {:016X} {:016X} {:016X} {:016X} +E5-E9 {:016X} {:016X} {:016X} {:016X} {:016X}", + self.registers.e0, + self.registers.e1, + self.registers.e2, + self.registers.e3, + self.registers.e4, + self.registers.e5, + self.registers.e6, + self.registers.e7, + self.registers.e8, + self.registers.e9, + ); + println!( + "F0-F4 {:016X} {:016X} {:016X} {:016X} {:016X} +F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", + self.registers.f0, + self.registers.f1, + self.registers.f2, + self.registers.f3, + self.registers.f4, + self.registers.f5, + self.registers.f6, + self.registers.f7, + self.registers.f8, + self.registers.f9, + ); + } + pub fn run(&mut self) -> Result { + use HaltStatus::*; + use RuntimeErrors::*; + loop { + // Break out of the loop + if self.index == self.program.len() { + break; + } + let op = self.program[self.index]; + println!("OP {} INDEX {}", self.program[self.index], self.index); + match op { + NOP => self.index += 1, + ADD => { + print!("Add"); + self.index += 1; + let mut lhs: Vec = vec![]; + let mut rhs: Vec = vec![]; + let mut lhs_signed = false; + let mut rhs_signed = false; + + match self.program[self.index] { + CONST_U8 => { + self.index += 1; + lhs.push(self.program[self.index]); + print!(" constant {:?}", lhs[0]); + lhs_signed = false; + self.index += 1; + } + CONST_U64 => { + self.index += 1; + lhs.push(self.program[self.index]); + self.index += 1; + lhs.push(self.program[self.index]); + self.index += 1; + lhs.push(self.program[self.index]); + self.index += 1; + lhs.push(self.program[self.index]); + + lhs_signed = false; + self.index += 1; + } + 0xA0..=0xC9 => { + println!("TRACE: 8 bit lhs"); + } + 0xD0..=0xFF => { + println!("TRACE: 64 bit lhs"); + } + op => return Err(InvalidOpcode(op)), + } + + match self.program[self.index] { + CONST_U8 => { + self.index += 1; + rhs.push(self.program[self.index]); + rhs_signed = false; + print!(" constant {:?}", rhs[0]); + self.index += 1; + } + + CONST_U64 => { + self.index += 1; + rhs.push(self.program[self.index]); + self.index += 1; + rhs.push(self.program[self.index]); + self.index += 1; + rhs.push(self.program[self.index]); + self.index += 1; + rhs.push(self.program[self.index]); + + print!(" constant {:?}", rhs[0]); + rhs_signed = false; + self.index += 1; + } + 0xA0..=0xC9 => { + println!("TRACE: 8 bit rhs"); + } + 0xD0..=0xFF => { + println!("TRACE: 64 bit rhs"); + } + + _ => { + panic!() + } + } + match self.program[self.index] { + 0xA0 => { + if lhs.len() > 1 { + panic!("LHS is not an 8 bit number") + } + if rhs.len() > 1 { + panic!("RHS is not an 8 bit number") + } + println!(" store in A0"); + + let sum = lhs[0] + rhs[0]; + self.registers.a0 = sum; + self.index += 1; + } + 0xB0 => { + if lhs.len() > 1 { + panic!("LHS is not an 8 bit number") + } + if rhs.len() > 1 { + panic!("RHS is not an 8 bit number") + } + println!(" store in B0"); + let sum = lhs[0] + rhs[0]; + self.registers.b0 = sum; + self.index += 1; + } + 0xC0 => { + if lhs.len() > 1 { + panic!("LHS is not an 8 bit number") + } + if rhs.len() > 1 { + panic!("RHS is not an 8 bit number") + } + println!(" store in C0"); + let sum = lhs[0] + rhs[0]; + self.registers.c8 = sum; + self.index += 1; + } + 0xD0 => { + if lhs.len() > 4 { + panic!("LHS is not an 8 bit number") + } + if rhs.len() > 4 { + panic!("RHS is not an 8 bit number") + } + println!(" store in D0"); + let lhs: u64 = Into::::into(lhs[3]) << 60; + println!("{}", lhs); + println!("{}", 2); + // let rhs: u64 = (rhs[4] << 16).into(); + let rhs: u64 = 0; + let sum = lhs + rhs; + self.registers.d0 = sum; + self.index += 1; + } + + op => { + println!("{}", op) + } + } + } + SUB => { + print!("Sub"); + self.index += 1; + let mut lhs: Vec = vec![]; + let mut rhs: Vec = vec![]; + let mut lhs_signed = false; + let mut rhs_signed = false; + + match self.program[self.index] { + 0xA0 => { + lhs.push(self.registers.a8); + lhs_signed = false; + print!(" constant {:?}", self.registers.a8); + self.index += 1; + } + 0xB0 => { + lhs.push(self.registers.b8); + lhs_signed = false; + print!(" constant {:?}", self.registers.b8); + self.index += 1; + } + CONST_U8 => { + self.index += 1; + lhs.push(self.program[self.index]); + print!(" constant {:?}", lhs[0]); + lhs_signed = false; + self.index += 1; + } + op => return Err(InvalidOpcode(op)), + } + + match self.program[self.index] { + 0xB0 => { + rhs.push(self.registers.b8); + rhs_signed = false; + print!(" constant {:?}", self.registers.b8); + self.index += 1; + } + _ => { + panic!() + } + } + match self.program[self.index] { + 0xA0 => { + if lhs.len() > 1 { + panic!("LHS is not an 8 bit number") + } + println!(" store in A8"); + + let sum = lhs[0] - rhs[0]; + self.registers.a8 = sum; + self.index += 1; + } + 0xB0 => { + if lhs.len() > 1 { + panic!("LHS is not an 8 bit number") + } + if rhs.len() > 1 { + panic!("RHS is not an 8 bit number") + } + println!(" store in B8"); + let sum = lhs[0] - rhs[0]; + self.registers.b8 = sum; + self.index += 1; + } + 0xC0 => { + if lhs.len() > 1 { + panic!("LHS is not an 8 bit number") + } + if rhs.len() > 1 { + panic!("RHS is not an 8 bit number") + } + println!(" store in B8"); + let sum = lhs[0] - rhs[0]; + self.registers.c8 = sum; + self.index += 1; + } + _ => { + panic!() + } + } + } + op => { + println!("INVALID OPCODE {}", op); + self.index += 1; + } + } + // Finish step + + if self.timer_callback.is_some() { + let ret = self.timer_callback.unwrap()(); + if (ret - self.last_timer_count) >= self.config.quantum { + return Ok(Running); + } + } + } + Ok(Halted) + } +} diff --git a/src/engine/regs.rs b/src/engine/regs.rs new file mode 100644 index 00000000..7d4710ab --- /dev/null +++ b/src/engine/regs.rs @@ -0,0 +1,30 @@ +#[rustfmt::skip] +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, + pub a3: u8, pub b3: u8, pub c3: u8, pub d3: u64, pub e3: u64, pub f3: u64, + pub a4: u8, pub b4: u8, pub c4: u8, pub d4: u64, pub e4: u64, pub f4: u64, + pub a5: u8, pub b5: u8, pub c5: u8, pub d5: u64, pub e5: u64, pub f5: u64, + pub a6: u8, pub b6: u8, pub c6: u8, pub d6: u64, pub e6: u64, pub f6: u64, + pub a7: u8, pub b7: u8, pub c7: u8, pub d7: u64, pub e7: u64, pub f7: u64, + pub a8: u8, pub b8: u8, pub c8: u8, pub d8: u64, pub e8: u64, pub f8: u64, + pub a9: u8, pub b9: u8, pub c9: u8, pub d9: u64, pub e9: u64, pub f9: u64, +} +impl Registers { + #[rustfmt::skip] + pub fn new() -> Self{ + Self { + a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, + a1: 0, b1: 0, c1: 0, d1: 0, e1: 0, f1: 0, + a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, + a3: 0, b3: 0, c3: 0, d3: 0, e3: 0, f3: 0, + a4: 0, b4: 0, c4: 0, d4: 0, e4: 0, f4: 0, + a5: 0, b5: 0, c5: 0, d5: 0, e5: 0, f5: 0, + a6: 0, b6: 0, c6: 0, d6: 0, e6: 0, f6: 0, + a7: 0, b7: 0, c7: 0, d7: 0, e7: 0, f7: 0, + a8: 0, b8: 0, c8: 0, d8: 0, e8: 0, f8: 0, + a9: 0, b9: 0, c9: 0, d9: 0, e9: 0, f9: 0, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 9796419f..52d5da53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,71 +1,17 @@ -#![allow(unused_assignments)] -#![allow(unused_must_use)] - pub mod bytecode; -use bytecode::*; +pub mod engine; +use bytecode::ops::*; +use bytecode::types::{CONST_F64, CONST_U8}; +use engine::Engine; pub struct Page { - data: [u8; 4096], + pub data: [u8; 4096 * 2], } -#[repr(u16)] -/// All instructions will use `op src dest` format (if they take arguments) -/// most `src`s can be replaced with a constant -pub enum Instructions { - Nop = 0, // No Operation or nothing to do - // Add takes two `src`s and adds into a `dest` - // add - Add, - Sub, - Mul, - Div, //HTML Div not division for that refer to ~~Blam~~ - - Store, - // Load a value from one src to one dest - // `load a8 c8` - Load, -} - -// A `src` may be any of the following -// Memory Address -// Register -// Constant -// ~~Port~~ - -// A `dest` may be any of the following -// Memory Address -// Register - -// 0000 ;; NOP -// // Once we get to an instruction that makes sense we can interpret the next bytes relative to that instruction -// 0001 ;; add - -// // EXAMPLE -// 0001 -// // This grouping is called a pairing and is useful as a short little guide for how to read AOB -// (0xC0 0x03)/*0xC0 represents a constant that is size u8, 0x03 is 3*/ -// (0xC1 0x01)/*0xC1 represents a constant that is size i8, 0x01 is 1*/ -// (0xA0 0x01)/* 0xA0 represents a the a8 register as an unsigned number, 0x01 is 1*/ -// 0002 -// (0xC3 0x01 0x00)/*0xC3 represents a constant that is size u16 , 0x01 0x00 is 256*/ -#[test] -fn main() { - #[rustfmt::skip] - let prog: Vec = vec![ - NOP, - ADD, CONST_U8, 1, CONST_U8, 20, RegisterA8, - ADD, CONST_U8, 1, CONST_U8, 0, RegisterB8, - SUB, CONST_U8, 3, RegisterA8, RegisterC8, - ]; - let mut eng = Engine::new(prog); - // eng.timer_callback = Some(time); - eng.run(); - eng.dump(); -} pub fn time() -> u32 { 9 } - +#[derive(Debug)] pub enum RuntimeErrors { InvalidOpcode(u8), RegisterTooSmall, @@ -77,265 +23,9 @@ pub enum HaltStatus { Running, } -#[rustfmt::skip] -pub struct Registers{ - a8: u8, a16: u16, a32: u32, a64: u64, - b8: u8, b16: u16, b32: u32, b64: u64, - c8: u8, c16: u16, c32: u32, c64: u64, - d8: u8, d16: u16, d32: u32, d64: u64, - e8: u8, e16: u16, e32: u32, e64: u64, - f8: u8, f16: u16, f32: u32, f64: u64, -} -impl Registers { - #[rustfmt::skip] - pub fn new() -> Self{ - Self{ - a8: 0, a16: 0, a32: 0, a64: 0, - b8: 0, b16: 0, b32: 0, b64: 0, - c8: 0, c16: 0, c32: 0, c64: 0, - d8: 0, d16: 0, d32: 0, d64: 0, - e8: 0, e16: 0, e32: 0, e64: 0, - f8: 0, f16: 0, f32: 0, f64: 0, - } - } -} - -pub const ENGINE_DELTA: u32 = 1; - -pub struct Engine { - index: usize, - program: Vec, - registers: Registers, - /// BUG: This DOES NOT account for overflowing - last_timer_count: u32, - timer_callback: Option u32>, -} -impl Engine { - pub fn new(program: Vec) -> Self { - Self { - index: 0, - program, - registers: Registers::new(), - last_timer_count: 0, - timer_callback: None, - } - } - pub fn dump(&self) { - println!("Reg A8 {}", self.registers.a8); - println!("Reg B8 {}", self.registers.b8); - println!("Reg C8 {}", self.registers.c8); - println!("Reg D8 {}", self.registers.d8); - println!("Reg E8 {}", self.registers.e8); - println!("Reg F8 {}", self.registers.f8); - } - pub fn run(&mut self) -> Result { - use HaltStatus::*; - use RuntimeErrors::*; - loop { - // Break out of the loop - if self.index == self.program.len() { - break; - } - let op = self.program[self.index]; - match op { - NOP => self.index += 1, - ADD => { - print!("Add"); - self.index += 1; - let mut lhs: Vec = vec![]; - let mut rhs: Vec = vec![]; - let mut lhs_signed = false; - let mut rhs_signed = false; - - match self.program[self.index] { - CONST_U8 => { - self.index += 1; - lhs.push(self.program[self.index]); - print!(" constant {:?}", lhs[0]); - lhs_signed = false; - self.index += 1; - } - op => return Err(InvalidOpcode(op)), - } - - match self.program[self.index] { - CONST_U8 => { - self.index += 1; - rhs.push(self.program[self.index]); - rhs_signed = false; - print!(" constant {:?}", rhs[0]); - self.index += 1; - } - _ => { - panic!() - } - } - match self.program[self.index] { - RegisterA8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - if rhs.len() > 1 { - panic!("RHS is not an 8 bit number") - } - println!(" store in A8"); - - let sum = lhs[0] + rhs[0]; - self.registers.a8 = sum; - self.index += 1; - } - RegisterB8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - if rhs.len() > 1 { - panic!("RHS is not an 8 bit number") - } - println!(" store in B8"); - let sum = lhs[0] + rhs[0]; - self.registers.b8 = sum; - self.index += 1; - } - RegisterC8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - if rhs.len() > 1 { - panic!("RHS is not an 8 bit number") - } - println!(" store in C8"); - let sum = lhs[0] + rhs[0]; - self.registers.c8 = sum; - self.index += 1; - } - - RegisterD8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - if rhs.len() > 1 { - panic!("RHS is not an 8 bit number") - } - println!(" store in D8"); - let sum = lhs[0] + rhs[0]; - self.registers.d8 = sum; - self.index += 1; - } - - _ => { - panic!() - } - } - } - SUB => { - print!("Sub"); - self.index += 1; - let mut lhs: Vec = vec![]; - let mut rhs: Vec = vec![]; - let mut lhs_signed = false; - let mut rhs_signed = false; - - match self.program[self.index] { - RegA8 => { - lhs.push(self.registers.a8); - lhs_signed = false; - print!(" constant {:?}", self.registers.a8); - self.index += 1; - } - RegB8 => { - lhs.push(self.registers.b8); - lhs_signed = false; - print!(" constant {:?}", self.registers.b8); - self.index += 1; - } - CONST_U8 => { - self.index += 1; - lhs.push(self.program[self.index]); - print!(" constant {:?}", lhs[0]); - lhs_signed = false; - self.index += 1; - } - op => return Err(InvalidOpcode(op)), - } - - match self.program[self.index] { - RegB8 => { - rhs.push(self.registers.b8); - rhs_signed = false; - print!(" constant {:?}", self.registers.b8); - self.index += 1; - } - _ => { - panic!() - } - } - match self.program[self.index] { - RegisterA8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - println!(" store in A8"); - - let sum = lhs[0] - rhs[0]; - self.registers.a8 = sum; - self.index += 1; - } - RegisterB8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - if rhs.len() > 1 { - panic!("RHS is not an 8 bit number") - } - println!(" store in B8"); - let sum = lhs[0] - rhs[0]; - self.registers.b8 = sum; - self.index += 1; - } - RegisterC8 => { - if lhs.len() > 1 { - panic!("LHS is not an 8 bit number") - } - if rhs.len() > 1 { - panic!("RHS is not an 8 bit number") - } - println!(" store in B8"); - let sum = lhs[0] - rhs[0]; - self.registers.c8 = sum; - self.index += 1; - } - _ => { - panic!() - } - } - } - op => { - println!("INVALID OPCODE {}", op); - self.index += 1; - } - } - // Finish step - - if self.timer_callback.is_some() { - let ret = self.timer_callback.unwrap()(); - if (ret - self.last_timer_count) >= ENGINE_DELTA { - return Ok(Running); - } - } - } - Ok(Halted) - } -} - pub struct HandSide { signed: bool, + float: bool, num8: Option, num64: Option, } - -pub fn math_handler(math_op: u8, lhs: (bool, [u8; 4]), rhs: [u8; 4]) { - match math_op { - ADD => {} - _ => {} - } -} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 00000000..ca985753 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,20 @@ +use holey_bytes::bytecode::ops::Operations::*; +use holey_bytes::bytecode::types::CONST_U64; +use holey_bytes::RuntimeErrors; +use holey_bytes::{bytecode::types::CONST_U8, engine::Engine}; + +fn main() -> Result<(), RuntimeErrors> { + #[rustfmt::skip] + let prog: Vec = vec![ + NOP as u8, + ADD as u8, CONST_U8, 1, CONST_U8, 20, 0xA0, + ADD as u8, CONST_U8, 1, CONST_U8, 0, 0xB0, + ADD as u8, CONST_U64, 0, 0, 0, 2, CONST_U64, 0, 0, 0, 2, 0xD0, + // SUB, CONST_U8, 4, CONST_U8, 1, 0xC8, + ]; + let mut eng = Engine::new(prog); + // eng.timer_callback = Some(time); + eng.run()?; + // eng.dump(); + Ok(()) +}