#![no_std]
extern crate inout_port_rs;
extern crate vgainfo_rs;
#[derive(Copy, Clone)]
#[repr(C, packed)]
struct __LowHigh {
l: u8,
h: u8,
}
#[derive(Copy, Clone)]
union __Cursor {
value: u16,
lh: __LowHigh,
}
fn set_cursor(y: usize, x: usize) {
let cursor = __Cursor {
value: (y * vgainfo_rs::WIDTH + x) as u16,
};
unsafe {
inout_port_rs::outb(0xe, 0x3d4);
inout_port_rs::outb(cursor.lh.h, 0x3d5);
inout_port_rs::outb(0xf, 0x3d4);
inout_port_rs::outb(cursor.lh.l, 0x3d5);
}
}
fn get_cursor() -> (usize, usize) {
let low: u8;
let high: u8;
unsafe {
inout_port_rs::outb(0xe, 0x3d4);
high = inout_port_rs::inb(0x3d5);
inout_port_rs::outb(0xf, 0x3d4);
low = inout_port_rs::inb(0x3d5);
}
let cursor = __Cursor {
lh: __LowHigh { l: low, h: high },
};
let value = unsafe { cursor.value } as usize;
let y = value / vgainfo_rs::WIDTH;
let x = value % vgainfo_rs::WIDTH;
(y, x)
}
pub struct VgaCursor {}
impl VgaCursor {
#[inline]
pub const fn new() -> Self {
Self {}
}
}
pub trait VgaCurSorHal {
fn set(&mut self, y: usize, x: usize);
fn get(&self) -> (usize, usize);
}
impl VgaCurSorHal for VgaCursor {
#[inline]
fn set(&mut self, y: usize, x: usize) {
set_cursor(y, x);
}
#[inline]
fn get(&self) -> (usize, usize) {
get_cursor()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn __cursor_works() {
let lh = __LowHigh { l: 1, h: 1 };
let cursor = __Cursor { lh: lh };
assert_eq!(unsafe { cursor.value }, (1u16 << 8) | (1u16 << 0));
}
#[test]
fn __usize_as_u16_works() {
let width = vgainfo_rs::WIDTH;
let high = vgainfo_rs::HIGH;
let width_u16 = width as u16;
let high_u16 = high as u16;
assert_eq!((width, high), (width_u16 as usize, high_u16 as usize));
}
}