TX-2 / TX-2-simulator

Simulator for the pioneering TX-2 computer
https://tx-2.github.io/
MIT License
21 stars 2 forks source link

Remove blocking I/O from the cpu library #46

Closed jamesyoungman closed 2 years ago

jamesyoungman commented 2 years ago

Describe the bug The paper-tape reader implementation (cpu/src/io/dev_petr.rs) performs syncronous I/O to read data from the input file representing a paper tape. But, there are problems with this synchronous I/O:

  1. Performing I/O against a local file won't work inside a web browser
  2. The I/O will block until a byte is ready, and we don't want the library to block.

To Reproduce Here's an illustration of where the problem is:

See this code in particular:

pub trait TapeIterator {
    fn next_tape(&mut self) -> Option<File>;
}
// ...
impl Petr {
    pub fn new(tapes: Box<dyn TapeIterator>) -> Petr {
    // ... 
   }
}

So the Petr struct takes onwership of a TapeIterator and uses it to read data for the tape. I/O is performed like this:

    fn do_read(&mut self) {
        // A line of the simulated tape should have appeared under the
        // read head.
        let mut buf: [u8; 1] = [0];
        match self.data_file.as_mut() {
            Some(f) => match f.read(&mut buf) {
            // ...
      }
     // ...
}

So the I/O is synchronous.

Expected behavior

Instead, the I/O should be performed by the library's caller. Ideally we should design a sufficiently general mechanism that we can apply the same sort of idea to the light pen position, the read channels of the Lincoln Writers and presumably also the magnetic tape.

Platform and version information: The code sample is taken from the source as of commit 5fad52225b5bea31c649e4c2eec83b20548e1247.

Additional context This issue is labelled "good first issue" because it's possible to work on it with only a minimal understanding of how the TX-2 worked.