Skip to content

Commit

Permalink
A blob to reproduce phil-opp/blog_os#403 (comment)
Browse files Browse the repository at this point in the history
  • Loading branch information
user committed Mar 25, 2018
0 parents commit b0756de
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 0 deletions.
Empty file added Xargo.toml
Empty file.
5 changes: 5 additions & 0 deletions dummy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# this file exists just because the only known way to create a custom "Run" command is run a bash script
# Intellij - shame on you!

$@
121 changes: 121 additions & 0 deletions src/vga_buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use core::fmt;
use volatile::Volatile;

const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80;


#[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)]
struct ColorCode(u8);

impl ColorCode {
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<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
}


pub struct Writer {
col_pos: usize,
row_pos: usize,
color_code: ColorCode,
buffer: &'static mut Buffer,
}

impl Writer {
pub fn write_byte(&mut self, byte: u8) {
match byte {
b'\n' => self.newline(),
byte => {
if self.col_pos >= BUFFER_WIDTH {
self.newline();
}

let row = self.row_pos;
let col = self.col_pos;

self.buffer.chars[row][col].write(ScreenChar {
ascii_character: byte,
color_code: self.color_code,
});

self.col_pos += 1;
}
}
}

pub fn write_string(&mut self, s: &str) {
s.bytes().map(|byte| self.write_byte(byte));
}

pub fn newline(&mut self) {
self.col_pos = 0;

if self.row_pos == BUFFER_HEIGHT - 1 {
// move all the rows to one line up
// the first row (upper) is going to be overwritten
for row in 1..BUFFER_HEIGHT {
for col in 0..BUFFER_WIDTH {
let ch = self.buffer.chars[row][col].read();
self.buffer.chars[row - 1][col].write(ch);
}
}

// blank the last (bottom) row
for col in 0..BUFFER_HEIGHT {
let row = BUFFER_HEIGHT - 1;
let ch = ScreenChar { ascii_character: b' ', color_code: self.color_code };

self.buffer.chars[row][col].write(ch);
}
}
else {
self.row_pos += 1;
}
}
}


impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_string(s);
Ok(())
}
}
14 changes: 14 additions & 0 deletions x86_64-blog_os.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"llvm-target": "x86_64-unknown-none",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "-mmx,-sse,+soft-float"
}

0 comments on commit b0756de

Please sign in to comment.