console moved out of vga
This commit is contained in:
parent
3e49ec75d3
commit
381b86d5e0
4 changed files with 122 additions and 122 deletions
|
|
@ -7,56 +7,126 @@ use keyboard::PS2;
|
||||||
use core::char;
|
use core::char;
|
||||||
use vga::*;
|
use vga::*;
|
||||||
|
|
||||||
fn dispatch(command: &str) -> Result<(), &'static str> {
|
pub static mut CONSOLE: Console = self::Console::new();
|
||||||
match command {
|
|
||||||
"help" | "h" => self::help(),
|
|
||||||
|
|
||||||
// multiboot
|
pub struct Console {
|
||||||
// "memory" => self::mb2_memory(),
|
command: [u8; 10],
|
||||||
// "multiboot" => self::mb2_info(),
|
command_len: usize,
|
||||||
// "sections" => self::mb2_sections(),
|
|
||||||
|
|
||||||
// ACPI
|
|
||||||
"acpi" => self::acpi_info(),
|
|
||||||
"reboot" => self::reboot(),
|
|
||||||
"shutdown" | "halt" | "q" => self::shutdown(),
|
|
||||||
|
|
||||||
// x86 specific
|
|
||||||
"stack" => self::print_stack(),
|
|
||||||
"regs" => self::regs(),
|
|
||||||
"cpu" => self::cpu(),
|
|
||||||
"int3" => self::int3(),
|
|
||||||
"overflow" => self::overflow(),
|
|
||||||
"page_fault" => self::page_fault(),
|
|
||||||
|
|
||||||
// time
|
|
||||||
"uptime" => self::uptime(),
|
|
||||||
|
|
||||||
_ => Err("Command unknown. (h|help for help)"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(cli: &Writer) -> Result<(), &'static str> {
|
impl Console {
|
||||||
let command = cli.get_command()?;
|
pub const fn new() -> Console {
|
||||||
if let Err(msg) = self::dispatch(command) {
|
Console {
|
||||||
set_color!(Red);
|
command: [b'\0'; 10],
|
||||||
println!("`{}`: {}", command, msg);
|
command_len: 0,
|
||||||
set_color!();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&self) {
|
||||||
|
set_color!();
|
||||||
|
// print!("{}", format_args!("{: ^4000}", r#" "#));
|
||||||
|
unsafe {
|
||||||
|
// VGA.buffer_pos = 0;
|
||||||
|
self.prompt();
|
||||||
|
VGA.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn backspace(&mut self) {
|
||||||
|
if self.command_len > 0 {
|
||||||
|
self.command_len -= 1;
|
||||||
|
unsafe { VGA.erase_byte(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prompt(&self) {
|
||||||
|
set_color!(Blue);
|
||||||
|
unsafe { VGA.write_str("> "); }
|
||||||
|
set_color!();
|
||||||
|
flush!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keypress(&mut self, ascii: u8) {
|
||||||
|
match ascii {
|
||||||
|
b'\n' if self.command_len == 0 => {
|
||||||
|
unsafe { VGA.write_byte(b'\n'); }
|
||||||
|
self.prompt();
|
||||||
|
}
|
||||||
|
b'\n' => {
|
||||||
|
unsafe { VGA.write_byte(b'\n'); }
|
||||||
|
self.exec();
|
||||||
|
self.command_len = 0;
|
||||||
|
self.prompt();
|
||||||
|
}
|
||||||
|
// _ if self.command_len >= 10 => (),
|
||||||
|
// byte if self.command_len == 0 && byte == b' ' => (),
|
||||||
|
byte => {
|
||||||
|
if self.command_len >= 10 {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.command[self.command_len] = byte;
|
||||||
|
unsafe { VGA.write_byte(byte); }
|
||||||
|
self.command_len += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flush!();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn get_command(&self) -> Result<&str, &'static str> {
|
||||||
|
match core::str::from_utf8(&self.command) {
|
||||||
|
Ok(y) => Ok(&y[..self.command_len]),
|
||||||
|
Err(_) => Err("Command is not utf8"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exec(&self) -> core::result::Result<(), &'static str> {
|
||||||
|
let command = self.get_command();
|
||||||
|
if let Err(msg) = command {
|
||||||
|
set_color!(Red);
|
||||||
|
println!("{}", msg);
|
||||||
|
set_color!();
|
||||||
|
}
|
||||||
|
match command.unwrap() {
|
||||||
|
"help" | "h" => self::help(),
|
||||||
|
|
||||||
|
// multiboot
|
||||||
|
// "memory" => self::mb2_memory(),
|
||||||
|
// "multiboot" => self::mb2_info(),
|
||||||
|
// "sections" => self::mb2_sections(),
|
||||||
|
|
||||||
|
// ACPI
|
||||||
|
"acpi" => self::acpi_info(),
|
||||||
|
"reboot" => self::reboot(),
|
||||||
|
"shutdown" | "halt" | "q" => self::shutdown(),
|
||||||
|
|
||||||
|
// x86 specific
|
||||||
|
"stack" => self::print_stack(),
|
||||||
|
"regs" => self::regs(),
|
||||||
|
"cpu" => self::cpu(),
|
||||||
|
"int3" => self::int3(),
|
||||||
|
"overflow" => self::overflow(),
|
||||||
|
"page_fault" => self::page_fault(),
|
||||||
|
|
||||||
|
// time
|
||||||
|
"uptime" => self::uptime(),
|
||||||
|
|
||||||
|
_ => Err("Command unknown. (try help)"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn help() -> Result<(), &'static str> {
|
fn help() -> Result<(), &'static str> {
|
||||||
println!("acpi => Return acpi state (ENABLED|DISABLE)");
|
println!("help | h => print this help");
|
||||||
println!("help | h => Print this help");
|
|
||||||
// println!("memory => Print memory areas");
|
// println!("memory => Print memory areas");
|
||||||
// println!("multiboot => Print multiboot information");
|
// println!("multiboot => Print multiboot information");
|
||||||
// println!("sections => Print elf sections");
|
// println!("sections => Print elf sections");
|
||||||
println!("reboot => Reboot");
|
println!("reboot => reboot");
|
||||||
println!("shutdown | halt | q => Kill a kitten, then shutdown");
|
println!("shutdown | halt | q => acpi shutdown");
|
||||||
println!("stack => Print kernel stack in a fancy way");
|
println!("acpi => acpi state");
|
||||||
println!("regs => Print controle register");
|
println!("stack => print kernel stack in a fancy way");
|
||||||
println!("cpu => Print cpu information");
|
println!("regs => print controle register");
|
||||||
|
println!("cpu => print cpu information");
|
||||||
println!("overflow => triggers a stack overflow");
|
println!("overflow => triggers a stack overflow");
|
||||||
println!("page_fault => triggers a page fault on 0xdead");
|
println!("page_fault => triggers a page fault on 0xdead");
|
||||||
flush!();
|
flush!();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
use vga;
|
use console;
|
||||||
use x86::devices::io::{Io, Pio};
|
use x86::devices::io::{Io, Pio};
|
||||||
|
|
||||||
const MAX_KEYS: usize = 59;
|
const MAX_KEYS: usize = 59;
|
||||||
|
|
@ -133,13 +133,13 @@ pub fn kbd_callback() {
|
||||||
0x38 => ALT = !is_release,
|
0x38 => ALT = !is_release,
|
||||||
0x1D => CTRL = !is_release,
|
0x1D => CTRL = !is_release,
|
||||||
0x0E if !is_release => {
|
0x0E if !is_release => {
|
||||||
vga::VGA.backspace();
|
console::CONSOLE.backspace();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Some(ascii) if !is_release => {
|
Some(ascii) if !is_release => {
|
||||||
let sym = if SHIFT { ascii[1] } else { ascii[0] };
|
let sym = if SHIFT { ascii[1] } else { ascii[0] };
|
||||||
vga::VGA.keypress(sym);
|
console::CONSOLE.keypress(sym);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ pub mod arch;
|
||||||
pub use arch::x86::consts::*;
|
pub use arch::x86::consts::*;
|
||||||
pub mod scheduling;
|
pub mod scheduling;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
pub mod pci;
|
||||||
|
|
||||||
/// kernel entry point. arch module is responsible for
|
/// kernel entry point. arch module is responsible for
|
||||||
/// calling this once the core has loaded
|
/// calling this once the core has loaded
|
||||||
|
|
@ -45,9 +46,10 @@ pub fn kmain() -> ! {
|
||||||
// memory init after heap is available
|
// memory init after heap is available
|
||||||
memory::init_noncore();
|
memory::init_noncore();
|
||||||
|
|
||||||
// load vga after core because is *not* cpu specific I think
|
// unsafe VGA
|
||||||
vga::init();
|
unsafe { console::CONSOLE.init(); }
|
||||||
|
|
||||||
|
pci::lspci();
|
||||||
// scheduler WIP
|
// scheduler WIP
|
||||||
// scheduling::schedule();
|
// scheduling::schedule();
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#![allow(unused_macros)]
|
|
||||||
|
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
|
|
||||||
|
|
@ -52,9 +50,9 @@ macro_rules! flush {
|
||||||
|
|
||||||
macro_rules! set_color {
|
macro_rules! set_color {
|
||||||
() => (unsafe { $crate::vga::VGA.color_code =
|
() => (unsafe { $crate::vga::VGA.color_code =
|
||||||
$crate::vga::ColorCode::new($crate::vga::Color::Black, $crate::vga::Color::Yellow)} );
|
$crate::vga::ColorCode::new($crate::vga::Color::White, $crate::vga::Color::Black)} );
|
||||||
($fg:ident) => (unsafe { $crate::vga::VGA.color_code =
|
($fg:ident) => (unsafe { $crate::vga::VGA.color_code =
|
||||||
$crate::vga::ColorCode::new($crate::vga::Color::$fg, $crate::vga::Color::Yellow)} );
|
$crate::vga::ColorCode::new($crate::vga::Color::$fg, $crate::vga::Color::Black)} );
|
||||||
($fg:ident, $bg:ident) => (unsafe { $crate::vga::VGA.color_code =
|
($fg:ident, $bg:ident) => (unsafe { $crate::vga::VGA.color_code =
|
||||||
$crate::vga::ColorCode::new($crate::vga::Color::$fg, $crate::vga::Color::$bg)} );
|
$crate::vga::ColorCode::new($crate::vga::Color::$fg, $crate::vga::Color::$bg)} );
|
||||||
}
|
}
|
||||||
|
|
@ -83,27 +81,13 @@ impl Writer {
|
||||||
pub const fn new() -> Writer {
|
pub const fn new() -> Writer {
|
||||||
Writer {
|
Writer {
|
||||||
buffer_pos: 0,
|
buffer_pos: 0,
|
||||||
color_code: ColorCode::new(Color::Black, Color::Yellow),
|
color_code: ColorCode::new(Color::White, Color::Black),
|
||||||
buffer: [0; BUFFER_ROWS * BUFFER_COLS],
|
buffer: [0; BUFFER_ROWS * BUFFER_COLS],
|
||||||
command: [b'\0'; 10],
|
command: [b'\0'; 10],
|
||||||
command_len: 0,
|
command_len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prompt(&mut self) {
|
|
||||||
set_color!(Blue);
|
|
||||||
self.write_str("> ");
|
|
||||||
set_color!();
|
|
||||||
flush!();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn backspace(&mut self) {
|
|
||||||
if self.command_len > 0 {
|
|
||||||
self.command_len -= 1;
|
|
||||||
self.erase_byte();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_command(&self) -> Result<&str, &'static str> {
|
pub fn get_command(&self) -> Result<&str, &'static str> {
|
||||||
match core::str::from_utf8(&self.command) {
|
match core::str::from_utf8(&self.command) {
|
||||||
Ok(y) => Ok(&y[..self.command_len]),
|
Ok(y) => Ok(&y[..self.command_len]),
|
||||||
|
|
@ -111,35 +95,6 @@ impl Writer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keypress(&mut self, ascii: u8) {
|
|
||||||
match ascii {
|
|
||||||
b'\n' if self.command_len == 0 => {
|
|
||||||
self.write_byte(b'\n');
|
|
||||||
self.prompt();
|
|
||||||
}
|
|
||||||
b'\n' => {
|
|
||||||
self.write_byte(b'\n');
|
|
||||||
if let Err(msg) = console::exec(&self) {
|
|
||||||
set_color!(Red, Yellow);
|
|
||||||
println!("Something wrong: {}", msg);
|
|
||||||
set_color!();
|
|
||||||
}
|
|
||||||
self.command_len = 0;
|
|
||||||
self.prompt();
|
|
||||||
}
|
|
||||||
_ if self.command_len >= 10 => (),
|
|
||||||
byte if self.command_len == 0 && byte == b' ' => (),
|
|
||||||
byte => {
|
|
||||||
if self.command_len >= 10 {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
self.command[self.command_len] = byte;
|
|
||||||
self.write_byte(byte);
|
|
||||||
self.command_len += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn erase_byte(&mut self) {
|
pub fn erase_byte(&mut self) {
|
||||||
self.buffer_pos -= 2;
|
self.buffer_pos -= 2;
|
||||||
|
|
@ -170,7 +125,7 @@ impl Writer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_str(&mut self, s: &str) {
|
pub fn write_str(&mut self, s: &str) {
|
||||||
for byte in s.bytes() {
|
for byte in s.bytes() {
|
||||||
self.write_byte(byte)
|
self.write_byte(byte)
|
||||||
}
|
}
|
||||||
|
|
@ -200,7 +155,7 @@ impl Writer {
|
||||||
for col in (0..BUFFER_COLS / 2).map(|x| x * 2) {
|
for col in (0..BUFFER_COLS / 2).map(|x| x * 2) {
|
||||||
self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col)] = b' ';
|
self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col)] = b' ';
|
||||||
self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col + 1)] =
|
self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col + 1)] =
|
||||||
ColorCode::new(Color::Black, Color::Yellow).0;
|
ColorCode::new(Color::White, Color::Black).0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buffer_pos = (BUFFER_ROWS - 1) * BUFFER_COLS;
|
self.buffer_pos = (BUFFER_ROWS - 1) * BUFFER_COLS;
|
||||||
|
|
@ -217,30 +172,3 @@ impl fmt::Write for Writer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
// set_color!(Yellow, Red);
|
|
||||||
// print!(
|
|
||||||
// "{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
|
|
||||||
// format_args!("{: ^80}", r#" ,--, "#),
|
|
||||||
// format_args!("{: ^80}", r#" ,--.'| ,----, "#),
|
|
||||||
// format_args!("{: ^80}", r#" ,--, | : .' .' \ "#),
|
|
||||||
// format_args!("{: ^80}", r#",---.'| : ' ,----,' | "#),
|
|
||||||
// format_args!("{: ^80}", r#"; : | | ; | : . ; "#),
|
|
||||||
// format_args!("{: ^80}", r#"| | : _' | ; |.' / "#),
|
|
||||||
// format_args!("{: ^80}", r#": : |.' | `----'/ ; "#),
|
|
||||||
// format_args!("{: ^80}", r#"| ' ' ; : / ; / "#),
|
|
||||||
// format_args!("{: ^80}", r#"\ \ .'. | ; / /-, "#),
|
|
||||||
// format_args!("{: ^80}", r#" `---`: | ' / / /.`| "#),
|
|
||||||
// format_args!("{: ^80}", r#" ' ; |./__; : "#),
|
|
||||||
// format_args!("{: ^80}", r#" | : ;| : .' "#),
|
|
||||||
// format_args!("{: ^80}", r#" ' ,/ ; | .' "#),
|
|
||||||
// format_args!("{: ^80}", r#" '--' `---' "#)
|
|
||||||
// );
|
|
||||||
unsafe {
|
|
||||||
VGA.prompt();
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
VGA.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue