diff options
Diffstat (limited to 'rsnix')
| -rw-r--r-- | rsnix/src/fs.rs | 2 | ||||
| -rw-r--r-- | rsnix/src/memory.rs | 7 | ||||
| -rw-r--r-- | rsnix/src/vt.rs | 33 |
3 files changed, 33 insertions, 9 deletions
diff --git a/rsnix/src/fs.rs b/rsnix/src/fs.rs index 95a84bf..df9308b 100644 --- a/rsnix/src/fs.rs +++ b/rsnix/src/fs.rs | |||
| @@ -418,7 +418,7 @@ pub fn remove_path(path: &str) -> Result<(), ()> { | |||
| 418 | 418 | ||
| 419 | fn version_text() -> String { | 419 | fn version_text() -> String { |
| 420 | alloc::format!( | 420 | alloc::format!( |
| 421 | "rsnix v{} — TempleOS-inspired toy kernel\nUEFI x86_64, identity paging, free-list heap, bitmap pages\n", | 421 | "rsnix v{} — Official RS-DOS kernel\nUEFI x86_64, identity paging, free-list heap, bitmap pages\n", |
| 422 | env!("CARGO_PKG_VERSION") | 422 | env!("CARGO_PKG_VERSION") |
| 423 | ) | 423 | ) |
| 424 | } | 424 | } |
diff --git a/rsnix/src/memory.rs b/rsnix/src/memory.rs index d33c781..c80edab 100644 --- a/rsnix/src/memory.rs +++ b/rsnix/src/memory.rs | |||
| @@ -436,6 +436,11 @@ pub fn heap_stats() -> HeapStats { | |||
| 436 | /// the heap itself (fixed-size stack arrays only). Returns true on success. | 436 | /// the heap itself (fixed-size stack arrays only). Returns true on success. |
| 437 | pub fn self_test() -> bool { | 437 | pub fn self_test() -> bool { |
| 438 | unsafe { | 438 | unsafe { |
| 439 | // Snapshot the heap before we start: earlier boot code (e.g. the | ||
| 440 | // vt cell grids) may legitimately hold live allocations. The test | ||
| 441 | // must return the heap to exactly this state, not to "empty". | ||
| 442 | let before = heap_stats(); | ||
| 443 | |||
| 439 | const N: usize = 128; | 444 | const N: usize = 128; |
| 440 | // (ptr, size, align) triplets — fixed array on the stack. | 445 | // (ptr, size, align) triplets — fixed array on the stack. |
| 441 | let mut blocks: [(usize, usize, usize); N] = [(0, 0, 0); N]; | 446 | let mut blocks: [(usize, usize, usize); N] = [(0, 0, 0); N]; |
| @@ -504,7 +509,7 @@ pub fn self_test() -> bool { | |||
| 504 | ALLOCATOR.dealloc(*ptr as *mut u8, layout); | 509 | ALLOCATOR.dealloc(*ptr as *mut u8, layout); |
| 505 | } | 510 | } |
| 506 | let stats = heap_stats(); | 511 | let stats = heap_stats(); |
| 507 | stats.free_blocks == 1 && stats.free_bytes == stats.heap_size | 512 | stats.free_blocks == before.free_blocks && stats.free_bytes == before.free_bytes |
| 508 | } | 513 | } |
| 509 | } | 514 | } |
| 510 | 515 | ||
diff --git a/rsnix/src/vt.rs b/rsnix/src/vt.rs index 3b81d68..4db08fc 100644 --- a/rsnix/src/vt.rs +++ b/rsnix/src/vt.rs | |||
| @@ -485,20 +485,29 @@ pub fn clear_all() { | |||
| 485 | // --------------------------------------------------------------------------- | 485 | // --------------------------------------------------------------------------- |
| 486 | 486 | ||
| 487 | /// Blit every cell whose content differs from what the framebuffer shows, | 487 | /// Blit every cell whose content differs from what the framebuffer shows, |
| 488 | /// then draw the logical cursor (inverse video) on top. | 488 | /// then draw the logical cursor (inverse video) on top. The cursor's |
| 489 | /// inverse colours are mirrored into RENDERED so that pixel shifts | ||
| 490 | /// (scrolling) or full clears can never leave a stale inverse block that | ||
| 491 | /// the diff can't see (blank-vs-blank). | ||
| 489 | fn flush() { | 492 | fn flush() { |
| 490 | let rows = unsafe { ROWS }; | 493 | let rows = unsafe { ROWS }; |
| 491 | let cols = unsafe { COLS }; | 494 | let cols = unsafe { COLS }; |
| 492 | let n = rows * cols; | 495 | let n = rows * cols; |
| 496 | let cursor_visible = unsafe { CURSOR_VISIBLE }; | ||
| 497 | let (cr, cc) = unsafe { (CURSOR_R, CURSOR_C) }; | ||
| 493 | { | 498 | { |
| 494 | let cells = cells(); | 499 | let cells = cells(); |
| 495 | let rendered = rendered_cells(); | 500 | let rendered = rendered_cells(); |
| 496 | for i in 0..n { | 501 | for i in 0..n { |
| 502 | let row = i / cols; | ||
| 503 | let col = i % cols; | ||
| 504 | // The visible cursor cell is owned by the cursor pass below. | ||
| 505 | if cursor_visible && row == cr && col == cc { | ||
| 506 | continue; | ||
| 507 | } | ||
| 497 | let c = cells[i]; | 508 | let c = cells[i]; |
| 498 | let r = rendered[i]; | 509 | let r = rendered[i]; |
| 499 | if c != r { | 510 | if c != r { |
| 500 | let row = i / cols; | ||
| 501 | let col = i % cols; | ||
| 502 | let fg = PALETTE[c.fg as usize]; | 511 | let fg = PALETTE[c.fg as usize]; |
| 503 | let bg = PALETTE[c.bg as usize]; | 512 | let bg = PALETTE[c.bg as usize]; |
| 504 | gop::blit_glyph(col, row, c.ch, fg, bg); | 513 | gop::blit_glyph(col, row, c.ch, fg, bg); |
| @@ -510,20 +519,30 @@ fn flush() { | |||
| 510 | unsafe { | 519 | unsafe { |
| 511 | let (lr, lc) = LAST_CURSOR; | 520 | let (lr, lc) = LAST_CURSOR; |
| 512 | let moved = (lr, lc) != (CURSOR_R, CURSOR_C); | 521 | let moved = (lr, lc) != (CURSOR_R, CURSOR_C); |
| 513 | // Erase the previous cursor position (restore its normal colours). | 522 | // Erase the previous cursor position (restore its normal colours) |
| 523 | // and record it in RENDERED so the diff stays in sync. | ||
| 514 | if (moved || !CURSOR_VISIBLE) && lr < rows && lc < cols { | 524 | if (moved || !CURSOR_VISIBLE) && lr < rows && lc < cols { |
| 515 | let c = cells()[idx(lr, lc)]; | 525 | let i = idx(lr, lc); |
| 526 | let c = cells()[i]; | ||
| 516 | let fg = PALETTE[c.fg as usize]; | 527 | let fg = PALETTE[c.fg as usize]; |
| 517 | let bg = PALETTE[c.bg as usize]; | 528 | let bg = PALETTE[c.bg as usize]; |
| 518 | gop::blit_glyph(lc, lr, c.ch, fg, bg); | 529 | gop::blit_glyph(lc, lr, c.ch, fg, bg); |
| 530 | rendered_cells()[i] = c; | ||
| 519 | } | 531 | } |
| 520 | LAST_CURSOR = (CURSOR_R, CURSOR_C); | 532 | LAST_CURSOR = (CURSOR_R, CURSOR_C); |
| 521 | // Draw the cursor as an inverse-video cell. | 533 | // Draw the cursor as an inverse-video cell, mirroring the inverse |
| 534 | // colours into RENDERED (scrolling/clearing then repair it). | ||
| 522 | if CURSOR_VISIBLE && CURSOR_R < rows && CURSOR_C < cols { | 535 | if CURSOR_VISIBLE && CURSOR_R < rows && CURSOR_C < cols { |
| 523 | let c = cells()[idx(CURSOR_R, CURSOR_C)]; | 536 | let i = idx(CURSOR_R, CURSOR_C); |
| 537 | let c = cells()[i]; | ||
| 524 | let fg = PALETTE[c.fg as usize]; | 538 | let fg = PALETTE[c.fg as usize]; |
| 525 | let bg = PALETTE[c.bg as usize]; | 539 | let bg = PALETTE[c.bg as usize]; |
| 526 | gop::blit_glyph(CURSOR_C, CURSOR_R, c.ch, bg, fg); | 540 | gop::blit_glyph(CURSOR_C, CURSOR_R, c.ch, bg, fg); |
| 541 | rendered_cells()[i] = Cell { | ||
| 542 | ch: c.ch, | ||
| 543 | fg: c.bg, | ||
| 544 | bg: c.fg, | ||
| 545 | }; | ||
| 527 | } | 546 | } |
| 528 | } | 547 | } |
| 529 | } | 548 | } |
