use super::{Backend, RegisterAddress, private};
use core::arch::asm;
use core::num::NonZeroU8;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Hash)]
pub struct PortIoAddress(pub(crate) u16);
impl RegisterAddress for PortIoAddress {
#[inline(always)]
fn add_offset(self, offset: u8) -> Self {
let port = self.0 + offset as u16;
Self(port)
}
}
impl private::Sealed for PortIoAddress {}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Hash)]
pub struct PioBackend(pub(crate) PortIoAddress );
impl private::Sealed for PioBackend {}
impl Backend for PioBackend {
type Address = PortIoAddress;
#[inline(always)]
fn base(&self) -> Self::Address {
self.0
}
#[inline(always)]
fn stride(&self) -> NonZeroU8 {
NonZeroU8::new(1).unwrap()
}
#[inline(always)]
unsafe fn _read_register(&mut self, port: PortIoAddress) -> u8 {
unsafe {
let ret: u8;
asm!(
"inb %dx, %al",
in("dx") port.0,
out("al") ret,
options(att_syntax, nostack, preserves_flags)
);
ret
}
}
#[inline(always)]
unsafe fn _write_register(&mut self, port: PortIoAddress, value: u8) {
unsafe {
asm!(
"outb %al, %dx",
in("al") value,
in("dx") port.0,
options(att_syntax, nostack, preserves_flags)
);
}
}
}