vga helper
parent
eb197c3122
commit
161df47dd5
@ -0,0 +1,84 @@
|
||||
use core::{fmt, ptr};
|
||||
|
||||
const VGA_WIDTH: usize = 80;
|
||||
const VGA_HEIGHT: usize = 25;
|
||||
|
||||
const COLOUR_MASK: u16 = 0x0a00;
|
||||
|
||||
pub struct VgaBuf {
|
||||
buf: *mut u16,
|
||||
col: usize,
|
||||
row: usize,
|
||||
}
|
||||
|
||||
impl VgaBuf {
|
||||
pub unsafe fn new(buf: *mut u16) -> Self {
|
||||
Self { buf, col: 0, row: 0 }
|
||||
}
|
||||
|
||||
pub fn vga_write_str(&mut self, s: &str) {
|
||||
for c in s.chars() {
|
||||
self.vga_write_char(c);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vga_write_char(&mut self, c: char) {
|
||||
let newline = c == '\n';
|
||||
|
||||
if newline || self.col >= VGA_WIDTH {
|
||||
self.col = 0;
|
||||
self.row += 1;
|
||||
}
|
||||
|
||||
if self.row >= VGA_HEIGHT {
|
||||
self.scroll();
|
||||
self.row -= 1;
|
||||
}
|
||||
|
||||
if !newline {
|
||||
self.vga_write_char_at(c, self.col, self.row);
|
||||
self.col += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vga_write_ascii_char_at(&mut self, c: u8, col: usize, row: usize) {
|
||||
let vga_val = COLOUR_MASK | u16::from(c);
|
||||
|
||||
if col < VGA_WIDTH && row < VGA_HEIGHT {
|
||||
unsafe {
|
||||
self.coord_ptr(col, row)
|
||||
.write_volatile(vga_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vga_write_char_at(&mut self, c: char, col: usize, row: usize) {
|
||||
let c = u8::try_from(c).unwrap_or(0xfe);
|
||||
self.vga_write_ascii_char_at(c, col, row);
|
||||
}
|
||||
|
||||
fn scroll(&mut self) {
|
||||
unsafe {
|
||||
ptr::copy(
|
||||
self.coord_ptr(0, 1),
|
||||
self.coord_ptr(0, 0),
|
||||
VGA_WIDTH * (VGA_HEIGHT - 1)
|
||||
);
|
||||
|
||||
for col in 0..VGA_WIDTH {
|
||||
self.vga_write_ascii_char_at(0, col, VGA_HEIGHT - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn coord_ptr(&self, col: usize, row: usize) -> *mut u16 {
|
||||
unsafe { self.buf.add((row * VGA_WIDTH) + col) }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for VgaBuf {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.vga_write_str(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue