feat(drivers): add VGA text-mode driver with scrolling and cursor

This commit is contained in:
dualfroz committed 2026-08-24 13:05:24 +02:00
1 parent 39f8c5fc48
commit 7b52e9d3f9
2 files changed
+124

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
#ifndef FROSTBYTE_VGA_H
#define FROSTBYTE_VGA_H
#include "types.h"
typedef enum {
vgaBlack = 0,
vgaBlue = 1,
vgaGreen = 2,
vgaCyan = 3,
vgaRed = 4,
vgaMagenta = 5,
vgaBrown = 6,
vgaLightGrey = 7,
vgaDarkGrey = 8,
vgaLightBlue = 9,
vgaLightGreen = 10,
vgaLightCyan = 11,
vgaLightRed = 12,
vgaPink = 13,
vgaYellow = 14,
vgaWhite = 15
} VgaColor;
void vgaInit(void);
void vgaClear(void);
void vgaPutChar(char c);
void vgaWriteString(const char* str);
void vgaSetColor(VgaColor foreground, VgaColor background);
#endif
+93
View File
@@ -0,0 +1,93 @@
#include "vga.h"
#include "ports.h"
#define vgaWidth 80
#define vgaHeight 25
#define vgaBuffer 0xB8000
static volatile uint16* const screen = (volatile uint16*)vgaBuffer;
static uint32 cursorRow;
static uint32 cursorColumn;
static uint8 currentColor;
static uint16 makeCell(char c, uint8 color)
{
return (uint16)c | ((uint16)color << 8);
}
static void updateHardwareCursor(void)
{
uint16 position = (uint16)(cursorRow * vgaWidth + cursorColumn);
outb(0x3D4, 0x0F);
outb(0x3D5, (uint8)(position & 0xFF));
outb(0x3D4, 0x0E);
outb(0x3D5, (uint8)((position >> 8) & 0xFF));
}
void vgaSetColor(VgaColor foreground, VgaColor background)
{
currentColor = (uint8)foreground | (uint8)(background << 4);
}
void vgaClear(void)
{
for (uint32 y = 0; y < vgaHeight; y++) {
for (uint32 x = 0; x < vgaWidth; x++)
screen[y * vgaWidth + x] = makeCell(' ', currentColor);
}
cursorRow = 0;
cursorColumn = 0;
updateHardwareCursor();
}
void vgaInit(void)
{
currentColor = (uint8)vgaLightGrey | (uint8)(vgaBlack << 4);
vgaClear();
}
static void scroll(void)
{
for (uint32 y = 1; y < vgaHeight; y++) {
for (uint32 x = 0; x < vgaWidth; x++)
screen[(y - 1) * vgaWidth + x] = screen[y * vgaWidth + x];
}
for (uint32 x = 0; x < vgaWidth; x++)
screen[(vgaHeight - 1) * vgaWidth + x] = makeCell(' ', currentColor);
cursorRow = vgaHeight - 1;
}
void vgaPutChar(char c)
{
if (c == '\n') {
cursorColumn = 0;
cursorRow++;
} else if (c == '\r') {
cursorColumn = 0;
} else if (c == '\b') {
if (cursorColumn > 0) {
cursorColumn--;
screen[cursorRow * vgaWidth + cursorColumn] = makeCell(' ', currentColor);
}
} else if (c == '\t') {
cursorColumn = (cursorColumn + 4) & ~3u;
} else {
screen[cursorRow * vgaWidth + cursorColumn] = makeCell(c, currentColor);
cursorColumn++;
}
if (cursorColumn >= vgaWidth) {
cursorColumn = 0;
cursorRow++;
}
if (cursorRow >= vgaHeight)
scroll();
updateHardwareCursor();
}
void vgaWriteString(const char* str)
{
while (*str)
vgaPutChar(*str++);
}