rk/vga.c

76 lines
1.9 KiB
C

/**
* @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 <vga.h>
#include <io.h>
#include <printf.h>
enum VGA_COLOR vga_color = VGA_COLOR_WHITE;
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] = vga_color;
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);
}
void set_color(enum VGA_COLOR col) {
vga_color = col;
}