-use core::ops::{AddAssign, Shl};
+use core::ops::{AddAssign, Deref, DerefMut, Shl, Sub};
+
+use volatile::Volatile;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
color_code: ColorCode,
}
+impl Deref for ScreenChar {
+ type Target = ScreenChar;
+
+ fn deref(&self) -> &Self::Target {
+ self
+ }
+}
+
+impl DerefMut for ScreenChar {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ self
+ }
+}
+
const BUFFER_WIDTH: usize = 80;
const BUFFER_HEIGHT: usize = 25;
#[repr(transparent)]
struct Buffer {
- chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
+ chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
pub struct Writer {
}
impl Writer {
+ #[inline(always)]
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.new_line(),
let col = self.column_position;
let color_code = self.color_code;
- self.buffer.chars[row][col] = ScreenChar {
+ self.buffer.chars[row][col].write(ScreenChar {
ascii_character: byte,
color_code,
- };
+ });
self.column_position.add_assign(1);
},
}
}
+ #[inline(always)]
pub fn write_string(&mut self, s: &str) {
for byte in s.bytes() {
match byte {
}
}
+ #[inline(always)]
fn new_line(&mut self) {
+ if self.row_position >= BUFFER_HEIGHT {
+ for row in 1..BUFFER_HEIGHT {
+ for col in 0..BUFFER_WIDTH {
+ let character = self.buffer.chars[row][col].read();
+ self.buffer.chars[row.sub(1)][col].write(character);
+ }
+ }
+
+ self.clear_row(BUFFER_HEIGHT.sub(1));
+ }
+ self.row_position.add_assign(1);
+ self.column_position = 0;
+ }
+
+ fn clear_row(&mut self, row: usize) {
+ let blank = ScreenChar {
+ ascii_character: b' ',
+ color_code: self.color_code,
+ };
+
+ for col in 0..BUFFER_WIDTH {
+ self.buffer.chars[row][col].write(blank);
+ }
}
}