summaryrefslogtreecommitdiff
path: root/src/kernel/dev
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 /src/kernel/dev
parent7c9a48b4e6d66cf4f62e7bad9e22ab06923e47ef (diff)
downloadTCE-593bf4df3d8db49286c1a7ae4ef75c887b629930.tar.gz
TCE-593bf4df3d8db49286c1a7ae4ef75c887b629930.zip
Devices using the VFS structure. Basic keyboard handler.
Diffstat (limited to 'src/kernel/dev')
-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
7 files changed, 436 insertions, 0 deletions
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
+