From 30ca73458b6e1e7f80b5f3a08c14824abd1bcaa5 Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Fri, 17 Sep 2021 21:29:33 -0500 Subject: [PATCH] Document code --- src/interrupts.rs | 9 ++++++--- src/main.rs | 1 + src/shell.rs | 3 +++ src/vga_buffer.rs | 30 +++++++++++++++++------------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/interrupts.rs b/src/interrupts.rs index fa5e501..4bd3a80 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -54,7 +54,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac } let mut keyboard = KEYBOARD.lock(); - let mut port = Port::new(0x60); + let mut port = Port::new(0x60); // PS/2 Keyboard Address let scancode: u8 = unsafe { port.read() }; if let Ok(Some(key_event)) = keyboard.add_byte(scancode) { @@ -69,11 +69,13 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac use arrayvec::ArrayString; let writer = crate::vga_buffer::WRITER.lock(); + // Gather all chars in the current row into one ArrayString let mut builder = ArrayString::<80>::new(); for character in &writer.buffer.chars[crate::vga_buffer::BUFFER_HEIGHT - 1] { builder.push(character.read().ascii_character as char); } + // We can be sure that we have the writer lock so we can safely call this method unsafe { crate::vga_buffer::WRITER.force_unlock(); } @@ -90,12 +92,12 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac }, DecodedKey::RawKey(key) => { match key { - // TODO KeyCode::ArrowLeft => { let mut writer = crate::vga_buffer::WRITER.lock(); let col = writer.column_position; let row = crate::vga_buffer::BUFFER_HEIGHT - 1; + // Barrier for the prompt if col != 4 { crate::vga_buffer::move_cursor((col as u16) - 1, row as u16); writer.column_position -= 1; @@ -106,10 +108,11 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac let col = writer.column_position; let row = crate::vga_buffer::BUFFER_HEIGHT - 1; + // We don't need a barrier here because if the cursor reaches the end of the line then the VGA buffer stops it automatically crate::vga_buffer::move_cursor((col as u16) + 1, row as u16); writer.column_position += 1; }, - _ => {} + _ => {} // Ignore all other special keys } }, } diff --git a/src/main.rs b/src/main.rs index 0eff33a..a1c33dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,7 @@ pub extern "C" fn _start() { test_main(); loop { + // Halt CPU so that usage isn't 100% all the time x86_64::instructions::hlt(); } } diff --git a/src/shell.rs b/src/shell.rs index bf87122..b1a0ffa 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -51,6 +51,7 @@ fn info(_arguments: &[&str]) { } fn echo(arguments: &[&str]) { + // Join the arguments back into an ArrayString let mut new: ArrayString<80> = ArrayString::new(); for arg in &arguments[1..] { new.push_str(arg); @@ -64,6 +65,8 @@ fn shutdown(_arguments: &[&str]) { use x86_64::instructions::port::Port; println!("KarxOS shutting down!"); + // QEMU shutdown hack + // TODO: acpi shutdown let mut shutdown_port: Port = Port::new(0x604); unsafe { shutdown_port.write(0x2000); diff --git a/src/vga_buffer.rs b/src/vga_buffer.rs index 55bc595..6b6c44f 100644 --- a/src/vga_buffer.rs +++ b/src/vga_buffer.rs @@ -43,12 +43,13 @@ pub struct ScreenChar { pub(crate) color_code: ColorCode } +// This is characters, not pixels pub(crate) const BUFFER_HEIGHT: usize = 25; pub(crate) const BUFFER_WIDTH: usize = 80; #[repr(transparent)] pub struct Buffer { - pub chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT] + pub chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT] // Use Volatile for futureproofing reads/writes } pub struct Writer { @@ -63,19 +64,17 @@ impl Writer { match byte { b'\n' => self.new_line(), byte => { - if self.column_position >= BUFFER_WIDTH { - self.new_line(); + if self.column_position < BUFFER_WIDTH { + let row = BUFFER_HEIGHT - 1; + let col = self.column_position; + + let color_code = self.color_code; + self.buffer.chars[row][col].write(ScreenChar { + ascii_character: byte, + color_code + }); + self.column_position += 1; } - - let row = BUFFER_HEIGHT - 1; - let col = self.column_position; - - let color_code = self.color_code; - self.buffer.chars[row][col].write(ScreenChar { - ascii_character: byte, - color_code - }); - self.column_position += 1; } } } @@ -83,6 +82,7 @@ impl Writer { pub fn write_string(&mut self, s: &str) { for byte in s.bytes() { match byte { + // Only write printable ASCII characters 0x20..=0x7e | b'\n' => self.write_byte(byte), _ => self.write_byte(0xfe) @@ -91,6 +91,7 @@ impl Writer { } fn new_line(&mut self) { + // Move all the rows up for row in 1..BUFFER_HEIGHT { for col in 0..BUFFER_WIDTH { let character = self.buffer.chars[row][col].read(); @@ -98,6 +99,7 @@ impl Writer { } } + // Clear top row self.clear_row(BUFFER_HEIGHT - 1); self.column_position = 0; } @@ -146,6 +148,7 @@ pub fn _print(args: fmt::Arguments) { use core::fmt::Write; use x86_64::instructions::interrupts; + // Turn off interrupts to avoid a deadlock interrupts::without_interrupts(|| { WRITER.lock().write_fmt(args).unwrap(); }); @@ -157,6 +160,7 @@ pub fn backspace() { let row = BUFFER_HEIGHT - 1; let col = writer.column_position; let color_code = writer.color_code; + // Barrier for prompt if col != 4 { writer.buffer.chars[row][col - 1].write(ScreenChar { ascii_character: b' ',