diff --git a/kernel-rs/src/keyboard.rs b/kernel-rs/src/keyboard.rs index daf172f5..09b4f3be 100644 --- a/kernel-rs/src/keyboard.rs +++ b/kernel-rs/src/keyboard.rs @@ -1 +1,32 @@ -pub static KEY_CODE_TO_ASCII: [u8; 59] = *b"??1234567890-=??qwertyuiop[]\n?asdfghjkl;'`?\\zxcvbnm,./?*? ?"; +pub static SCANCODE_TO_ASCII: [u8; 59] = *b"??1234567890-=??qwertyuiop[]\n?asdfghjkl;'`?\\zxcvbnm,./?*? ?"; + +use vga; +use cpuio; + +use vga::buffer::{Writer, Screen}; + +pub fn kbd_loop(writer: &mut Writer) { + let terminal_one: vga::terminal::Terminal = vga::Screen::new(); + // let terminal_two: vga::terminal::Terminal = vga::Screen::new(); + + let control = unsafe { cpuio::inb(0x64) }; + if (control & 1) == 1 { + let scancode = unsafe { cpuio::inb(0x60) }; + + //TODO current_screen() with mutex lock? + let current_screen = terminal_one; + + //TODO implement logic to translate scancode->ascii + match self::SCANCODE_TO_ASCII.get(scancode as usize) { + Some(ascii) => { + //TODO screen switching logic + // if let Some(action) = Screen::keypress(current_screen, *ascii as char) { + if let Some(action) = current_screen.keypress(*ascii as char) { + writer.action(action); + } + }, + None =>{}, + // None => println!("nokey ctrl {:x}", control), + } + } +} diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index a4556262..636dbbfb 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -9,7 +9,7 @@ extern crate volatile; extern crate rlibc; #[macro_use] -mod vga_buffer; +mod vga; #[allow(dead_code)] mod cpuio; @@ -17,39 +17,30 @@ mod keyboard; #[no_mangle] pub extern fn kmain() -> ! { - use vga_buffer::WRITER; - use vga_buffer::Color; - use vga_buffer::ColorCode; + // use vga::VgaScreen; + // use vga::color::Color; + // use vga::color::ColorCode; - WRITER.lock().reset_screen(); - WRITER.lock().color_code = ColorCode::new(Color::Yellow, Color::Black); - println!(r#" ,--, "#); - println!(r#" ,--.'| ,----, "#); - println!(r#" ,--, | : .' .' \ "#); - println!(r#",---.'| : ' ,----,' | "#); - println!(r#"; : | | ; | : . ; "#); - println!(r#"| | : _' | ; |.' / "#); - println!(r#": : |.' | `----'/ ; "#); - println!(r#"| ' ' ; : / ; / "#); - println!(r#"\ \ .'. | ; / /-, "#); - println!(r#" `---`: | ' / / /.`| "#); - println!(r#" ' ; |./__; : "#); - println!(r#" | : ;| : .' "#); - println!(r#" ' ,/ ; | .' "#); - println!(r#" '--' `---' "#); - WRITER.lock().color_code = ColorCode::new(Color::White, Color::Black); - println!(">> Kernel startup..."); - loop { - let control = unsafe { cpuio::inb(0x64) }; - if (control & 1) == 1 { - let keycode = unsafe { cpuio::inb(0x60) }; - match keyboard::KEY_CODE_TO_ASCII.get(keycode as usize) { - Some(ascii) => print!("{}", *ascii as char), - None =>{}, - // None => println!("nokey ctrl {:x}", control), - } - } - } + // WRITER.lock().reset_screen(); + // WRITER.lock().color_code = ColorCode::new(Color::Yellow, Color::Black); + // println!(r#" ,--, "#); + // println!(r#" ,--.'| ,----, "#); + // println!(r#" ,--, | : .' .' \ "#); + // println!(r#",---.'| : ' ,----,' | "#); + // println!(r#"; : | | ; | : . ; "#); + // println!(r#"| | : _' | ; |.' / "#); + // println!(r#": : |.' | `----'/ ; "#); + // println!(r#"| ' ' ; : / ; / "#); + // println!(r#"\ \ .'. | ; / /-, "#); + // println!(r#" `---`: | ' / / /.`| "#); + // println!(r#" ' ; |./__; : "#); + // println!(r#" | : ;| : .' "#); + // println!(r#" ' ,/ ; | .' "#); + // println!(r#" '--' `---' "#); + // WRITER.lock().color_code = ColorCode::new(Color::White, Color::Black); + // println!(">> Kernel startup..."); + + unsafe { loop { keyboard::kbd_loop(&mut vga::buffer::WRITER); } }; } #[lang = "eh_personality"] #[no_mangle] @@ -59,11 +50,12 @@ pub extern fn eh_personality() { #[lang = "panic_fmt"] #[no_mangle] pub extern fn panic_fmt( - fmt: core::fmt::Arguments, file: &'static str, line: u32) + // fmt: core::fmt::Arguments, file: &'static str, line: u32 + ) -> ! { - println!("PANIC: {}", fmt); - println!("FILE: {}", file); - println!("LINE: {}", line); + // println!("PANIC: {}", fmt); + // println!("FILE: {}", file); + // println!("LINE: {}", line); loop {} } diff --git a/kernel-rs/src/vga_buffer.rs b/kernel-rs/src/vga/buffer.rs similarity index 65% rename from kernel-rs/src/vga_buffer.rs rename to kernel-rs/src/vga/buffer.rs index 5bbaedfb..34617c44 100644 --- a/kernel-rs/src/vga_buffer.rs +++ b/kernel-rs/src/vga/buffer.rs @@ -7,24 +7,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use volatile::Volatile; + +use super::{Color, ColorCode}; use core::ptr::Unique; use core::fmt; -use spin::Mutex; -use volatile::Volatile; + +#[derive(Debug, Clone, Copy)] +#[repr(C)] +struct ScreenChar { + ascii_character: u8, + color_code: ColorCode, +} const BUFFER_HEIGHT: usize = 25; const BUFFER_WIDTH: usize = 80; -pub static WRITER: Mutex = Mutex::new(Writer { +pub struct Writer { + pub column_position: usize, + pub color_code: ColorCode, + vgabuffer: Unique, +} + +// Writer is the default object to use to print to screen +pub static mut WRITER: Writer = Writer { column_position: 0, color_code: ColorCode::new(Color::White, Color::Black), vgabuffer: unsafe { Unique::new_unchecked(0xb8000 as *mut _) }, -}); - -// cursor is lightgray for everyone -static CURSOR: ScreenChar = ScreenChar { - ascii_character: b' ', - color_code: ColorCode::new(Color::LightGray, Color::LightGray), }; // blank is black for everyone, could make screens choose this @@ -33,29 +42,14 @@ static BLANK: ScreenChar = ScreenChar { color_code: ColorCode::new(Color::White, Color::Black), }; -pub struct Writer { - column_position: usize, - pub color_code: ColorCode, - vgabuffer: Unique, -} - -macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -} - -macro_rules! print { - ($($arg:tt)*) => ({ - $crate::vga_buffer::print(format_args!($($arg)*)); - }); -} - -pub fn print(args: fmt::Arguments) { - use core::fmt::Write; - WRITER.lock().write_fmt(args).unwrap(); -} - impl Writer { + pub fn action(&mut self, action: BufferAction) { + match action { + BufferAction::WRITE_BYTE(ascii) => self.write_byte(ascii as u8), + BufferAction::CLEAR_SCREEN => self.reset_screen(), + } + } + pub fn reset_screen(&mut self) { let color_code = self.color_code; @@ -72,7 +66,7 @@ impl Writer { pub fn write_byte(&mut self, byte: u8) { match byte { - b'\n' => self.new_line(), + b'\n' => { self.new_line(); } byte => { if self.column_position >= BUFFER_WIDTH { self.new_line(); @@ -87,9 +81,6 @@ impl Writer { self.column_position += 1; } } - let row = BUFFER_HEIGHT - 1; - let col = self.column_position; - self.buffer().chars[row][col].write(CURSOR); } fn buffer(&mut self) -> &mut Buffer { @@ -97,11 +88,6 @@ impl Writer { } fn new_line(&mut self) { - // remove cursor if newline isnt from end of screen - if self.column_position < BUFFER_WIDTH { - let col = self.column_position; - self.buffer().chars[BUFFER_HEIGHT - 1][col].write(BLANK); - } for row in 1..BUFFER_HEIGHT { for col in 0..BUFFER_WIDTH { let buffer = self.buffer(); @@ -129,44 +115,19 @@ impl fmt::Write for Writer { } } -#[allow(dead_code)] -#[derive(Debug, Clone, Copy)] -#[repr(u8)] -pub enum Color { - Black = 0, - Blue = 1, - Green = 2, - Cyan = 3, - Red = 4, - Magenta = 5, - Brown = 6, - LightGray = 7, - DarkGray = 8, - LightBlue = 9, - LightGreen = 10, - LightCyan = 11, - LightRed = 12, - Pink = 13, - Yellow = 14, - White = 15, -} - -#[derive(Debug, Clone, Copy)] -pub struct ColorCode(u8); - -impl ColorCode { - pub const fn new(foreground: Color, background: Color) -> ColorCode { - ColorCode((background as u8) << 4 | (foreground as u8)) - } -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -struct ScreenChar { - ascii_character: u8, - color_code: ColorCode, -} - struct Buffer { chars: [[Volatile; BUFFER_WIDTH]; BUFFER_HEIGHT], } + +pub enum BufferAction { + WRITE_BYTE(char), + CLEAR_SCREEN, +} + +/// Implementors of this trait can use the vga screen for any purpose +pub trait Screen { + fn new() -> Self; // + fn keypress(self, keycode: char) -> Option; + // fn load(); + // fn unload() -> ; +} diff --git a/kernel-rs/src/vga/color.rs b/kernel-rs/src/vga/color.rs new file mode 100644 index 00000000..dc24b1ef --- /dev/null +++ b/kernel-rs/src/vga/color.rs @@ -0,0 +1,30 @@ +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +#[repr(u8)] +pub enum Color { + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + Pink = 13, + Yellow = 14, + White = 15, +} + +#[derive(Debug, Clone, Copy)] +pub struct ColorCode(u8); + +impl ColorCode { + pub const fn new(foreground: Color, background: Color) -> ColorCode { + ColorCode((background as u8) << 4 | (foreground as u8)) + } +} diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs new file mode 100644 index 00000000..2a7984e3 --- /dev/null +++ b/kernel-rs/src/vga/mod.rs @@ -0,0 +1,27 @@ +#[macro_use] +pub mod buffer; +pub mod color; +pub mod terminal; + +pub use self::color::{Color, ColorCode}; +pub use self::buffer::{WRITER, Screen, BufferAction}; + +// use self::buffer::Writer; +// use core::fmt; +// use core::ptr::Unique; + +// macro_rules! println { +// ($fmt:expr) => (print!(concat!($fmt, "\n"))); +// ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); +// } + +// macro_rules! print { +// ($($arg:tt)*) => ({ +// $crate::vga::print(format_args!($($arg)*)); +// }); +// } + +// pub fn print(args: fmt::Arguments) { +// use core::fmt::Write; +// self::WRITER.write_fmt(args).unwrap(); +// } diff --git a/kernel-rs/src/vga/terminal.rs b/kernel-rs/src/vga/terminal.rs new file mode 100644 index 00000000..0f1fcb9a --- /dev/null +++ b/kernel-rs/src/vga/terminal.rs @@ -0,0 +1,19 @@ +//! terminal.rs implements a basic cursor terminal using the vga::buffer module + +use super::{Color, ColorCode}; +use vga; + +// cursor is lightgray for everyone +static CURSOR: ColorCode = ColorCode::new(Color::LightGray, Color::White); + +pub struct Terminal { } + +impl vga::Screen for Terminal { + fn new() -> Terminal { + Terminal { } + } + + fn keypress(self, ascii: char) -> Option { + Some(vga::BufferAction::WRITE_BYTE(ascii)) + } +}