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.
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;
}
if (term_row >= VGA_HEIGHT) {
- // TODO: Implement scrolling
- term_row = 0;
+ vga_scroll();
}
spin_unlock_irqrestore(&vga_lock, flags);
}
if (term_row >= VGA_HEIGHT) {
- term_row = 0;
+ vga_scroll();
}
}