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
50
51
52
use core;
use core::fmt::Write;

use arch::x86::io::{inb, outb};

pub struct Uart {
    ioaddr: u16
}

impl Uart {
    pub unsafe fn new(ioaddr: u16) -> Uart {
        outb(ioaddr + 1, 0);    // Disable interrupts
        // Set baud rate divisor to 1 (115200 baud)
        outb(ioaddr + 3, 0x80);
        outb(ioaddr, 1);
        outb(ioaddr + 1, 0);
        // 8n1
        outb(ioaddr + 3, 3);
        // Clear FIFOs and enable
        outb(ioaddr + 2, 0xC7);

        Uart { ioaddr: ioaddr }
    }

    pub fn data_available(&self) -> bool {
        (inb(self.ioaddr + 5) & 1) != 0
    }

    pub fn read(&self) -> u8 {
        assert!(self.data_available());
        inb(self.ioaddr)
    }

    pub fn tx_ready(&self) -> bool {
        (inb(self.ioaddr + 5) & 0x20) != 0
    }

    pub fn write(&self, x: u8) {
        assert!(self.tx_ready());
        outb(self.ioaddr, x);
    }
}

impl Write for Uart {
    fn write_str(&mut self, s: &str) -> core::fmt::Result {
        for c in s.chars() {
            while !self.tx_ready() { }
            self.write(c as u8);
        }
        Ok(())
    }
}