From e9660fbc767f7641e417ebc3471d876eee217ee5 Mon Sep 17 00:00:00 2001 From: Conzer Date: Tue, 3 Dec 2024 16:16:06 -0500 Subject: [PATCH] make println! --- Cargo.lock | 30 ++++++++++++++++++++++ Cargo.toml | 6 +++++ src/main.rs | 4 +-- src/vga_buffer.rs | 63 +++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34cc842..bb298fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,4 +13,34 @@ name = "donald" version = "0.1.0" dependencies = [ "bootloader", + "lazy_static", + "spin 0.5.2", + "volatile", ] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "volatile" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b06ad3ed06fef1713569d547cdbdb439eafed76341820fb0e0344f29a41945" diff --git a/Cargo.toml b/Cargo.toml index bb00d9f..3b7fe70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,9 @@ build-std = ["core", "compiler_builtins"] [dependencies] bootloader = "0.9" +volatile = "0.2.6" +spin = "0.5.2" + +[dependencies.lazy_static] +version = "1.0" +features = ["spin_no_std"] diff --git a/src/main.rs b/src/main.rs index 6bd4c83..38ed1e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,11 +9,11 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -static HELLO: &[u8] = b"Hello World!"; #[no_mangle] pub extern "C" fn _start() -> ! { - vga_buffer::print_something(); + println!("Hello World!"); + loop {} } diff --git a/src/vga_buffer.rs b/src/vga_buffer.rs index be682f0..8a44798 100644 --- a/src/vga_buffer.rs +++ b/src/vga_buffer.rs @@ -1,5 +1,15 @@ // Handles VGA text printing +use volatile::Volatile; +use core::fmt; + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.write_string(s); + Ok(()) + } +} + #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] @@ -44,7 +54,7 @@ const BUFFER_WIDTH: usize = 80; #[repr(transparent)] struct Buffer { - chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT], + chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT], } pub struct Writer { @@ -66,10 +76,10 @@ 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 += 1; } } @@ -85,17 +95,50 @@ impl Writer { } } - fn new_line(&mut self) {/*TODO */} + fn new_line(&mut self) { + for row in 1..BUFFER_HEIGHT { + for col in 0..BUFFER_WIDTH { + let character = self.buffer.chars[row][col].read(); + self.buffer.chars[row - 1][col].write(character); + } + } + self.clear_row(BUFFER_HEIGHT - 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); + } + } } -pub fn print_something() { - let mut writer = Writer { +use lazy_static::lazy_static; +use spin::Mutex; +lazy_static! { + pub static ref WRITER: Mutex = Mutex::new(Writer { column_position: 0, color_code: ColorCode::new(Color::Yellow, Color::Black), buffer: unsafe { &mut *(0xb8000 as *mut Buffer) }, - }; + }); +} - writer.write_byte(b'H'); - writer.write_string("ello "); - writer.write_string("World!") +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::vga_buffer::_print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + () => ($crate::print!("\n")); + ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); +} + +#[doc(hidden)] +pub fn _print(args: fmt::Arguments) { + use core::fmt::Write; + WRITER.lock().write_fmt(args).unwrap(); } \ No newline at end of file