From 37db55f73ccc287c68128b532921fb416c8b9e0f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 10 Jul 2020 20:34:46 +0200 Subject: [PATCH 1/3] Optimze shell printing --- src/kernel/vga.rs | 19 +++++++++++-------- src/user/shell.rs | 24 ++++++++++++------------ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/kernel/vga.rs b/src/kernel/vga.rs index 2ef3ec038..5a465c66c 100644 --- a/src/kernel/vga.rs +++ b/src/kernel/vga.rs @@ -215,26 +215,25 @@ impl Writer { self.buffer.chars[y - 1][x].write(character); } } - self.clear_row(BUFFER_HEIGHT - 1); + self.clear_row_after(0, BUFFER_HEIGHT - 1); } self.writer[0] = 0; } - /// Clears a row by overwriting it with blank characters - fn clear_row(&mut self, y: usize) { + fn clear_row_after(&mut self, x: usize, y: usize) { let blank = ScreenChar { ascii_code: b' ', color_code: self.color_code, }; - for x in 0..BUFFER_WIDTH { - self.buffer.chars[y][x].write(blank); + for i in x..BUFFER_WIDTH { + self.buffer.chars[y][i].write(blank); } } pub fn clear_screen(&mut self) { for y in 0..BUFFER_HEIGHT { - self.clear_row(y); + self.clear_row_after(0, y); } self.set_writer_position(0, 0); self.set_cursor_position(0, 0); @@ -332,11 +331,15 @@ pub fn clear_screen() { } pub fn clear_row() { + clear_row_after(0); +} + +pub fn clear_row_after(x: usize) { let (_, y) = writer_position(); interrupts::without_interrupts(|| { - WRITER.lock().clear_row(y); + WRITER.lock().clear_row_after(x, y); }); - set_writer_position(0, y); + set_writer_position(x, y); } pub fn screen_width() -> usize { diff --git a/src/user/shell.rs b/src/user/shell.rs index 6aa0662f5..35cf42cf7 100644 --- a/src/user/shell.rs +++ b/src/user/shell.rs @@ -121,8 +121,9 @@ impl Shell { self.history_index -= 1; } let cmd = &self.history[self.history_index]; - kernel::vga::clear_row(); - self.print_prompt(); + let n = self.prompt.len(); + kernel::vga::clear_row_after(n + cmd.len()); + kernel::vga::set_writer_position(n, y); print!("{}", cmd); } }, @@ -135,8 +136,9 @@ impl Shell { } else { &self.cmd }; - kernel::vga::clear_row(); - self.print_prompt(); + let n = self.prompt.len(); + kernel::vga::clear_row_after(n + cmd.len()); + kernel::vga::set_writer_position(n, y); print!("{}", cmd); } }, @@ -170,9 +172,7 @@ impl Shell { self.cmd.clear(); self.cmd.push_str(before_cursor); self.cmd.push_str(after_cursor); - kernel::vga::clear_row(); - self.print_prompt(); - print!("{}", self.cmd); + print!("{}{} ", c, after_cursor); kernel::vga::set_cursor_position(x - 1, y); kernel::vga::set_writer_position(x - 1, y); } @@ -193,9 +193,7 @@ impl Shell { self.cmd.push_str(before_cursor); self.cmd.push(c); self.cmd.push_str(after_cursor); - kernel::vga::clear_row(); - self.print_prompt(); - print!("{}", self.cmd); + print!("{}{}", c, after_cursor); kernel::vga::set_cursor_position(x + 1, y); kernel::vga::set_writer_position(x + 1, y); } else { @@ -293,8 +291,10 @@ impl Shell { args[i] = &self.autocomplete[self.autocomplete_index]; let cmd = args.join(" "); - kernel::console::clear_row(); - self.print_prompt(); + let n = self.prompt.len(); + let (_, y) = kernel::vga::cursor_position(); + kernel::vga::clear_row_after(n + cmd.len()); + kernel::vga::set_writer_position(n, y); print!("{}", cmd); } From badf37100ae04210d59892e148daefefca60ca3d Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Fri, 10 Jul 2020 21:24:38 +0200 Subject: [PATCH 2/3] Fix autocomplete with serial output --- src/kernel/console.rs | 51 +++++++++++++++++++++++++++++++++++++++---- src/user/shell.rs | 10 ++++----- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/kernel/console.rs b/src/kernel/console.rs index d95bf032d..81aa5d32f 100644 --- a/src/kernel/console.rs +++ b/src/kernel/console.rs @@ -44,13 +44,56 @@ pub fn has_cursor() -> bool { } #[cfg(feature="vga")] -pub fn clear_row() { - kernel::vga::clear_row(); +pub fn clear_row_after(x: usize) { + kernel::vga::clear_row_after(x); } #[cfg(feature="serial")] -pub fn clear_row() { - print!("\x1b[2K\r"); +pub fn clear_row_after(x: usize) { + print!("\r"); // Move cursor to begining of line + print!("\x1b[{}C", x); // Move cursor forward to position + print!("\x1b[K"); // Clear line after position +} + +#[cfg(feature="vga")] +pub fn cursor_position() -> (usize, usize) { + kernel::vga::cursor_position() +} + +#[cfg(feature="serial")] +pub fn cursor_position() -> (usize, usize) { + print!("\x1b[6n"); // Ask cursor position + get_char(); // ESC + get_char(); // [ + let mut x = String::new(); + let mut y = String::new(); + loop { + let c = get_char(); + if c == ';' { + break; + } else { + y.push(c); + } + } + loop { + let c = get_char(); + if c == 'R' { + break; + } else { + x.push(c); + } + } + (x.parse().unwrap_or(1), y.parse().unwrap_or(1)) +} + +#[cfg(feature="vga")] +pub fn set_writer_position(x: usize, y: usize) { + kernel::vga::set_writer_position(x, y); +} + +#[cfg(feature="serial")] +pub fn set_writer_position(x: usize, y: usize) { + print!("\x1b[{};{}H", y + 1, x + 1); } #[cfg(feature="vga")] diff --git a/src/user/shell.rs b/src/user/shell.rs index 35cf42cf7..8a7418cfa 100644 --- a/src/user/shell.rs +++ b/src/user/shell.rs @@ -122,7 +122,7 @@ impl Shell { } let cmd = &self.history[self.history_index]; let n = self.prompt.len(); - kernel::vga::clear_row_after(n + cmd.len()); + kernel::console::clear_row_after(n + cmd.len()); kernel::vga::set_writer_position(n, y); print!("{}", cmd); } @@ -137,7 +137,7 @@ impl Shell { &self.cmd }; let n = self.prompt.len(); - kernel::vga::clear_row_after(n + cmd.len()); + kernel::console::clear_row_after(n + cmd.len()); kernel::vga::set_writer_position(n, y); print!("{}", cmd); } @@ -292,9 +292,9 @@ impl Shell { let cmd = args.join(" "); let n = self.prompt.len(); - let (_, y) = kernel::vga::cursor_position(); - kernel::vga::clear_row_after(n + cmd.len()); - kernel::vga::set_writer_position(n, y); + let (_, y) = kernel::console::cursor_position(); + kernel::console::clear_row_after(n + cmd.len()); + kernel::console::set_writer_position(n, y); print!("{}", cmd); } From c2f29344ed02313b4803b8d708a7edadca8f18fe Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Sat, 11 Jul 2020 00:36:13 +0200 Subject: [PATCH 3/3] Use cfg macro to dry code --- src/kernel/console.rs | 121 ++++++++++++++++------------------------- src/kernel/keyboard.rs | 2 +- 2 files changed, 49 insertions(+), 74 deletions(-) diff --git a/src/kernel/console.rs b/src/kernel/console.rs index 81aa5d32f..a12c40371 100644 --- a/src/kernel/console.rs +++ b/src/kernel/console.rs @@ -33,106 +33,81 @@ lazy_static! { pub static ref RAW: Mutex = Mutex::new(false); } -#[cfg(feature="vga")] pub fn has_cursor() -> bool { - true + cfg!(feature="vga") } -#[cfg(feature="serial")] -pub fn has_cursor() -> bool { - false -} - -#[cfg(feature="vga")] -pub fn clear_row_after(x: usize) { - kernel::vga::clear_row_after(x); -} - -#[cfg(feature="serial")] pub fn clear_row_after(x: usize) { - print!("\r"); // Move cursor to begining of line - print!("\x1b[{}C", x); // Move cursor forward to position - print!("\x1b[K"); // Clear line after position -} - -#[cfg(feature="vga")] -pub fn cursor_position() -> (usize, usize) { - kernel::vga::cursor_position() + if cfg!(feature="vga") { + kernel::vga::clear_row_after(x); + } else { + print!("\r"); // Move cursor to begining of line + print!("\x1b[{}C", x); // Move cursor forward to position + print!("\x1b[K"); // Clear line after position + } } -#[cfg(feature="serial")] pub fn cursor_position() -> (usize, usize) { - print!("\x1b[6n"); // Ask cursor position - get_char(); // ESC - get_char(); // [ - let mut x = String::new(); - let mut y = String::new(); - loop { - let c = get_char(); - if c == ';' { - break; - } else { - y.push(c); + if cfg!(feature="vga") { + kernel::vga::cursor_position() + } else { + print!("\x1b[6n"); // Ask cursor position + get_char(); // ESC + get_char(); // [ + let mut x = String::new(); + let mut y = String::new(); + loop { + let c = get_char(); + if c == ';' { + break; + } else { + y.push(c); + } } - } - loop { - let c = get_char(); - if c == 'R' { - break; - } else { - x.push(c); + loop { + let c = get_char(); + if c == 'R' { + break; + } else { + x.push(c); + } } + (x.parse().unwrap_or(1), y.parse().unwrap_or(1)) } - (x.parse().unwrap_or(1), y.parse().unwrap_or(1)) -} - -#[cfg(feature="vga")] -pub fn set_writer_position(x: usize, y: usize) { - kernel::vga::set_writer_position(x, y); } -#[cfg(feature="serial")] pub fn set_writer_position(x: usize, y: usize) { - print!("\x1b[{};{}H", y + 1, x + 1); -} - -#[cfg(feature="vga")] -#[macro_export] -macro_rules! print { - ($($arg:tt)*) => ({ - $crate::kernel::vga::print_fmt(format_args!($($arg)*)); - }); + if cfg!(feature="vga") { + kernel::vga::set_writer_position(x, y); + } else { + print!("\x1b[{};{}H", y + 1, x + 1); + } } -#[cfg(feature="serial")] #[macro_export] macro_rules! print { ($($arg:tt)*) => ({ - $crate::kernel::serial::print_fmt(format_args!($($arg)*)); - }); -} - -#[cfg(feature="vga")] -#[macro_export] -macro_rules! log { - ($($arg:tt)*) => ({ - let uptime = $crate::kernel::clock::uptime(); - let csi_color = $crate::kernel::console::color("LightGreen"); - let csi_reset = $crate::kernel::console::color("Reset"); - $crate::kernel::vga::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); - $crate::kernel::vga::print_fmt(format_args!($($arg)*)); + if cfg!(feature="vga") { + $crate::kernel::vga::print_fmt(format_args!($($arg)*)); + } else { + $crate::kernel::serial::print_fmt(format_args!($($arg)*)); + } }); } -#[cfg(feature="serial")] #[macro_export] macro_rules! log { ($($arg:tt)*) => ({ let uptime = $crate::kernel::clock::uptime(); let csi_color = $crate::kernel::console::color("LightGreen"); let csi_reset = $crate::kernel::console::color("Reset"); - $crate::kernel::serial::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); - $crate::kernel::serial::print_fmt(format_args!($($arg)*)); + if cfg!(feature="vga") { + $crate::kernel::vga::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); + $crate::kernel::vga::print_fmt(format_args!($($arg)*)); + } else { + $crate::kernel::serial::print_fmt(format_args!("{}[{:.6}]{} ", csi_color, uptime, csi_reset)); + $crate::kernel::serial::print_fmt(format_args!($($arg)*)); + } }); } diff --git a/src/kernel/keyboard.rs b/src/kernel/keyboard.rs index aaa6d76cd..e40475f9f 100644 --- a/src/kernel/keyboard.rs +++ b/src/kernel/keyboard.rs @@ -72,7 +72,7 @@ pub fn init() { kernel::idt::set_irq_handler(1, interrupt_handler); } -pub fn read_scancode() -> u8 { +fn read_scancode() -> u8 { let mut port = Port::new(0x60); unsafe { port.read()