/** * 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) } } } }