#include "vga.h" #include "stddef.h" #define ROWS 25 #define COLUMNS 80 typedef struct { uint8_t character; uint8_t color; } vga_char_t; static vga_char_t* vga_buffer = (vga_char_t*)0xb8000; static uint8_t cursor_row = 0; static uint8_t cursor_col = 0; void vga_put_char(char character, uint8_t color) { switch (character) { case '\n': { cursor_row += 1; cursor_col = 0; break; } case '\r': { cursor_col = 0; break; } case '\t': { uint8_t 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 = character, .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 vga_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; }