1use crate::{TagHeader, TagType};
4use core::fmt;
5use multiboot2_common::{MaybeDynSized, Tag};
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[repr(C, align(8))]
11pub struct VBEInfoTag {
12 header: TagHeader,
13 mode: u16,
14 interface_segment: u16,
15 interface_offset: u16,
16 interface_length: u16,
17 control_info: VBEControlInfo,
18 mode_info: VBEModeInfo,
19}
20
21impl VBEInfoTag {
22 #[must_use]
24 pub fn new(
25 mode: u16,
26 interface_segment: u16,
27 interface_offset: u16,
28 interface_length: u16,
29 control_info: VBEControlInfo,
30 mode_info: VBEModeInfo,
31 ) -> Self {
32 Self {
33 header: TagHeader::new(Self::ID, size_of::<Self>().try_into().unwrap()),
34 mode,
35 interface_segment,
36 interface_offset,
37 interface_length,
38 control_info,
39 mode_info,
40 }
41 }
42
43 #[must_use]
45 pub const fn mode(&self) -> u16 {
46 self.mode
47 }
48
49 #[must_use]
54 pub const fn interface_segment(&self) -> u16 {
55 self.interface_segment
56 }
57 #[must_use]
62 pub const fn interface_offset(&self) -> u16 {
63 self.interface_offset
64 }
65 #[must_use]
70 pub const fn interface_length(&self) -> u16 {
71 self.interface_length
72 }
73 #[must_use]
75 pub const fn control_info(&self) -> VBEControlInfo {
76 self.control_info
77 }
78 #[must_use]
80 pub const fn mode_info(&self) -> VBEModeInfo {
81 self.mode_info
82 }
83}
84
85impl MaybeDynSized for VBEInfoTag {
86 type Header = TagHeader;
87
88 const BASE_SIZE: usize = size_of::<Self>();
89}
90
91impl Tag for VBEInfoTag {
92 type IDType = TagType;
93
94 const ID: TagType = TagType::Vbe;
95}
96
97#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
106#[repr(C, packed)]
107pub struct VBEControlInfo {
108 pub signature: [u8; 4],
110
111 pub version: u16,
113
114 pub oem_string_ptr: u32,
116
117 pub capabilities: VBECapabilities,
119
120 pub mode_list_ptr: u32,
122
123 pub total_memory: u16,
125
126 pub oem_software_revision: u16,
128
129 pub oem_vendor_name_ptr: u32,
131
132 pub oem_product_name_ptr: u32,
134
135 pub oem_product_revision_ptr: u32,
137
138 reserved: [u8; 222],
140
141 oem_data: [u8; 256],
143}
144
145impl fmt::Debug for VBEControlInfo {
146 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147 f.debug_struct("VBEControlInfo")
148 .field("signature", &self.signature)
149 .field("version", &{ self.version })
150 .field("oem_string_ptr", &{ self.oem_string_ptr })
151 .field("capabilities", &{ self.capabilities })
152 .field("mode_list_ptr", &{ self.mode_list_ptr })
153 .field("total_memory", &{ self.total_memory })
154 .field("oem_software_revision", &{ self.oem_software_revision })
155 .field("oem_vendor_name_ptr", &{ self.oem_vendor_name_ptr })
156 .field("oem_product_name_ptr", &{ self.oem_product_name_ptr })
157 .field("oem_product_revision_ptr", &{
158 self.oem_product_revision_ptr
159 })
160 .finish()
161 }
162}
163
164impl Default for VBEControlInfo {
165 fn default() -> Self {
166 Self {
167 signature: Default::default(),
168 version: 0,
169 oem_string_ptr: 0,
170 capabilities: Default::default(),
171 mode_list_ptr: 0,
172 total_memory: 0,
173 oem_software_revision: 0,
174 oem_vendor_name_ptr: 0,
175 oem_product_name_ptr: 0,
176 oem_product_revision_ptr: 0,
177 reserved: [0; 222],
178 oem_data: [0; 256],
179 }
180 }
181}
182
183#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
186#[repr(C, packed)]
187pub struct VBEModeInfo {
188 pub mode_attributes: VBEModeAttributes,
190
191 pub window_a_attributes: VBEWindowAttributes,
193
194 pub window_b_attributes: VBEWindowAttributes,
196
197 pub window_granularity: u16,
199
200 pub window_size: u16,
202
203 pub window_a_segment: u16,
205
206 pub window_b_segment: u16,
208
209 pub window_function_ptr: u32,
211
212 pub pitch: u16,
214
215 pub resolution: (u16, u16),
217
218 pub character_size: (u8, u8),
220
221 pub number_of_planes: u8,
223
224 pub bpp: u8,
226
227 pub number_of_banks: u8,
229
230 pub memory_model: VBEMemoryModel,
232
233 pub bank_size: u8,
235
236 pub number_of_image_pages: u8,
238
239 reserved0: u8,
241
242 pub red_field: VBEField,
244
245 pub green_field: VBEField,
247
248 pub blue_field: VBEField,
250
251 pub reserved_field: VBEField,
253
254 pub direct_color_attributes: VBEDirectColorAttributes,
256
257 pub framebuffer_base_ptr: u32,
259
260 pub offscreen_memory_offset: u32,
266
267 pub offscreen_memory_size: u16,
273
274 reserved1: [u8; 206],
276}
277
278impl fmt::Debug for VBEModeInfo {
279 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280 f.debug_struct("VBEModeInfo")
281 .field("mode_attributes", &{ self.mode_attributes })
282 .field("window_a_attributes", &self.window_a_attributes)
283 .field("window_b_attributes", &self.window_b_attributes)
284 .field("window_granularity", &{ self.window_granularity })
285 .field("window_size", &{ self.window_size })
286 .field("window_a_segment", &{ self.window_a_segment })
287 .field("window_b_segment", &{ self.window_b_segment })
288 .field("window_function_ptr", &{ self.window_function_ptr })
289 .field("pitch", &{ self.pitch })
290 .field("resolution", &{ self.resolution })
291 .field("character_size", &self.character_size)
292 .field("number_of_planes", &self.number_of_planes)
293 .field("bpp", &self.bpp)
294 .field("number_of_banks", &self.number_of_banks)
295 .field("memory_model", &self.memory_model)
296 .field("bank_size", &self.bank_size)
297 .field("number_of_image_pages", &self.number_of_image_pages)
298 .field("red_field", &self.red_field)
299 .field("green_field", &self.green_field)
300 .field("blue_field", &self.blue_field)
301 .field("reserved_field", &self.reserved_field)
302 .field("direct_color_attributes", &self.direct_color_attributes)
303 .field("framebuffer_base_ptr", &{ self.framebuffer_base_ptr })
304 .field("offscreen_memory_offset", &{ self.offscreen_memory_offset })
305 .field("offscreen_memory_size", &{ self.offscreen_memory_size })
306 .finish()
307 }
308}
309
310impl Default for VBEModeInfo {
311 fn default() -> Self {
312 Self {
313 mode_attributes: Default::default(),
314 window_a_attributes: Default::default(),
315 window_b_attributes: Default::default(),
316 window_granularity: 0,
317 window_size: 0,
318 window_a_segment: 0,
319 window_b_segment: 0,
320 window_function_ptr: 0,
321 pitch: 0,
322 resolution: (0, 0),
323 character_size: (0, 0),
324 number_of_planes: 0,
325 bpp: 0,
326 number_of_banks: 0,
327 memory_model: Default::default(),
328 bank_size: 0,
329 number_of_image_pages: 0,
330 reserved0: 0,
331 red_field: Default::default(),
332 green_field: Default::default(),
333 blue_field: Default::default(),
334 reserved_field: Default::default(),
335 direct_color_attributes: Default::default(),
336 framebuffer_base_ptr: 0,
337 offscreen_memory_offset: 0,
338 offscreen_memory_size: 0,
339 reserved1: [0; 206],
340 }
341 }
342}
343
344#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
348#[repr(C, packed)]
349pub struct VBEField {
350 pub size: u8,
352
353 pub position: u8,
356}
357
358bitflags! {
359 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
361 #[repr(transparent)]
362 pub struct VBECapabilities: u32 {
363 const SWITCHABLE_DAC = 0x1;
365
366 const NOT_VGA_COMPATIBLE = 0x2;
368
369 const RAMDAC_FIX = 0x4;
373 }
374}
375
376bitflags! {
377 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
379 #[repr(transparent)]
380 pub struct VBEModeAttributes: u16 {
381 const SUPPORTED = 0x1;
383
384 const TTY_SUPPORTED = 0x4;
386
387 const COLOR = 0x8;
389
390 const GRAPHICS = 0x10;
392
393 const NOT_VGA_COMPATIBLE = 0x20;
395
396 const NO_VGA_WINDOW = 0x40;
400
401 const LINEAR_FRAMEBUFFER = 0x80;
405 }
406}
407
408bitflags! {
409 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
412 #[repr(transparent)]
413 pub struct VBEWindowAttributes: u8 {
414 const RELOCATABLE = 0x1;
416
417 const READABLE = 0x2;
419
420 const WRITABLE = 0x4;
422 }
423}
424
425bitflags! {
426 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
436 #[repr(transparent)]
437 pub struct VBEDirectColorAttributes: u8 {
438 const PROGRAMMABLE = 0x1;
440
441 const RESERVED_USABLE = 0x2;
443 }
444}
445
446#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
448#[repr(u8)]
449#[expect(missing_docs)]
450pub enum VBEMemoryModel {
451 #[default]
452 Text = 0x00,
453 CGAGraphics = 0x01,
454 HerculesGraphics = 0x02,
455 Planar = 0x03,
456 PackedPixel = 0x04,
457 Unchained = 0x05,
458 DirectColor = 0x06,
459 YUV = 0x07,
460}