On my bare-metal application, I am trying loop over a custom function, to print in VGA mode, to fill the whole screen, but to my surprise it doesn't fill the whole screen, it only fills 4 and 1/5 rows instead of 25 full rows.
//main.rs
#![no_std]
#![no_main]
use core::panic::PanicInfo;
mod vga_buffer;
use vga_buffer::*;
use vga_buffer::Color::*;
#[panic_handler]
fn panic(_info: &PanicInfo) -> !{ loop{} }
#[no_mangle]
pub extern "C" fn _start() -> ! {
// print(b"\n\n\nThe ", White);
// print(b"Great ", Red);
// print(b"Journey ", Blue);
// print(b"Has ", Yellow);
// print(b"Begun", Pink);
loop { print(b"!", White); }
}
//vga_buffer.rs
use lazy_static::lazy_static;
use spin::Mutex;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[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
}
lazy_static! {
pub static ref VGA_COLUMN: Mutex<u8> = Mutex::new(0);
pub static ref VGA_ROW: Mutex<u8> = Mutex::new(0);
}
pub fn print(text: &[u8], color: Color){
let vga_buffer = 0xb8000 as *mut u8;
for (_, &byte) in text.iter().enumerate() {
if byte == b'\n' {
*VGA_COLUMN.lock() = 0;
*VGA_ROW.lock() += 1;
}
else if byte == b'\t'{
*VGA_COLUMN.lock() += 4;
if *VGA_COLUMN.lock() >= 80 {
*VGA_COLUMN.lock() -= 80;
*VGA_ROW.lock() += 1;
}
} else {
unsafe {
*vga_buffer.offset((*VGA_ROW.lock() * 80 + *VGA_COLUMN.lock()) as isize * 2) = byte;
*vga_buffer.offset((*VGA_ROW.lock() * 80 + *VGA_COLUMN.lock()) as isize * 2 + 1) = color as u8;
}
*VGA_COLUMN.lock() += 1;
if *VGA_COLUMN.lock() >= 80 {
// Wrap text to the next line when we reach the end of a *VGA_ROW.lock()
*VGA_COLUMN.lock() = 0;
*VGA_ROW.lock() += 1;
}
}
}
}
#Makefile
run:
clear
cargo bootimage
qemu-system-x86_64 -drive format=raw,file=target/x86_64-hayabusa/debug/bootimage-hayabusa.bin
