From 50b42eda0d785c290ecee2510af05177c4975a3f Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Wed, 2 Feb 2022 13:36:08 -0700 Subject: [PATCH] VBE mode info in Rust binary --- src/lib.rs | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f6d5347..5e298c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,6 +55,61 @@ impl ThunkData { } } +#[derive(Clone, Copy, Debug)] +#[repr(packed)] +pub struct VbeCardInfo { + signature: [u8; 4], + version: u16, + oemstring: u32, + capabilities: u32, + videomodeptr: u32, + totalmemory: u16, + oemsoftwarerev: u16, + oemvendornameptr: u32, + oemproductnameptr: u32, + oemproductrevptr: u32, + reserved: [u8; 222], + oemdata: [u8; 256], +} + +#[derive(Clone, Copy, Debug)] +#[repr(packed)] +pub struct VbeModeInfo { + attributes: u16, + winA: u8, + winB: u8, + granularity: u16, + winsize: u16, + segmentA: u16, + segmentB: u16, + winfuncptr: u32, + bytesperscanline: u16, + xresolution: u16, + yresolution: u16, + xcharsize: u8, + ycharsize: u8, + numberofplanes: u8, + bitsperpixel: u8, + numberofbanks: u8, + memorymodel: u8, + banksize: u8, + numberofimagepages: u8, + unused: u8, + redmasksize: u8, + redfieldposition: u8, + greenmasksize: u8, + greenfieldposition: u8, + bluemasksize: u8, + bluefieldposition: u8, + rsvdmasksize: u8, + rsvdfieldposition: u8, + directcolormodeinfo: u8, + physbaseptr: u32, + offscreenmemoryoffset: u32, + offscreenmemsize: u16, + reserved: [u8; 206], +} + #[derive(Clone, Copy)] #[repr(packed)] pub struct VgaTextBlock { @@ -178,15 +233,59 @@ pub unsafe extern "C" fn kstart( (VgaTextColor::White as u8); } - writeln!(vga, "Arrow keys and space select mode, enter to continue"); + { + // Get card info + let mut data = ThunkData::new(); + data.ax = 0x4F00; + data.di = 0x1000; + data.with(thunk10); + if data.ax == 0x004F { + let card_info = ptr::read(0x1000 as *const VbeCardInfo); + let mut modes = card_info.videomodeptr as *const u16; + loop { + let mode = *modes; + if mode == 0xFFFF { + break; + } + modes = modes.add(1); + + // Get mode info + let mut data = ThunkData::new(); + data.ax = 0x4F01; + // Ask for linear frame buffer with mode + data.cx = mode | (1 << 14); + data.di = 0x2000; + data.with(thunk10); + if data.ax == 0x004F { + let mode_info = ptr::read(0x2000 as *const VbeModeInfo); + + // We only support 32-bits per pixel modes + if mode_info.bitsperpixel == 32 { + writeln!( + vga, + "{}x{}", + mode_info.xresolution, + mode_info.yresolution + ); + } + } else { + writeln!(vga, "Failed to read VBE mode 0x{:04X} info: 0x{:04X}", mode, data.ax); + } + } + } else { + writeln!(vga, "Failed to read VBE card info: 0x{:04X}", data.ax); + } + } + + writeln!(vga, "Arrow keys and space select mode, enter to continue"); loop { // Read keypress let mut data = ThunkData::new(); data.with(thunk16); writeln!( vga, - "'{}' 0x{:02X}", + "{:?} 0x{:02X}", (data.ax as u8) as char, (data.ax >> 8) as u8 ); -- GitLab