diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-17 17:56:23 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-17 17:56:23 +0200 |
commit | 593bf4df3d8db49286c1a7ae4ef75c887b629930 (patch) | |
tree | 988a104c9611d72e1252282789688586efd9a394 /src/kernel/dev | |
parent | 7c9a48b4e6d66cf4f62e7bad9e22ab06923e47ef (diff) | |
download | TCE-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.h | 38 | ||||
-rw-r--r-- | src/kernel/dev/keyboard.cpp | 150 | ||||
-rw-r--r-- | src/kernel/dev/keyboard.h | 99 | ||||
-rw-r--r-- | src/kernel/dev/ps2keyboard.cpp | 55 | ||||
-rw-r--r-- | src/kernel/dev/ps2keyboard.h | 21 | ||||
-rw-r--r-- | src/kernel/dev/vgatxt.cpp | 50 | ||||
-rw-r--r-- | src/kernel/dev/vgatxt.h | 23 |
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 + |