Advertisement
mdgaziur001

codename hammer vga writer

Aug 12th, 2022
1,582
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.68 KB | None | 0 0
  1. use crate::{serial_print, serial_println};
  2. use core::arch::asm;
  3. use core::fmt::Write;
  4. use lazy_static::lazy_static;
  5. use noto_sans_mono_bitmap::{get_bitmap, BitmapHeight, FontWeight};
  6. use spin::Mutex;
  7. use x86_64::instructions::interrupts::without_interrupts;
  8.  
  9. lazy_static! {
  10.     pub static ref WRITER: Mutex<VGATextWriter> = Mutex::new(VGATextWriter::uninit());
  11. }
  12.  
  13. pub struct VGATextWriter {
  14.     addr: usize,
  15.     height: usize,
  16.     width: usize,
  17.     pitch: usize,
  18.     bpp: usize,
  19.     pos_x: usize,
  20.     pos_y: usize,
  21. }
  22.  
  23. unsafe impl Send for VGATextWriter {}
  24.  
  25. impl VGATextWriter {
  26.     pub fn uninit() -> Self {
  27.         Self {
  28.             addr: 0,
  29.             height: 0,
  30.             width: 0,
  31.             pitch: 0,
  32.             bpp: 0,
  33.             pos_x: 0,
  34.             pos_y: 0,
  35.         }
  36.     }
  37.  
  38.     pub fn init(addr: usize, height: usize, width: usize, pitch: usize, bpp: usize) -> Self {
  39.         Self {
  40.             addr,
  41.             height,
  42.             width,
  43.             pitch,
  44.             bpp,
  45.             pos_x: 0,
  46.             pos_y: 0,
  47.         }
  48.     }
  49.  
  50.     fn draw_white_pixel(&self) {
  51.         let pixel = self.addr + self.pos_y * self.pitch + self.pos_x * (self.bpp / 8);
  52.  
  53.         self.draw_pixel(pixel, 255, 255, 255);
  54.     }
  55.  
  56.     pub fn draw_pixel(&self, pixel: usize, r: u8, g: u8, b: u8) {
  57.         assert_ne!(self.addr, 0);
  58.  
  59.         let pixel_addr = pixel as *mut u8;
  60.         unsafe {
  61.             *pixel_addr = r;
  62.             *pixel_addr.offset(1) = g;
  63.             *pixel_addr.offset(2) = b;
  64.         }
  65.     }
  66. }
  67.  
  68. impl Write for VGATextWriter {
  69.     fn write_str(&mut self, s: &str) -> core::fmt::Result {
  70.         if self.addr == 0 {
  71.             // When paging isn't yet done
  72.             return Ok(());
  73.         }
  74.  
  75.         for ch in s.chars() {
  76.             let mut backup_pos_y = self.pos_y;
  77.             let bitmap_char = get_bitmap(ch, FontWeight::Light, BitmapHeight::Size18)
  78.                 .unwrap_or(get_bitmap('?', FontWeight::Light, BitmapHeight::Size18).unwrap());
  79.  
  80.             let bitmap = bitmap_char.bitmap();
  81.  
  82.             if ch == '\n' {
  83.                 self.pos_x = 0;
  84.                 self.pos_y += bitmap_char.height();
  85.                 return Ok(());
  86.             }
  87.             if self.pos_x + bitmap_char.width() >= self.width {
  88.                 self.pos_x = 0;
  89.                 self.pos_y += bitmap_char.height();
  90.                 backup_pos_y = self.pos_y;
  91.             }
  92.             for y in 0..bitmap_char.height() {
  93.                 let line = bitmap[y];
  94.  
  95.                 let pos_x_backup = self.pos_x;
  96.                 for x in 0..bitmap_char.width() {
  97.                     let bit = line[x];
  98.  
  99.                     // do not support font weight for now
  100.                     if bit != 0 {
  101.                         self.draw_white_pixel();
  102.                     }
  103.  
  104.                     self.pos_x += 1;
  105.                 }
  106.  
  107.                 self.pos_x = pos_x_backup;
  108.                 self.pos_y += 1;
  109.             }
  110.  
  111.             self.pos_y = backup_pos_y;
  112.             self.pos_x += bitmap_char.width();
  113.             if self.pos_x >= self.width {
  114.                 self.pos_x = 0;
  115.                 self.pos_y += bitmap_char.height();
  116.             }
  117.         }
  118.  
  119.         Ok(())
  120.     }
  121. }
  122.  
  123. #[doc(hidden)]
  124. pub fn print(args: core::fmt::Arguments) {
  125.     without_interrupts(|| WRITER.lock().write_fmt(args).unwrap());
  126. }
  127.  
  128. #[macro_export]
  129. macro_rules! vprintln {
  130.     () => (vprint!("\n"));
  131.     ($fmt:expr) => (vprint!(concat!($fmt, "\n")));
  132.     ($fmt:expr, $($arg:tt)*) => (vprint!(concat!($fmt, "\n"), $($arg)*));
  133. }
  134.  
  135. #[macro_export]
  136. macro_rules! vprint {
  137.     ($($arg:tt)*) => ({
  138.         $crate::vga::print(format_args!($($arg)*));
  139.     });
  140. }
  141.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement