]> git.lizzy.rs Git - loadnothing.git/blobdiff - stage2/src/vga.rs
Unbreak again
[loadnothing.git] / stage2 / src / vga.rs
index d0527246245bdf33903714e6cb717ac266c514a0..22499b79add55a6fe44342b791562f18e53489af 100644 (file)
@@ -1,4 +1,6 @@
-use core::ops::{AddAssign, Shl};
+use core::ops::{AddAssign, Deref, DerefMut, Shl, Sub};
+
+use volatile::Volatile;
 
 #[allow(dead_code)]
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -39,12 +41,26 @@ struct ScreenChar {
     color_code: ColorCode,
 }
 
+impl Deref for ScreenChar {
+    type Target = ScreenChar;
+
+    fn deref(&self) -> &Self::Target {
+        self
+    }
+}
+
+impl DerefMut for ScreenChar {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self
+    }
+}
+
 const BUFFER_WIDTH: usize = 80;
 const BUFFER_HEIGHT: usize = 25;
 
 #[repr(transparent)]
 struct Buffer {
-    chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
+    chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
 }
 
 pub struct Writer {
@@ -55,6 +71,7 @@ pub struct Writer {
 }
 
 impl Writer {
+    #[inline(always)]
     pub fn write_byte(&mut self, byte: u8) {
         match byte {
             b'\n' => self.new_line(),
@@ -67,16 +84,17 @@ impl Writer {
                 let col = self.column_position;
 
                 let color_code = self.color_code;
-                self.buffer.chars[row][col] = ScreenChar {
+                self.buffer.chars[row][col].write(ScreenChar {
                     ascii_character: byte,
                     color_code,
-                };
+                });
 
                 self.column_position.add_assign(1);
             },
         }
     }
 
+    #[inline(always)]
     pub fn write_string(&mut self, s: &str) {
         for byte in s.bytes() {
             match byte {
@@ -88,8 +106,32 @@ impl Writer {
         }
     }
 
+    #[inline(always)]
     fn new_line(&mut self) {
+        if self.row_position >= BUFFER_HEIGHT {
+            for row in 1..BUFFER_HEIGHT {
+                for col in 0..BUFFER_WIDTH {
+                    let character = self.buffer.chars[row][col].read();
+                    self.buffer.chars[row.sub(1)][col].write(character);
+                }
+            }
+
+            self.clear_row(BUFFER_HEIGHT.sub(1));
+        }
 
+        self.row_position.add_assign(1);
+        self.column_position = 0;
+    }
+
+    fn clear_row(&mut self, row: usize) {
+        let blank = ScreenChar {
+            ascii_character: b' ',
+            color_code: self.color_code,
+        };
+
+        for col in 0..BUFFER_WIDTH {
+            self.buffer.chars[row][col].write(blank);
+        }
     }
 }