1use core::{arch::asm, marker::PhantomData};
2
3use super::io::Io;
4
5#[derive(Copy, Clone)]
7pub struct Pio<T> {
8 port: u16,
9 value: PhantomData<T>,
10}
11
12impl<T> Pio<T> {
13 pub const fn new(port: u16) -> Self {
15 Pio::<T> {
16 port,
17 value: PhantomData,
18 }
19 }
20}
21
22impl Io for Pio<u8> {
24 type Value = u8;
25
26 #[inline(always)]
28 fn read(&self) -> u8 {
29 let value: u8;
30 unsafe {
31 asm!("in al, dx", in("dx") self.port, out("al") value, options(nostack, nomem, preserves_flags));
32 }
33 value
34 }
35
36 #[inline(always)]
38 fn write(&mut self, value: u8) {
39 unsafe {
40 asm!("out dx, al", in("dx") self.port, in("al") value, options(nostack, nomem, preserves_flags));
41 }
42 }
43}
44
45impl Io for Pio<u16> {
47 type Value = u16;
48
49 #[inline(always)]
51 fn read(&self) -> u16 {
52 let value: u16;
53 unsafe {
54 asm!("in ax, dx", in("dx") self.port, out("ax") value, options(nostack, nomem, preserves_flags));
55 }
56 value
57 }
58
59 #[inline(always)]
61 fn write(&mut self, value: u16) {
62 unsafe {
63 asm!("out dx, ax", in("dx") self.port, in("ax") value, options(nostack, nomem, preserves_flags));
64 }
65 }
66}
67
68impl Io for Pio<u32> {
70 type Value = u32;
71
72 #[inline(always)]
74 fn read(&self) -> u32 {
75 let value: u32;
76 unsafe {
77 asm!("in eax, dx", in("dx") self.port, out("eax") value, options(nostack, nomem, preserves_flags));
78 }
79 value
80 }
81
82 #[inline(always)]
84 fn write(&mut self, value: u32) {
85 unsafe {
86 asm!("out dx, eax", in("dx") self.port, in("eax") value, options(nostack, nomem, preserves_flags));
87 }
88 }
89}