Files
Espresso/drivers/tty.c
2025-06-27 14:48:06 -05:00

250 lines
5.1 KiB
C

#include <string.h>
#include <vga/vga.h>
#include <tty.h>
static size_t terminal_row;
static size_t terminal_column;
static uint8_t terminal_color;
static uint16_t* terminal_buffer;
void terminal_initialize(void)
{
terminal_initializec(0x00);
}
void terminal_initializec(uint8_t color)
{
terminal_row = 0;
terminal_column = 0;
if (color == 0x00)
{
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
}
else {
terminal_color = color;
}
terminal_buffer = VGA_MEMORY;
for (size_t y = 0; y < VGA_HEIGHT; y++)
{
for (size_t x = 0; x < VGA_WIDTH; x++)
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}
void terminal_setcolor(uint8_t color)
{
terminal_color = color;
}
uint8_t terminal_getcolor(void)
{
return terminal_color;
}
void terminal_putentryat(unsigned char c, uint8_t color, size_t x, size_t y)
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(c, color);
}
void terminal_putchar(const char c)
{
unsigned char uc = c;
if (uc == '\n')
{
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
{
terminal_scroll();
terminal_row = VGA_HEIGHT - 1;
}
return;
}
else if (uc == '\t')
{
terminal_column += 4;
if (terminal_column >= VGA_WIDTH)
{
terminal_putchar('\n');
}
return;
}
else if (uc == '\b')
{
if (terminal_column == 0)
{
terminal_row -= 1;
if (terminal_row == (size_t)-1)
{
terminal_row = 0;
}
terminal_column = VGA_WIDTH;
terminal_putentryat(' ', terminal_getcolor(), (size_t)terminal_column, (size_t)terminal_row);
}
else
{
terminal_putentryat(' ', terminal_getcolor(), (size_t)--terminal_column, (size_t)terminal_row);
}
return;
}
terminal_putentryat(uc, terminal_color, terminal_column, terminal_row);
if (++terminal_column == VGA_WIDTH)
{
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
{
terminal_scroll();
terminal_row = VGA_HEIGHT - 1;
}
}
}
void terminal_write(const char* data, size_t size)
{
for (size_t i = 0; i < size; i++)
{
terminal_putchar(data[i]);
}
}
void terminal_writestring(const char* data)
{
terminal_write(data, strlen(data));
}
void terminal_debug_writestring(const char* data)
{
terminal_writestring("[ DEBUG ] ");
terminal_writestring(data);
}
void terminal_writeline(const char* data)
{
terminal_column = 0;
terminal_writestring(data);
}
void terminal_writechar_r(const char ch)
{
unsigned char uch = ch;
for (size_t i = 0; i < VGA_WIDTH; i++)
{
terminal_putchar(uch);
}
}
void terminal_clear(void)
{
terminal_clearl(-1);
}
void terminal_clearl(size_t num_lines)
{
if (num_lines == (size_t)-1)
{
terminal_initializec(terminal_getcolor());
}
else
{
/* XXX note to self: VGA_HEIGHT is 25, and VGA_WIDTH is 80 XXX */
/* static size_t terminal_row; static size_t terminal_column; */
terminal_row = VGA_HEIGHT;
terminal_column = 0;
while (terminal_row < num_lines)
{
for (int32_t k = 0; k < (int32_t)VGA_WIDTH; k++)
{
terminal_putentryat((unsigned char)' ', terminal_getcolor(), (size_t)terminal_row, (size_t)k);
}
terminal_row -= 1;
}
}
}
void terminal_scroll(void)
{
for (size_t y = 1; y < VGA_HEIGHT; y++)
{
for (size_t x = 0; x < VGA_WIDTH; x++)
{
const size_t src_index = y * VGA_WIDTH + x;
const size_t dst_index = (y - 1) * VGA_WIDTH + x;
terminal_buffer[dst_index] = terminal_buffer[src_index];
}
}
for (size_t x = 0; x < VGA_WIDTH; x++)
{
const size_t index = (VGA_HEIGHT - 1) * VGA_WIDTH + x;
terminal_buffer[index] = (terminal_color << 8) | ' ';
}
}
unsigned char terminal_get_shifted(unsigned char uc)
{
unsigned char lowerc[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\0' };
unsigned char upperc[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\0' };
unsigned char nums[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\0' };
unsigned char nsyms[] = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '\0' };
unsigned char syms1[] = { ',', '.', '/', ';', '\'', '[', ']', '`', '-', '=', '\\', '\0' };
unsigned char syms2[] = { '<', '>', '?', ':', '\"', '{', '}', '~', '_', '+', '|', '\0' };
for (int32_t i = 0; i < (int32_t)(strlen((char*)lowerc)); ++i)
{
if (uc == lowerc[i])
{
return upperc[i];
}
else if (uc == upperc[i])
{
return lowerc[i];
}
}
for (int32_t i = 0; i < (int32_t)(strlen((char*)nums)); ++i)
{
if (uc == nums[i])
{
return nsyms[i];
}
else if (uc == nsyms[i])
{
return nums[i];
}
}
for (int32_t i = 0; i < (int32_t)(strlen((char*)syms1)); ++i)
{
if (uc == syms1[i])
{
return syms2[i];
}
else if (uc == syms2[i])
{
return syms1[i];
}
}
return '\0';
}