mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
107 lines
2.7 KiB
C
107 lines
2.7 KiB
C
#include <drivers/vga.h>
|
|
#include <arch/x86_64/io.h>
|
|
#include <lib/string.h>
|
|
|
|
static volatile uint16_t* const VGA_BUFFER = (uint16_t*)VGA_MEMORY;
|
|
static uint8_t vga_color = 0x07;
|
|
static int vga_row = 0;
|
|
static int vga_col = 0;
|
|
|
|
void vga_set_cursor(int row, int col) {
|
|
vga_row = row;
|
|
vga_col = col;
|
|
uint16_t pos = row * VGA_WIDTH + col;
|
|
|
|
outb(0x3D4, 0x0F);
|
|
outb(0x3D5, (uint8_t)(pos & 0xFF));
|
|
outb(0x3D4, 0x0E);
|
|
outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF));
|
|
}
|
|
|
|
void vga_get_cursor(int* row, int* col) {
|
|
if (row) *row = vga_row;
|
|
if (col) *col = vga_col;
|
|
}
|
|
|
|
void vga_enable_cursor(uint8_t cursor_start, uint8_t cursor_end) {
|
|
outb(0x3D4, 0x0A);
|
|
outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start);
|
|
outb(0x3D4, 0x0B);
|
|
outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end);
|
|
}
|
|
|
|
void vga_disable_cursor(void) {
|
|
outb(0x3D4, 0x0A);
|
|
outb(0x3D5, 0x20);
|
|
}
|
|
|
|
void vga_set_color(enum vga_color fg, enum vga_color bg) {
|
|
vga_color = vga_entry_color(fg, bg);
|
|
}
|
|
|
|
void vga_clear(void) {
|
|
for (int y = 0; y < VGA_HEIGHT; y++) {
|
|
for (int x = 0; x < VGA_WIDTH; x++) {
|
|
VGA_BUFFER[y * VGA_WIDTH + x] = vga_entry(' ', vga_color);
|
|
}
|
|
}
|
|
vga_set_cursor(0, 0);
|
|
}
|
|
|
|
static void vga_scroll(void) {
|
|
for (int y = 0; y < VGA_HEIGHT - 1; y++) {
|
|
for (int x = 0; x < VGA_WIDTH; x++) {
|
|
VGA_BUFFER[y * VGA_WIDTH + x] = VGA_BUFFER[(y + 1) * VGA_WIDTH + x];
|
|
}
|
|
}
|
|
for (int x = 0; x < VGA_WIDTH; x++) {
|
|
VGA_BUFFER[(VGA_HEIGHT - 1) * VGA_WIDTH + x] = vga_entry(' ', vga_color);
|
|
}
|
|
vga_row = VGA_HEIGHT - 1;
|
|
}
|
|
|
|
void vga_putc(char c) {
|
|
if (c == '\n') {
|
|
vga_col = 0;
|
|
if (++vga_row >= VGA_HEIGHT) {
|
|
vga_scroll();
|
|
}
|
|
} else if (c == '\r') {
|
|
vga_col = 0;
|
|
} else if (c == '\t') {
|
|
vga_col = (vga_col + 8) & ~7;
|
|
if (vga_col >= VGA_WIDTH) {
|
|
vga_col = 0;
|
|
if (++vga_row >= VGA_HEIGHT) {
|
|
vga_scroll();
|
|
}
|
|
}
|
|
} else if (c == '\b') {
|
|
if (vga_col > 0) {
|
|
vga_col--;
|
|
VGA_BUFFER[vga_row * VGA_WIDTH + vga_col] = vga_entry(' ', vga_color);
|
|
}
|
|
} else {
|
|
VGA_BUFFER[vga_row * VGA_WIDTH + vga_col] = vga_entry(c, vga_color);
|
|
if (++vga_col >= VGA_WIDTH) {
|
|
vga_col = 0;
|
|
if (++vga_row >= VGA_HEIGHT) {
|
|
vga_scroll();
|
|
}
|
|
}
|
|
}
|
|
vga_set_cursor(vga_row, vga_col);
|
|
}
|
|
|
|
void vga_write(const char* str) {
|
|
while (*str) {
|
|
vga_putc(*str++);
|
|
}
|
|
}
|
|
|
|
void vga_init(void) {
|
|
vga_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
|
|
vga_clear();
|
|
vga_enable_cursor(14, 15);
|
|
}
|