Skip to main content

game_toolkit_dosbus/
signal.rs

1/// An ISA interrupt request line, IRQ 0 through IRQ 15.
2///
3/// Includes IRQ 2, the AT cascade line; machine-specific reservations belong to
4/// the host's interrupt controller.
5#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
6pub struct IrqLine(u8);
7
8impl IrqLine {
9    /// Validate a physical IRQ line number.
10    pub const fn new(line: u8) -> Option<Self> {
11        if line < 16 { Some(Self(line)) } else { None }
12    }
13
14    /// Physical IRQ line number.
15    pub const fn number(self) -> u8 {
16        self.0
17    }
18}
19
20/// The current level driven by a device on an IRQ line.
21///
22/// Repeated observation is not acknowledgement. The host's PIC decides how a
23/// level becomes an interrupt; the device's own I/O protocol clears its source.
24#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
25pub struct IrqRequest {
26    /// The configured interrupt line.
27    pub line: IrqLine,
28    /// Whether the device is currently asserting the line.
29    pub asserted: bool,
30}
31
32/// Width of one ISA DMA transfer unit.
33#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
34pub enum DmaWidth {
35    /// An 8-bit transfer on channels 0 through 3.
36    Byte,
37    /// A 16-bit transfer on channels 5 through 7.
38    Word,
39}
40
41/// An ISA DMA data channel: 0 through 3 or 5 through 7.
42///
43/// Channel 4 cascades the two AT DMA controllers and cannot transfer device data.
44#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
45pub struct DmaChannel(u8);
46
47impl DmaChannel {
48    /// Validate a DMA data channel, excluding the cascade channel.
49    pub const fn new(channel: u8) -> Option<Self> {
50        match channel {
51            0..=3 | 5..=7 => Some(Self(channel)),
52            _ => None,
53        }
54    }
55
56    /// Physical DMA channel number.
57    pub const fn number(self) -> u8 {
58        self.0
59    }
60
61    /// Width implied by the selected channel.
62    pub const fn width(self) -> DmaWidth {
63        if self.0 < 4 {
64            DmaWidth::Byte
65        } else {
66            DmaWidth::Word
67        }
68    }
69}
70
71/// Direction of a DMA transfer, named from the device's perspective.
72#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
73pub enum DmaDirection {
74    /// The controller reads memory and delivers data to the device.
75    MemoryToDevice,
76    /// The controller reads the device and writes data to memory.
77    DeviceToMemory,
78}
79
80/// An asserted DMA request (DRQ), without a memory address or transfer count.
81///
82/// The host's DMA controller owns address, count, page wrapping, masking and
83/// terminal-count behavior. This descriptor only reports the device's request;
84/// it neither performs nor acknowledges a transfer.
85#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
86pub struct DmaRequest {
87    /// DMA channel configured for this device.
88    pub channel: DmaChannel,
89    /// Whether data flows into or out of the device.
90    pub direction: DmaDirection,
91}