summaryrefslogtreecommitdiff
path: root/kernel/lib
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lib')
-rw-r--r--kernel/lib/framebuffer.cpp316
1 files changed, 33 insertions, 283 deletions
diff --git a/kernel/lib/framebuffer.cpp b/kernel/lib/framebuffer.cpp
index 476abaa..4cd163d 100644
--- a/kernel/lib/framebuffer.cpp
+++ b/kernel/lib/framebuffer.cpp
@@ -1,297 +1,37 @@
// ============================================================================
-// lib/framebuffer.cpp - Early kernel framebuffer console
+// lib/framebuffer.cpp — kcon:: delegation layer
//
-// Renders text directly to the linear framebuffer using a minimal
-// built-in 8x16 bitmap font (PC VGA style, ASCII 32-126).
+// The kcon:: namespace preserves the original console API. All rendering
+// is now handled by whichever ConsoleDriver is active (typically
+// FramebufferConsole via the driver framework). Formatting functions
+// (put_hex, put_dec, kprintf) are kept here since they are pure formatters
+// that call putchar/puts.
// ============================================================================
#include <kernel/kprint.h>
+#include <kernel/console_driver.h>
#include <stdarg.h>
namespace kcon {
-// ── Character cell dimensions ──────────────────────────────────────────────
-
-static constexpr uint32_t CHAR_W = 8; // Font glyph width in pixels
-static constexpr uint32_t CHAR_H = 16; // Font glyph height in pixels
-static constexpr uint32_t TAB_WIDTH = 4; // Tab stop width in character cells
-
-// ── Colors (0x00RRGGBB) ────────────────────────────────────────────────────
-
-static constexpr uint32_t FG_COLOR = CONFIG_FBCON_FG_COLOR; // Light grey
-static constexpr uint32_t BG_COLOR = CONFIG_FBCON_BG_COLOR; // Dark blue
-
-// ── Console state ──────────────────────────────────────────────────────────
-//
-// All mutable state lives in one struct so callers can reason about it as
-// a unit and we avoid scattered bare globals.
-#pragma message("when i add drivers abstract, move it to another console interface and use framebuffer as driver")
-
-struct Console {
-public:
- uint32_t* fb = nullptr; // Framebuffer base (as 32-bit pixels)
- uint32_t width = 0; // Pixels per row
- uint32_t height = 0; // Rows in pixels
- uint32_t pitch = 0; // Bytes per scanline (>= width * 4)
- uint32_t col = 0; // Cursor column in character cells
- uint32_t row = 0; // Cursor row in character cells
- bool is_bgr = false;
-
- // C++23 multi-dimensional subscript: direct reference to pixel (x, y).
- // pitch is in bytes; each pixel is 4 bytes. No bounds checking — callers
- // must validate coordinates before calling (put_pixel does this).
- [[nodiscard]] uint32_t& operator[](uint32_t x, uint32_t y) noexcept {
- auto* row_ptr = reinterpret_cast<uint32_t*>(
- reinterpret_cast<uintptr_t>(fb) + static_cast<uintptr_t>(y) * pitch);
- return row_ptr[x];
- }
-};
-
-static Console g_con{};
-
-// ── Minimal 8x16 bitmap font (ASCII 32–126) ───────────────────────────────
-// Each character is 16 bytes (one byte per row, 8 pixels wide).
-// We store a blank (space) for anything outside the range.
-
-// clang-format off
-static const uint8_t g_font[][16] = {
- // 32: space
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 33: !
- {0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
- // 34: "
- {0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 35: #
- {0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00},
- // 36: $
- {0x00,0x10,0x10,0x7C,0xD6,0xD0,0x7C,0x16,0xD6,0x7C,0x10,0x10,0x00,0x00,0x00,0x00},
- // 37: %
- {0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00},
- // 38: &
- {0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
- // 39: '
- {0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 40: (
- {0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00},
- // 41: )
- {0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00},
- // 42: *
- {0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00},
- // 43: +
- {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
- // 44: ,
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00},
- // 45: -
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 46: .
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
- // 47: /
- {0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00},
- // 48-57: 0-9
- {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00},
- // 58: :
- {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00},
- // 59: ;
- {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00},
- // 60: <
- {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00},
- // 61: =
- {0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 62: >
- {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00},
- // 63: ?
- {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
- // 64: @
- {0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0xC0,0x7C,0x00,0x00,0x00,0x00},
- // 65-90: A-Z
- {0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00},
- {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00},
- // 91: [
- {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00},
- // 92: backslash
- {0x00,0x00,0x00,0x80,0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00,0x00,0x00,0x00,0x00},
- // 93: ]
- {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00},
- // 94: ^
- {0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 95: _
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},
- // 96: `
- {0x00,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- // 97-122: a-z
- {0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
- {0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00},
- {0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00},
- {0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0xD6,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00},
- {0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00},
- // 123: {
- {0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00},
- // 124: |
- {0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
- // 125: }
- {0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00},
- // 126: ~
- {0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-};
-// clang-format on
-
-static constexpr int FONT_FIRST = 32;
-static constexpr int FONT_LAST = 126;
-
-// ── Pixel helpers ──────────────────────────────────────────────────────────
-
-static void put_pixel(uint32_t x, uint32_t y, uint32_t rgb) noexcept {
- if (x >= g_con.width || y >= g_con.height) return;
-
- // Swap R and B channels if the framebuffer uses BGR layout.
- const uint32_t color = g_con.is_bgr
- ? ((rgb & 0xFFu) << 16) | (rgb & 0xFF00u) | ((rgb >> 16) & 0xFFu)
- : rgb;
-
- g_con[x, y] = color; // C++23 multi-dimensional subscript
-}
-
-// ── Scroll the screen up by one character row ──────────────────────────────
-
-static void scroll() noexcept {
- const uint32_t shift = CHAR_H * g_con.pitch;
- const uint32_t total = g_con.height * g_con.pitch;
- auto* const fb_bytes = reinterpret_cast<uint8_t*>(g_con.fb);
-
- // Shift everything up by CHAR_H rows (raw byte memmove equivalent).
- for (uint32_t i = 0; i < total - shift; ++i)
- fb_bytes[i] = fb_bytes[i + shift];
-
- // Fill the newly exposed bottom rows with the background color.
- for (uint32_t row = g_con.height - CHAR_H; row < g_con.height; ++row)
- for (uint32_t col = 0; col < g_con.width; ++col)
- put_pixel(col, row, BG_COLOR);
-}
-
-// ── Render a glyph at character-cell position (col, row) ──────────────────
-
-static void render_char(uint32_t col, uint32_t row, char c) noexcept {
- // Treat char as unsigned to avoid negative indices for high-ASCII.
- int idx = static_cast<int>(static_cast<unsigned char>(c)) - FONT_FIRST;
- if (idx < 0 || idx > (FONT_LAST - FONT_FIRST)) idx = 0; // fall back to space
-
- const uint32_t px = col * CHAR_W;
- const uint32_t py = row * CHAR_H;
-
- for (uint32_t y = 0; y < CHAR_H; ++y) {
- const uint8_t bits = g_font[idx][y];
- for (uint32_t x = 0; x < CHAR_W; ++x) {
- const uint32_t color = (bits & (0x80u >> x)) ? FG_COLOR : BG_COLOR;
- put_pixel(px + x, py + y, color);
- }
- }
-}
-
-// ── Public API ─────────────────────────────────────────────────────────────
+// ── Lifecycle ─────────────────────────────────────────────────────────────
void init(const FramebufferInfo& fb) {
- g_con.fb = reinterpret_cast<uint32_t*>(fb.base);
- g_con.width = fb.width;
- g_con.height = fb.height;
- g_con.pitch = fb.pitch;
- g_con.is_bgr = (fb.format == PixelFormat::BGR);
- g_con.col = 0;
- g_con.row = 0;
- clear();
+#ifdef CONFIG_DRIVER_FBCON
+ console::init_framebuffer(fb);
+#endif
+ (void)fb;
}
-void clear() {
- for (uint32_t y = 0; y < g_con.height; ++y)
- for (uint32_t x = 0; x < g_con.width; ++x)
- put_pixel(x, y, BG_COLOR);
- g_con.col = 0;
- g_con.row = 0;
-}
+// ── Character / string output (delegate to active console) ────────────────
void putchar(char c) {
- const uint32_t max_cols = g_con.width / CHAR_W;
- const uint32_t max_rows = g_con.height / CHAR_H;
-
- if (c == '\n') {
- g_con.col = 0;
- ++g_con.row;
- } else if (c == '\r') {
- g_con.col = 0;
- } else if (c == '\t') {
- // Advance to the next TAB_WIDTH-aligned column.
- g_con.col = (g_con.col + TAB_WIDTH) & ~(TAB_WIDTH - 1u);
- } else {
- render_char(g_con.col, g_con.row, c);
- ++g_con.col;
- }
-
- if (g_con.col >= max_cols) {
- g_con.col = 0;
- ++g_con.row;
- }
-
- if (g_con.row >= max_rows) {
- scroll();
- g_con.row = max_rows - 1;
+ if (auto* con = console::active()) {
+ con->putchar(c);
}
}
void puts(const char* s) {
- if (!s) return;
while (*s) putchar(*s++);
}
@@ -300,11 +40,19 @@ void println(const char* s) {
putchar('\n');
}
+void clear() {
+ if (auto* con = console::active()) {
+ con->clear();
+ }
+}
+
+// ── Formatting (unchanged — these only call putchar/puts) ─────────────────
+
void put_hex(uint64_t val) {
puts("0x");
bool leading = true;
for (int i = 60; i >= 0; i -= 4) {
- const uint8_t nibble = static_cast<uint8_t>((val >> i) & 0xFu);
+ uint8_t nibble = (val >> i) & 0xF;
if (nibble == 0 && leading && i > 0) continue;
leading = false;
putchar(nibble < 10 ? '0' + nibble : 'A' + nibble - 10);
@@ -315,12 +63,12 @@ void put_hex(uint64_t val) {
void put_dec(uint64_t val) {
if (val == 0) { putchar('0'); return; }
char buf[20];
- int len = 0;
+ int i = 0;
while (val > 0) {
- buf[len++] = static_cast<char>('0' + val % 10);
+ buf[i++] = '0' + (val % 10);
val /= 10;
}
- for (int j = len - 1; j >= 0; --j) putchar(buf[j]);
+ for (int j = i - 1; j >= 0; j--) putchar(buf[j]);
}
void kprintf(const char* fmt, ...) {
@@ -332,7 +80,7 @@ void kprintf(const char* fmt, ...) {
putchar(*fmt++);
continue;
}
- ++fmt; // skip '%'
+ fmt++; // skip '%'
switch (*fmt) {
case 's': {
@@ -347,12 +95,14 @@ void kprintf(const char* fmt, ...) {
break;
}
case 'u': {
- put_dec(va_arg(args, uint64_t));
+ uint64_t v = va_arg(args, uint64_t);
+ put_dec(v);
break;
}
case 'x':
case 'p': {
- put_hex(va_arg(args, uint64_t));
+ uint64_t v = va_arg(args, uint64_t);
+ put_hex(v);
break;
}
case '%':
@@ -365,7 +115,7 @@ void kprintf(const char* fmt, ...) {
putchar(*fmt);
break;
}
- ++fmt;
+ fmt++;
}
done:
va_end(args);