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

Reviewed-on: https://git.ablecorp.us/IntoTheNight/holey-bytes/pulls/1
This commit is contained in:
IntoTheNight 2023-07-11 09:28:48 +00:00
commit b83d1838aa
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(());
} 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);

View file

@ -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<VmRunOk, VmRunError> {
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,
}