@@ 1,3 1,5 @@
+use std::io;
+
pub struct Processor<'a> {
reg: [u16;32],
flags: [bool;2], //Flag A, then B
@@ 5,6 7,7 @@ pub struct Processor<'a> {
pub memory: &'a mut [u16], //Public since memory should be modifiable by the system.
pub disk: &'a mut [u16],
pub vram: &'a mut [u16],
+ stdin_buf: Vec<u16>,
}
pub fn new<'a>(memory: &'a mut [u16], disk: &'a mut [u16], vram: &'a mut [u16]) -> Processor<'a> {
@@ 15,6 18,7 @@ pub fn new<'a>(memory: &'a mut [u16], disk: &'a mut [u16], vram: &'a mut [u16])
memory,
disk,
vram,
+ stdin_buf: Vec::new(),
}
}
@@ 286,8 290,20 @@ impl <'a> Processor<'a> {
1 => self.reg[operands.0] = self.memory[self.reg[operands.1] as usize], //Main memory
2 => self.reg[operands.0] = self.disk[self.reg[operands.1] as usize], //Disk
3 => self.reg[operands.0] = self.vram[self.reg[operands.1] as usize], //VRAM
- 4 => todo!(), //Serial port, todo as stdin handling would be preferably
- //dealt with as part of the main program loop
+ 4 => { //Serial port
+ if self.stdin_buf == Vec::new() { //Fill stdin_buf if empty
+ let mut buffer = String::new();
+ io::stdin().read_line(&mut buffer).expect("STDIN read failure");
+ for byte in buffer.as_bytes().iter().rev() { //Reversed so values
+ //can be simply popped
+ //from the vec
+ self.stdin_buf.push(*byte as u16);
+ }
+ }
+ self.reg[operands.0] = self.stdin_buf.pop().unwrap_or(0); //If stdin is
+ //empty, pass
+ //in 0
+ }
_ => return true
}
}