diff --git a/src/lib.rs b/src/lib.rs index 29afba64..8cbf9724 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ // limitations under the License. #![feature(no_std, lang_items)] -#![feature(const_fn)] +#![feature(const_fn, unique)] #![no_std] extern crate rlibc; diff --git a/src/vga_buffer.rs b/src/vga_buffer.rs index efc42ed7..46c5f73a 100644 --- a/src/vga_buffer.rs +++ b/src/vga_buffer.rs @@ -1,3 +1,5 @@ +use core::ptr::Unique; + const BUFFER_HEIGHT: usize = 25; const BUFFER_WIDTH: usize = 80; @@ -21,6 +23,55 @@ pub enum Color { White = 15, } +pub struct Writer { + column_position: usize, + color_code: ColorCode, + buffer: Unique, +} + +impl Writer { + pub fn write_byte(&mut self, byte: u8) { + match byte { + b'\n' => self.new_line(), + byte => { + if self.column_position >= BUFFER_WIDTH { + self.new_line(); + } + let row = BUFFER_HEIGHT - 1; + let col = self.column_position; + + self.buffer().chars[row][col] = ScreenChar { + ascii_character: byte, + color_code: self.color_code, + }; + self.column_position += 1; + } + } + } + + fn buffer(&mut self) -> &mut Buffer { + unsafe{self.buffer.get_mut()} + } + + fn new_line(&mut self) { + for row in 0..(BUFFER_HEIGHT-1) { + let buffer = self.buffer(); + buffer.chars[row] = buffer.chars[row + 1] + } + self.clear_row(BUFFER_HEIGHT-1); + self.column_position = 0; + } + + fn clear_row(&mut self, row: usize) { + let blank = ScreenChar { + ascii_character: ' ' as u8, + color_code: self.color_code, + }; + self.buffer().chars[row] = [blank; BUFFER_WIDTH]; + } +} + +#[derive(Clone, Copy)] struct ColorCode(u8); impl ColorCode { @@ -29,6 +80,7 @@ impl ColorCode { } } +#[derive(Clone, Copy)] struct ScreenChar { ascii_character: u8, color_code: ColorCode,