Document code
This commit is contained in:
parent
c201ddd35a
commit
30ca73458b
|
@ -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
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<u16> = Port::new(0x604);
|
||||
unsafe {
|
||||
shutdown_port.write(0x2000);
|
||||
|
|
|
@ -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<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT]
|
||||
pub chars: [[Volatile<ScreenChar>; 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' ',
|
||||
|
|
Loading…
Reference in a new issue