diff --git a/hbvm/src/main.rs b/hbvm/src/main.rs index 255384e8..5f9b27f0 100644 --- a/hbvm/src/main.rs +++ b/hbvm/src/main.rs @@ -18,7 +18,7 @@ fn main() -> Result<(), Box> { return Ok(()); } else { unsafe { - let mut vm = Vm::new_unchecked(&prog, TestTrapHandler); + let mut vm = Vm::<_, 0>::new_unchecked(&prog, TestTrapHandler); vm.memory.insert_test_page(); println!("Program interrupt: {:?}", vm.run()); println!("{:?}", vm.registers); diff --git a/hbvm/src/vm/mod.rs b/hbvm/src/vm/mod.rs index 0f6fa2f0..182b574d 100644 --- a/hbvm/src/vm/mod.rs +++ b/hbvm/src/vm/mod.rs @@ -79,7 +79,7 @@ macro_rules! cond_jump { } /// HoleyBytes Virtual Machine -pub struct Vm<'a, T> { +pub struct Vm<'a, T, const TIMER_QUOTIENT: usize> { /// Holds 256 registers /// /// Writing to register 0 is considered undefined behaviour @@ -97,9 +97,12 @@ pub struct Vm<'a, T> { /// Program program: &'a [u8], + + /// Program timer + timer: usize, } -impl<'a, T: HandleTrap> Vm<'a, T> { +impl<'a, T: HandleTrap, const TIMER_QUOTIENT: usize> Vm<'a, T, TIMER_QUOTIENT> { /// Create a new VM with program and trap handler /// /// # Safety @@ -111,6 +114,7 @@ impl<'a, T: HandleTrap> Vm<'a, T> { traph, pc: 0, program, + timer: 0, } } @@ -123,12 +127,12 @@ impl<'a, T: HandleTrap> Vm<'a, T> { /// Execute program /// /// Program can return [`VmRunError`] if a trap handling failed - pub fn run(&mut self) -> Result<(), VmRunError> { + pub fn run(&mut self) -> Result { use hbbytecode::opcode::*; loop { // Fetch instruction let Some(&opcode) = self.program.get(self.pc) - else { return Ok(()) }; + else { return Ok(VmRunOk::End) }; // Big match unsafe { @@ -318,6 +322,13 @@ impl<'a, T: HandleTrap> Vm<'a, T> { } } } + + if TIMER_QUOTIENT != 0 { + self.timer = self.timer.wrapping_add(1); + if self.timer % TIMER_QUOTIENT == 0 { + return Ok(VmRunOk::Timer); + } + } } } @@ -350,3 +361,13 @@ pub enum VmRunError { /// Unhandled store access exception StoreAccessEx(u64), } + +/// Virtual machine halt ok +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum VmRunOk { + /// Program has eached its end + End, + + /// Program was interrupted by a timer + Timer, +}