147 lines
3.4 KiB
C
147 lines
3.4 KiB
C
#include <drivers/terminal/terminal.h>
|
|
#include <drivers/device/device.h>
|
|
|
|
size_t terminal_row;
|
|
size_t terminal_column;
|
|
uint8_t terminal_color;
|
|
uint16_t *terminal_buffer;
|
|
framebuffer_t *terminal_framebuffer;
|
|
|
|
void terminal_clear() {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
static inline void terminal_writestring(const char* data) {
|
|
terminal_write(data, strlen(data));
|
|
}
|
|
|
|
static inline void terminal_writeline(const char* data) {
|
|
terminal_writestring(data);
|
|
terminal_putchar('\n');
|
|
}
|
|
*/
|
|
|
|
void* terminal_devread(void* data) {
|
|
return NULL;
|
|
}
|
|
|
|
void* terminal_devwrite(void* data) {
|
|
terminal_putchar(*((char*)data));
|
|
return NULL;
|
|
}
|
|
|
|
int terminal_initialize(framebuffer_t *terminal_fb) {
|
|
terminal_framebuffer = terminal_fb;
|
|
terminal_row = 0;
|
|
terminal_column = 0;
|
|
terminal_color = vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE);
|
|
terminal_buffer = (uint16_t*) 0xB8000;
|
|
terminal_clear();
|
|
|
|
struct device terminal_device = {
|
|
write: &terminal_devwrite,
|
|
read: &terminal_devread
|
|
};
|
|
|
|
return push_device(terminal_device);
|
|
}
|
|
|
|
void terminal_setcolor(uint8_t color) {
|
|
terminal_color = color;
|
|
}
|
|
|
|
void terminal_clearline(size_t line) {
|
|
for (size_t x = 0; x < VGA_WIDTH; x++) {
|
|
const size_t index = line * VGA_WIDTH + x;
|
|
terminal_buffer[index] = vga_entry(' ', terminal_color);
|
|
}
|
|
}
|
|
|
|
void terminal_clearlines(size_t from, size_t to) {
|
|
for (size_t y = from; y <= to; 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_updatecursor() {
|
|
size_t temp = terminal_row * VGA_WIDTH + terminal_column;
|
|
outportb(0x3D4, 14);
|
|
outportb(0x3D5, temp >> 8);
|
|
outportb(0x3D4, 15);
|
|
outportb(0x3D5, temp);
|
|
}
|
|
|
|
void terminal_scrollup() {
|
|
for (size_t index = 0; index < VGA_WIDTH * (VGA_HEIGHT - 1); index++) {
|
|
terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH];
|
|
}
|
|
terminal_clearline(VGA_HEIGHT);
|
|
if ((terminal_row - 1) < 0) {
|
|
terminal_row = 0;
|
|
terminal_column = 0;
|
|
} else {
|
|
terminal_row -= 1;
|
|
}
|
|
terminal_updatecursor();
|
|
}
|
|
|
|
void terminal_checknewline() {
|
|
if (terminal_row >= VGA_HEIGHT - 1) {
|
|
terminal_scrollup();
|
|
}
|
|
}
|
|
|
|
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) {
|
|
//terminal_buffer[y * VGA_WIDTH + x] = vga_entry(c, color);
|
|
draw_psf_char(terminal_framebuffer, c, x, y, 0xFFFFFFFF, 0);
|
|
}
|
|
|
|
void terminal_putchar(char c) {
|
|
outportb(0x3F8, c); // log terminal to serial.log when running on qemu
|
|
switch (c) {
|
|
case '\b':
|
|
if (--terminal_column < 0) {
|
|
if (terminal_row-- > 0) {
|
|
terminal_column = VGA_WIDTH - 1;
|
|
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
|
|
}
|
|
} else {
|
|
terminal_putentryat(' ', terminal_color, terminal_column, terminal_row);
|
|
}
|
|
terminal_updatecursor();
|
|
return;
|
|
case '\r':
|
|
terminal_column = 0;
|
|
break;
|
|
case '\n':
|
|
terminal_column = 0;
|
|
terminal_row++;
|
|
break;
|
|
default:
|
|
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
|
|
terminal_column++;
|
|
}
|
|
|
|
if (terminal_column >= VGA_WIDTH) {
|
|
terminal_column = 0;
|
|
terminal_row++;
|
|
}
|
|
|
|
terminal_updatecursor();
|
|
terminal_checknewline();
|
|
}
|
|
|
|
void terminal_write(const char* data, size_t size) {
|
|
for (size_t i = 0; i < size; i++)
|
|
terminal_putchar(data[i]);
|
|
}
|