use core::fmt; use core::fmt::Write; use lazy_static::lazy_static; use spin::Mutex; #[doc(hidden)] pub fn _print(args: fmt::Arguments) { WRITER.lock().write_fmt(args).unwrap(); } lazy_static! { pub static ref WRITER: Mutex = Mutex::new(Writer::new()); } #[derive(Default)] pub struct Writer { max_y: isize, max_x: isize, x: isize, y: isize, addr: u32, } impl Writer { pub fn new() -> Self { Self { x: 0, y: 0, max_y: 25, max_x: 80, addr: 0xb8000, } } pub fn write(&mut self, c: char, b: u8) { let off: isize = self.y * self.max_x + self.x; let vga_buffer = self.addr as *mut u8; if c != '\n' { unsafe { *vga_buffer.offset(2 * off) = c as u8; *vga_buffer.offset(2 * off + 1) = b; } self.x += 1; } else { self.x = 0; self.y += 1; } if self.x >= self.max_x { self.x = 0; self.y += 1; } if self.y >= self.max_y { self.y = 0; } } pub fn print(&mut self, s: &str, b: u8) { for i in s.chars() { self.write(i, b); } } } impl fmt::Write for Writer { fn write_str(&mut self, s: &str) -> fmt::Result { self.print(s, 0xb); Ok(()) } }