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]
|
|
|
|
|
|
2015-11-08 01:09:07 -08:00
|
|
|
extern crate rlibc;
|
|
|
|
|
|
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);
|
2015-11-07 23:11:07 -08:00
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
|
|
2015-11-10 01:25:46 -08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-07 22:53:31 -08:00
|
|
|
#[lang = "eh_personality"]
|
|
|
|
|
extern fn eh_personality() {}
|
|
|
|
|
|
|
|
|
|
#[lang = "panic_fmt"]
|
|
|
|
|
extern fn panic_fmt() -> ! { loop {}}
|