/** * @file vga.c * @brief Basic functions for interacting with the CRTC controller in VGA text-mode. * @author rami * @version 0.1 * @date 2024-02-03 */ #include #include #include uint16_t get_cursor_pos() { uint16_t pos = 0; /* Tell CRTC controller we want the low cursor position */ outportb(CRTC_ADDR_PORT, CRTC_CURSOR_LO_REGISTER); /* Read it through the data port */ pos = inportb(CRTC_DATA_PORT); /* Repeat with high position */ outportb(CRTC_ADDR_PORT, CRTC_CURSOR_HI_REGISTER); uint16_t hi_pos = 0; hi_pos = inportb(CRTC_DATA_PORT); pos |= hi_pos << 8; return pos; } void set_cursor_pos(uint16_t pos) { /* Tell CRTC controller we want the low cursor position */ outportb(CRTC_ADDR_PORT, CRTC_CURSOR_LO_REGISTER); outportb(CRTC_DATA_PORT, (uint8_t)(pos & 0xFF)); /* Repeat with high position */ outportb(CRTC_ADDR_PORT, CRTC_CURSOR_HI_REGISTER); outportb(CRTC_DATA_PORT, (uint8_t)((pos >> 8) & 0xFF)); } void clear_screen(void) { char *video_memory = (char *)VGA_MEMORY_ADDR; for (int i = 0; i < VGA_MAX_COLS * VGA_MAX_ROWS; i++) { video_memory[i * 2] = 0; } set_cursor_pos(0); } /* Implementation of _putchar. Function is defined in print.h */ void _putchar(char character) { uint16_t pos = get_cursor_pos(); char *video_memory = (char *)VGA_MEMORY_ADDR + pos * 2; if (character == '\n') { uint16_t next_line = VGA_MAX_COLS * (pos / VGA_MAX_COLS + 1); set_cursor_pos(next_line); } else { video_memory[0] = character; video_memory[1] = WHITE_ON_BLACK; set_cursor_pos(pos + 1); } } void popchar() { uint16_t pos = get_cursor_pos(); if (pos == 0) return; char *video_memory = (char *)(VGA_MEMORY_ADDR + (pos - 1) * 2); video_memory[0] = 0; set_cursor_pos(pos - 1); }