Files
frostbyte/src/vga.c
T

94 lines
2.2 KiB
C

#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++);
}