#include #include #include "tty.h" #include "kernel.h" #include "interrupt.h" #include "ioport.h" #include "string.h" #include #define make_color(fg, bg) (fg | bg << 4) #define make_vga(ch, color) ((uint16_t)(ch & 0xff | color << 8)) #define VGA_WIDTH 80 #define VGA_HEIGHT 25 static struct virtual_console { int row, column; uint8_t color; } con; struct terminal terminal = { 0 }; static void clear() { int i; uint16_t blank = make_vga(' ', terminal.color); for (i=0; i < VGA_WIDTH * VGA_HEIGHT; i++) { terminal.vmem[i] = blank; } } static void scroll(int lines) { uint16_t *base, *offset; uint16_t blank; int i; base = terminal.vmem; offset = base + VGA_WIDTH * lines; memmove(base, offset, (VGA_WIDTH * VGA_HEIGHT - lines) * 2); offset = base + (VGA_WIDTH * VGA_HEIGHT - lines); blank = make_vga(' ', terminal.color); for (i=0; i < VGA_WIDTH * lines; i++) { offset[i] = blank; } } static void putentryat(int c, uint8_t color, size_t x, size_t y) { size_t index = y * VGA_WIDTH + x; terminal.vmem[index] = make_vga(c, color); } static void putchar(int c) { if (terminal.escape) { switch(c) { } return; } switch (c) { case '\n': terminal.column = 0; if (++terminal.row == VGA_HEIGHT) { terminal.row = VGA_HEIGHT-1; scroll(1); } break; case '\r': terminal.column = 0; break; default: putentryat(c, terminal.color, terminal.column, terminal.row); terminal.column++; break; } if (terminal.column == VGA_WIDTH) { terminal.column = 0; if (++terminal.row == VGA_HEIGHT) { terminal.row = VGA_HEIGHT-1; scroll(1); } } } static void setcursor(int row, int col) { uint16_t position = (row*VGA_WIDTH) + col; /* cursor low port to vga index register */ outport8(0x3D4, 0x0F); outport8(0x3D5, (unsigned char)(position&0xFF)); /* cursor high port to vga index register */ outport8(0x3D4, 0x0E); outport8(0x3D5, (unsigned char )((position>>8)&0xFF)); } static void updcursor() { setcursor(terminal.row, terminal.column); } static void writestring(const char *data) { size_t i = 0; while (data[i]) { putchar(data[i++]); } updcursor(); } void terminal_initialize() { terminal.putchar = putchar; terminal.clear = clear; terminal.scroll = scroll; terminal.writestring = writestring; terminal.vc = &con; terminal.vmem = (uint16_t *) (0xb8000 + _asm_physmap); terminal.update_cursor = updcursor; terminal.row = 0; terminal.column = 0; updcursor(); terminal.color = make_color(VGA_LIGHT_GREY, VGA_BLACK); clear(); }