Skip to content

Commit

Permalink
Use volatile accesses in VGA code and make font dependency optional (#67
Browse files Browse the repository at this point in the history
)
  • Loading branch information
64 authored and phil-opp committed Jul 16, 2019
1 parent 369821f commit 0e7f27d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 26 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ fixedvec = "0.2.3"
version = "0.2.4"
default-features = false
features = ["unicode"]
optional = true

[build-dependencies]
llvm-tools = "0.1"

[features]
default = []
vga_320x200 = []
vga_320x200 = ["font8x8"]
recursive_page_table = []
map_physical_memory = []

Expand Down
3 changes: 3 additions & 0 deletions src/printer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ pub use self::vga_text_80x25::*;
#[cfg(feature = "vga_320x200")]
pub use self::vga_320x200::*;

#[cfg(feature = "vga_320x200")]
mod vga_320x200;

#[cfg(not(feature = "vga_320x200"))]
mod vga_text_80x25;
25 changes: 12 additions & 13 deletions src/printer/vga_320x200.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
use core::fmt::{Result, Write};
use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering};

const VGA_BUFFER: *mut u8 = 0xa0000 as *mut _;
const SCREEN_WIDTH: usize = 320;
const SCREEN_HEIGHT: usize = 200;

pub static X_POS: AtomicUsize = AtomicUsize::new(1); // must not be 0 so that we don't have a .bss section
pub static Y_POS: AtomicUsize = AtomicUsize::new(1); // must not be 0 so that we don't have a .bss section
// must not be 0 so that we don't have a .bss section
pub static X_POS: AtomicUsize = AtomicUsize::new(1);
pub static Y_POS: AtomicUsize = AtomicUsize::new(1);

pub struct Printer;

impl Printer {
pub fn clear_screen(&mut self) {
let vga_buffer = Self::vga_buffer();
for byte in vga_buffer {
*byte = 0x00;
for i in 0..(SCREEN_WIDTH * SCREEN_HEIGHT) {
unsafe {
VGA_BUFFER.offset(i as isize).write_volatile(0);
}
}

X_POS.store(0, Ordering::SeqCst);
Y_POS.store(0, Ordering::SeqCst);
}

fn vga_buffer() -> &'static mut [u8] {
unsafe { slice::from_raw_parts_mut(VGA_BUFFER, SCREEN_WIDTH * SCREEN_HEIGHT) }
}

fn newline(&mut self) {
let y_pos = Y_POS.fetch_add(8, Ordering::SeqCst);
X_POS.store(0, Ordering::SeqCst);
Expand All @@ -41,8 +39,6 @@ impl Printer {
return;
}

let vga_buffer = Self::vga_buffer();

let x_pos = X_POS.fetch_add(8, Ordering::SeqCst);
let y_pos = Y_POS.load(Ordering::SeqCst);

Expand All @@ -57,7 +53,10 @@ impl Printer {
continue;
}
let color = 0xf;
vga_buffer[(y_pos + y) * SCREEN_WIDTH + x_pos + x] = color;
let idx = (y_pos + y) * SCREEN_WIDTH + x_pos + x;
unsafe {
VGA_BUFFER.offset(idx as isize).write_volatile(color);
}
}
}
}
Expand Down
24 changes: 12 additions & 12 deletions src/printer/vga_text_80x25.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
use core::fmt::{Result, Write};
use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering};

const VGA_BUFFER: *mut u8 = 0xb8000 as *mut _;
const SCREEN_SIZE: usize = 80 * 25;

// must not be 0 so that we don't have a .bss section
pub static CURRENT_OFFSET: AtomicUsize = AtomicUsize::new(160);

pub struct Printer;

impl Printer {
pub fn clear_screen(&mut self) {
let vga_buffer = Self::vga_buffer();
for byte in vga_buffer {
*byte = 0;
for i in 0..SCREEN_SIZE {
unsafe {
VGA_BUFFER.offset(i as isize).write_volatile(0);
}
}
CURRENT_OFFSET.store(0, Ordering::Relaxed);
}

fn vga_buffer() -> &'static mut [u8] {
unsafe { slice::from_raw_parts_mut(VGA_BUFFER, SCREEN_SIZE * 2) }
CURRENT_OFFSET.store(0, Ordering::Relaxed);
}
}

impl Write for Printer {
fn write_str(&mut self, s: &str) -> Result {
let vga_buffer = Self::vga_buffer();
for byte in s.bytes() {
let index = CURRENT_OFFSET.fetch_add(2, Ordering::Relaxed);
vga_buffer[index] = byte;
vga_buffer[index + 1] = 0x4f;
let index = CURRENT_OFFSET.fetch_add(2, Ordering::Relaxed) as isize;

unsafe {
VGA_BUFFER.offset(index).write_volatile(byte);
VGA_BUFFER.offset(index + 1).write_volatile(0x4f);
}
}

Ok(())
Expand Down

0 comments on commit 0e7f27d

Please sign in to comment.