1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! Serial device driver.
use crate::x86_64::pio::Pio;

/// Initialize a serial.
pub unsafe fn init() {
    Pio::new(0x3f8 + 2).write_u8(0);
    Pio::new(0x3f8 + 3).write_u8(0x80);
    Pio::new(0x3f8).write_u8((115200 / 9600) as u8);
    Pio::new(0x3f8 + 1).write_u8(0);
    Pio::new(0x3f8 + 3).write_u8(0x3 & !0x80);
    Pio::new(0x3f8 + 4).write_u8(0);
    Pio::new(0x3f8 + 1).write_u8(1);
    Pio::new(0x3f8 + 2).read_u8();
    Pio::new(0x3f8).read_u8();
}

pub(crate) fn write_str(s: &str) {
    for b in s.as_bytes() {
        for _ in 0..12800 {
            if Pio::new(0x3f8 + 5).read_u8() & 0x20 != 0 {
                break;
            }
            // delay
            Pio::new(0x84).read_u8();
            Pio::new(0x84).read_u8();
            Pio::new(0x84).read_u8();
            Pio::new(0x84).read_u8();
        }
        Pio::new(0x3f8).write_u8(*b);
    }
}

pub struct Serial {
    _p: (),
}

impl Serial {
    /// Create a new serial device interface.
    pub const fn new() -> Self {
        Serial { _p: () }
    }
}

impl core::fmt::Write for Serial {
    fn write_str(&mut self, s: &str) -> core::fmt::Result {
        write_str(s);
        Ok(())
    }
}