about summary refs log tree commit diff stats
path: root/kernel.soso/tty.c
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-09-14 01:42:29 -0700
committerKartik Agaram <vc@akkartik.com>2019-09-14 01:45:55 -0700
commit46bb1d3157f9ad575c83a4bfa1e32b0d21bc8546 (patch)
tree28918f653d7cf970d33d5592047ef663289aca40 /kernel.soso/tty.c
parentded2b24ce28f4a9df75ce40117f0f06f09574369 (diff)
downloadmu-46bb1d3157f9ad575c83a4bfa1e32b0d21bc8546.tar.gz
5650 - support a second OS: soso
https://github.com/ozkl/soso

+ Much smaller than Linux; builds instantly
+ Supports graphics
- No network support
- Doesn't work on a cloud server (yet?)
Diffstat (limited to 'kernel.soso/tty.c')
-rw-r--r--kernel.soso/tty.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/kernel.soso/tty.c b/kernel.soso/tty.c
new file mode 100644
index 00000000..a9753c34
--- /dev/null
+++ b/kernel.soso/tty.c
@@ -0,0 +1,175 @@
+#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;
+}