#include #include static size_t vga_x, vga_y; static uint8_t vga_color; static uint16_t *vga_buffer; void vga_init(void) { vga_x = vga_y = 0; vga_set_color(VGA_LIGHT_MAGENTA, VGA_BLACK); vga_buffer = (uint16_t *)0xB8000; for (size_t y = 0; y < VGA_HEIGHT; y++) for (size_t x = 0; x < VGA_WIDTH; x++) vga_buffer[y * VGA_WIDTH + x] = ' ' | (vga_color << 8); } void vga_scroll() { if (vga_y < VGA_HEIGHT) return; for (size_t y = 0; y < VGA_HEIGHT - 1; y++) { for (size_t x = 0; x < VGA_WIDTH; x++) { const size_t from = (y + 1) * VGA_WIDTH + x; const size_t to = y * VGA_WIDTH + x; vga_buffer[to] = vga_buffer[from]; } } vga_y = VGA_HEIGHT - 1; for (size_t x = 0; x < VGA_HEIGHT; x++) { vga_buffer[vga_y * VGA_WIDTH + x] = ' ' | (vga_color << 8); } } void vga_update_cursor(void) { size_t index = vga_y * VGA_WIDTH + vga_x; outb(0x3D4, 14); outb(0x3D5, index >> 8); outb(0x3D4, 15); outb(0x3D5, index); } void vga_putn(const size_t number) { char digits[32] = { 0 }; size_t num = number, count = 0; do { digits[count] = (num % 10) + '0'; count++; } while ((num /= 10) > 0); do { vga_putc(digits[count]); } while (count-- > 0); } void vga_putx(const size_t hex) { char digits[32] = { 0 }; size_t num = hex, count = 0; do { digits[count] = "0123456789abcdef"[num % 16]; count++; } while ((num /= 16) > 0); vga_puts("0x"); do { vga_putc(digits[count]); } while (count-- > 0); } void vga_putc(const char c) { switch (c) { case '\n': vga_x = 0; vga_y++; break; case '\b': if (vga_x > 0) vga_x--; break; case '\r': vga_x = 0; break; case '\t': break; default: // Any character greater than and including a space, is a printable character if (c >= ' ') vga_buffer[vga_y * VGA_WIDTH + vga_x++] = (uint16_t) c | ((uint16_t) vga_color << 8); } if (vga_x >= VGA_WIDTH) { vga_x = 0; vga_y++; } vga_scroll(); vga_update_cursor(); } void vga_puts(const char *s) { while (*s) vga_putc(*s++); } void vga_putsn(const char *s, const size_t len) { for (size_t i = 0; i < len; i++) vga_putc(s[i]); } void vga_set_color(const uint8_t fg, const uint8_t bg) { vga_color = fg | bg << 4; }