]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
fix: implement VGA text-mode scrolling instead of wrap-to-row-0
authorTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 04:14:19 +0000 (01:14 -0300)
committerTulio A M Mendes <[email protected]>
Tue, 10 Feb 2026 04:14:19 +0000 (01:14 -0300)
When the cursor reached the bottom of the 25-row VGA text buffer,
term_row was reset to 0, overwriting the top of the screen. This
made boot output unreadable once it exceeded 25 lines.

Add vga_scroll() that shifts all rows up by one and clears the
last row. Called from both vga_put_char and vga_print.

Passes: make, cppcheck, QEMU smoke test.

src/drivers/vga_console.c

index 1890a2c1fb6ab9cd70b8561845b77121a0591b39..17770b4c62cf0cfe654a62e7e6981958cbe3a6a8 100644 (file)
@@ -14,6 +14,18 @@ static uint8_t term_color = 0x0F; // White on Black
 
 static spinlock_t vga_lock = {0};
 
+static void vga_scroll(void) {
+    for (int y = 1; y < VGA_HEIGHT; y++) {
+        for (int x = 0; x < VGA_WIDTH; x++) {
+            VGA_BUFFER[(y - 1) * VGA_WIDTH + x] = VGA_BUFFER[y * VGA_WIDTH + x];
+        }
+    }
+    for (int x = 0; x < VGA_WIDTH; x++) {
+        VGA_BUFFER[(VGA_HEIGHT - 1) * VGA_WIDTH + x] = (uint16_t)' ' | (uint16_t)term_color << 8;
+    }
+    term_row = VGA_HEIGHT - 1;
+}
+
 void vga_init(void) {
     VGA_BUFFER = (volatile uint16_t*)hal_video_text_buffer();
     term_col = 0;
@@ -60,8 +72,7 @@ void vga_put_char(char c) {
     }
 
     if (term_row >= VGA_HEIGHT) {
-        // TODO: Implement scrolling
-        term_row = 0;
+        vga_scroll();
     }
 
     spin_unlock_irqrestore(&vga_lock, flags);
@@ -92,7 +103,7 @@ void vga_print(const char* str) {
         }
 
         if (term_row >= VGA_HEIGHT) {
-            term_row = 0;
+            vga_scroll();
         }
     }