Document code

This commit is contained in:
Yash Karandikar 2021-09-17 21:29:33 -05:00
parent c201ddd35a
commit 30ca73458b
Signed by: karx
GPG key ID: A794DA2529474BA5
4 changed files with 27 additions and 16 deletions

View file

@ -54,7 +54,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
} }
let mut keyboard = KEYBOARD.lock(); 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() }; let scancode: u8 = unsafe { port.read() };
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) { 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; use arrayvec::ArrayString;
let writer = crate::vga_buffer::WRITER.lock(); let writer = crate::vga_buffer::WRITER.lock();
// Gather all chars in the current row into one ArrayString
let mut builder = ArrayString::<80>::new(); let mut builder = ArrayString::<80>::new();
for character in &writer.buffer.chars[crate::vga_buffer::BUFFER_HEIGHT - 1] { for character in &writer.buffer.chars[crate::vga_buffer::BUFFER_HEIGHT - 1] {
builder.push(character.read().ascii_character as char); 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 { unsafe {
crate::vga_buffer::WRITER.force_unlock(); crate::vga_buffer::WRITER.force_unlock();
} }
@ -90,12 +92,12 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
}, },
DecodedKey::RawKey(key) => { DecodedKey::RawKey(key) => {
match key { match key {
// TODO
KeyCode::ArrowLeft => { KeyCode::ArrowLeft => {
let mut writer = crate::vga_buffer::WRITER.lock(); let mut writer = crate::vga_buffer::WRITER.lock();
let col = writer.column_position; let col = writer.column_position;
let row = crate::vga_buffer::BUFFER_HEIGHT - 1; let row = crate::vga_buffer::BUFFER_HEIGHT - 1;
// Barrier for the prompt
if col != 4 { if col != 4 {
crate::vga_buffer::move_cursor((col as u16) - 1, row as u16); crate::vga_buffer::move_cursor((col as u16) - 1, row as u16);
writer.column_position -= 1; writer.column_position -= 1;
@ -106,10 +108,11 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
let col = writer.column_position; let col = writer.column_position;
let row = crate::vga_buffer::BUFFER_HEIGHT - 1; 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); crate::vga_buffer::move_cursor((col as u16) + 1, row as u16);
writer.column_position += 1; writer.column_position += 1;
}, },
_ => {} _ => {} // Ignore all other special keys
} }
}, },
} }

View file

@ -50,6 +50,7 @@ pub extern "C" fn _start() {
test_main(); test_main();
loop { loop {
// Halt CPU so that usage isn't 100% all the time
x86_64::instructions::hlt(); x86_64::instructions::hlt();
} }
} }

View file

@ -51,6 +51,7 @@ fn info(_arguments: &[&str]) {
} }
fn echo(arguments: &[&str]) { fn echo(arguments: &[&str]) {
// Join the arguments back into an ArrayString
let mut new: ArrayString<80> = ArrayString::new(); let mut new: ArrayString<80> = ArrayString::new();
for arg in &arguments[1..] { for arg in &arguments[1..] {
new.push_str(arg); new.push_str(arg);
@ -64,6 +65,8 @@ fn shutdown(_arguments: &[&str]) {
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
println!("KarxOS shutting down!"); println!("KarxOS shutting down!");
// QEMU shutdown hack
// TODO: acpi shutdown
let mut shutdown_port: Port<u16> = Port::new(0x604); let mut shutdown_port: Port<u16> = Port::new(0x604);
unsafe { unsafe {
shutdown_port.write(0x2000); shutdown_port.write(0x2000);

View file

@ -43,12 +43,13 @@ pub struct ScreenChar {
pub(crate) color_code: ColorCode pub(crate) color_code: ColorCode
} }
// This is characters, not pixels
pub(crate) const BUFFER_HEIGHT: usize = 25; pub(crate) const BUFFER_HEIGHT: usize = 25;
pub(crate) const BUFFER_WIDTH: usize = 80; pub(crate) const BUFFER_WIDTH: usize = 80;
#[repr(transparent)] #[repr(transparent)]
pub struct Buffer { pub struct Buffer {
pub chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT] pub chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT] // Use Volatile for futureproofing reads/writes
} }
pub struct Writer { pub struct Writer {
@ -63,19 +64,17 @@ impl Writer {
match byte { match byte {
b'\n' => self.new_line(), b'\n' => self.new_line(),
byte => { byte => {
if self.column_position >= BUFFER_WIDTH { if self.column_position < BUFFER_WIDTH {
self.new_line(); 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) { pub fn write_string(&mut self, s: &str) {
for byte in s.bytes() { for byte in s.bytes() {
match byte { match byte {
// Only write printable ASCII characters
0x20..=0x7e | b'\n' => self.write_byte(byte), 0x20..=0x7e | b'\n' => self.write_byte(byte),
_ => self.write_byte(0xfe) _ => self.write_byte(0xfe)
@ -91,6 +91,7 @@ impl Writer {
} }
fn new_line(&mut self) { fn new_line(&mut self) {
// Move all the rows up
for row in 1..BUFFER_HEIGHT { for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH { for col in 0..BUFFER_WIDTH {
let character = self.buffer.chars[row][col].read(); let character = self.buffer.chars[row][col].read();
@ -98,6 +99,7 @@ impl Writer {
} }
} }
// Clear top row
self.clear_row(BUFFER_HEIGHT - 1); self.clear_row(BUFFER_HEIGHT - 1);
self.column_position = 0; self.column_position = 0;
} }
@ -146,6 +148,7 @@ pub fn _print(args: fmt::Arguments) {
use core::fmt::Write; use core::fmt::Write;
use x86_64::instructions::interrupts; use x86_64::instructions::interrupts;
// Turn off interrupts to avoid a deadlock
interrupts::without_interrupts(|| { interrupts::without_interrupts(|| {
WRITER.lock().write_fmt(args).unwrap(); WRITER.lock().write_fmt(args).unwrap();
}); });
@ -157,6 +160,7 @@ pub fn backspace() {
let row = BUFFER_HEIGHT - 1; let row = BUFFER_HEIGHT - 1;
let col = writer.column_position; let col = writer.column_position;
let color_code = writer.color_code; let color_code = writer.color_code;
// Barrier for prompt
if col != 4 { if col != 4 {
writer.buffer.chars[row][col - 1].write(ScreenChar { writer.buffer.chars[row][col - 1].write(ScreenChar {
ascii_character: b' ', ascii_character: b' ',