ttvm 0.2.3

Runtime and compiler infrastructure API for Rust
Documentation
use super::*;

pub struct Device {
    power_on: bool,
    disks: Box<[Option<*mut Disk>]>,
    mem: Box<[u8]>,
    regset: Box<[u128]>,
    pc: usize
}

impl Device {
    pub fn new() -> Device {
        Device {
            power_on: false,
            disks: vec![None; 3].into_boxed_slice(),
            mem: vec![0x0; 0xFFFF].into_boxed_slice(),
            regset: vec![0x0; 0xFF].into_boxed_slice(),
            pc: 0
        }
    }

    pub fn power(&mut self) {
        if self.power_on {
            self.power_on = false;
        } else {
            self.power_on = true;

            for i in 0..0xFFFF {
                if self.mem[i] != 0x0 {
                    self.mem[i] = 0x0;
                }
            }

            for i in 0..0xFF {
                if self.regset[i] != 0x0 {
                    self.regset[i] = 0x0;
                }
            }

            self.pc = 0;

            match self.disks[0] {
                Some(some) => unsafe {
                    let content: Box<[u8]> = (*some).clone_into_vec().into_boxed_slice();
                    let mut index = 0;

                    for byte in content.iter() {
                        self.mem[index] = *byte;

                        index = index + 1;
                    }
                },
                None => ()
            };

            loop {                
                if self.mem[self.pc] == JMP_F {
                    self.pc = self.pc + 1;

                    if self.pc < 0xFFFF {
                        let l = self.mem[self.pc];
                        
                        self.pc = self.pc + l as usize;
                    }
                } else if self.mem[self.pc] == JMP_R {
                    self.pc = self.pc + 1;

                    if self.pc < 0xFFFF {
                        let l = self.mem[self.pc];

                        if l < 0xFF {
                            self.pc = self.regset[l as usize] as usize;
                        }
                    }
                } else if self.mem[self.pc] == JMP_B {
                    self.pc = self.pc + 1;

                    if self.pc < 0xFFFF {
                        let l = self.mem[self.pc];
                        
                        self.pc = self.pc - l as usize;
                    }
                } else if self.mem[self.pc] == MOV_N {
                    self.pc = self.pc + 1;

                    if self.pc < 0xFFFF {
                        let l = self.mem[self.pc];

                        self.pc = self.pc + 1;

                        if self.pc < 0xFFFF {
                            let r = self.mem[self.pc];
                            
                            self.mem[self.regset[l as usize] as usize] = r;
                        }
                    }
                } else if self.mem[self.pc] == MOV_R {
                    self.pc = self.pc + 1;

                    if self.pc < 0xFFFF {
                        let l = self.mem[self.pc];

                        self.pc = self.pc + 1;

                        if self.pc < 0xFFFF {
                            let r = self.mem[self.pc];
                            
                            self.regset[l as usize] = r as u128;
                        }
                    }
                } else if self.mem[self.pc] == QHALT {
                    self.pc = self.pc + 1;
                    self.power_on = false;

                    break;
                } else if self.mem[self.pc] == PRT_D {
                    self.pc = self.pc + 1;

                    if self.pc < 0xFFFF {
                        let l = self.mem[self.pc];

                        print!("{}", l as char);
                    }
                } else {
                    self.pc = self.pc + 1;
                }

                if self.pc == 0xFFFF {
                    self.pc = 0;
                }
            }
        }
    }

    pub fn attach(&mut self, port: usize, disk: &mut Disk) -> Option<DiskIOError> {
        if port < 3 && self.disks[port] == None {
            self.disks[port] = Some(disk);

            None
        } else {
            Some(DiskIOError::with_string(format!("port {} is not available", port)))
        }
    }

    pub fn detach(&mut self, port: usize) -> Option<DiskIOError> {
        if port < 3 && self.disks[port] != None {
            self.disks[port] = None;
            
            None
        } else {
            Some(DiskIOError::with_string(format!("port {} is not available", port)))
        }
    }
}