Implement timer

This commit is contained in:
Erin 2023-07-11 10:29:23 +02:00
parent bde00c13f2
commit 5ee8a91479
2 changed files with 23 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,19 @@ 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) };
if TIMER_QUOTIENT != 0 {
self.timer += 1;
if self.timer % TIMER_QUOTIENT == 0 {
return Ok(VmRunOk::Timer);
}
}
// Big match
unsafe {
@ -350,3 +361,10 @@ pub enum VmRunError {
/// Unhandled store access exception
StoreAccessEx(u64),
}
/// Virtual machine halt ok
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum VmRunOk {
End,
Timer,
}