Files
low-level-programming/rust_experiments/src/lib.rs

220 lines
5.0 KiB
Rust
Raw Normal View History

2015-11-07 22:53:31 -08:00
2015-11-08 03:05:27 -08:00
#![feature(no_std, lang_items, const_fn)]
2015-11-07 22:53:31 -08:00
#![no_std]
#[cfg(test)]
#[macro_use]
extern crate std;
extern crate rlibc;
extern {
fn asm_printchar() -> u32;
fn get_rdtsc() -> u32;
}
2015-11-07 22:53:31 -08:00
#[no_mangle]
2015-11-07 23:11:07 -08:00
pub extern fn rust_main() {
2015-11-10 00:46:08 -08:00
clear();
2015-11-10 00:52:26 -08:00
checkerboard(vga_buffer::Color::Red);
unsafe {
let a = asm_printchar();
if a == 1 {
checkerboard(vga_buffer::Color::Blue);
}
}
2015-11-07 23:11:07 -08:00
let mut cur_checkerboard = vga_buffer::Color::Red;
let mut update_checkerboard = move || {
cur_checkerboard = match cur_checkerboard {
vga_buffer::Color::Red => vga_buffer::Color::Blue,
_ => vga_buffer::Color::Red,
};
checkerboard(cur_checkerboard);
};
let mut timer;
let mut prev_timer = 0;
let mut count: u32 = 0;
loop {
timer = unsafe { get_rdtsc() };
let color_code = vga_buffer::ColorCode::new(vga_buffer::Color::White, vga_buffer::Color::Black);
if timer - prev_timer > 4_000_000_000 {
update_checkerboard();
let s = util::u32_to_chars(timer);
vga_buffer::print_array(s, 10, color_code);
vga_buffer::print_array(
util::u32_to_chars(count), 11, color_code);
count += 1;
timer = 0;
}
}
2015-11-10 00:46:08 -08:00
loop {}
}
2015-11-08 03:05:27 -08:00
2015-11-10 00:46:08 -08:00
fn clear() {
2015-11-10 00:52:26 -08:00
use vga_buffer::*;
2015-11-08 03:05:27 -08:00
2015-11-10 00:52:26 -08:00
let blank_color = ColorCode::new( Color::White, Color::Black);
for i in 0..BUFFER_WIDTH {
for j in 0..BUFFER_HEIGHT {
write_to_coord(i, j, b' ', blank_color);
}
}
}
fn checkerboard(color: vga_buffer::Color) {
use vga_buffer::*;
let active = ColorCode::new(color, color);
let blank = ColorCode::new(Color::White, Color::Black);
for i in 0..BUFFER_WIDTH {
for j in 0..BUFFER_HEIGHT {
if (i + j) % 2 == 0 {
write_to_coord(i, j, b' ', active);
} else {
write_to_coord(i, j, b' ', blank);
}
2015-11-10 00:46:08 -08:00
}
}
2015-11-07 23:11:07 -08:00
}
2015-11-07 22:53:31 -08:00
// 123 |3,2,1
mod util {
pub fn u32_to_chars(n: u32) -> [u8; 10] {
let mut accum = [0; 10];
let mut i = 0;
let mut val = n;
loop {
if val < 10 {
let ch = b'0' + (val as u8);
accum[i] = ch;
break;
} else {
let ch = b'0' + ((val % 10) as u8);
val = val / 10;
accum[i] = ch;
i += 1;
}
}
let mut output = [0; 10];
let mut j = 0;
loop {
output[j] = accum[i];
j += 1;
if i == 0 { break; }
i -= 1;
}
output
}
#[test]
fn test_u32_to_chars() {
assert_eq!(u32_to_chars(12345), [b'1', b'2', b'3', b'4', b'5', 0, 0, 0, 0, 0]);
assert_eq!(u32_to_chars(9), [b'9', 0, 0, 0, 0, 0, 0, 0, 0, 0]);
}
}
2015-11-08 03:05:27 -08:00
mod vga_buffer {
#[repr(u8)]
2015-11-10 00:52:26 -08:00
#[derive(Clone, Copy)]
2015-11-08 03:05:27 -08:00
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(Clone, Copy)]
2015-11-10 00:46:08 -08:00
pub struct ColorCode(u8);
2015-11-08 03:05:27 -08:00
impl ColorCode {
2015-11-10 00:46:08 -08:00
pub const fn new(foreground: Color, background: Color) -> ColorCode {
2015-11-08 03:05:27 -08:00
ColorCode((background as u8) << 4 | (foreground as u8))
}
}
#[repr(C)]
struct ScreenChar {
ascii_char: u8,
color_code: ColorCode
}
2015-11-10 00:46:08 -08:00
pub const BUFFER_HEIGHT: usize = 25;
pub const BUFFER_WIDTH: usize = 80;
2015-11-08 03:05:27 -08:00
const BUFFER_PTR: usize = 0xb8000;
pub fn charloop() {
for ch in 32..255 {
let ptr = BUFFER_PTR + 2*ch as usize;
let data = ScreenChar {
ascii_char: ch,
color_code: ColorCode::new(Color::Black, Color::White)
};
unsafe {
*(ptr as *mut _) = data;
}
}
}
pub fn print_array(array: [u8; 10], line: usize, color_code: ColorCode) {
let mut x = 0;
for ch in array.into_iter() {
if *ch == 0 {
break;
}
write_to_coord(x, line, *ch, color_code);
x += 1;
}
}
2015-11-10 00:46:08 -08:00
pub fn write_to_coord(x: usize, y: usize, character: u8, color_code: ColorCode) {
let ptr = BUFFER_PTR + (2*x as usize) + (BUFFER_WIDTH*2*y as usize);
2015-11-08 03:05:27 -08:00
let data = ScreenChar {
ascii_char: character,
2015-11-10 00:46:08 -08:00
color_code: color_code,
2015-11-08 03:05:27 -08:00
};
2015-11-10 00:46:08 -08:00
if x > BUFFER_WIDTH || y > BUFFER_HEIGHT {
return;
}
2015-11-08 03:05:27 -08:00
unsafe {
*(ptr as *mut _) = data;
}
}
}
#[cfg(not(test))]
2015-11-07 22:53:31 -08:00
#[lang = "eh_personality"]
extern fn eh_personality() {}
#[cfg(not(test))]
2015-11-07 22:53:31 -08:00
#[lang = "panic_fmt"]
extern fn panic_fmt() -> ! { loop {}}