about summary refs log tree commit diff stats
path: root/tools/iso/kernel.soso/tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/iso/kernel.soso/tty.c')
-rw-r--r--tools/iso/kernel.soso/tty.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/tools/iso/kernel.soso/tty.c b/tools/iso/kernel.soso/tty.c
new file mode 100644
index 00000000..9e53c339
--- /dev/null
+++ b/tools/iso/kernel.soso/tty.c
@@ -0,0 +1,153 @@
+#include "tty.h"
+#include "alloc.h"
+
+Tty* createTty(uint16 lineCount, uint16 columnCount, TtyFlushScreenFunction flushFunction) {
+    Tty* tty = kmalloc(sizeof(Tty));
+    memset((uint8*)tty, 0, sizeof(Tty));
+
+    tty->lineCount = lineCount;
+    tty->columnCount = columnCount;
+    tty->buffer = kmalloc(tty->lineCount * tty->columnCount * 2);
+    tty->currentColumn = 0;
+    tty->currentLine = 0;
+    tty->color = 0x0A;
+
+    memset(tty->lineBuffer, 0, TTY_LINEBUFFER_SIZE);
+    tty->lineBufferIndex = 0;
+    tty->keyBuffer = FifoBuffer_create(64);
+    tty->flushScreen = flushFunction;
+
+    tty->term.c_cc[VMIN] = 1;
+    tty->term.c_lflag |= ECHO;
+    tty->term.c_lflag |= ICANON;
+
+    Tty_Clear(tty);
+
+    return tty;
+}
+
+void destroyTty(Tty* tty) {
+    FifoBuffer_destroy(tty->keyBuffer);
+    kfree(tty->buffer);
+    kfree(tty);
+}
+
+void Tty_Print(Tty* tty, int row, int column, const char* text) {
+    unsigned char * video = tty->buffer;
+
+    video += (row * tty->columnCount + column) * 2;
+    while(*text != 0) {
+        *video++ = *text++;
+        *video++ = tty->color;
+    }
+}
+
+//One line
+void Tty_ScrollUp(Tty* tty) {
+    unsigned char * videoLine = tty->buffer;
+    unsigned char * videoLineNext = tty->buffer;
+    int line = 0;
+    int column = 0;
+
+    for (line = 0; line < tty->lineCount - 1; ++line) {
+        for (column = 0; column < tty->columnCount; ++column) {
+            videoLine = tty->buffer + (line * tty->columnCount + column) * 2;
+            videoLineNext = tty->buffer + ((line + 1) * tty->columnCount + column) * 2;
+
+            videoLine[0] = videoLineNext[0];
+            videoLine[1] = videoLineNext[1];
+        }
+    }
+
+    //Last line should be empty.
+    unsigned char * lastLine = tty->buffer + ((tty->lineCount - 1) * tty->columnCount) * 2;
+    for (int i = 0; i < tty->columnCount * 2; i += 2) {
+        lastLine[i] = 0;
+        lastLine[i + 1] = tty->color;
+    }
+}
+
+void Tty_Clear(Tty* tty) {
+    unsigned char * video = tty->buffer;
+    int i = 0;
+
+    for (i = 0; i < tty->lineCount * tty->columnCount; ++i) {
+        *video++ = 0;
+        *video++ = tty->color;
+    }
+
+    tty->currentLine = 0;
+    tty->currentColumn = 0;
+}
+
+void Tty_PutChar(Tty* tty, char c) {
+    unsigned char * video = tty->buffer;
+
+    if ('\n' == c || '\r' == c) {
+        ++tty->currentLine;
+        tty->currentColumn = 0;
+
+        if (tty->currentLine >= tty->lineCount - 0) {
+            --tty->currentLine;
+            Tty_ScrollUp(tty);
+        }
+
+        Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn);
+        return;
+    }
+    else if ('\b' == c) {
+        if (tty->currentColumn > 0) {
+            --tty->currentColumn;
+            c = '\0';
+            video = tty->buffer + (tty->currentLine * tty->columnCount + tty->currentColumn) * 2;
+            video[0] = c;
+            video[1] = tty->color;
+            Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn);
+            return;
+        }
+        else if (tty->currentColumn == 0) {
+            if (tty->currentLine > 0) {
+                --tty->currentLine;
+                tty->currentColumn = tty->columnCount - 1;
+                c = '\0';
+                video = tty->buffer + (tty->currentLine * tty->columnCount + tty->currentColumn) * 2;
+                video[0] = c;
+                video[1] = tty->color;
+                Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn);
+                return;
+            }
+        }
+    }
+
+    if (tty->currentColumn >= tty->columnCount) {
+        ++tty->currentLine;
+        tty->currentColumn = 0;
+    }
+
+    if (tty->currentLine >= tty->lineCount - 0) {
+        --tty->currentLine;
+        Tty_ScrollUp(tty);
+    }
+
+    video += (tty->currentLine * tty->columnCount + tty->currentColumn) * 2;
+
+    video[0] = c;
+    video[1] = tty->color;
+
+    ++tty->currentColumn;
+
+    Tty_MoveCursor(tty, tty->currentLine, tty->currentColumn);
+}
+
+void Tty_PutText(Tty* tty, const char* text) {
+    const char* c = text;
+    while (*c) {
+        Tty_PutChar(tty, *c);
+        ++c;
+    }
+}
+
+void Tty_MoveCursor(Tty* tty, uint16 line, uint16 column) {
+    tty->currentLine = line;
+    tty->currentColumn = column;
+}