70 lines
1.8 KiB
C
70 lines
1.8 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>
|
|
|
|
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);
|
|
}
|