Merge pull request 'master' (#1) from AbleOS/holey-bytes:master into master

Reviewed-on: #1
master
IntoTheNight 2023-07-11 09:28:48 +00:00
commit da8dc69ea0
2 changed files with 26 additions and 5 deletions

View File

@ -18,7 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
return Ok(()); return Ok(());
} else { } else {
unsafe { unsafe {
let mut vm = Vm::new_unchecked(&prog, TestTrapHandler); let mut vm = Vm::<_, 0>::new_unchecked(&prog, TestTrapHandler);
vm.memory.insert_test_page(); vm.memory.insert_test_page();
println!("Program interrupt: {:?}", vm.run()); println!("Program interrupt: {:?}", vm.run());
println!("{:?}", vm.registers); println!("{:?}", vm.registers);

View File

@ -79,7 +79,7 @@ macro_rules! cond_jump {
} }
/// HoleyBytes Virtual Machine /// HoleyBytes Virtual Machine
pub struct Vm<'a, T> { pub struct Vm<'a, T, const TIMER_QUOTIENT: usize> {
/// Holds 256 registers /// Holds 256 registers
/// ///
/// Writing to register 0 is considered undefined behaviour /// Writing to register 0 is considered undefined behaviour
@ -97,9 +97,12 @@ pub struct Vm<'a, T> {
/// Program /// Program
program: &'a [u8], 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 /// Create a new VM with program and trap handler
/// ///
/// # Safety /// # Safety
@ -111,6 +114,7 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
traph, traph,
pc: 0, pc: 0,
program, program,
timer: 0,
} }
} }
@ -123,12 +127,12 @@ impl<'a, T: HandleTrap> Vm<'a, T> {
/// Execute program /// Execute program
/// ///
/// Program can return [`VmRunError`] if a trap handling failed /// Program can return [`VmRunError`] if a trap handling failed
pub fn run(&mut self) -> Result<(), VmRunError> { pub fn run(&mut self) -> Result<VmRunOk, VmRunError> {
use hbbytecode::opcode::*; use hbbytecode::opcode::*;
loop { loop {
// Fetch instruction // Fetch instruction
let Some(&opcode) = self.program.get(self.pc) let Some(&opcode) = self.program.get(self.pc)
else { return Ok(()) }; else { return Ok(VmRunOk::End) };
// Big match // Big match
unsafe { 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 /// Unhandled store access exception
StoreAccessEx(u64), 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,
}