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