X-Git-Url: https://pd.if.org/git/?p=zos;a=blobdiff_plain;f=tty.c;fp=tty.c;h=d619a65b6e8aa59c5a11892eb9892516b605ac78;hp=0000000000000000000000000000000000000000;hb=3afdcc11364fbed161b57409f90fe572fc789047;hpb=ede887c1b1d1700bc36da685788d96a19a5d2065 diff --git a/tty.c b/tty.c new file mode 100644 index 0000000..d619a65 --- /dev/null +++ b/tty.c @@ -0,0 +1,132 @@ +#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(); +}