]> git.lizzy.rs Git - loadnothing.git/commitdiff
Start VGA API
authorHimbeerserverDE <himbeerserverde@gmail.com>
Sun, 18 Sep 2022 14:39:13 +0000 (16:39 +0200)
committerHimbeerserverDE <himbeerserverde@gmail.com>
Sun, 18 Sep 2022 14:39:13 +0000 (16:39 +0200)
stage2/src/main.rs
stage2/src/vga.rs [new file with mode: 0644]

index 33e691cb47320141c986e02a2359f640fc8d6f36..4894afbeca33e0cb1d1f45b0bfce158a512baae4 100644 (file)
@@ -3,12 +3,11 @@
 
 #![warn(clippy::arithmetic)]
 
+mod vga;
+
 use core::arch::asm;
-use core::ops::{Add, Mul};
 use core::panic::PanicInfo;
 
-static HELLO: &[u8] = b"Hello Stage2!";
-
 #[panic_handler]
 fn panic(_info: &PanicInfo) -> ! {
     loop {}
@@ -16,24 +15,7 @@ fn panic(_info: &PanicInfo) -> ! {
 
 #[no_mangle]
 pub extern "C" fn _start() -> ! {
-    let vga_buffer = 0xb8000 as *mut u8;
-    let vga_max = 0xf9e;
-
-    // Clear the screen
-    for i in 0..vga_max {
-        unsafe {
-            *vga_buffer.offset((i as isize).mul(2)) = 0x00;
-            *vga_buffer.offset((i as isize).mul(2).add(1)) = 0x07;
-        }
-    }
-
-    // Print welcome message
-    for (i, &byte) in HELLO.iter().enumerate() {
-        unsafe {
-            *vga_buffer.offset((i as isize).mul(2)) = byte;
-            *vga_buffer.offset((i as isize).mul(2).add(1)) = 0x07;
-        }
-    }
+    vga::test_print();
 
     unsafe {
         loop {
diff --git a/stage2/src/vga.rs b/stage2/src/vga.rs
new file mode 100644 (file)
index 0000000..d052724
--- /dev/null
@@ -0,0 +1,105 @@
+use core::ops::{AddAssign, Shl};
+
+#[allow(dead_code)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(u8)]
+pub enum Color {
+    Black = 0,
+    Blue = 1,
+    Green = 2,
+    Cyan = 3,
+    Red = 4,
+    Magenta = 5,
+    Brown = 6,
+    LightGray = 7,
+    DarkGray = 8,
+    LightBlue = 9,
+    LightGreen = 10,
+    LightCyan = 11,
+    LightRed = 12,
+    Pink = 13,
+    Yellow = 14,
+    White = 15,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(transparent)]
+pub struct ColorCode(u8);
+
+impl ColorCode {
+    pub fn new(foreground: Color, background: Color) -> ColorCode {
+        ColorCode((background as u8).shl(4) | (foreground as u8))
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(C)]
+struct ScreenChar {
+    ascii_character: u8,
+    color_code: ColorCode,
+}
+
+const BUFFER_WIDTH: usize = 80;
+const BUFFER_HEIGHT: usize = 25;
+
+#[repr(transparent)]
+struct Buffer {
+    chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
+}
+
+pub struct Writer {
+    row_position: usize,
+    column_position: usize,
+    color_code: ColorCode,
+    buffer: &'static mut Buffer,
+}
+
+impl Writer {
+    pub fn write_byte(&mut self, byte: u8) {
+        match byte {
+            b'\n' => self.new_line(),
+            byte => {
+                if self.column_position >= BUFFER_WIDTH {
+                    self.new_line();
+                }
+
+                let row = self.row_position;
+                let col = self.column_position;
+
+                let color_code = self.color_code;
+                self.buffer.chars[row][col] = ScreenChar {
+                    ascii_character: byte,
+                    color_code,
+                };
+
+                self.column_position.add_assign(1);
+            },
+        }
+    }
+
+    pub fn write_string(&mut self, s: &str) {
+        for byte in s.bytes() {
+            match byte {
+                // Printable ASCII character or \n
+                0x20..=0x7e | b'\n' => self.write_byte(byte),
+                // Not printable, write error char instead
+                _ => self.write_byte(0xfe),
+            }
+        }
+    }
+
+    fn new_line(&mut self) {
+
+    }
+}
+
+pub fn test_print() {
+    let mut writer = Writer {
+        row_position: 1,
+        column_position: 0,
+        color_code: ColorCode::new(Color::Yellow, Color::Black),
+        buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
+    };
+
+    writer.write_string("Hello Stage2!");
+}