summaryrefslogtreecommitdiffstats
path: root/rsnix/src/gop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/gop.rs')
-rw-r--r--rsnix/src/gop.rs44
1 files changed, 36 insertions, 8 deletions
diff --git a/rsnix/src/gop.rs b/rsnix/src/gop.rs
index 8e804e5..012a9d0 100644
--- a/rsnix/src/gop.rs
+++ b/rsnix/src/gop.rs
@@ -293,13 +293,16 @@ pub fn init(gop: &mut GraphicsOutputProtocol) {
293 .map(|c| core::str::from_utf8(c).unwrap_or("?")) 293 .map(|c| core::str::from_utf8(c).unwrap_or("?"))
294 .collect(); 294 .collect();
295 dump_lines(&lines); 295 dump_lines(&lines);
296 crate::gop::boot_marker("gop: NO-SHADOW (fallback mode)"); 296 crate::gop::boot_marker_at("gop: NO-SHADOW (fallback)", bottom_row(0));
297 } else { 297 } else {
298 crate::gop::boot_marker(&alloc::format!( 298 crate::gop::boot_marker_at(
299 "gop: shadow {:#x} {:.2} MiB", 299 &alloc::format!(
300 SHADOW as usize, 300 "gop: shadow {:#x} {:.2} MiB",
301 swords as f64 * 4.0 / 1048576.0 301 SHADOW as usize,
302 )); 302 swords as f64 * 4.0 / 1048576.0
303 ),
304 bottom_row(0),
305 );
303 } 306 }
304 } 307 }
305 } 308 }
@@ -313,6 +316,16 @@ pub fn init(gop: &mut GraphicsOutputProtocol) {
313/// direct-display glyph path (the shadow may not exist yet in early 316/// direct-display glyph path (the shadow may not exist yet in early
314/// boot); the shell banner overwrites row 0 at first paint. 317/// boot); the shell banner overwrites row 0 at first paint.
315pub fn boot_marker(msg: &str) { 318pub fn boot_marker(msg: &str) {
319 boot_marker_at(msg, 0);
320}
321
322/// boot_marker at an explicit text row. The shell's first paint
323/// occupies grid rows 0 (motd) and 1 (=== banner) and the prompt sits
324/// at row 2 — markers whose *values* matter after boot (shadow state,
325/// vt grid pointers) are anchored to the bottom of the screen via
326/// `bottom_row`, which also survives a stale crash.log replay (the
327/// fault band is ~20 lines starting at grid row 2).
328pub fn boot_marker_at(msg: &str, row: usize) {
316 // Record the stage so a later panic band can show how far boot got. 329 // Record the stage so a later panic band can show how far boot got.
317 unsafe { 330 unsafe {
318 let n = msg.len().min(STAGE_MAX); 331 let n = msg.len().min(STAGE_MAX);
@@ -323,24 +336,39 @@ pub fn boot_marker(msg: &str) {
323 let Some(fb) = fb().as_ref() else { 336 let Some(fb) = fb().as_ref() else {
324 return; 337 return;
325 }; 338 };
339 if row >= fb.height / 16 {
340 return;
341 }
326 let cols = fb.width / 8; 342 let cols = fb.width / 8;
327 let white = (0xFFu8, 0xFFu8, 0xFFu8); 343 let white = (0xFFu8, 0xFFu8, 0xFFu8);
328 let black = (0x00u8, 0x00u8, 0x00u8); 344 let black = (0x00u8, 0x00u8, 0x00u8);
329 let mut c = 0usize; 345 let mut c = 0usize;
330 for &b in msg.as_bytes().iter().take(cols) { 346 for &b in msg.as_bytes().iter().take(cols) {
331 if b < 0x80 { 347 if b < 0x80 {
332 blit_glyph(c, 0, b as u16, white, black); 348 blit_glyph(c, row, b as u16, white, black);
333 c += 1; 349 c += 1;
334 } 350 }
335 } 351 }
336 // Blank the rest of the row so a shorter message can't leave stale 352 // Blank the rest of the row so a shorter message can't leave stale
337 // glyphs behind. 353 // glyphs behind.
338 while c < cols { 354 while c < cols {
339 blit_glyph(c, 0, b' ' as u16, white, black); 355 blit_glyph(c, row, b' ' as u16, white, black);
340 c += 1; 356 c += 1;
341 } 357 }
342} 358}
343 359
360/// Text-row count of the active framebuffer (each row is 16 px tall).
361pub fn text_rows() -> usize {
362 fb().as_ref().map(|f| f.height / 16).unwrap_or(0)
363}
364
365/// Row index of the `off`-th text row from the bottom (0 = last row).
366/// Bottom-anchored markers survive the shell banner + prompt at the top
367/// and a stale crash.log replay below it.
368pub fn bottom_row(off: usize) -> usize {
369 text_rows().saturating_sub(1 + off)
370}
371
344// --------------------------------------------------------------------------- 372// ---------------------------------------------------------------------------
345// Public text API — the text surface now lives in `crate::vt`; these wrappers 373// Public text API — the text surface now lives in `crate::vt`; these wrappers
346// keep callers (shell, macros) unchanged. 374// keep callers (shell, macros) unchanged.