51 lines
1.6 KiB
Rust
51 lines
1.6 KiB
Rust
|
/**
|
||
|
* The system device
|
||
|
*/
|
||
|
#[derive(Debug)]
|
||
|
struct SystemDevice {
|
||
|
buffer: [u8; 0xF],
|
||
|
}
|
||
|
|
||
|
impl SystemDevice {
|
||
|
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)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|