ableos_userland/drivers/graphics/vgable/src/main.rs

120 lines
3.7 KiB
Rust

#![no_std]
#![no_main]
use core::ptr;
use able_graphics_library::engine3d::display::parse_display_string;
const VGA_ADDRESS: *mut u8 = 0xB8000 as *mut u8;
#[no_mangle]
fn start() {
// TODO: Initialize the VGA hardware and configure it to the desired video mode
// (e.g. 640x480, 800x600, etc.).
let result = parse_display_string("680x480x16@60");
use able_graphics_library::engine3d::display::DisplayError::*;
match result {
Ok(display) => {
let (width, height, bpp, fps) = display;
let vga_mode = VGAMode::get_vga_mode(width, height, bpp).unwrap_or(VGAMode::Mode0);
let mut vga_state = VGAState::new(vga_mode);
}
Err(err) => match err {
InvalidFormat => panic!("Invalid format"),
InvalidWidth => panic!("Invalid width"),
InvalidHeight => panic!("Invalid height"),
InvalidBPP => panic!("Invalid bpp"),
InvalidFPS => panic!("Invalid fps"),
},
}
}
#[derive(Debug, Clone, Copy)]
enum VGAMode {
Mode0 = 0, //: 640x480 pixels, 16 colors
Mode1 = 1, //: 640x480 pixels, 256 colors
Mode2 = 2, //: 640x480 pixels, 16-bit color
Mode3 = 3, //: 800x600 pixels, 16 colors
Mode4 = 4, //: 800x600 pixels, 256 colors
Mode5 = 5, //: 800x600 pixels, 16-bit color
Mode6 = 6, //: 1024x768 pixels, 16 colors
Mode7 = 7, //: 1024x768 pixels, 256 colors
Mode8 = 8, //: 1024x768 pixels, 16-bit color
Mode9 = 9, //: 1280x1024 pixels, 16 colors
Mode10 = 10, //: 1280x1024 pixels, 256 colors
Mode11 = 11, //: 1280x1024 pixels, 16-bit color
}
impl VGAMode {
fn get_vga_mode(width: u32, height: u32, bpp: u32) -> Option<VGAMode> {
match (width, height, bpp) {
(640, 480, 4) => Some(VGAMode::Mode0),
(640, 480, 8) => Some(VGAMode::Mode1),
(640, 480, 16) => Some(VGAMode::Mode2),
(800, 600, 4) => Some(VGAMode::Mode3),
(800, 600, 8) => Some(VGAMode::Mode4),
(800, 600, 16) => Some(VGAMode::Mode5),
(1024, 768, 4) => Some(VGAMode::Mode6),
(1024, 768, 8) => Some(VGAMode::Mode7),
(1024, 768, 16) => Some(VGAMode::Mode8),
(1280, 1024, 4) => Some(VGAMode::Mode9),
(1280, 1024, 8) => Some(VGAMode::Mode10),
(1280, 1024, 16) => Some(VGAMode::Mode11),
_ => None,
}
}
}
#[allow(dead_code)]
struct VGAState<'a> {
mode: VGAMode,
buffer: &'a mut u8,
}
#[allow(dead_code)]
impl<'a> VGAState<'a> {
fn new(mode: VGAMode) -> Self {
let mut state = Self {
mode,
buffer: unsafe { &mut *VGA_ADDRESS },
};
unsafe {
state.initialize_hardware();
}
state
}
unsafe fn set_vga_mode(&mut self, mode: VGAMode) {
self.mode = mode;
// Set registers here
}
unsafe fn initialize_hardware(&mut self) {
// set vga mode
self.set_vga_mode(self.mode)
// initalize the graphics lib to be usable
}
unsafe fn set_register(address: u16, value: u8) -> Result<(), VGAError> {
let address_ptr = address as *mut u8;
let value_ptr = value as u8;
// TODO: check if this works
ptr::write_volatile(address_ptr, value_ptr);
let read_value = Self::read_register(address);
if read_value != value {
return Err(VGAError::WrittenValueNotReadValue);
}
Ok(())
}
unsafe fn read_register(address: u16) -> u8 {
let address_ptr = address as *mut u8;
ptr::read_volatile(address_ptr)
}
}
pub enum VgaRegister {}
pub enum VGAError {
/// The value written is not the same as the value read
WrittenValueNotReadValue,
}