[][src]Struct pir_8_emu::vm::Ports

pub struct Ports { /* fields omitted */ }

256B of I/O ports with R/W tracking and per-port handler logic

Methods

impl Ports[src]

pub fn new() -> Ports[src]

Create fresh zero-initialised unread and unwritten ports with no handlers

pub fn install_handler<H: PortHandler + 'static>(
    &mut self,
    handler: H,
    ports: &[u8]
) -> Result<usize, (H, PortHandlerInstallError)>
[src]

Install the specified handler on the specified ports

On success, calls PortHandler::init() on the specified handler and returns a unique ID thereof

Will return an error if the specified ports are already occupied, or the handler doesn't take the amount of ports specified, or too many handlers've been registered

Examples

struct InitableHandler(Option<u8>);
impl PortHandler for InitableHandler {
    fn init(&mut self, ports: &[u8]) { self.0 = Some(ports[0]); }
}

let mut ports = Ports::new();

let handler_id = ports.install_handler(InitableHandler(None), &[0xA1])
                      .map_err(|(_, e)| e).unwrap();

assert_eq!(ports.get_handler(handler_id).and_then(|h| h.downcast_ref()),
           Some(&InitableHandler(Some(0xA1))));

pub fn get_handler(&self, idx: usize) -> Option<&(dyn PortHandler + 'static)>[src]

Get reference to the handler with the specified ID, if exists

pub fn get_handler_mut(
    &mut self,
    idx: usize
) -> Option<&mut (dyn PortHandler + 'static)>
[src]

Get mutable reference to the handler with the specified ID, if exists

pub fn uninstall_handler(
    &mut self,
    idx: usize
) -> Option<Box<dyn PortHandler + 'static>>
[src]

Remove, unregister, and deinitialise the handler with the specified ID and return it, if exists

Examples

struct DeInitableHandler(Option<u8>, bool);
impl PortHandler for DeInitableHandler {
    fn init(&mut self, ports: &[u8]) { self.0 = Some(ports[0]); }
    fn uninit(&mut self) { self.1 = true; }
}

let mut ports = Ports::new();

let handler_id = ports.install_handler(DeInitableHandler(None, false), &[0xA1])
                      .map_err(|(_, e)| e).unwrap();
assert_eq!(ports.uninstall_handler(handler_id).and_then(|h| h.downcast().ok()),
           Some(Box::new(DeInitableHandler(Some(0xA1), true))));

assert!(ports.get_handler(handler_id).is_none());

pub fn read(&mut self, port: u8) -> u8[src]

Read from the specified port

If a handler is installed there, delegate thereto and cache the result

Marks the port read

Examples

struct PassthroughHandler;
impl PortHandler for PassthroughHandler {
    fn handle_read(&mut self, port: u8) -> u8 { port }
}

let mut ports = Ports::new();

ports.install_handler(PassthroughHandler, &[0xA1]).map_err(|(_, e)| e).unwrap();

assert_eq!(ports.read(0xBE), 0);
assert_eq!(ports.read(0xA1), 0xA1);

pub fn write(&mut self, port: u8, byte: u8)[src]

Write to the specified port

If a handler is installed there, delegate thereto

Caches the specified byte

Marks the port written

Examples

struct StorageHandler(u8);
impl PortHandler for StorageHandler {
    fn handle_read(&mut self, _: u8) -> u8 { self.0 * 2 }
    fn handle_write(&mut self, _: u8, data: u8) { self.0 = data; }
}

let mut ports = Ports::new();

let handler_id = ports.install_handler(StorageHandler(3), &[0xA1])
                      .map_err(|(_, e)| e).unwrap();

assert_eq!(ports.read(0xA1), 6);
ports.write(0xA1, 12);
assert_eq!(ports.read(0xA1), 24);

assert_eq!(ports.get_handler(handler_id).and_then(|h| h.downcast_ref()),
           Some(&StorageHandler(12)));

pub fn iter_rw(&self) -> PortsReadWrittenIterator[src]

Get an iterator over the read and written port cells

Examples

let mut ports = Ports::new();
let val = ports.read(0xA1);
ports.write(0x4B, val);
println!("{}", ports.read(0x4B));
ports.write(0xEB, 0x12);

// (address, value, was_read, was_written)
assert_eq!(ports.iter_rw().collect::<Vec<_>>(),
           &[(0x4B, 0x00, true, true),
             (0xA1, 0x00, true, false),
             (0xEB, 0x12, false, true)]);

pub fn reset_rw(&mut self)[src]

Mark all ports as unread and unwritten

Examples

let mut ports = Ports::new();
let val = ports.read(0xA1);
ports.write(0x4B, val);
println!("{}", ports.read(0x4B));
ports.write(0xEB, 0x12);

ports.reset_rw();
assert_eq!(ports.iter_rw().collect::<Vec<_>>(), &[]);

Trait Implementations

impl Debug for Ports[src]

impl Default for Ports[src]

impl Drop for Ports[src]

impl Eq for Ports[src]

impl Hash for Ports[src]

impl Index<Range<u8>> for Ports[src]

type Output = [u8]

The returned type after indexing.

impl Index<RangeFrom<u8>> for Ports[src]

type Output = [u8]

The returned type after indexing.

impl Index<RangeFull> for Ports[src]

type Output = [u8]

The returned type after indexing.

impl Index<RangeInclusive<u8>> for Ports[src]

type Output = [u8]

The returned type after indexing.

impl Index<RangeTo<u8>> for Ports[src]

type Output = [u8]

The returned type after indexing.

impl Index<RangeToInclusive<u8>> for Ports[src]

type Output = [u8]

The returned type after indexing.

impl IndexMut<Range<u8>> for Ports[src]

impl IndexMut<RangeFrom<u8>> for Ports[src]

impl IndexMut<RangeFull> for Ports[src]

impl IndexMut<RangeInclusive<u8>> for Ports[src]

impl IndexMut<RangeTo<u8>> for Ports[src]

impl IndexMut<RangeToInclusive<u8>> for Ports[src]

impl Ord for Ports[src]

impl PartialEq<[u8]> for Ports[src]

impl PartialEq<Ports> for Ports[src]

impl PartialOrd<Ports> for Ports[src]

Auto Trait Implementations

impl !RefUnwindSafe for Ports

impl !Send for Ports

impl !Sync for Ports

impl Unpin for Ports

impl !UnwindSafe for Ports

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Downcast for T where
    T: Any
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.