1use bit_field::BitField;
2use core::{
3 convert::TryFrom,
4 fmt::{self, Debug, Formatter},
5};
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub enum DevselTiming {
11 Fast = 0x0,
12 Medium = 0x1,
13 Slow = 0x2,
14}
15
16#[derive(Debug)]
17pub struct TryFromDevselTimingError {
18 number: u8,
19}
20
21impl fmt::Display for TryFromDevselTimingError {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 write!(f, "No discriminant in `DevselTiming` matches the value `{}`", self.number)
24 }
25}
26
27impl TryFrom<u8> for DevselTiming {
28 type Error = TryFromDevselTimingError;
29
30 fn try_from(value: u8) -> Result<Self, Self::Error> {
31 match value {
32 0x0 => Ok(DevselTiming::Fast),
33 0x1 => Ok(DevselTiming::Medium),
34 0x2 => Ok(DevselTiming::Slow),
35 number => Err(TryFromDevselTimingError { number }),
36 }
37 }
38}
39
40#[derive(Clone, Copy, Eq, PartialEq)]
41pub struct StatusRegister(u16);
42
43impl StatusRegister {
44 pub fn new(value: u16) -> Self {
45 StatusRegister(value)
46 }
47
48 pub fn parity_error_detected(&self) -> bool {
50 self.0.get_bit(15)
51 }
52
53 pub fn signalled_system_error(&self) -> bool {
55 self.0.get_bit(14)
56 }
57
58 pub fn received_master_abort(&self) -> bool {
61 self.0.get_bit(13)
62 }
63
64 pub fn received_target_abort(&self) -> bool {
66 self.0.get_bit(12)
67 }
68
69 pub fn signalled_target_abort(&self) -> bool {
71 self.0.get_bit(11)
72 }
73
74 pub fn devsel_timing(&self) -> Result<DevselTiming, TryFromDevselTimingError> {
79 let bits = self.0.get_bits(9..11);
80 DevselTiming::try_from(bits as u8)
81 }
82
83 pub fn master_data_parity_error(&self) -> bool {
88 self.0.get_bit(8)
89 }
90
91 pub fn fast_back_to_back_capable(&self) -> bool {
96 self.0.get_bit(7)
97 }
98
99 pub fn capable_66mhz(&self) -> bool {
103 self.0.get_bit(5)
104 }
105
106 pub fn has_capability_list(&self) -> bool {
111 self.0.get_bit(4)
112 }
113
114 pub fn interrupt_status(&self) -> bool {
118 self.0.get_bit(3)
119 }
120}
121
122impl Debug for StatusRegister {
123 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
124 f.debug_struct("StatusRegister")
125 .field("parity_error_detected", &self.parity_error_detected())
126 .field("signalled_system_error", &self.signalled_system_error())
127 .field("received_master_abort", &self.received_master_abort())
128 .field("received_target_abort", &self.received_target_abort())
129 .field("signalled_target_abort", &self.signalled_target_abort())
130 .field("devsel_timing", &self.devsel_timing())
131 .field("master_data_parity_error", &self.master_data_parity_error())
132 .field("fast_back_to_back_capable", &self.fast_back_to_back_capable())
133 .field("capable_66mhz", &self.capable_66mhz())
134 .field("has_capability_list", &self.has_capability_list())
135 .field("interrupt_status", &self.interrupt_status())
136 .finish()
137 }
138}
139
140bitflags::bitflags! {
141 #[repr(transparent)]
142 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
143 pub struct CommandRegister: u16 {
144 const IO_ENABLE = 1 << 0;
145 const MEMORY_ENABLE = 1 << 1;
146 const BUS_MASTER_ENABLE = 1 << 2;
147 const SPECIAL_CYCLE_ENABLE = 1 << 3;
148 const MEMORY_WRITE_AND_INVALIDATE = 1 << 4;
149 const VGA_PALETTE_SNOOP = 1 << 5;
150 const PARITY_ERROR_RESPONSE = 1 << 6;
151 const IDSEL_STEP_WAIT_CYCLE_CONTROL = 1 << 7;
152 const SERR_ENABLE = 1 << 8;
153 const FAST_BACK_TO_BACK_ENABLE = 1 << 9;
154 const INTERRUPT_DISABLE = 1 << 10;
155 const _ = !0;
156 }
157}