Files
nub-os/src/arch/x86_64/vga.c
nub31 204c747c43 ...
2025-09-03 13:32:40 +02:00

120 lines
2.5 KiB
C

#include "vga.h"
#include "stddef.h"
#define ROWS 25
#define COLUMNS 80
typedef struct
{
uint8_t character;
uint8_t color;
} vga_char_t;
static vga_char_t* vga_buffer = (vga_char_t*)0xb8000;
static uint8_t cursor_row = 0;
static uint8_t cursor_col = 0;
void vga_put_char(char character, uint8_t color)
{
switch (character)
{
case '\n':
{
cursor_row += 1;
cursor_col = 0;
break;
}
case '\r':
{
cursor_col = 0;
break;
}
case '\t':
{
uint8_t remainder = 4 - (cursor_col % 4);
cursor_col += remainder;
break;
}
case '\b':
{
if (cursor_col > 0)
{
cursor_col -= 1;
}
else if (cursor_row > 0)
{
cursor_row -= 1;
cursor_col = 0;
for (int col = COLUMNS - 1; col >= 0; col--)
{
vga_char_t cell = vga_buffer[cursor_row * COLUMNS + col];
if (cell.character != ' ')
{
cursor_col = col;
break;
}
}
}
vga_buffer[cursor_row * COLUMNS + cursor_col] = (vga_char_t){
.character = ' ',
.color = VGA_DEFAULT_COLOR,
};
break;
}
default:
{
vga_buffer[COLUMNS * cursor_row + cursor_col] = (vga_char_t){
.character = character,
.color = color,
};
cursor_col += 1;
break;
}
}
if (cursor_col >= COLUMNS)
{
cursor_col = 0;
cursor_row += 1;
}
if (cursor_row >= ROWS)
{
for (size_t row = 1; row < ROWS; row++)
{
for (size_t col = 0; col < COLUMNS; col++)
{
vga_buffer[COLUMNS * (row - 1) + col] = vga_buffer[COLUMNS * row + col];
}
}
for (size_t col = 0; col < COLUMNS; col++)
{
vga_buffer[COLUMNS * (ROWS - 1) + col] = (vga_char_t){
.character = ' ',
.color = VGA_DEFAULT_COLOR,
};
};
cursor_row = ROWS - 1;
}
}
void vga_clear()
{
for (size_t row = 0; row < ROWS; row++)
{
for (size_t col = 0; col < COLUMNS; col++)
{
vga_buffer[COLUMNS * row + col] = (vga_char_t){
.character = ' ',
.color = VGA_DEFAULT_COLOR,
};
}
}
cursor_row = 0;
cursor_col = 0;
}