doesnt compile, 2 sec
This commit is contained in:
parent
4f809497ca
commit
3c2b7f3f75
5 changed files with 186 additions and 214 deletions
|
|
@ -1,7 +1,3 @@
|
||||||
//! Rust wrappers around the x86-family I/O instructions.
|
|
||||||
//! this cmodule uses inline assembly so you need to add
|
|
||||||
//! `#![feature(asm)]` to yourcrate attributes
|
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
/// Read a `u8`-sized value from `port`.
|
/// Read a `u8`-sized value from `port`.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ extern crate core;
|
||||||
|
|
||||||
use cpuio;
|
use cpuio;
|
||||||
use context::CONTEXT;
|
use context::CONTEXT;
|
||||||
// use vga::color::{Color, ColorCode};
|
|
||||||
|
|
||||||
const MAX_KEYS: usize = 59;
|
const MAX_KEYS: usize = 59;
|
||||||
const KEYMAP_US: [[u8;2]; MAX_KEYS] = [
|
const KEYMAP_US: [[u8;2]; MAX_KEYS] = [
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,16 @@
|
||||||
extern crate rlibc;
|
extern crate rlibc;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod vga; // 80x25 screen and terminal
|
/// 80x25 screen and simplistic terminal driver
|
||||||
mod context; // kernel init and environment
|
pub mod vga;
|
||||||
mod keyboard; // PS/2 detection and processing
|
/// kernel init and environment
|
||||||
mod console; // vga terminal commands
|
pub mod context;
|
||||||
mod cpuio; // asm wrapper to cpu i/o
|
/// PS/2 detection and processing
|
||||||
|
pub mod keyboard;
|
||||||
|
/// simplisitc kernel commands
|
||||||
|
pub mod console;
|
||||||
|
/// wrappers around the x86-family I/O instructions.
|
||||||
|
pub mod cpuio;
|
||||||
|
|
||||||
use context::CONTEXT;
|
use context::CONTEXT;
|
||||||
use vga::{Color, ColorCode};
|
use vga::{Color, ColorCode};
|
||||||
|
|
|
||||||
|
|
@ -1,188 +0,0 @@
|
||||||
// Copyright 2016 Philipp Oppermann. See the README.md
|
|
||||||
// file at the top-level directory of this distribution.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use super::{Color, ColorCode};
|
|
||||||
use ::context::CONTEXT;
|
|
||||||
use cpuio;
|
|
||||||
use ::console;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
struct ScreenChar {
|
|
||||||
ascii_character: u8,
|
|
||||||
color_code: ColorCode,
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! print {
|
|
||||||
($($arg:tt)*) => ({
|
|
||||||
$crate::vga::buffer::print(format_args!($($arg)*));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! println {
|
|
||||||
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
|
||||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print(args: fmt::Arguments) {
|
|
||||||
use core::fmt::Write;
|
|
||||||
unsafe { CONTEXT.current_term().write_fmt(args).unwrap() };
|
|
||||||
unsafe { CONTEXT.current_term().flush() };
|
|
||||||
}
|
|
||||||
|
|
||||||
extern crate core;
|
|
||||||
|
|
||||||
const BUFFER_ROWS: usize = 25;
|
|
||||||
const BUFFER_COLS: usize = 80 * 2;
|
|
||||||
|
|
||||||
pub struct Writer {
|
|
||||||
pub buffer_pos: usize,
|
|
||||||
pub color_code: ColorCode,
|
|
||||||
buffer: [u8; BUFFER_ROWS * BUFFER_COLS],
|
|
||||||
command: [u8; 10],
|
|
||||||
command_len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Writer {
|
|
||||||
pub const fn new() -> Writer {
|
|
||||||
Writer {
|
|
||||||
buffer_pos: 0,
|
|
||||||
color_code: ColorCode::new(Color::White, Color::Black),
|
|
||||||
buffer: [0; BUFFER_ROWS * BUFFER_COLS],
|
|
||||||
command: [b'\0'; 10],
|
|
||||||
command_len: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prompt(&mut self) {
|
|
||||||
let color_code_save = self.color_code;
|
|
||||||
self.color_code = ColorCode::new(Color::Blue, Color::Black);
|
|
||||||
self.write_str("> ");
|
|
||||||
self.color_code = color_code_save;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn backspace(&mut self) {
|
|
||||||
if self.command_len > 0 {
|
|
||||||
self.command_len -= 1;
|
|
||||||
self.erase_byte();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn keypress(&mut self, ascii: u8) {
|
|
||||||
match ascii {
|
|
||||||
b'\n' => {
|
|
||||||
self.write_byte(b'\n');
|
|
||||||
{
|
|
||||||
let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len];
|
|
||||||
match command {
|
|
||||||
"shutdown" | "halt" => console::shutdown(),
|
|
||||||
"reboot" => console::reboot(),
|
|
||||||
"stack" => console::print_kernel_stack(),
|
|
||||||
_ => {
|
|
||||||
let color_code_save = self.color_code;
|
|
||||||
self.color_code = ColorCode::new(Color::Red, Color::Black);
|
|
||||||
println!("`{}': Command unknown ", command);
|
|
||||||
self.color_code = color_code_save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.command_len = 0;
|
|
||||||
self.prompt();
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
self.buffer_pos -= 2;
|
|
||||||
let i = self.buffer_pos;
|
|
||||||
self.buffer[i] = b' ';
|
|
||||||
self.buffer[i + 1] = 0;
|
|
||||||
self.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_byte(&mut self, byte: u8) {
|
|
||||||
let i = self.buffer_pos;
|
|
||||||
|
|
||||||
match byte {
|
|
||||||
|
|
||||||
b'\n' => {
|
|
||||||
let current_line = self.buffer_pos / (BUFFER_COLS);
|
|
||||||
self.buffer_pos = (current_line + 1) * BUFFER_COLS;
|
|
||||||
}
|
|
||||||
byte => {
|
|
||||||
self.buffer[i] = byte;
|
|
||||||
self.buffer[i + 1] = self.color_code.0;
|
|
||||||
self.buffer_pos += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.buffer_pos >= self.buffer.len() {
|
|
||||||
self.scroll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_str(&mut self, s: &str) {
|
|
||||||
for byte in s.bytes() {
|
|
||||||
self.write_byte(byte)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush_cursor(&self)
|
|
||||||
{
|
|
||||||
let cursor_position = self.buffer_pos / 2;
|
|
||||||
// 14 awaits the rightmost 8bits
|
|
||||||
cpuio::outb(14, 0x3D4);
|
|
||||||
cpuio::outb((cursor_position >> 8) as u8, 0x3D5);
|
|
||||||
// 15 awaits the leftmost 8bits
|
|
||||||
cpuio::outb(15, 0x3D4);
|
|
||||||
cpuio::outb((cursor_position >> 0) as u8 & 0x00ff, 0x3D5);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn flush(&mut self) {
|
|
||||||
let slice = unsafe { core::slice::from_raw_parts_mut(0xb8000 as *mut u8, 4000) };
|
|
||||||
slice.as_mut().clone_from_slice(&self.buffer);
|
|
||||||
self.flush_cursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scroll(&mut self) {
|
|
||||||
|
|
||||||
for row in 1..BUFFER_ROWS {
|
|
||||||
for col in 0..BUFFER_COLS {
|
|
||||||
let prev_position = ((row - 1) * BUFFER_COLS) + col;
|
|
||||||
let current_position = (row * BUFFER_COLS) + col;
|
|
||||||
self.buffer[prev_position] = self.buffer[current_position];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for col in 0..BUFFER_COLS/2 {
|
|
||||||
self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col * 2)] = b' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
self.buffer_pos = (BUFFER_ROWS - 1) * BUFFER_COLS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// trait needed by formatting macros
|
|
||||||
use core::fmt;
|
|
||||||
impl fmt::Write for Writer {
|
|
||||||
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
|
|
||||||
for byte in s.bytes() {
|
|
||||||
self.write_byte(byte)
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,22 +5,182 @@ pub mod color;
|
||||||
pub use self::color::{Color, ColorCode};
|
pub use self::color::{Color, ColorCode};
|
||||||
pub use self::buffer::{Writer};
|
pub use self::buffer::{Writer};
|
||||||
|
|
||||||
// use self::buffer::Writer;
|
use super::{Color, ColorCode};
|
||||||
// use core::fmt;
|
use ::context::CONTEXT;
|
||||||
// use core::ptr::Unique;
|
use cpuio;
|
||||||
|
use ::console;
|
||||||
|
|
||||||
// macro_rules! println {
|
#[derive(Debug, Clone, Copy)]
|
||||||
// ($fmt:expr) => (print!(concat!($fmt, "\n")));
|
#[repr(C)]
|
||||||
// ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
struct ScreenChar {
|
||||||
// }
|
ascii_character: u8,
|
||||||
|
color_code: ColorCode,
|
||||||
|
}
|
||||||
|
|
||||||
// macro_rules! print {
|
macro_rules! print {
|
||||||
// ($($arg:tt)*) => ({
|
($($arg:tt)*) => ({
|
||||||
// $crate::vga::print(format_args!($($arg)*));
|
$crate::vga::buffer::print(format_args!($($arg)*));
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// pub fn print(args: fmt::Arguments) {
|
macro_rules! println {
|
||||||
// use core::fmt::Write;
|
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||||
// self::WRITER.write_fmt(args).unwrap();
|
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
pub fn print(args: fmt::Arguments) {
|
||||||
|
use core::fmt::Write;
|
||||||
|
unsafe { CONTEXT.current_term().write_fmt(args).unwrap() };
|
||||||
|
unsafe { CONTEXT.current_term().flush() };
|
||||||
|
}
|
||||||
|
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
|
const BUFFER_ROWS: usize = 25;
|
||||||
|
const BUFFER_COLS: usize = 80 * 2;
|
||||||
|
|
||||||
|
pub struct Writer {
|
||||||
|
pub buffer_pos: usize,
|
||||||
|
pub color_code: ColorCode,
|
||||||
|
buffer: [u8; BUFFER_ROWS * BUFFER_COLS],
|
||||||
|
command: [u8; 10],
|
||||||
|
command_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Writer {
|
||||||
|
pub const fn new() -> Writer {
|
||||||
|
Writer {
|
||||||
|
buffer_pos: 0,
|
||||||
|
color_code: ColorCode::new(Color::White, Color::Black),
|
||||||
|
buffer: [0; BUFFER_ROWS * BUFFER_COLS],
|
||||||
|
command: [b'\0'; 10],
|
||||||
|
command_len: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prompt(&mut self) {
|
||||||
|
let color_code_save = self.color_code;
|
||||||
|
self.color_code = ColorCode::new(Color::Blue, Color::Black);
|
||||||
|
self.write_str("> ");
|
||||||
|
self.color_code = color_code_save;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn backspace(&mut self) {
|
||||||
|
if self.command_len > 0 {
|
||||||
|
self.command_len -= 1;
|
||||||
|
self.erase_byte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keypress(&mut self, ascii: u8) {
|
||||||
|
match ascii {
|
||||||
|
b'\n' => {
|
||||||
|
self.write_byte(b'\n');
|
||||||
|
{
|
||||||
|
let command: &str = &core::str::from_utf8(&self.command).unwrap()[..self.command_len];
|
||||||
|
match command {
|
||||||
|
"shutdown" | "halt" => console::shutdown(),
|
||||||
|
"reboot" => console::reboot(),
|
||||||
|
"stack" => console::print_kernel_stack(),
|
||||||
|
_ => {
|
||||||
|
let color_code_save = self.color_code;
|
||||||
|
self.color_code = ColorCode::new(Color::Red, Color::Black);
|
||||||
|
println!("`{}': Command unknown ", command);
|
||||||
|
self.color_code = color_code_save;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.command_len = 0;
|
||||||
|
self.prompt();
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
self.buffer_pos -= 2;
|
||||||
|
let i = self.buffer_pos;
|
||||||
|
self.buffer[i] = b' ';
|
||||||
|
self.buffer[i + 1] = 0;
|
||||||
|
self.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_byte(&mut self, byte: u8) {
|
||||||
|
let i = self.buffer_pos;
|
||||||
|
|
||||||
|
match byte {
|
||||||
|
|
||||||
|
b'\n' => {
|
||||||
|
let current_line = self.buffer_pos / (BUFFER_COLS);
|
||||||
|
self.buffer_pos = (current_line + 1) * BUFFER_COLS;
|
||||||
|
}
|
||||||
|
byte => {
|
||||||
|
self.buffer[i] = byte;
|
||||||
|
self.buffer[i + 1] = self.color_code.0;
|
||||||
|
self.buffer_pos += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.buffer_pos >= self.buffer.len() {
|
||||||
|
self.scroll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_str(&mut self, s: &str) {
|
||||||
|
for byte in s.bytes() {
|
||||||
|
self.write_byte(byte)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush_cursor(&self)
|
||||||
|
{
|
||||||
|
let cursor_position = self.buffer_pos / 2;
|
||||||
|
// 14 awaits the rightmost 8bits
|
||||||
|
cpuio::outb(14, 0x3D4);
|
||||||
|
cpuio::outb((cursor_position >> 8) as u8, 0x3D5);
|
||||||
|
// 15 awaits the leftmost 8bits
|
||||||
|
cpuio::outb(15, 0x3D4);
|
||||||
|
cpuio::outb((cursor_position >> 0) as u8 & 0x00ff, 0x3D5);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flush(&mut self) {
|
||||||
|
let slice = unsafe { core::slice::from_raw_parts_mut(0xb8000 as *mut u8, 4000) };
|
||||||
|
slice.as_mut().clone_from_slice(&self.buffer);
|
||||||
|
self.flush_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scroll(&mut self) {
|
||||||
|
|
||||||
|
for row in 1..BUFFER_ROWS {
|
||||||
|
for col in 0..BUFFER_COLS {
|
||||||
|
let prev_position = ((row - 1) * BUFFER_COLS) + col;
|
||||||
|
let current_position = (row * BUFFER_COLS) + col;
|
||||||
|
self.buffer[prev_position] = self.buffer[current_position];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for col in 0..BUFFER_COLS/2 {
|
||||||
|
self.buffer[((BUFFER_ROWS - 1) * BUFFER_COLS) + (col * 2)] = b' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
self.buffer_pos = (BUFFER_ROWS - 1) * BUFFER_COLS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trait needed by formatting macros
|
||||||
|
use core::fmt;
|
||||||
|
impl fmt::Write for Writer {
|
||||||
|
fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
|
||||||
|
for byte in s.bytes() {
|
||||||
|
self.write_byte(byte)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue