use crate::dev::virtio::framebuffer_update; use crate::dev::{FRAMEBUFFER_ADDR, FRAMEBUFFER_BPP, FRAMEBUFFER_HEIGHT, FRAMEBUFFER_WIDTH}; use crate::trafficcontrol::TrafficControl; use core::sync::atomic::Ordering; pub mod console; pub const VAPFONT: &[u8] = include_bytes!("./vapfont.data"); pub const VAPFONT_W: usize = 256; pub const VAPFONT_H: usize = 112; pub struct FBColor { pub red: u8, pub green: u8, pub blue: u8, } pub const FB_BG_COLOR: FBColor = FBColor { red: 216, green: 216, blue: 216, }; pub const FB_FG_COLOR: FBColor = FBColor { red: 0, green: 0, blue: 0, }; impl FBColor { #[inline] pub const fn to_bytes(&self) -> [u8; 3] { [self.red, self.green, self.blue] } } pub fn fb_write_char_array(tc: &mut TrafficControl, mut x: usize, y: usize, chars: &[char]) { let ogx = x; let ogy = y; const BYTES: [u8; 3] = FB_FG_COLOR.to_bytes(); let fbaddr = FRAMEBUFFER_ADDR.load(Ordering::Relaxed); if fbaddr == 0 { return; } let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH; const CHAR_SIZE: usize = 16; for c in chars { let c = *c; if c == ' ' { x += CHAR_SIZE; } else if c as u8 > 32 { let c = c as u8 - 32; let cx = (c % 16) as usize * CHAR_SIZE; let cy = (c / 16) as usize * CHAR_SIZE; for row in 0..CHAR_SIZE { for col in 0..CHAR_SIZE { let coff = (VAPFONT_W * (cy + row)) + (cx + col); let draw = VAPFONT[coff / 8] & (0x80 >> (coff % 8)); if draw != 0 { unsafe { let fb = (fbaddr as *mut u8) .add(((y + row) * fbstride) + ((x + col) * 4)) as *mut u32; fb.write_volatile(u32::from_ne_bytes([ 0, BYTES[0], BYTES[1], BYTES[2], ])); } } } } x += CHAR_SIZE; } } framebuffer_update( tc, 0, 0, FRAMEBUFFER_WIDTH as u32, FRAMEBUFFER_HEIGHT as u32, ); } pub fn fb_clearscreen(tc: &mut TrafficControl) { const BYTES: [u8; 3] = FB_BG_COLOR.to_bytes(); let fbaddr = FRAMEBUFFER_ADDR.load(Ordering::Relaxed); if fbaddr == 0 { return; } let fbstride = FRAMEBUFFER_BPP.load(Ordering::Relaxed) * FRAMEBUFFER_WIDTH; for y in 0..FRAMEBUFFER_HEIGHT { for x in 0..FRAMEBUFFER_WIDTH { unsafe { let fb = (fbaddr as *mut u8).add(((y) * fbstride) + ((x) * 4)) as *mut u32; fb.write_volatile(u32::from_ne_bytes([0, BYTES[0], BYTES[1], BYTES[2]])); } } } framebuffer_update( tc, 0, 0, FRAMEBUFFER_WIDTH as u32, FRAMEBUFFER_HEIGHT as u32, ); }