]> pd.if.org Git - zos/commitdiff
terminal and vga screen
authorNathan Wagner <nw@hydaspes.if.org>
Tue, 25 Oct 2016 01:33:02 +0000 (20:33 -0500)
committerNathan Wagner <nw@hydaspes.if.org>
Tue, 25 Oct 2016 01:40:31 +0000 (20:40 -0500)
tty.c [new file with mode: 0644]
tty.h [new file with mode: 0644]

diff --git a/tty.c b/tty.c
new file mode 100644 (file)
index 0000000..d619a65
--- /dev/null
+++ b/tty.c
@@ -0,0 +1,132 @@
+#include <stddef.h>
+#include <stdint.h>
+#include "tty.h"
+
+#include "kernel.h"
+#include "interrupt.h"
+#include "ioport.h"
+
+#include "string.h"
+
+#include <mem.h>
+
+#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();
+}
diff --git a/tty.h b/tty.h
new file mode 100644 (file)
index 0000000..17a5c29
--- /dev/null
+++ b/tty.h
@@ -0,0 +1,42 @@
+#ifndef _TTY_H_
+#define _TTY_H_ 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+enum vga_color {
+       VGA_BLACK = 0,
+       VGA_BLUE = 1,
+       VGA_GREEN = 2,
+       VGA_CYAN = 3,
+       VGA_RED = 4,
+       VGA_MAGENTA = 5,
+       VGA_BROWN = 6,
+       VGA_LIGHT_GREY = 7,
+       VGA_DARK_GREY = 8,
+       VGA_LIGHT_BLUE = 9,
+       VGA_LIGHT_GREEN = 10,
+       VGA_LIGHT_CYAN = 11,
+       VGA_LIGHT_RED = 12,
+       VGA_LIGHT_MAGENTA = 13,
+       VGA_LIGHT_BROWN = 14,
+       VGA_WHITE = 15
+};
+struct terminal {
+        void (*putchar)(int);
+        void (*clear)(void);
+        void (*scroll)(int);
+       void (*writestring)(const char *);
+       void (*update_cursor)(void);
+       uint16_t *vmem;
+        struct virtual_console *vc;
+       int row, column;
+       int color;
+       int escape;
+};
+
+extern struct terminal terminal;
+
+void terminal_initialize();
+#endif