diff --git a/src/devices/bochs.rs b/src/devices/bochs.rs index 8794ab8..22064cb 100644 --- a/src/devices/bochs.rs +++ b/src/devices/bochs.rs @@ -1,5 +1,5 @@ use super::pci::{find_pci_device, PciDevice, PciHeader}; -use crate::writers::GraphicsWriter; +use crate::drawing::{Bresenham, Point, Rectangle}; use x86_64::{instructions::port::Port, PhysAddr, VirtAddr}; const BOCHS_ID: u32 = 0x1111_1234; @@ -17,25 +17,18 @@ const VBE_DISPI_GETCAPS: u16 = 0x02; const VBE_DISPI_LFB_ENABLED: u16 = 0x40; const VBE_DISPI_BPP_32: u16 = 0x20; -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Default)] pub struct Resolution { - width: u16, - height: u16, + width: usize, + height: usize, } impl Resolution { - pub fn new(width: u16, height: u16) -> Resolution { + pub fn new(width: usize, height: usize) -> Resolution { Resolution { width, height } } } -#[derive(Debug, Copy, Clone)] -pub struct Capabilities { - width: u16, - height: u16, - bpp: u16, -} - #[derive(Debug)] pub struct BochsDevice { index_port: Port, @@ -43,6 +36,7 @@ pub struct BochsDevice { pci_device: PciDevice, physical_address: PhysAddr, virtual_address: VirtAddr, + current_resolution: Resolution, } impl BochsDevice { @@ -61,6 +55,7 @@ impl BochsDevice { data_port, physical_address, virtual_address, + current_resolution: Resolution::default(), }) } else { None @@ -79,7 +74,7 @@ impl BochsDevice { self.virtual_address = virtual_address; } - pub fn capabilities(&mut self) -> Capabilities { + pub fn capabilities(&mut self) -> Resolution { unsafe { // Save original value of VBE_DISPI_INDEX_ENABLE self.index_port.write(VBE_DISPI_INDEX_ENABLE); @@ -88,21 +83,51 @@ impl BochsDevice { // Read max width self.index_port.write(VBE_DISPI_INDEX_XRES); - let width = self.data_port.read(); + let width = self.data_port.read() as usize; // Read max height self.index_port.write(VBE_DISPI_INDEX_YRES); - let height = self.data_port.read(); - - // Read max bpp - self.index_port.write(VBE_DISPI_INDEX_BPP); - let bpp = self.data_port.read(); + let height = self.data_port.read() as usize; // Restore original VBE_DISPI_INDEX_ENABLE self.index_port.write(VBE_DISPI_INDEX_ENABLE); self.data_port.write(original_value); - Capabilities { width, height, bpp } + Resolution { width, height } + } + } + + pub fn clear_screen(&self, color: u32) { + let screen_size = self.current_resolution.width * self.current_resolution.height; + let frame_buffer = self.virtual_address.as_mut_ptr::(); + for offset in 0..screen_size { + unsafe { + frame_buffer.add(offset).write_volatile(color); + } + } + } + + pub fn draw_line(&self, start: Point, end: Point, color: u32) { + for (x, y) in Bresenham::new(start, end) { + self.set_pixel(x as usize, y as usize, color); + } + } + + pub fn fill_rectangle(&self, rectangle: &Rectangle, color: u32) { + for y in rectangle.top..rectangle.bottom { + for x in rectangle.left..rectangle.right { + self.set_pixel(x, y, color); + } + } + } + + pub fn set_pixel(&self, x: usize, y: usize, color: u32) { + let offset = (y * self.current_resolution.width) + x; + unsafe { + self.virtual_address + .as_mut_ptr::() + .add(offset) + .write_volatile(color); } } @@ -133,33 +158,34 @@ impl BochsDevice { self.set_height(resolution.height); self.set_bpp(); self.enable_display(); + self.current_resolution = resolution; } - pub fn get_width(&mut self) -> u16 { + pub fn get_width(&mut self) -> usize { unsafe { self.index_port.write(VBE_DISPI_INDEX_XRES); - self.data_port.read() + self.data_port.read() as usize } } - pub fn get_height(&mut self) -> u16 { + pub fn get_height(&mut self) -> usize { unsafe { self.index_port.write(VBE_DISPI_INDEX_YRES); - self.data_port.read() + self.data_port.read() as usize } } - fn set_width(&mut self, width: u16) { + fn set_width(&mut self, width: usize) { unsafe { self.index_port.write(VBE_DISPI_INDEX_XRES); - self.data_port.write(width); + self.data_port.write(width as u16); } } - fn set_height(&mut self, height: u16) { + fn set_height(&mut self, height: usize) { unsafe { self.index_port.write(VBE_DISPI_INDEX_YRES); - self.data_port.write(height); + self.data_port.write(height as u16); } } diff --git a/src/drawing/mod.rs b/src/drawing/mod.rs index 5d15c03..5c36d16 100644 --- a/src/drawing/mod.rs +++ b/src/drawing/mod.rs @@ -11,6 +11,25 @@ use octant::Octant; /// A point in 2D space. pub type Point = (T, T); +#[derive(Debug, Copy, Clone)] +pub struct Rectangle { + pub left: usize, + pub top: usize, + pub right: usize, + pub bottom: usize, +} + +impl Rectangle { + pub fn new(left: usize, top: usize, right: usize, bottom: usize) -> Rectangle { + Rectangle { + left, + top, + right, + bottom, + } + } +} + pub(crate) trait SignedNum: Signed + Ord + Copy + NumCast + NumAssignOps { fn cast(value: T) -> Self { NumCast::from(value).unwrap()