summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2012-05-17 17:56:23 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2012-05-17 17:56:23 +0200
commit593bf4df3d8db49286c1a7ae4ef75c887b629930 (patch)
tree988a104c9611d72e1252282789688586efd9a394
parent7c9a48b4e6d66cf4f62e7bad9e22ab06923e47ef (diff)
downloadTCE-593bf4df3d8db49286c1a7ae4ef75c887b629930.tar.gz
TCE-593bf4df3d8db49286c1a7ae4ef75c887b629930.zip
Devices using the VFS structure. Basic keyboard handler.
-rw-r--r--src/kernel/Makefile7
-rw-r--r--src/kernel/core/kmain.cpp56
-rw-r--r--src/kernel/core/monitor.cpp114
-rw-r--r--src/kernel/core/monitor.h21
-rw-r--r--src/kernel/core/sys.cpp25
-rw-r--r--src/kernel/dev/display.h38
-rw-r--r--src/kernel/dev/keyboard.cpp150
-rw-r--r--src/kernel/dev/keyboard.h99
-rw-r--r--src/kernel/dev/ps2keyboard.cpp55
-rw-r--r--src/kernel/dev/ps2keyboard.h21
-rw-r--r--src/kernel/dev/vgatxt.cpp50
-rw-r--r--src/kernel/dev/vgatxt.h23
-rw-r--r--src/kernel/lib/std.cpp8
-rw-r--r--src/kernel/mem/gdt.cpp3
-rw-r--r--src/kernel/mem/mem.cpp11
-rw-r--r--src/kernel/mem/paging.cpp20
-rw-r--r--src/kernel/task/idt.cpp11
-rw-r--r--src/kernel/task/syscall.cpp4
-rw-r--r--src/kernel/task/task.cpp26
-rw-r--r--src/kernel/task/timer.cpp3
-rw-r--r--src/kernel/ui/vt.cpp159
-rw-r--r--src/kernel/ui/vt.h49
-rw-r--r--src/kernel/vfs/node.cpp10
-rw-r--r--src/kernel/vfs/node.h8
-rw-r--r--src/kernel/vfs/vdir.h1
25 files changed, 745 insertions, 227 deletions
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index 0537388..bfa5908 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -1,11 +1,12 @@
Out = kernel.elf
Obj = core/loader_.o core/kmain.o core/sys.o \
- core/monitor.o task/timer.o \
- task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o task/sched.o \
+ task/timer.o task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o task/sched.o \
lib/bitset.o lib/std.o lib/cpp.o \
mem/mem.o mem/paging.o mem/gdt.o mem/_dlmalloc.o mem/seg.o \
linker/elf.o \
- vfs/node.o vfs/vdir.o
+ vfs/node.o vfs/vdir.o \
+ dev/vgatxt.o dev/keyboard.o dev/ps2keyboard.o \
+ ui/vt.o
ExtObj = $(SrcPath)/common/_common.o
diff --git a/src/kernel/core/kmain.cpp b/src/kernel/core/kmain.cpp
index eb2c3ec..e74ff33 100644
--- a/src/kernel/core/kmain.cpp
+++ b/src/kernel/core/kmain.cpp
@@ -2,8 +2,8 @@
#include <config.h>
#include "multiboot.h"
-#include "monitor.h"
#include "sys.h"
+#include <dev/vgatxt.h>
#include <task/idt.h>
#include <task/timer.h>
#include <task/task.h>
@@ -12,6 +12,8 @@
#include <mem/mem.h>
#include <linker/elf.h>
#include <vfs/node.h>
+#include <ui/vt.h>
+#include <dev/ps2keyboard.h>
/* The kernel's main procedure. This function is called in loader_.asm.
This function calls the initializer functions for all system parts.
@@ -35,47 +37,59 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) {
mem_placementAddr = (mods[i].mod_end & 0xFFFFF000) + 0x1000;
}
- monitor_clear();
-
- monitor_write(K_OS_NAME);
- monitor_write(" version ");
- monitor_write(K_OS_VER);
- monitor_write(" codename '");
- monitor_write(K_OS_CODENAME);
- monitor_write("' starting up :\n");
-
+ // Init memory managment functions
idt_init();
-
totalRam = ((mbd->mem_upper + mbd->mem_lower) * 1024);
paging_init(totalRam);
gdt_init();
paging_cleanup();
_no_more_ksbrk = true;
- //kheap_init();
+ // Init higher level stuff
timer_init(30);
tasking_init();
-
vfs_setup();
-
- monitor_write("\nLoading modules :\n");
+
+ // Init display devices
+ text_display = new vgatxt(dot_dev);
+ dot_dev->add_child("vgatxt", text_display);
+ ke_vt = new vt(dot_dev, 80, 25);
+ dot_ui->add_child("klog", ke_vt);
+ ke_vt->outputTo(text_display);
+
+ // Say hello
+ ke_vt->fgcolor = TC_LIGHTGRAY;
+ ke_vt->writeStr("Hello. This is ");
+ ke_vt->fgcolor = TC_WHITE; ke_vt->writeStr(K_OS_NAME);
+ ke_vt->fgcolor = TC_LIGHTGRAY; ke_vt->writeStr(" version ");
+ ke_vt->fgcolor = TC_WHITE; ke_vt->writeStr(K_OS_VER);
+ ke_vt->fgcolor = TC_LIGHTGRAY; ke_vt->writeStr(" codename '");
+ ke_vt->fgcolor = TC_WHITE; ke_vt->writeStr(K_OS_CODENAME);
+ ke_vt->fgcolor = TC_LIGHTGRAY; ke_vt->writeStr("'. Enjoy!\n");
+
+ // Init devices
+ kbd = new ps2kbd(dot_dev);
+ dot_dev->add_child("ps2kbd", kbd);
+
+ // Load modules
+ ke_vt->writeStr("Loading modules :\n");
for (i = 0; i < mbd->mods_count; i++) {
- monitor_write(" * ");
- monitor_write((char*)mods[i].string);
+ ke_vt->writeStr(" * ");
+ ke_vt->writeStr((char*)mods[i].string);
if (elf_check((uint8_t*)mods[i].mod_start)) {
- monitor_write(" : Invalid ELF file\n");
+ ke_vt->writeStr(" : Invalid ELF file\n");
} else {
process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_USER);
if (pr == 0) {
- monitor_write(" : Error loading\n");
+ ke_vt->writeStr(" : Error loading\n");
} else {
- monitor_write(" : OK, pid="); monitor_writeDec(pr->pid); monitor_write("\n");
+ ke_vt->writeStr(" : OK, pid="); ke_vt->writeDec(pr->pid); ke_vt->writeStr("\n");
}
}
}
- monitor_write("Giving control to userland processes.\n\n");
+ ke_vt->writeStr("Giving control to userland processes.\n\n");
sti();
schedule();
PANIC("Should never happen. Something probably went wrong with multitasking.");
diff --git a/src/kernel/core/monitor.cpp b/src/kernel/core/monitor.cpp
deleted file mode 100644
index ba2a6df..0000000
--- a/src/kernel/core/monitor.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "monitor.h"
-#include "sys.h"
-
-#include "mem/mem.h"
-
-static int cursor_x = 0, cursor_y = 0;
-static uint16_t *video_memory = (uint16_t*)((size_t)K_HIGHHALF_ADDR + 0xB8000);
-
-static uint8_t attribute = 0x07; // 0 = background = black, 7 = foreground = white
-
-/* For internal use only. Tells hardware to move the cursor at (cursor_x, cursor_y). */
-static void move_cursor() {
- uint16_t cursor_location = cursor_y * 80 + cursor_x;
- outb(0x3D4, 14); //Sending high cursor byte
- outb(0x3D5, cursor_location >> 8);
- outb(0x3D4, 15); //Sending high cursor byte
- outb(0x3D5, cursor_location);
-}
-
-/* For internal use only. Scrolls everything up one line. */
-static void scroll() {
- uint16_t blank = (attribute << 8) | 0x20;
-
- if (cursor_y >= 25) {
- int i;
- for (i = 0; i < 80*24; i++) {
- video_memory[i] = video_memory[i+80];
- }
- for (i = 80*24; i < 80*25; i++) {
- video_memory[i] = blank;
- }
- cursor_y = 24;
- }
-}
-
-/* Put one character on the screen. This function handles special characters \b, \t, \r and \n. */
-void monitor_put(char c) {
- if (c == '\b' && cursor_x) { //Backspace
- cursor_x--;
- } else if (c == '\t') { //Tab
- cursor_x = (cursor_x + 8) & ~(8 - 1);
- } else if (c == '\r') { //Carriage return
- cursor_x = 0;
- } else if (c == '\n') { //New line
- cursor_x = 0;
- cursor_y++;
- } else if (c >= ' ') { //Any printable character
- video_memory[cursor_y * 80 + cursor_x] = c | (attribute << 8);
- cursor_x++;
- }
- if (cursor_x >= 80) {
- cursor_x = 0;
- cursor_y++;
- }
-
- scroll();
- move_cursor();
-}
-
-/* Clears the screen and moves cursor to (0,0) (top left corner) */
-void monitor_clear() {
- uint16_t blank = (attribute << 8) | 0x20;
-
- int i;
-
- for (i = 0; i < 80*25; i++) {
- video_memory[i] = blank;
- }
-
- cursor_x = 0; cursor_y = 0;
- move_cursor();
-}
-
-/* Writes a string to the monitor */
-void monitor_write(char *s) {
- while (*s) {
- monitor_put(*(s++));
- }
-}
-
-/* Writes a number in hexadecimal notation to the monitor */
-void monitor_writeHex(uint32_t v) {
- int i;
-
- monitor_put('0'); monitor_put('x');
- char hexdigits[] = "0123456789abcdef";
-
- for (i = 0; i < 8; i++) {
- monitor_put(hexdigits[v >> 28]);
- v = v << 4;
- }
-}
-
-/* Writes a number in decimal notation to the monitor */
-void monitor_writeDec(uint32_t v) {
- if (v == 0) {
- monitor_put('0');
- return;
- }
-
- char numbers[] = "0123456789";
- while (v > 0) {
- int order = 1, no = 1;
- while (v / order > 0) order *= 10;
- order /= 10;
- monitor_put(numbers[v / order]);
- v = v - (v / order * order);
- while (v / no > 0) no *= 10;
- while (no < order) {
- monitor_put('0');
- no *= 10;
- }
- }
-}
diff --git a/src/kernel/core/monitor.h b/src/kernel/core/monitor.h
deleted file mode 100644
index bb8e16e..0000000
--- a/src/kernel/core/monitor.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef DEF_MONITOR_H
-#define DEF_MONITOR_H
-
-#include "types.h"
-
-void monitor_put(char c);
-void monitor_clear();
-void monitor_write(char *s);
-void monitor_writeHex(uint32_t v);
-void monitor_writeDec(uint32_t v);
-
-#define NL monitor_put('\n');
-#define TAB monitor_put('\t');
-#define WHERE { monitor_write("(kernel:"); \
- monitor_write(__FILE__); \
- monitor_write(":"); \
- monitor_writeDec(__LINE__); \
- monitor_write(")\t"); }
-
-#endif
-
diff --git a/src/kernel/core/sys.cpp b/src/kernel/core/sys.cpp
index d95b678..2eefa57 100644
--- a/src/kernel/core/sys.cpp
+++ b/src/kernel/core/sys.cpp
@@ -1,5 +1,6 @@
#include "sys.h"
-#include "monitor.h"
+#include <ui/vt.h>
+#include <dev/vgatxt.h>
#include "mem/mem.h"
@@ -30,9 +31,9 @@ uint16_t inw(uint16_t port) {
void stack_trace(size_t bp) {
uint32_t *stack = (uint32_t*)bp, i;
for (i = 0; i < 5 && (size_t)stack > K_HIGHHALF_ADDR && (size_t)stack < (bp + 0x8000); i++) {
- monitor_write("| "); monitor_writeHex((size_t)stack);
- monitor_write("\tnext:"); monitor_writeHex(stack[0]); monitor_write("\t\tret:"); monitor_writeHex(stack[1]);
- monitor_write("\n");
+ ke_vt->writeStr("| "); ke_vt->writeHex((size_t)stack);
+ ke_vt->writeStr("\tnext:"); ke_vt->writeHex(stack[0]); ke_vt->writeStr("\t\tret:"); ke_vt->writeHex(stack[1]);
+ ke_vt->writeStr("\n");
stack = (uint32_t*)stack[0];
}
}
@@ -40,21 +41,27 @@ void stack_trace(size_t bp) {
/* For internal use only. Used by panic and panic_assert. */
static void panic_do(char* file, int line) {
asm volatile("cli;");
- monitor_write("\n File:\t\t"); monitor_write(file); monitor_put(':'); monitor_writeDec(line);
- monitor_write("\nTrace:\n");
+ ke_vt->writeStr("\n File:\t\t"); ke_vt->writeStr(file); ke_vt->writeStr(":"); ke_vt->writeDec(line);
+ ke_vt->writeStr("\nTrace:\n");
size_t bp; asm volatile("mov %%ebp,%0" : "=r"(bp)); stack_trace(bp);
- monitor_write("\n\t\tSystem halted -_-'");
+ ke_vt->writeStr("\n\t\tSystem halted -_-'");
asm volatile("hlt");
}
/* These functions stop the system, reporting an error message, because something bad happenned. */
void panic(char* message, char* file, int line) {
- monitor_write("\nPANIC:\t\t"); monitor_write(message);
+ ke_vt->fgcolor = TC_WHITE;
+ ke_vt->bgcolor = TC_BLUE;
+ ke_vt->outputTo(text_display);
+ ke_vt->writeStr("\nPANIC:\t\t"); ke_vt->writeStr(message);
panic_do(file, line);
}
void panic_assert(char* assertion, char* file, int line) {
- monitor_write("\nASSERT FAILED:\t"); monitor_write(assertion);
+ ke_vt->fgcolor = TC_WHITE;
+ ke_vt->bgcolor = TC_RED;
+ ke_vt->outputTo(text_display);
+ ke_vt->writeStr("\nASSERT FAILED:\t"); ke_vt->writeStr(assertion);
panic_do(file, line);
}
diff --git a/src/kernel/dev/display.h b/src/kernel/dev/display.h
new file mode 100644
index 0000000..04a6d67
--- /dev/null
+++ b/src/kernel/dev/display.h
@@ -0,0 +1,38 @@
+#ifndef DEF_DEV_DISPLAY_H
+#define DEF_DEV_DISPLAY_H
+
+#include <vfs/node.h>
+
+#define TC_BLACK 0
+#define TC_BLUE 1
+#define TC_GREEN 2
+#define TC_TURQUOISE 3
+#define TC_RED 4
+#define TC_PURPLE 5
+#define TC_BROWN 6
+#define TC_LIGHTGRAY 7
+#define TC_WHITE 15
+
+class vt;
+class display : public node {
+
+ public:
+ vt *connected_vt;
+
+ display(node* parent) : node(parent, FT_DEV) {
+ dev_type = DT_DISPLAY;
+ connected_vt = 0;
+ }
+ virtual ~display() {}
+
+ virtual display* as_display() { return this; }
+
+ virtual int text_w() = 0;
+ virtual int text_h() = 0;
+ virtual void text_setcsr(int l, int c, bool visible) = 0;
+ virtual void text_put(int l, int c, int ch, uint8_t fgcolor, uint8_t bgcolor) = 0;
+ virtual void text_scroll(int n, uint8_t fgcolor, uint8_t bgcolor) = 0;
+};
+
+#endif
+
diff --git a/src/kernel/dev/keyboard.cpp b/src/kernel/dev/keyboard.cpp
new file mode 100644
index 0000000..479996d
--- /dev/null
+++ b/src/kernel/dev/keyboard.cpp
@@ -0,0 +1,150 @@
+#include "keyboard.h"
+
+#include <ui/vt.h>
+
+int ctrlkeys[] = {
+/* 0x00 */ 0, KB_ESCAPE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_BACKSPACE, KB_TAB,
+/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_ENTER, KB_LCTRL, 0, 0,
+/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_LSHIFT, 0, 0, 0, 0, 0,
+/* 0x30 */ 0, 0, 0, 0, 0, 0, KB_RSHIFT, 0, KB_ALT, 0, KB_CAPSLOCK, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5,
+/* 0x40 */ KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_NUMLOCK, KB_SCRLLOCK, KB_KPHOME, KB_KPUP, KB_KPPGUP, 0, KB_KPLEFT, KB_KP5, KB_KPRIGHT, 0, KB_KPEND,
+/* 0x50 */ KB_KPDOWN, KB_KPPGDOWN, KB_KPINS, KB_KPDEL, KB_SYSREQ, 0, 0, KB_F11, KB_F12, 0, 0, 0, 0, 0, 0, 0,
+/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_ENTER, KB_RCTRL, 0, 0,
+/* 0xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xB0 */ 0, 0, 0, 0, 0, 0, 0, KB_PRTSCN, KB_ALTGR, 0, 0, 0, 0, 0, 0, 0,
+/* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, KB_HOME, KB_UP, KB_PGUP, 0, KB_LEFT, 0, KB_RIGHT, 0, KB_END,
+/* 0xD0 */ KB_DOWN, KB_PGDOWN, KB_INS, KB_DEL, 0, 0, 0, 0, 0, 0, 0, KB_LSUPER, KB_RSUPER, KB_MENU, 0, 0,
+/* 0xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 0xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static keymap default_km = {
+ { // normal
+ /* 0x00 */ 0, 0, '&', L'é', '"', '\'', '(', '-', L'è', '_', L'ç', L'à', ')', '=', 0, 0,
+ /* 0x10 */ 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '^', '$', 0, 0, 'q', 's',
+ /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', L'ù', L'²', 0, '*', 'w', 'x', 'c', 'v',
+ /* 0x30 */ 'b', 'n', ',', ';', ':', '!', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0,
+ /* 0x50 */ 0, 0, 0, 0, 0, 0, '<', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ { // shift
+ /* 0x00 */ 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', L'°', '+', 0, 0,
+ /* 0x10 */ 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', L'¨', L'£', 0, 0, 'Q', 'S',
+ /* 0x20 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', '%', '~', 0, L'µ', 'W', 'X', 'C', 'V',
+ /* 0x30 */ 'B', 'N', '?', '.', '/', L'§', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0,
+ /* 0x50 */ 0, 0, 0, 0, 0, 0, '>', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ { // caps
+ /* 0x00 */ 0, 0, '&', L'É', '"', '\'', '(', '-', L'È', '_', L'Ç', L'À', ')', '=', 0, 0,
+ /* 0x10 */ 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', L'¨', '$', 0, 0, 'Q', 'S',
+ /* 0x20 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', L'Ù', L'²', 0, '*', 'W', 'X', 'C', 'V',
+ /* 0x30 */ 'B', 'N', ',', ';', ':', '!', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0,
+ /* 0x50 */ 0, 0, 0, 0, 0, 0, '>', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ { // alt gr
+ /* 0x00 */ 0, 0, L'¹', '~', '#', '{', '[', '|', '`', '\\', '^', '@', ']', '}', 0, 0,
+ /* 0x10 */ L'æ', L'«', L'€', L'¶', L'ŧ', L'←', L'↓', L'→',
+ L'ø', L'þ', L'¨', L'¤', 0, 0, '@', L'ß',
+ /* 0x20 */ L'ð', L'đ', L'ŋ', L'ħ', 'j', L'ĸ', L'ł', L'µ',
+ '^', L'¬', 0, '`', L'ł', L'»', L'¢', L'“',
+ /* 0x30 */ L'”', 'n', L'´', ';', L'·', '!', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0,
+ /* 0x50 */ 0, 0, 0, 0, 0, 0, '|', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ { // shift + alt gr
+ /* 0x00 */ 0, 0, L'¡', L'⅛', L'£', '$', L'⅜', L'⅝', L'⅞', L'™', L'±', L'°', L'¿', L'˛', 0, 0,
+ /* 0x10 */ L'Æ', '<', L'¢', L'®', L'Ŧ', L'¥', L'↑', L'ı', L'Ø', L'Þ', L'°', L'¯', 0, 0, L'Ω', L'§',
+ /* 0x20 */ L'Ð', L'ª', L'Ŋ', L'Ħ', 'J', '&', L'Ł', L'º', L'ˇ', L'¬', 0, L'˘', L'Ł', '>', L'©', L'‘',
+ /* 0x30 */ L'’', 'N', L'˝', L'×', L'÷', L'˙', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
+ /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0,
+ /* 0x50 */ 0, 0, 0, 0, 0, 0, L'¦', 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ }
+};
+
+keyboard::keyboard(node *parent) : node(parent, FT_DEV) {
+ dev_type = DT_KEYBOARD;
+
+ km = &default_km;
+ num = true;
+ caps = scroll = false;
+ shift = altgr = alt = ctrl = false;
+}
+
+void keyboard::handle(int scancode, bool pressed) {
+ keypress kp;
+ kp.scancode = scancode;
+ kp.pressed = pressed;
+ kp.command = ctrlkeys[scancode];
+ if (kp.command == 0) kp.command = ctrlkeys[scancode & 0x7F];
+
+ if (kp.command == 0) {
+ kp.command = (alt ? KB_CMD_ALT : 0) | (ctrl ? KB_CMD_CTRL : 0);
+ if (shift xor caps) {
+ if (altgr) {
+ kp.character = km->shiftaltgr[scancode];
+ } else {
+ if (shift) {
+ kp.character = km->shift[scancode];
+ } else {
+ kp.character = km->caps[scancode];
+ }
+ }
+ } else {
+ if (altgr) {
+ kp.character = km->altgr[scancode];
+ } else {
+ kp.character = km->normal[scancode];
+ }
+ }
+ } else if (kp.command >= KB_KPDEL && kp.command <= KB_KPPGUP && num) {
+ if (kp.command == KB_KPDEL) {
+ kp.character = '.';
+ } else {
+ kp.character = '0' + kp.command - KB_KPINS;
+ }
+ kp.command = (alt ? KB_CMD_ALT : 0) | (ctrl ? KB_CMD_CTRL : 0);
+ } else if (kp.command == KB_ALT) {
+ alt = pressed;
+ } else if (kp.command == KB_ALTGR) {
+ altgr = pressed;
+ } else if (kp.command == KB_LCTRL || kp.command == KB_RCTRL) {
+ ctrl = pressed;
+ } else if (kp.command == KB_LSHIFT || kp.command == KB_RSHIFT) {
+ shift = pressed;
+ } else if (kp.command == KB_CAPSLOCK) {
+ caps = !caps;
+ updateLeds();
+ } else if (kp.command == KB_NUMLOCK) {
+ num = !num;
+ updateLeds();
+ } else if (kp.command == KB_SCRLLOCK) {
+ scroll = !scroll;
+ updateLeds();
+ } else if (kp.command == KB_TAB) {
+ kp.character = '\t';
+ } else if (kp.command == KB_BACKSPACE) {
+ kp.character = '\b';
+ } else if (kp.command == KB_ENTER) {
+ kp.character = '\n';
+ }
+
+ // process keypress
+ if (kp.character && kp.pressed) {
+ ke_vt->put(kp.character);
+ }
+}
diff --git a/src/kernel/dev/keyboard.h b/src/kernel/dev/keyboard.h
new file mode 100644
index 0000000..61fdbe7
--- /dev/null
+++ b/src/kernel/dev/keyboard.h
@@ -0,0 +1,99 @@
+#ifndef DEF_DEV_KEYBOARD_H
+#define DEF_DEV_KEYBOARD_H
+
+#include <vfs/node.h>
+
+
+// Control keys - arbitrary constants
+#define KB_ESCAPE 1
+#define KB_BACKSPACE 2
+#define KB_TAB 3
+#define KB_ENTER 4
+#define KB_LCTRL 5
+#define KB_RCTRL 6
+#define KB_LSHIFT 7
+#define KB_RSHIFT 8
+#define KB_ALT 9
+#define KB_CAPSLOCK 10
+#define KB_F1 11
+#define KB_F2 12
+#define KB_F3 13
+#define KB_F4 14
+#define KB_F5 15
+#define KB_F6 16
+#define KB_F7 17
+#define KB_F8 18
+#define KB_F9 19
+#define KB_F10 20
+#define KB_F11 21
+#define KB_F12 22
+#define KB_NUMLOCK 23
+#define KB_SCRLLOCK 24
+
+#define KB_KPDEL 25 // also keypad .
+#define KB_KPINS 26 // also keypad 0
+#define KB_KPEND 27 // also 1
+#define KB_KPDOWN 28 // also 2
+#define KB_KPPGDOWN 29 // also 3
+#define KB_KPLEFT 30 //...
+#define KB_KP5 31
+#define KB_KPRIGHT 32
+#define KB_KPHOME 33
+#define KB_KPUP 34
+#define KB_KPPGUP 35 // also 9
+
+#define KB_SYSREQ 36
+#define KB_PRTSCN 38
+#define KB_ALTGR 39
+#define KB_HOME 40
+#define KB_END 41
+#define KB_PGUP 42
+#define KB_PGDOWN 43
+#define KB_INS 44
+#define KB_DEL 45
+#define KB_DOWN 46
+#define KB_UP 47
+#define KB_LEFT 48
+#define KB_RIGHT 49
+#define KB_LSUPER 50
+#define KB_RSUPER 51
+#define KB_MENU 52
+
+#define KB_CMD_ALT 64 // any command with alt will have this flag
+#define KB_CMD_CTRL 128 // any command with controll will have this flag
+
+struct keypress {
+ bool pressed; // false = key was released
+ int scancode;
+ int command;
+ int character;
+};
+
+struct keymap {
+ int normal[128];
+ int shift[128];
+ int caps[128];
+ int altgr[128];
+ int shiftaltgr[128];
+};
+
+class keyboard : public node {
+ private:
+ keymap* km;
+
+ protected:
+ bool num, caps, scroll;
+ bool shift, altgr;
+ bool alt, ctrl;
+
+ virtual void updateLeds() = 0;
+
+ public:
+ keyboard(node* parent);
+ virtual ~keyboard() {}
+
+ void handle(int scancode, bool pressed);
+};
+
+#endif
+
diff --git a/src/kernel/dev/ps2keyboard.cpp b/src/kernel/dev/ps2keyboard.cpp
new file mode 100644
index 0000000..31cd75f
--- /dev/null
+++ b/src/kernel/dev/ps2keyboard.cpp
@@ -0,0 +1,55 @@
+#include "ps2keyboard.h"
+
+#include <core/sys.h>
+#include <task/idt.h>
+
+ps2kbd *kbd = 0;
+
+static void kbd_irq(registers*) {
+ kbd->kbdIrq();
+}
+
+ps2kbd::ps2kbd(node* parent) : keyboard(parent) {
+ uint8_t temp = inb(0x60), temp2 = 0;
+ while (temp != temp2) {
+ temp2 = temp;
+ temp = inb(0x60);
+ }
+
+ kbd = this;
+ idt_handleIrq(1, kbd_irq);
+
+ escaped = false;
+
+ updateLeds();
+}
+
+void ps2kbd::updateLeds() {
+ uint8_t tmp = 0;
+ if (scroll) tmp |= 1;
+ if (num) tmp |= 2;
+ if (caps) tmp |= 4;
+ outb(0x60, tmp);
+}
+
+void ps2kbd::kbdIrq() {
+ uint8_t scancode = inb(0x60);
+ if (scancode == 0xE0) {
+ escaped = true;
+ } else {
+ if (scancode & 0x80) {
+ if (escaped) {
+ handle(scancode, false);
+ } else {
+ handle(scancode & 0x7F, false);
+ }
+ } else {
+ if (escaped) {
+ handle(scancode | 0x80, true);
+ } else {
+ handle(scancode, true);
+ }
+ }
+ escaped = false;
+ }
+}
diff --git a/src/kernel/dev/ps2keyboard.h b/src/kernel/dev/ps2keyboard.h
new file mode 100644
index 0000000..a0e261d
--- /dev/null
+++ b/src/kernel/dev/ps2keyboard.h
@@ -0,0 +1,21 @@
+#ifndef DEF_DEV_PS2KBD_H
+#define DEF_DEV_PS2KBD_H
+
+#include "keyboard.h"
+
+class ps2kbd : public keyboard {
+ private:
+ bool escaped;
+
+ void updateLeds();
+
+ public:
+ ps2kbd(node *parent);
+ virtual ~ps2kbd() {}
+
+ void kbdIrq();
+};
+
+extern ps2kbd *kbd;
+
+#endif
diff --git a/src/kernel/dev/vgatxt.cpp b/src/kernel/dev/vgatxt.cpp
new file mode 100644
index 0000000..75071fb
--- /dev/null
+++ b/src/kernel/dev/vgatxt.cpp
@@ -0,0 +1,50 @@
+#include "vgatxt.h"
+
+#include <core/sys.h>
+#include <mem/mem.h>
+
+static uint16_t *video_memory = (uint16_t*)((size_t)K_HIGHHALF_ADDR + 0xB8000);
+
+vgatxt *text_display;
+
+vgatxt::vgatxt(node *parent) : display(parent) {
+ // nothing to do, really
+}
+
+int vgatxt::text_w() {
+ return 80;
+}
+
+int vgatxt::text_h() {
+ return 25;
+}
+
+void vgatxt::text_setcsr(int l, int c, bool visible) {
+ uint16_t cursor_location = l * 80 + c;
+ if (!visible) cursor_location = 10000;
+ outb(0x3D4, 14); //Sending high cursor byte
+ outb(0x3D5, cursor_location >> 8);
+ outb(0x3D4, 15); //Sending high cursor byte
+ outb(0x3D5, cursor_location);
+}
+
+void vgatxt::text_put(int l, int c, int ch, uint8_t fgcolor, uint8_t bgcolor) {
+ if (ch >= 0x80) ch = '?';
+ video_memory[l * 80 + c] = (char)ch | ((bgcolor << 4 | fgcolor) << 8);
+}
+
+void vgatxt::text_scroll(int n, uint8_t fgcolor, uint8_t bgcolor) {
+ //TODO: optimize
+ for (int i = 0; i < n; i++) {
+
+ uint16_t blank = (((bgcolor << 4) | fgcolor) << 8) | 0x20;
+ int j;
+ for (j = 0; j < 80*24; j++) {
+ video_memory[j] = video_memory[j+80];
+ }
+ for (j = 80*24; j < 80*25; j++) {
+ video_memory[j] = blank;
+ }
+
+ }
+}
diff --git a/src/kernel/dev/vgatxt.h b/src/kernel/dev/vgatxt.h
new file mode 100644
index 0000000..550d4ba
--- /dev/null
+++ b/src/kernel/dev/vgatxt.h
@@ -0,0 +1,23 @@
+#ifndef DEF_MONITOR_H
+#define DEF_MONITOR_H
+
+#include <types.h>
+
+#include "display.h"
+
+class vgatxt : public display {
+ public:
+ vgatxt(node *parent);
+ virtual ~vgatxt() {}
+
+ virtual int text_w();
+ virtual int text_h();
+ virtual void text_setcsr(int l, int c, bool visible);
+ virtual void text_put(int l, int c, int ch, uint8_t fgcolor, uint8_t bgcolor);
+ virtual void text_scroll(int n, uint8_t fgcolor, uint8_t bgcolor);
+};
+
+extern vgatxt *text_display;
+
+#endif
+
diff --git a/src/kernel/lib/std.cpp b/src/kernel/lib/std.cpp
index 7ab4f64..aa5f606 100644
--- a/src/kernel/lib/std.cpp
+++ b/src/kernel/lib/std.cpp
@@ -1,12 +1,12 @@
#include "std.h"
#include "core/sys.h"
-#include "core/monitor.h"
+#include "ui/vt.h"
int errno = 0;
void abort() {
- monitor_write("\n\n ABORT - errno: ");
- monitor_writeDec(errno);
- monitor_write("\n");
+ ke_vt->writeStr("\n\n ABORT - errno: ");
+ ke_vt->writeDec(errno);
+ ke_vt->writeStr("\n");
PANIC("abort() called, probably a memory manager failure.");
}
diff --git a/src/kernel/mem/gdt.cpp b/src/kernel/mem/gdt.cpp
index 49fbd82..cca1767 100644
--- a/src/kernel/mem/gdt.cpp
+++ b/src/kernel/mem/gdt.cpp
@@ -1,6 +1,5 @@
#include "gdt.h"
#include <stdlib_common.h>
-#include <core/monitor.h>
extern "C" void gdt_flush(uint32_t); //ASM (imported from idt_.asm)
extern "C" void tss_flush();
@@ -59,6 +58,4 @@ void gdt_init() {
gdt_flush((uint32_t)&gdt_ptr);
tss_flush();
-
- monitor_write("[GDT] ");
}
diff --git a/src/kernel/mem/mem.cpp b/src/kernel/mem/mem.cpp
index 5e04de3..dfdd5dd 100644
--- a/src/kernel/mem/mem.cpp
+++ b/src/kernel/mem/mem.cpp
@@ -1,6 +1,5 @@
#include "mem.h"
#include <core/sys.h>
-#include <core/monitor.h>
#include "paging.h"
#include <config.h>
@@ -88,12 +87,6 @@ void* ksbrk(size_t size) {
size_t tmp = mem_placementAddr;
size_t er_begin, er_end, i;
- /* (DBG) monitor_write("<ksbrk ");
- monitor_writeHex(size);
- monitor_write(":");
- monitor_writeHex(tmp);
- monitor_write("> "); */
-
mem_placementAddr += size;
if (_no_more_ksbrk) { // paging enabled, we must allocate these pages
@@ -125,10 +118,6 @@ void* ksbrk(size_t size) {
}
void kbrk(void* ptr) {
- monitor_write("<kbrk ");
- monitor_writeHex((uint32_t)ptr);
- monitor_write(">\n");
-
if ((size_t)ptr > (size_t)&end) {
ksbrk((size_t)ptr - (size_t)mem_placementAddr);
} else {
diff --git a/src/kernel/mem/paging.cpp b/src/kernel/mem/paging.cpp
index 206cc08..01a1780 100644
--- a/src/kernel/mem/paging.cpp
+++ b/src/kernel/mem/paging.cpp
@@ -1,11 +1,11 @@
#include "paging.h"
#include <bitset.h>
#include <stdlib_common.h>
-#include <core/monitor.h>
#include "mem.h"
#include "seg.h"
#include <core/sys.h>
#include <task/task.h>
+#include <ui/vt.h>
static bitset frames;
@@ -57,10 +57,7 @@ void paging_init(size_t totalRam) {
kernel_pagedir->tables[i] = kernel_pagedir->tables[i + FIRST_KERNEL_PAGETABLE];
}
- monitor_write("{PD: ");
- monitor_writeHex(kernel_pagedir->physicalAddr);
pagedir_switch(kernel_pagedir);
- monitor_write("} [Paging] ");
}
/* De-allocates pages at 0x00000000 where kernel code was read from with the GDT from loader_.asm. */
@@ -70,7 +67,6 @@ void paging_cleanup() {
kernel_pagedir->tablesPhysical[i] = 0;
kernel_pagedir->tables[i] = 0;
}
- monitor_write("[PD Cleanup] ");
}
/************************* PAGING EVERYDAY USE *****************************/
@@ -140,14 +136,14 @@ uint32_t paging_fault(registers *regs) {
}
if (seg == 0) {
- NL; WHERE; monitor_write("Unhandled Page Fault\t");
- monitor_write("cr2:"); monitor_writeHex(addr);
+ NL; WHERE; ke_vt->writeStr("Unhandled Page Fault\t");
+ ke_vt->writeStr("cr2:"); ke_vt->writeHex(addr);
NL; TAB;
- if (regs->err_code & 0x1) monitor_write("present"); TAB;
- if (regs->err_code & 0x2) monitor_write("write"); TAB;
- if (regs->err_code & 0x4) monitor_write("user"); TAB;
- if (regs->err_code & 0x8) monitor_write("rsvd"); TAB;
- if (regs->err_code & 0x10) monitor_write("opfetch");
+ if (regs->err_code & 0x1) ke_vt->writeStr("present"); TAB;
+ if (regs->err_code & 0x2) ke_vt->writeStr("write"); TAB;
+ if (regs->err_code & 0x4) ke_vt->writeStr("user"); TAB;
+ if (regs->err_code & 0x8) ke_vt->writeStr("rsvd"); TAB;
+ if (regs->err_code & 0x10) ke_vt->writeStr("opfetch");
return 1;
}
return 0;
diff --git a/src/kernel/task/idt.cpp b/src/kernel/task/idt.cpp
index c09034e..634350c 100644
--- a/src/kernel/task/idt.cpp
+++ b/src/kernel/task/idt.cpp
@@ -1,11 +1,12 @@
#include "idt.h"
-#include <core/monitor.h>
#include <core/sys.h>
#include <mem/paging.h>
#include <lib/cpp.h>
#include "task.h"
#include "syscall.h"
+#include <ui/vt.h>
+
#include <stdlib_common.h>
extern "C" {
@@ -80,9 +81,9 @@ static struct irq_waiter {
extern "C" void idt_isrHandler(registers regs) {
if ((regs.int_no == 14 && paging_fault(&regs) != 0) || regs.int_no != 14) {
if (tasking_handleException(&regs) == 0) {
- monitor_write("\nREALLY BAD THIS TIME\t\tUnhandled exception\t#");
- monitor_writeDec(regs.int_no);
- monitor_write("\t@"); monitor_writeHex(regs.eip);
+ ke_vt->writeStr("\nREALLY BAD THIS TIME\t\tUnhandled exception\t#");
+ ke_vt->writeDec(regs.int_no);
+ ke_vt->writeStr("\t@"); ke_vt->writeHex(regs.eip);
PANIC("Unhandled Exception");
}
}
@@ -191,8 +192,6 @@ void idt_init() {
idt_setGate(64, (int32_t)syscall64, 0x08, 0x8E);
idt_flush((int32_t)&idt_ptr);
-
- monitor_write("[IDT] ");
}
/* Sets up an IRQ handler for given IRQ. */
diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp
index 797c5db..e9f9d3a 100644
--- a/src/kernel/task/syscall.cpp
+++ b/src/kernel/task/syscall.cpp
@@ -1,7 +1,7 @@
#include "syscall.h"
#include "task.h"
#include "timer.h"
-#include <core/monitor.h>
+#include <ui/vt.h>
#include <core/sys.h>
#include <vfs/node.h>
@@ -32,7 +32,7 @@ CALL1V(process_brk, proc_brk_sc);
CALL1V(close, close_sc);
static void printk_sc(registers *r) {
- monitor_write((char*)r->ebx);
+ ke_vt->writeStr((char*)r->ebx);
}
static void thread_new_sc(registers* r) {
diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp
index 3998bfe..e54b96e 100644
--- a/src/kernel/task/task.cpp
+++ b/src/kernel/task/task.cpp
@@ -1,12 +1,13 @@
#include "task.h"
#include "sched.h"
#include <core/sys.h>
-#include <core/monitor.h>
#include <lib/cpp.h>
#include <mem/seg.h>
#include <mem/gdt.h>
#include "timer.h"
+#include <ui/vt.h>
+
#define KSTACKSIZE 0x8000
//Static routines for handling threads exiting and all cleanup
@@ -39,7 +40,6 @@ void tasking_init() {
current_thread = 0;
idle_thread = new thread(kernel_process, task_idle, 0, 0);
sti();
- monitor_write("[Tasking] ");
}
/* Called by the paging functions when a page table is allocated in the kernel space (>K_HIGHHALF_ADDR).
@@ -97,23 +97,23 @@ void schedule() {
Ends the thread for most exceptions, ends the whole process for page faults. */
uint32_t tasking_handleException(registers *regs) {
if (current_thread == 0) return 0; //No tasking yet
- NL; WHERE; monitor_write("exception:`");
+ NL; WHERE; ke_vt->writeStr("exception:`");
char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint",
"Into Detected Overflow","Out of Bounds","Invalid Opcode","No Coprocessor", "Double Fault",
"Coprocessor Segment Overrun","Bad TSS","Segment Not Present","Stack Fault","General Protection Fault",
"Page Fault","Unknown Interrupt","Coprocessor Fault","Alignment Check","Machine Check"};
- monitor_write(exception_messages[regs->int_no]);
- monitor_write("'\teip:"); monitor_writeHex(regs->eip);
+ ke_vt->writeStr(exception_messages[regs->int_no]);
+ ke_vt->writeStr("'\teip:"); ke_vt->writeHex(regs->eip);
if (regs->eip >= K_HIGHHALF_ADDR) {
- monitor_write("\n Exception stack trace :\n");
+ ke_vt->writeStr("\n Exception stack trace :\n");
stack_trace(regs->ebp);
PANIC("Kernel error'd.");
}
if (regs->int_no == 14) {
- monitor_write("\n>>> Process exiting.\n");
+ ke_vt->writeStr("\n>>> Process exiting.\n");
thread_exit_stackJmp(EX_PR_EXCEPTION);
} else {
- monitor_write("\n>>> Thread exiting.\n");
+ ke_vt->writeStr("\n>>> Thread exiting.\n");
thread_exit_stackJmp(EX_TH_EXCEPTION);
}
PANIC("This should never have happened. Please report this.");
@@ -372,11 +372,11 @@ size_t process_sbrk(size_t size) {
ret = p->data;
p->data += size;
}
- /* (DBG) monitor_write("(sbrk ");
- monitor_writeHex(size);
- monitor_write(" ");
- monitor_writeHex(ret);
- monitor_write(")"); */
+ /* (DBG) ke_vt->writeStr("(sbrk ");
+ ke_vt->writeHex(size);
+ ke_vt->writeStr(" ");
+ ke_vt->writeHex(ret);
+ ke_vt->writeStr(")"); */
return ret;
}
diff --git a/src/kernel/task/timer.cpp b/src/kernel/task/timer.cpp
index ccc3c79..0e92b57 100644
--- a/src/kernel/task/timer.cpp
+++ b/src/kernel/task/timer.cpp
@@ -3,7 +3,6 @@
#include "idt.h"
#include <mem/mem.h>
#include <core/sys.h>
-#include <core/monitor.h>
static uint32_t tick = 0, frequency = 0, uptime = 0;
@@ -23,8 +22,6 @@ void timer_init(uint32_t freq) {
uint8_t l = (divisor & 0xFF), h = (divisor >> 8);
outb(0x40, l);
outb(0x40, h);
-
- monitor_write("[PIT] ");
}
/* Accessor function to get machine uptime. */
diff --git a/src/kernel/ui/vt.cpp b/src/kernel/ui/vt.cpp
new file mode 100644
index 0000000..4675cdc
--- /dev/null
+++ b/src/kernel/ui/vt.cpp
@@ -0,0 +1,159 @@
+#include "vt.h"
+#include <dev/display.h>
+
+vt *ke_vt = 0;
+
+vt::vt(node* parent, int ww, int hh) : node(parent, FT_TERMINAL) {
+ w = ww; h = hh;
+ fgcolor = TC_LIGHTGRAY;
+ bgcolor = TC_BLACK;
+ output = 0;
+ cursor_visible = true;
+
+ text = 0;
+ if (w != 0 && h != 0) {
+ text = (vt_char*)kmalloc(w * h * sizeof(vt_char));
+ clear();
+ }
+}
+
+void vt::put_at(int l, int c, int ch) {
+ text[l * w + c].fgcolor = fgcolor;
+ text[l * w + c].bgcolor = bgcolor;
+ text[l * w + c].ch = ch;
+ if (output != 0) output->text_put(l, c, ch, fgcolor, bgcolor);
+}
+
+void vt::put(int c) {
+ if (text == 0) return;
+
+ if (c == '\b' && csr_c != 0) {
+ csr_c--;
+ put_at(csr_l, csr_c, ' ');
+ } else if (c == '\t') {
+ int csr_nc = (csr_c + 8) & ~(8 - 1);
+ for (int i = csr_c; i < csr_nc && i < w; i++) put_at(csr_l, i, ' ');
+ csr_c = csr_nc;
+ } else if (c == '\r') {
+ csr_c = 0;
+ } else if (c == '\n') {
+ csr_c = 0;
+ csr_l++;
+ } else if (c >= ' ') {
+ put_at(csr_l, csr_c, c);
+ csr_c++;
+ }
+ if (csr_c >= w) {
+ csr_c = 0;
+ csr_l++;
+ }
+ if (csr_l == h) {
+ if (output != 0 && output->connected_vt == this) {
+ output->text_scroll(1, fgcolor, bgcolor);
+ }
+ for (int j = 0; j < w * (h-1); j++) {
+ text[j] = text[j + w];
+ }
+ for (int j = w * (h-1); j < w * h; j++) {
+ text[j].fgcolor = fgcolor;
+ text[j].bgcolor = bgcolor;
+ text[j].ch = ' ';
+ }
+ csr_l--;
+ }
+ if (output != 0 && output->connected_vt == this) output->text_setcsr(csr_l, csr_c, cursor_visible);
+}
+
+void vt::clear() {
+ for (int i = 0; i < w; i++) {
+ for (int j = 0; j < h; j++) {
+ put_at(j, i, ' ');
+ }
+ }
+ csr_c = csr_l = 0;
+}
+
+void vt::writeStr(char *s) {
+ while (*s) {
+ put(*(s++));
+ }
+}
+
+void vt::writeHex(uint32_t v) {
+ int i;
+
+ put('0'); put('x');
+ char hexdigits[] = "0123456789abcdef";
+
+ for (i = 0; i < 8; i++) {
+ put(hexdigits[v >> 28]);
+ v = v << 4;
+ }
+}
+
+void vt::writeDec(uint32_t v) {
+ if (v == 0) {
+ put('0');
+ return;
+ }
+
+ char numbers[] = "0123456789";
+ while (v > 0) {
+ int order = 1, no = 1;
+ while (v / order > 0) order *= 10;
+ order /= 10;
+ put(numbers[v / order]);
+ v = v - (v / order * order);
+ while (v / no > 0) no *= 10;
+ while (no < order) {
+ put('0');
+ no *= 10;
+ }
+ }
+}
+
+// *******
+
+int vt::outputTo(display *display) {
+ output = display;
+ if (output == 0) return 0;
+ output->connected_vt = this;
+
+ if (output->text_w() != w || output->text_h() != h) {
+ int ow = w, oh = h;
+ vt_char *old_text = text;
+
+ w = output->text_w();
+ h = output->text_h();
+ text = (vt_char*)malloc(w * h * sizeof(vt_char));
+ for (int c = 0; c < w; c++) {
+ for (int l = 0; l < h; l++) {
+ if (c < ow && l < oh) {
+ put_at(l, c, old_text[l * ow + c].ch);
+ } else {
+ put_at(l, c, ' ');
+ }
+ }
+ }
+ if (old_text != 0) free(old_text);
+ if (csr_c >= w) csr_c = w;
+ if (csr_l >= h) csr_l = h;
+ } else {
+ for (int c = 0; c < w; c++) {
+ for (int l = 0; l < h; l++) {
+ output->text_put(l, c, text[l*w+c].ch, text[l*w+c].fgcolor, text[l*w+c].bgcolor);
+ }
+ }
+ }
+ return 0;
+}
+
+int vt::write(size_t offset, size_t len, char* buffer) {
+ // ignore offset
+ for (unsigned i = 0; i < len; i++) put(buffer[i]);
+ return len;
+}
+
+size_t vt::get_size() {
+ return ((w << 16) + h);
+}
diff --git a/src/kernel/ui/vt.h b/src/kernel/ui/vt.h
new file mode 100644
index 0000000..b4f3672
--- /dev/null
+++ b/src/kernel/ui/vt.h
@@ -0,0 +1,49 @@
+#ifndef DEF_UI_VT_H
+#define DEF_UI_VT_H
+
+#include <vfs/node.h>
+#include <dev/display.h>
+
+struct vt_char {
+ int ch;
+ uint8_t fgcolor, bgcolor;
+};
+
+class vt : public node {
+ private:
+ display *output;
+ int w, h, csr_l, csr_c;
+ vt_char *text;
+
+ void put_at(int l, int c, int ch);
+ bool cursor_visible;
+
+ public:
+ uint8_t fgcolor, bgcolor;
+
+ vt(node* parent, int w, int h);
+
+ // internal use
+ void put(int c);
+ void clear();
+ void writeStr(char* str);
+ void writeHex(uint32_t v);
+ void writeDec(uint32_t v);
+
+ int outputTo(display *display);
+
+ virtual int write(size_t offset, size_t len, char* buffer);
+ virtual size_t get_size();
+};
+
+extern vt *ke_vt;
+#define NL ke_vt->writeStr("\n");
+#define TAB ke_vt->writeStr("\t");
+#define WHERE { ke_vt->writeStr("(ke:"); \
+ ke_vt->writeStr(__FILE__); \
+ ke_vt->writeStr(":"); \
+ ke_vt->writeDec(__LINE__); \
+ ke_vt->writeStr(") "); }
+
+#endif
+
diff --git a/src/kernel/vfs/node.cpp b/src/kernel/vfs/node.cpp
index 9900a3c..e174bd6 100644
--- a/src/kernel/vfs/node.cpp
+++ b/src/kernel/vfs/node.cpp
@@ -1,6 +1,5 @@
#include "node.h"
#include "vdir.h"
-#include <core/monitor.h>
int node::open(process *proc, int mode) {
//TODO : permission checks
@@ -17,13 +16,14 @@ int node::stat(file_info *info) {
return 0;
}
-node *root = 0;
+node *root = 0, *dot_dev = 0, *dot_ui = 0;
void vfs_setup() {
root = new vdir(0);
- root->add_child(".dev", new vdir(root));
-
- monitor_write("[VFS] ");
+ dot_dev = new vdir(root);
+ root->add_child(".dev", dot_dev);
+ dot_ui = new vdir(root);
+ root->add_child(".ui", dot_ui);
}
node* vfs_find(node* root, char* path) {
diff --git a/src/kernel/vfs/node.h b/src/kernel/vfs/node.h
index 2d16dab..9005d55 100644
--- a/src/kernel/vfs/node.h
+++ b/src/kernel/vfs/node.h
@@ -6,6 +6,8 @@
#include <task/task.h>
+class display;
+
class node {
public:
node* parent;
@@ -13,6 +15,7 @@ class node {
int mode, uid, gid;
node(node* p, int t) : parent(p), type(t) {}
+ virtual ~node() {}
virtual int open(process *proc, int mode);
virtual void close(process *proc) {}
@@ -22,11 +25,16 @@ class node {
virtual node* get_child(char* name) { return 0; }
virtual int add_child(char* name, node *child) { return E_NOT_IMPLEMENTED; }
virtual size_t get_size() { return 0; }
+
+ // kind of like dynamic_cast'int these things
+ virtual display *as_display() { return 0; }
};
void vfs_setup();
node* vfs_find(node* root, char* filename);
+extern node *root, *dot_dev, *dot_ui;
+
// syscall interface
FILE open(char* filename, int mode);
FILE open_relative(FILE root, char* filename, int mode);
diff --git a/src/kernel/vfs/vdir.h b/src/kernel/vfs/vdir.h
index 9595409..609a504 100644
--- a/src/kernel/vfs/vdir.h
+++ b/src/kernel/vfs/vdir.h
@@ -20,6 +20,7 @@ class vdir : public node {
public:
vdir(node* parent);
+ virtual ~vdir() {}
virtual int read(size_t offset, size_t len, char* buffer);
virtual int write(size_t offset, size_t len, char* buffer); // rename file