From: HimbeerserverDE Date: Sun, 18 Sep 2022 14:39:13 +0000 (+0200) Subject: Start VGA API X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=31ab03368a7bcace88b21b174f033983b8f0a6d7;p=loadnothing.git Start VGA API --- diff --git a/stage2/src/main.rs b/stage2/src/main.rs index 33e691c..4894afb 100644 --- a/stage2/src/main.rs +++ b/stage2/src/main.rs @@ -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 index 0000000..d052724 --- /dev/null +++ b/stage2/src/vga.rs @@ -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!"); +}