ttvm 0.4.1

tt64 emulator API for Rust
Documentation
use super::*;
use std::ops;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Bus<T: IODev> {
    carry: u8,
    dev: *mut T,
}

impl<T: IODev> Bus<T> {
    pub fn new(dev: &mut T) -> Self {
        Bus { carry: 0, dev }
    }

    pub fn fetch(&self) -> u8 {
        self.carry
    }

    pub fn store(&mut self, byte: u8) {
        self.carry = byte;
    }
}

impl<T: IODev> IODev for Bus<T> {
    fn read(&self, addr: usize) -> Result<&u8, IOError> {
        unsafe {
            match (*self.dev).read(addr) {
                Ok(ok) => Ok(ok),
                Err(err) => Err(err),
            }
        }
    }

    fn read_mut(&mut self, addr: usize) -> Result<&mut u8, IOError> {
        unsafe {
            match (*self.dev).read_mut(addr) {
                Ok(ok) => Ok(ok),
                Err(err) => Err(err),
            }
        }
    }

    fn write(&mut self, addr: usize, data: u8) -> Result<usize, IOError> {
        unsafe {
            match (*self.dev).write(addr, data) {
                Ok(ok) => {
                    self.carry = data;

                    Ok(ok)
                }
                Err(err) => Err(err),
            }
        }
    }

    fn size(&self) -> usize {
        unsafe { (*self.dev).size() }
    }
}

impl<T: IODev> ops::Index<usize> for Bus<T> {
    type Output = u8;

    fn index(&self, addr: usize) -> &Self::Output {
        match self.read(addr) {
            Ok(ok) => ok,
            Err(_) => panic!("addr ({}) is out of bounds", addr),
        }
    }
}

impl<T: IODev> ops::IndexMut<usize> for Bus<T> {
    fn index_mut(&mut self, addr: usize) -> &mut Self::Output {
        match self.read_mut(addr) {
            Ok(ok) => ok,
            Err(_) => panic!("addr ({}) is out of bounds", addr),
        }
    }
}