Implement timer
This commit is contained in:
parent
bde00c13f2
commit
5ee8a91479
|
@ -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);
|
||||||
|
|
|
@ -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,19 @@ 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) };
|
||||||
|
|
||||||
|
if TIMER_QUOTIENT != 0 {
|
||||||
|
self.timer += 1;
|
||||||
|
if self.timer % TIMER_QUOTIENT == 0 {
|
||||||
|
return Ok(VmRunOk::Timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Big match
|
// Big match
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -350,3 +361,10 @@ 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 {
|
||||||
|
End,
|
||||||
|
Timer,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue