uxn/src/device/system.rs

53 lines
1.7 KiB
Rust

use crate::device::Device;
use crate::vm::Uxn;
/**
* The system device
*/
#[derive(Debug)]
pub struct SystemDevice {
buffer: [u8; 0xF],
}
impl SystemDevice {
pub fn new() -> SystemDevice {
SystemDevice { buffer: [0; 0xF] }
}
}
impl Device for SystemDevice {
fn dei1(&mut self, vm: &mut Uxn, port: u8) -> u8 {
let slot = port & 0xF;
match slot {
0x2 => vm.wst.idx,
0x3 => vm.rst.idx,
x => self.buffer[x as usize],
}
}
fn dei2(&mut self, vm: &mut Uxn, port: u8) -> u16 {
return ((self.dei1(vm, port) as u16) << 8) + self.dei1(vm, port + 1) as u16;
}
fn deo1(&mut self, vm: &mut Uxn, port: u8, val: u8) {
let slot = port & 0xF;
match slot {
// Note: This VM does not support mutating the stack pointers.
// This operation is not well defined upstream
0x2 => panic!("Invoked unsupported mutation of the data stack pointer"),
0x3 => panic!("Invoked unsupported mutation of the return stack pointer"),
x => self.buffer[x as usize] = val,
}
}
fn deo2(&mut self, vm: &mut Uxn, port: u8, val: u16) {
let slot = port & 0xF;
assert!(slot < 0xF, "Double-write beyond the end of the device");
match slot {
0x2 => panic!("The data stack is single-width, panic on spurious double-write"),
0x3 => panic!("The return stack is single-width, panic on spurious double-write"),
x => {
let [high, low] = val.to_be_bytes();
self.deo1(vm, x, high);
self.deo1(vm, x + 1, low)
}
}
}
}