#include "console.h" #define ROWS 25 #define COLUMNS 80 typedef struct { u8 character; u8 color; } vga_char_t; static vga_char_t* vga_buffer = (vga_char_t*)0xb8000; static u8 cursor_row = 0; static u8 cursor_col = 0; void console_putchar(char c, u8 color) { switch (c) { case '\n': { cursor_row += 1; cursor_col = 0; break; } case '\r': { cursor_col = 0; break; } case '\t': { u8 remainder = 4 - (cursor_col % 4); cursor_col += remainder; break; } case '\b': { if (cursor_col > 0) { cursor_col -= 1; } else if (cursor_row > 0) { cursor_row -= 1; cursor_col = 0; for (int col = COLUMNS - 1; col >= 0; col--) { vga_char_t cell = vga_buffer[cursor_row * COLUMNS + col]; if (cell.character != ' ') { cursor_col = col; break; } } } vga_buffer[cursor_row * COLUMNS + cursor_col] = (vga_char_t){ .character = ' ', .color = VGA_DEFAULT_COLOR, }; break; } default: { vga_buffer[COLUMNS * cursor_row + cursor_col] = (vga_char_t){ .character = c, .color = color, }; cursor_col += 1; break; } } if (cursor_col >= COLUMNS) { cursor_col = 0; cursor_row += 1; } if (cursor_row >= ROWS) { for (size_t row = 1; row < ROWS; row++) { for (size_t col = 0; col < COLUMNS; col++) { vga_buffer[COLUMNS * (row - 1) + col] = vga_buffer[COLUMNS * row + col]; } } for (size_t col = 0; col < COLUMNS; col++) { vga_buffer[COLUMNS * (ROWS - 1) + col] = (vga_char_t){ .character = ' ', .color = VGA_DEFAULT_COLOR, }; }; cursor_row = ROWS - 1; } } void console_clear() { for (size_t row = 0; row < ROWS; row++) { for (size_t col = 0; col < COLUMNS; col++) { vga_buffer[COLUMNS * row + col] = (vga_char_t){ .character = ' ', .color = VGA_DEFAULT_COLOR, }; } } cursor_row = 0; cursor_col = 0; }