Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use crate::{serial_print, serial_println};
- use core::arch::asm;
- use core::fmt::Write;
- use lazy_static::lazy_static;
- use noto_sans_mono_bitmap::{get_bitmap, BitmapHeight, FontWeight};
- use spin::Mutex;
- use x86_64::instructions::interrupts::without_interrupts;
- lazy_static! {
- pub static ref WRITER: Mutex<VGATextWriter> = Mutex::new(VGATextWriter::uninit());
- }
- pub struct VGATextWriter {
- addr: usize,
- height: usize,
- width: usize,
- pitch: usize,
- bpp: usize,
- pos_x: usize,
- pos_y: usize,
- }
- unsafe impl Send for VGATextWriter {}
- impl VGATextWriter {
- pub fn uninit() -> Self {
- Self {
- addr: 0,
- height: 0,
- width: 0,
- pitch: 0,
- bpp: 0,
- pos_x: 0,
- pos_y: 0,
- }
- }
- pub fn init(addr: usize, height: usize, width: usize, pitch: usize, bpp: usize) -> Self {
- Self {
- addr,
- height,
- width,
- pitch,
- bpp,
- pos_x: 0,
- pos_y: 0,
- }
- }
- fn draw_white_pixel(&self) {
- let pixel = self.addr + self.pos_y * self.pitch + self.pos_x * (self.bpp / 8);
- self.draw_pixel(pixel, 255, 255, 255);
- }
- pub fn draw_pixel(&self, pixel: usize, r: u8, g: u8, b: u8) {
- assert_ne!(self.addr, 0);
- let pixel_addr = pixel as *mut u8;
- unsafe {
- *pixel_addr = r;
- *pixel_addr.offset(1) = g;
- *pixel_addr.offset(2) = b;
- }
- }
- }
- impl Write for VGATextWriter {
- fn write_str(&mut self, s: &str) -> core::fmt::Result {
- if self.addr == 0 {
- // When paging isn't yet done
- return Ok(());
- }
- for ch in s.chars() {
- let mut backup_pos_y = self.pos_y;
- let bitmap_char = get_bitmap(ch, FontWeight::Light, BitmapHeight::Size18)
- .unwrap_or(get_bitmap('?', FontWeight::Light, BitmapHeight::Size18).unwrap());
- let bitmap = bitmap_char.bitmap();
- if ch == '\n' {
- self.pos_x = 0;
- self.pos_y += bitmap_char.height();
- return Ok(());
- }
- if self.pos_x + bitmap_char.width() >= self.width {
- self.pos_x = 0;
- self.pos_y += bitmap_char.height();
- backup_pos_y = self.pos_y;
- }
- for y in 0..bitmap_char.height() {
- let line = bitmap[y];
- let pos_x_backup = self.pos_x;
- for x in 0..bitmap_char.width() {
- let bit = line[x];
- // do not support font weight for now
- if bit != 0 {
- self.draw_white_pixel();
- }
- self.pos_x += 1;
- }
- self.pos_x = pos_x_backup;
- self.pos_y += 1;
- }
- self.pos_y = backup_pos_y;
- self.pos_x += bitmap_char.width();
- if self.pos_x >= self.width {
- self.pos_x = 0;
- self.pos_y += bitmap_char.height();
- }
- }
- Ok(())
- }
- }
- #[doc(hidden)]
- pub fn print(args: core::fmt::Arguments) {
- without_interrupts(|| WRITER.lock().write_fmt(args).unwrap());
- }
- #[macro_export]
- macro_rules! vprintln {
- () => (vprint!("\n"));
- ($fmt:expr) => (vprint!(concat!($fmt, "\n")));
- ($fmt:expr, $($arg:tt)*) => (vprint!(concat!($fmt, "\n"), $($arg)*));
- }
- #[macro_export]
- macro_rules! vprint {
- ($($arg:tt)*) => ({
- $crate::vga::print(format_args!($($arg)*));
- });
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement