VGA Output Not Filling The Whole Screen In Qemu (Rust)

48 Views Asked by At

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

QEMU VGA Output

0

There are 0 best solutions below