diff --git a/include/keyboard.h b/include/keyboard.h index 0ca4a68..1d24452 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -16,6 +16,8 @@ /************************************************************************/ #define KB_IN_BYTES 320 /* size of keyboard input buffer */ /* FIXME */ #define MOUSE_IN_BYTES 4 +#define DEBUGNEW +#ifndef DEBUGNEW #define MAP_COLS 3 /* Number of columns in keymap */ #define NR_SCAN_CODES 0x80 /* Number of scan codes (rows in keymap) */ @@ -118,7 +120,7 @@ #define PAD_INS PAD_0 /* Ins */ #define PAD_MID PAD_5 /* Middle key */ #define PAD_DEL PAD_DOT /* Del */ - +#endif #define PS2_PORT_DATA (0x60) #define PS2_PORT_CMD (0x64) diff --git a/include/minix_keymap.h b/include/minix_keymap.h new file mode 100644 index 0000000..d3b36ff --- /dev/null +++ b/include/minix_keymap.h @@ -0,0 +1,801 @@ +#ifndef _MINIX_KEYMAP_H +#define _MINIX_KEYMAP_H + +#include "type.h" + +#ifdef _SYSTEM + +/* Device type. */ +#define INPUT_DEV_KBD 0x01 /* keyboard device */ +#define INPUT_DEV_MOUSE 0x02 /* mouse device */ + +/* Known-invalid input device ID. */ +#define INVALID_INPUT_ID (-1) + +#endif /* _SYSTEM */ + +/* + * The input server heavily draws on the USB HID specification for events. + * Every driver should convert its event codes into this format. This also + * implies that we use the U.S. keyboard layout for key events. The mapping to + * localized keyboard layouts will be done at a different place (TTY, Xserver). + */ + +/* A single event, as read from one of the input devices. */ +struct input_event { + u16 page; /* event page (INPUT_PAGE_) */ + u16 code; /* page-specific event code */ + i32 value; /* event value */ + u16 flags; /* event flags (INPUT_FLAG_) */ + u16 devid; /* identifier of source device */ + u16 rsvd[2]; /* reserved for a future timestamp */ +}; + +/* Event pages. */ +#define INPUT_PAGE_GD 0x0001 /* General Desktop page */ +#define INPUT_PAGE_KEY 0x0007 /* Keyboard/Keypad page */ +#define INPUT_PAGE_LED 0x0008 /* LED page */ +#define INPUT_PAGE_BUTTON 0x0009 /* Button page */ +#define INPUT_PAGE_CONS 0x000C /* Consumer page */ + +/* Event values. Not exhaustive. */ +#define INPUT_RELEASE 0 +#define INPUT_PRESS 1 + +/* Event flags. */ +#define INPUT_FLAG_ABS 0x00 /* absolute value (the default) */ +#define INPUT_FLAG_REL 0x04 /* relative value */ + +/* Page-specific event codes. */ +enum { + INPUT_GD_X = 0x0030, + INPUT_GD_Y, + + INPUT_GD_SYSTEM_POWER_DOWN = 0x0081, + INPUT_GD_SYSTEM_SLEEP, + INPUT_GD_SYSTEM_WAKE_UP +}; + +enum { + INPUT_KEY_A = 0x0004, + INPUT_KEY_B, + INPUT_KEY_C, + INPUT_KEY_D, + INPUT_KEY_E, + INPUT_KEY_F, + INPUT_KEY_G, + INPUT_KEY_H, + INPUT_KEY_I, + INPUT_KEY_J, + INPUT_KEY_K, + INPUT_KEY_L, + INPUT_KEY_M, + INPUT_KEY_N, + INPUT_KEY_O, + INPUT_KEY_P, + INPUT_KEY_Q, + INPUT_KEY_R, + INPUT_KEY_S, + INPUT_KEY_T, + INPUT_KEY_U, + INPUT_KEY_V, + INPUT_KEY_W, + INPUT_KEY_X, + INPUT_KEY_Y, + INPUT_KEY_Z, + INPUT_KEY_1, + INPUT_KEY_2, + INPUT_KEY_3, + INPUT_KEY_4, + INPUT_KEY_5, + INPUT_KEY_6, + INPUT_KEY_7, + INPUT_KEY_8, + INPUT_KEY_9, + INPUT_KEY_0, + + INPUT_KEY_ENTER, + INPUT_KEY_ESCAPE, + INPUT_KEY_BACKSPACE, + INPUT_KEY_TAB, + INPUT_KEY_SPACEBAR, + INPUT_KEY_DASH, + INPUT_KEY_EQUAL, + INPUT_KEY_OPEN_BRACKET, + INPUT_KEY_CLOSE_BRACKET, + INPUT_KEY_BACKSLASH, + INPUT_KEY_EUROPE_1, + INPUT_KEY_SEMICOLON, + INPUT_KEY_APOSTROPH, + INPUT_KEY_GRAVE_ACCENT, + INPUT_KEY_COMMA, + INPUT_KEY_PERIOD, + INPUT_KEY_SLASH, + INPUT_KEY_CAPS_LOCK, + + INPUT_KEY_F1, + INPUT_KEY_F2, + INPUT_KEY_F3, + INPUT_KEY_F4, + INPUT_KEY_F5, + INPUT_KEY_F6, + INPUT_KEY_F7, + INPUT_KEY_F8, + INPUT_KEY_F9, + INPUT_KEY_F10, + INPUT_KEY_F11, + INPUT_KEY_F12, + + INPUT_KEY_PRINT_SCREEN, + INPUT_KEY_SCROLL_LOCK, + INPUT_KEY_PAUSE, + INPUT_KEY_INSERT, + INPUT_KEY_HOME, + INPUT_KEY_PAGE_UP, + INPUT_KEY_DELETE, + INPUT_KEY_END, + INPUT_KEY_PAGE_DOWN, + INPUT_KEY_RIGHT_ARROW, + INPUT_KEY_LEFT_ARROW, + INPUT_KEY_DOWN_ARROW, + INPUT_KEY_UP_ARROW, + INPUT_KEY_NUM_LOCK, + + INPUT_KEY_KP_SLASH, + INPUT_KEY_KP_STAR, + INPUT_KEY_KP_DASH, + INPUT_KEY_KP_PLUS, + INPUT_KEY_KP_ENTER, + INPUT_KEY_KP_1, + INPUT_KEY_KP_2, + INPUT_KEY_KP_3, + INPUT_KEY_KP_4, + INPUT_KEY_KP_5, + INPUT_KEY_KP_6, + INPUT_KEY_KP_7, + INPUT_KEY_KP_8, + INPUT_KEY_KP_9, + INPUT_KEY_KP_0, + INPUT_KEY_KP_PERIOD, + + INPUT_KEY_EUROPE_2, + INPUT_KEY_APPLICATION, + INPUT_KEY_POWER, + INPUT_KEY_KP_EQUAL, + + INPUT_KEY_F13, + INPUT_KEY_F14, + INPUT_KEY_F15, + INPUT_KEY_F16, + INPUT_KEY_F17, + INPUT_KEY_F18, + INPUT_KEY_F19, + INPUT_KEY_F20, + INPUT_KEY_F21, + INPUT_KEY_F22, + INPUT_KEY_F23, + INPUT_KEY_F24, + + INPUT_KEY_EXECUTE, + INPUT_KEY_HELP, + INPUT_KEY_MENU, + INPUT_KEY_SELECT, + INPUT_KEY_STOP, + INPUT_KEY_AGAIN, + INPUT_KEY_UNDO, + INPUT_KEY_CUT, + INPUT_KEY_COPY, + INPUT_KEY_PASTE, + INPUT_KEY_FIND, + INPUT_KEY_MUTE, + INPUT_KEY_VOLUME_UP, + INPUT_KEY_VOLUME_DOWN, + INPUT_KEY_LOCKING_CAPS_LOCK, + INPUT_KEY_LOCKING_NUM_LOCK, + INPUT_KEY_LOCKING_SCROLL_LOCK, + INPUT_KEY_KP_COMMA, + INPUT_KEY_EQUAL_SIGN, + INPUT_KEY_I10L_1, + INPUT_KEY_I10L_2, + INPUT_KEY_I10L_3, + INPUT_KEY_I10L_4, + INPUT_KEY_I10L_5, + INPUT_KEY_I10L_6, + INPUT_KEY_I10L_7, + INPUT_KEY_I10L_8, + INPUT_KEY_I10L_9, + INPUT_KEY_LANG_1, + INPUT_KEY_LANG_2, + INPUT_KEY_LANG_3, + INPUT_KEY_LANG_4, + INPUT_KEY_LANG_5, + INPUT_KEY_LANG_6, + INPUT_KEY_LANG_7, + INPUT_KEY_LANG_8, + INPUT_KEY_LANG_9, + INPUT_KEY_ALT_ERASE, + INPUT_KEY_SYSREQ, + INPUT_KEY_CANCEL, + INPUT_KEY_CLEAR, + INPUT_KEY_PRIOR, + INPUT_KEY_RETURN, + INPUT_KEY_SEPARATOR, + INPUT_KEY_OUT, + INPUT_KEY_OPER, + INPUT_KEY_CLEAR_AGAIN, + INPUT_KEY_CR_SEL, + INPUT_KEY_EX_SEL, + + /* 0x00A5 -- 0x00AF RESERVED */ + + INPUT_KEY_KP_00 = 0x00B0, + INPUT_KEY_KP_000, + INPUT_KEY_THOUSANDS_SEP, + INPUT_KEY_DECIMAL_SEP, + INPUT_KEY_CURRENCY_UNIT, + INPUT_KEY_CURRENCY_SUBUNIT, + INPUT_KEY_KP_OPEN_PARENTHESIS, + INPUT_KEY_KP_CLOSE_PARENTHESIS, + INPUT_KEY_KP_OPEN_BRACE, + INPUT_KEY_KP_CLOSE_BRACE, + INPUT_KEY_KP_TAB, + INPUT_KEY_KP_BACKSPACE, + INPUT_KEY_KP_A, + INPUT_KEY_KP_B, + INPUT_KEY_KP_C, + INPUT_KEY_KP_D, + INPUT_KEY_KP_E, + INPUT_KEY_KP_F, + INPUT_KEY_KP_XOR, + INPUT_KEY_KP_CARET, + INPUT_KEY_KP_PERCENT, + INPUT_KEY_KP_SMALLER_THEN, + INPUT_KEY_KP_GREATER_THEN, + INPUT_KEY_KP_AMP, + INPUT_KEY_KP_DOUBLE_AMP, + INPUT_KEY_KP_PIPE, + INPUT_KEY_KP_DOUBLE_PIPE, + INPUT_KEY_KP_COLON, + INPUT_KEY_KP_NUMBER, + INPUT_KEY_KP_SPACE, + INPUT_KEY_KP_AT, + INPUT_KEY_KP_EXCLAMATION_MARK, + INPUT_KEY_KP_MEM_STORE, + INPUT_KEY_KP_MEM_RECALL, + INPUT_KEY_KP_MEM_CLEAR, + INPUT_KEY_KP_MEM_ADD, + INPUT_KEY_KP_MEM_SUBTRACT, + INPUT_KEY_KP_MEM_MULTIPLY, + INPUT_KEY_KP_MEM_DIVIDE, + INPUT_KEY_KP_PLUS_MINUS, + INPUT_KEY_KP_CLEAR, + INPUT_KEY_KP_CLEAR_ENTRY, + INPUT_KEY_KP_BIN, + INPUT_KEY_KP_OCT, + INPUT_KEY_KP_DEC, + INPUT_KEY_KP_HEX, + + /* 0x00DE, 0x00DF RESERVED */ + + INPUT_KEY_LEFT_CTRL = 0x00E0, + INPUT_KEY_LEFT_SHIFT, + INPUT_KEY_LEFT_ALT, + INPUT_KEY_LEFT_GUI, + INPUT_KEY_RIGHT_CTRL, + INPUT_KEY_RIGHT_SHIFT, + INPUT_KEY_RIGHT_ALT, + INPUT_KEY_RIGHT_GUI + + /* 0x00E8 -- 0xFFFF RESERVED */ +}; + +enum { + INPUT_LED_NUMLOCK = 0x0001, + INPUT_LED_CAPSLOCK, + INPUT_LED_SCROLLLOCK +}; + +enum { + INPUT_BUTTON_1 = 0x0001, +}; + +enum { + INPUT_CONS_SCAN_NEXT_TRACK = 0x00B5, + INPUT_CONS_SCAN_PREVIOUS_TRACK, + INPUT_CONS_STOP, + + INPUT_CONS_PLAY_PAUSE = 0x00CD, + + INPUT_CONS_MUTE = 0x00E2, + + INPUT_CONS_VOLUME_UP = 0x00E9, + INPUT_CONS_VOLUME_DOWN, + + INPUT_CONS_AL_MEDIA_SELECT = 0x0183, + + INPUT_CONS_AL_EMAIL_READER = 0x018A, + + INPUT_CONS_AL_CALCULATOR = 0x0192, + + INPUT_CONS_AL_LOCAL_BROWSER = 0x0194, + + INPUT_CONS_AC_SEARCH = 0x0221, + INPUT_CONS_AC_GO_TO, + INPUT_CONS_AC_HOME, + INPUT_CONS_AC_BACK, + INPUT_CONS_AC_FORWARD, + INPUT_CONS_AC_STOP, + INPUT_CONS_AC_REFRESH, + + INPUT_CONS_AC_BOOKMARKS = 0x022A +}; + +/* Standard and AT keyboard. (PS/2 MCA implies AT throughout.) */ +#define KEYBD 0x60 /* I/O port for keyboard data */ + +/* AT keyboard. */ +#define KB_COMMAND 0x64 /* I/O port for commands on AT */ +#define KB_STATUS 0x64 /* I/O port for status on AT */ +#define KB_ACK 0xFA /* keyboard ack response */ +#define KB_AUX_BYTE 0x20 /* Auxiliary Device Output Buffer Full */ +#define KB_OUT_FULL 0x01 /* status bit set when keypress char pending */ +#define KB_IN_FULL 0x02 /* status bit set when not ready to receive */ +#define KBC_RD_RAM_CCB 0x20 /* Read controller command byte */ +#define KBC_WR_RAM_CCB 0x60 /* Write controller command byte */ +#define KBC_DI_AUX 0xA7 /* Disable Auxiliary Device */ +#define KBC_EN_AUX 0xA8 /* Enable Auxiliary Device */ +#define KBC_DI_KBD 0xAD /* Disable Keybard Interface */ +#define KBC_EN_KBD 0xAE /* Enable Keybard Interface */ +#define LED_CODE 0xED /* command to keyboard to set LEDs */ + +#define KBC_WAIT_TIME 100000 /* wait this many usecs for a status update */ +#define KBC_READ_TIME 1000000 /* wait this many usecs for a result byte */ + +#define KBC_IN_DELAY 7 /* wait 7 microseconds when polling */ + +#define KBD_OUT_BUFSZ 16 /* Output buffer for data to the keyboard. */ + +#define KBD_SCAN_CODES 0x80 + +#define SCAN_RELEASE 0x80 +#define SCAN_CTRL 0x1D +#define SCAN_NUMLOCK 0x45 +#define SCAN_EXT0 0xE0 +#define SCAN_EXT1 0xE1 + +#define LED_SCROLL_LOCK 0x01 +#define LED_NUM_LOCK 0x02 +#define LED_CAPS_LOCK 0x04 + +struct scanmap { + u16 page; + u16 code; +}; + +const static struct scanmap scanmap_normal[KBD_SCAN_CODES] = { + [0x01] = { INPUT_PAGE_KEY, INPUT_KEY_ESCAPE }, + [0x02] = { INPUT_PAGE_KEY, INPUT_KEY_1 }, + [0x03] = { INPUT_PAGE_KEY, INPUT_KEY_2 }, + [0x04] = { INPUT_PAGE_KEY, INPUT_KEY_3 }, + [0x05] = { INPUT_PAGE_KEY, INPUT_KEY_4 }, + [0x06] = { INPUT_PAGE_KEY, INPUT_KEY_5 }, + [0x07] = { INPUT_PAGE_KEY, INPUT_KEY_6 }, + [0x08] = { INPUT_PAGE_KEY, INPUT_KEY_7 }, + [0x09] = { INPUT_PAGE_KEY, INPUT_KEY_8 }, + [0x0A] = { INPUT_PAGE_KEY, INPUT_KEY_9 }, + [0x0B] = { INPUT_PAGE_KEY, INPUT_KEY_0 }, + [0x0C] = { INPUT_PAGE_KEY, INPUT_KEY_DASH }, + [0x0D] = { INPUT_PAGE_KEY, INPUT_KEY_EQUAL }, + [0x0E] = { INPUT_PAGE_KEY, INPUT_KEY_BACKSPACE }, + [0x0F] = { INPUT_PAGE_KEY, INPUT_KEY_TAB }, + [0x10] = { INPUT_PAGE_KEY, INPUT_KEY_Q }, + [0x11] = { INPUT_PAGE_KEY, INPUT_KEY_W }, + [0x12] = { INPUT_PAGE_KEY, INPUT_KEY_E }, + [0x13] = { INPUT_PAGE_KEY, INPUT_KEY_R }, + [0x14] = { INPUT_PAGE_KEY, INPUT_KEY_T }, + [0x15] = { INPUT_PAGE_KEY, INPUT_KEY_Y }, + [0x16] = { INPUT_PAGE_KEY, INPUT_KEY_U }, + [0x17] = { INPUT_PAGE_KEY, INPUT_KEY_I }, + [0x18] = { INPUT_PAGE_KEY, INPUT_KEY_O }, + [0x19] = { INPUT_PAGE_KEY, INPUT_KEY_P }, + [0x1A] = { INPUT_PAGE_KEY, INPUT_KEY_OPEN_BRACKET }, + [0x1B] = { INPUT_PAGE_KEY, INPUT_KEY_CLOSE_BRACKET }, + [0x1C] = { INPUT_PAGE_KEY, INPUT_KEY_ENTER }, + [0x1D] = { INPUT_PAGE_KEY, INPUT_KEY_LEFT_CTRL }, + [0x1E] = { INPUT_PAGE_KEY, INPUT_KEY_A }, + [0x1F] = { INPUT_PAGE_KEY, INPUT_KEY_S }, + [0x20] = { INPUT_PAGE_KEY, INPUT_KEY_D }, + [0x21] = { INPUT_PAGE_KEY, INPUT_KEY_F }, + [0x22] = { INPUT_PAGE_KEY, INPUT_KEY_G }, + [0x23] = { INPUT_PAGE_KEY, INPUT_KEY_H }, + [0x24] = { INPUT_PAGE_KEY, INPUT_KEY_J }, + [0x25] = { INPUT_PAGE_KEY, INPUT_KEY_K }, + [0x26] = { INPUT_PAGE_KEY, INPUT_KEY_L }, + [0x27] = { INPUT_PAGE_KEY, INPUT_KEY_SEMICOLON }, + [0x28] = { INPUT_PAGE_KEY, INPUT_KEY_APOSTROPH }, + [0x29] = { INPUT_PAGE_KEY, INPUT_KEY_GRAVE_ACCENT }, + [0x2A] = { INPUT_PAGE_KEY, INPUT_KEY_LEFT_SHIFT }, + [0x2B] = { INPUT_PAGE_KEY, INPUT_KEY_BACKSLASH }, + [0x2C] = { INPUT_PAGE_KEY, INPUT_KEY_Z }, + [0x2D] = { INPUT_PAGE_KEY, INPUT_KEY_X }, + [0x2E] = { INPUT_PAGE_KEY, INPUT_KEY_C }, + [0x2F] = { INPUT_PAGE_KEY, INPUT_KEY_V }, + [0x30] = { INPUT_PAGE_KEY, INPUT_KEY_B }, + [0x31] = { INPUT_PAGE_KEY, INPUT_KEY_N }, + [0x32] = { INPUT_PAGE_KEY, INPUT_KEY_M }, + [0x33] = { INPUT_PAGE_KEY, INPUT_KEY_COMMA }, + [0x34] = { INPUT_PAGE_KEY, INPUT_KEY_PERIOD }, + [0x35] = { INPUT_PAGE_KEY, INPUT_KEY_SLASH }, + [0x36] = { INPUT_PAGE_KEY, INPUT_KEY_RIGHT_SHIFT }, + [0x37] = { INPUT_PAGE_KEY, INPUT_KEY_KP_STAR }, + [0x38] = { INPUT_PAGE_KEY, INPUT_KEY_LEFT_ALT }, + [0x39] = { INPUT_PAGE_KEY, INPUT_KEY_SPACEBAR }, + [0x3A] = { INPUT_PAGE_KEY, INPUT_KEY_CAPS_LOCK }, + [0x3B] = { INPUT_PAGE_KEY, INPUT_KEY_F1 }, + [0x3C] = { INPUT_PAGE_KEY, INPUT_KEY_F2 }, + [0x3D] = { INPUT_PAGE_KEY, INPUT_KEY_F3 }, + [0x3E] = { INPUT_PAGE_KEY, INPUT_KEY_F4 }, + [0x3F] = { INPUT_PAGE_KEY, INPUT_KEY_F5 }, + [0x40] = { INPUT_PAGE_KEY, INPUT_KEY_F6 }, + [0x41] = { INPUT_PAGE_KEY, INPUT_KEY_F7 }, + [0x42] = { INPUT_PAGE_KEY, INPUT_KEY_F8 }, + [0x43] = { INPUT_PAGE_KEY, INPUT_KEY_F9 }, + [0x44] = { INPUT_PAGE_KEY, INPUT_KEY_F10 }, + [0x45] = { INPUT_PAGE_KEY, INPUT_KEY_NUM_LOCK }, + [0x46] = { INPUT_PAGE_KEY, INPUT_KEY_SCROLL_LOCK }, + [0x47] = { INPUT_PAGE_KEY, INPUT_KEY_KP_7 }, + [0x48] = { INPUT_PAGE_KEY, INPUT_KEY_KP_8 }, + [0x49] = { INPUT_PAGE_KEY, INPUT_KEY_KP_9 }, + [0x4A] = { INPUT_PAGE_KEY, INPUT_KEY_KP_DASH }, + [0x4B] = { INPUT_PAGE_KEY, INPUT_KEY_KP_4 }, + [0x4C] = { INPUT_PAGE_KEY, INPUT_KEY_KP_5 }, + [0x4D] = { INPUT_PAGE_KEY, INPUT_KEY_KP_6 }, + [0x4E] = { INPUT_PAGE_KEY, INPUT_KEY_KP_PLUS }, + [0x4F] = { INPUT_PAGE_KEY, INPUT_KEY_KP_1 }, + [0x50] = { INPUT_PAGE_KEY, INPUT_KEY_KP_2 }, + [0x51] = { INPUT_PAGE_KEY, INPUT_KEY_KP_3 }, + [0x52] = { INPUT_PAGE_KEY, INPUT_KEY_KP_0 }, + [0x53] = { INPUT_PAGE_KEY, INPUT_KEY_KP_PERIOD }, + [0x54] = { INPUT_PAGE_KEY, INPUT_KEY_SYSREQ }, + [0x56] = { INPUT_PAGE_KEY, INPUT_KEY_EUROPE_2 }, + [0x57] = { INPUT_PAGE_KEY, INPUT_KEY_F11 }, + [0x58] = { INPUT_PAGE_KEY, INPUT_KEY_F12 }, + [0x59] = { INPUT_PAGE_KEY, INPUT_KEY_KP_EQUAL }, + [0x5C] = { INPUT_PAGE_KEY, INPUT_KEY_I10L_6 }, + [0x64] = { INPUT_PAGE_KEY, INPUT_KEY_F13 }, + [0x65] = { INPUT_PAGE_KEY, INPUT_KEY_F14 }, + [0x66] = { INPUT_PAGE_KEY, INPUT_KEY_F15 }, + [0x67] = { INPUT_PAGE_KEY, INPUT_KEY_F16 }, + [0x68] = { INPUT_PAGE_KEY, INPUT_KEY_F17 }, + [0x69] = { INPUT_PAGE_KEY, INPUT_KEY_F18 }, + [0x6A] = { INPUT_PAGE_KEY, INPUT_KEY_F19 }, + [0x6B] = { INPUT_PAGE_KEY, INPUT_KEY_F20 }, + [0x6C] = { INPUT_PAGE_KEY, INPUT_KEY_F21 }, + [0x6D] = { INPUT_PAGE_KEY, INPUT_KEY_F22 }, + [0x6E] = { INPUT_PAGE_KEY, INPUT_KEY_F23 }, + [0x70] = { INPUT_PAGE_KEY, INPUT_KEY_I10L_2 }, + /* The following two keys (0x71, 0x72) are release-only. */ + [0x71] = { INPUT_PAGE_KEY, INPUT_KEY_LANG_2 }, + [0x72] = { INPUT_PAGE_KEY, INPUT_KEY_LANG_1 }, + [0x73] = { INPUT_PAGE_KEY, INPUT_KEY_I10L_1 }, + /* The following key (0x76) can be either F24 or LANG_5. */ + [0x76] = { INPUT_PAGE_KEY, INPUT_KEY_F24 }, + [0x77] = { INPUT_PAGE_KEY, INPUT_KEY_LANG_4 }, + [0x78] = { INPUT_PAGE_KEY, INPUT_KEY_LANG_3 }, + [0x79] = { INPUT_PAGE_KEY, INPUT_KEY_I10L_4 }, + [0x7B] = { INPUT_PAGE_KEY, INPUT_KEY_I10L_5 }, + [0x7D] = { INPUT_PAGE_KEY, INPUT_KEY_I10L_3 }, + [0x7E] = { INPUT_PAGE_KEY, INPUT_KEY_EQUAL_SIGN }, +}; + +const static struct scanmap scanmap_escaped[KBD_SCAN_CODES] = { + [0x10] = { INPUT_PAGE_CONS, INPUT_CONS_SCAN_PREVIOUS_TRACK }, + [0x19] = { INPUT_PAGE_CONS, INPUT_CONS_SCAN_NEXT_TRACK }, + [0x1C] = { INPUT_PAGE_KEY, INPUT_KEY_KP_ENTER }, + [0x1D] = { INPUT_PAGE_KEY, INPUT_KEY_RIGHT_CTRL }, + [0x20] = { INPUT_PAGE_CONS, INPUT_CONS_MUTE }, + [0x21] = { INPUT_PAGE_CONS, INPUT_CONS_AL_CALCULATOR }, + [0x22] = { INPUT_PAGE_CONS, INPUT_CONS_PLAY_PAUSE }, + [0x24] = { INPUT_PAGE_CONS, INPUT_CONS_STOP }, + [0x2E] = { INPUT_PAGE_CONS, INPUT_CONS_VOLUME_DOWN }, + [0x30] = { INPUT_PAGE_CONS, INPUT_CONS_VOLUME_UP }, + [0x32] = { INPUT_PAGE_CONS, INPUT_CONS_AC_HOME }, + [0x35] = { INPUT_PAGE_KEY, INPUT_KEY_KP_SLASH }, + [0x37] = { INPUT_PAGE_KEY, INPUT_KEY_PRINT_SCREEN }, + [0x38] = { INPUT_PAGE_KEY, INPUT_KEY_RIGHT_ALT }, + [0x46] = { INPUT_PAGE_KEY, INPUT_KEY_PAUSE }, + [0x47] = { INPUT_PAGE_KEY, INPUT_KEY_HOME }, + [0x48] = { INPUT_PAGE_KEY, INPUT_KEY_UP_ARROW }, + [0x49] = { INPUT_PAGE_KEY, INPUT_KEY_PAGE_UP }, + [0x4B] = { INPUT_PAGE_KEY, INPUT_KEY_LEFT_ARROW }, + [0x4D] = { INPUT_PAGE_KEY, INPUT_KEY_RIGHT_ARROW }, + [0x4F] = { INPUT_PAGE_KEY, INPUT_KEY_END }, + [0x50] = { INPUT_PAGE_KEY, INPUT_KEY_DOWN_ARROW }, + [0x51] = { INPUT_PAGE_KEY, INPUT_KEY_PAGE_DOWN }, + [0x52] = { INPUT_PAGE_KEY, INPUT_KEY_INSERT }, + [0x53] = { INPUT_PAGE_KEY, INPUT_KEY_DELETE }, + [0x5B] = { INPUT_PAGE_KEY, INPUT_KEY_LEFT_GUI }, + [0x5C] = { INPUT_PAGE_KEY, INPUT_KEY_RIGHT_GUI }, + [0x5D] = { INPUT_PAGE_KEY, INPUT_KEY_APPLICATION }, + /* The following extended key (0x5E) may also be INPUT_KEY_POWER. */ + [0x5E] = { INPUT_PAGE_GD, INPUT_GD_SYSTEM_POWER_DOWN }, + [0x5F] = { INPUT_PAGE_GD, INPUT_GD_SYSTEM_SLEEP }, + [0x63] = { INPUT_PAGE_GD, INPUT_GD_SYSTEM_WAKE_UP }, + [0x65] = { INPUT_PAGE_CONS, INPUT_CONS_AC_SEARCH }, + [0x66] = { INPUT_PAGE_CONS, INPUT_CONS_AC_BOOKMARKS }, + [0x67] = { INPUT_PAGE_CONS, INPUT_CONS_AC_REFRESH }, + [0x68] = { INPUT_PAGE_CONS, INPUT_CONS_AC_STOP }, + [0x69] = { INPUT_PAGE_CONS, INPUT_CONS_AC_FORWARD }, + [0x6A] = { INPUT_PAGE_CONS, INPUT_CONS_AC_BACK }, + [0x6B] = { INPUT_PAGE_CONS, INPUT_CONS_AL_LOCAL_BROWSER }, + [0x6C] = { INPUT_PAGE_CONS, INPUT_CONS_AL_EMAIL_READER }, + [0x6D] = { INPUT_PAGE_CONS, INPUT_CONS_AL_MEDIA_SELECT }, +}; +#define K(k) [INPUT_KEY_ ## k] /* Map to key entry */ + +#define C(c) ((c) & 0x1F) /* Map to control code */ +#define A(c) ((c) | 0x80) /* Set eight bit (ALT) */ +#define CA(c) A(C(c)) /* Control-Alt */ +#define N(c) ((c) | HASNUM) /* Add "Num Lock has effect" attribute */ +#define L(c) ((c) | HASCAPS) /* Add "Caps Lock has effect" attribute */ + +#define EXT 0x0100 /* Normal function keys */ +#define CTRLKEY 0x0200 /* Control key */ +#define SHIFT 0x0400 /* Shift key */ +#define ALT 0x0800 /* Alternate key */ +#define HASNUM 0x4000 /* Num Lock has effect */ +#define HASCAPS 0x8000 /* Caps Lock has effect */ + +/* The left and right versions for the actual keys in the keymap. */ +#define LCTRL CTRLKEY +#define RCTRL (CTRLKEY | EXT) +#define LSHIFT SHIFT +#define RSHIFT (SHIFT | EXT) +#define LALT ALT +#define RALT (ALT | EXT) + +/* Delete key */ +#define DEL 0177 + +/* Numeric keypad */ +#define HOME (0x01 + EXT) +#define END (0x02 + EXT) +#define UP (0x03 + EXT) +#define DOWN (0x04 + EXT) +#define LEFT (0x05 + EXT) +#define RIGHT (0x06 + EXT) +#define PGUP (0x07 + EXT) +#define PGDN (0x08 + EXT) +#define MID (0x09 + EXT) +/* UNUSED (0x0A + EXT) */ +/* UNUSED (0x0B + EXT) */ +#define INSRT (0x0C + EXT) + +/* Keys affected by Num Lock */ +#define NHOME N(HOME) +#define NEND N(END) +#define NUP N(UP) +#define NDOWN N(DOWN) +#define NLEFT N(LEFT) +#define NRIGHT N(RIGHT) +#define NPGUP N(PGUP) +#define NPGDN N(PGDN) +#define NMID N(MID) +#define NINSRT N(INSRT) +#define NDEL N(DEL) + +/* Alt + Numeric keypad */ +#define AHOME (0x01 + ALT) +#define AEND (0x02 + ALT) +#define AUP (0x03 + ALT) +#define ADOWN (0x04 + ALT) +#define ALEFT (0x05 + ALT) +#define ARIGHT (0x06 + ALT) +#define APGUP (0x07 + ALT) +#define APGDN (0x08 + ALT) +#define AMID (0x09 + ALT) +#define AMIN (0x0A + ALT) +#define APLUS (0x0B + ALT) +#define AINSRT (0x0C + ALT) + +/* Ctrl + Numeric keypad */ +#define CHOME (0x01 + CTRLKEY) +#define CEND (0x02 + CTRLKEY) +#define CUP (0x03 + CTRLKEY) +#define CDOWN (0x04 + CTRLKEY) +#define CLEFT (0x05 + CTRLKEY) +#define CRIGHT (0x06 + CTRLKEY) +#define CPGUP (0x07 + CTRLKEY) +#define CPGDN (0x08 + CTRLKEY) +#define CMID (0x09 + CTRLKEY) +#define CNMIN (0x0A + CTRLKEY) +#define CPLUS (0x0B + CTRLKEY) +#define CINSRT (0x0C + CTRLKEY) + +/* Lock keys */ +#define CALOCK (0x0D + EXT) /* caps lock */ +#define NLOCK (0x0E + EXT) /* number lock */ +#define SLOCK (0x0F + EXT) /* scroll lock */ + +/* Function keys */ +#define F1 (0x10 + EXT) +#define F2 (0x11 + EXT) +#define F3 (0x12 + EXT) +#define F4 (0x13 + EXT) +#define F5 (0x14 + EXT) +#define F6 (0x15 + EXT) +#define F7 (0x16 + EXT) +#define F8 (0x17 + EXT) +#define F9 (0x18 + EXT) +#define F10 (0x19 + EXT) +#define F11 (0x1A + EXT) +#define F12 (0x1B + EXT) + +/* Alt+Fn */ +#define AF1 (0x10 + ALT) +#define AF2 (0x11 + ALT) +#define AF3 (0x12 + ALT) +#define AF4 (0x13 + ALT) +#define AF5 (0x14 + ALT) +#define AF6 (0x15 + ALT) +#define AF7 (0x16 + ALT) +#define AF8 (0x17 + ALT) +#define AF9 (0x18 + ALT) +#define AF10 (0x19 + ALT) +#define AF11 (0x1A + ALT) +#define AF12 (0x1B + ALT) + +/* Ctrl+Fn */ +#define CF1 (0x10 + CTRLKEY) +#define CF2 (0x11 + CTRLKEY) +#define CF3 (0x12 + CTRLKEY) +#define CF4 (0x13 + CTRLKEY) +#define CF5 (0x14 + CTRLKEY) +#define CF6 (0x15 + CTRLKEY) +#define CF7 (0x16 + CTRLKEY) +#define CF8 (0x17 + CTRLKEY) +#define CF9 (0x18 + CTRLKEY) +#define CF10 (0x19 + CTRLKEY) +#define CF11 (0x1A + CTRLKEY) +#define CF12 (0x1B + CTRLKEY) + +/* Shift+Fn */ +#define SF1 (0x10 + SHIFT) +#define SF2 (0x11 + SHIFT) +#define SF3 (0x12 + SHIFT) +#define SF4 (0x13 + SHIFT) +#define SF5 (0x14 + SHIFT) +#define SF6 (0x15 + SHIFT) +#define SF7 (0x16 + SHIFT) +#define SF8 (0x17 + SHIFT) +#define SF9 (0x18 + SHIFT) +#define SF10 (0x19 + SHIFT) +#define SF11 (0x1A + SHIFT) +#define SF12 (0x1B + SHIFT) + +/* Alt+Shift+Fn */ +#define ASF1 (0x10 + ALT + SHIFT) +#define ASF2 (0x11 + ALT + SHIFT) +#define ASF3 (0x12 + ALT + SHIFT) +#define ASF4 (0x13 + ALT + SHIFT) +#define ASF5 (0x14 + ALT + SHIFT) +#define ASF6 (0x15 + ALT + SHIFT) +#define ASF7 (0x16 + ALT + SHIFT) +#define ASF8 (0x17 + ALT + SHIFT) +#define ASF9 (0x18 + ALT + SHIFT) +#define ASF10 (0x19 + ALT + SHIFT) +#define ASF11 (0x1A + ALT + SHIFT) +#define ASF12 (0x1B + ALT + SHIFT) + +#define MAP_COLS 6 /* Number of columns in keymap */ +#define NR_SCAN_CODES 0xE8 /* Number of scan codes (rows in keymap) */ + +static u16 minix_keymap[NR_SCAN_CODES][MAP_COLS] = { +/* scan-code !Shift Shift Alt1 Alt2 Alt+Sh Ctrl */ +/* ==================================================================== */ + K(A) = { L('a'), 'A', A('a'), A('a'), A('A'), C('A') }, + K(B) = { L('b'), 'B', A('b'), A('b'), A('B'), C('B') }, + K(C) = { L('c'), 'C', A('c'), A('c'), A('C'), C('C') }, + K(D) = { L('d'), 'D', A('d'), A('d'), A('D'), C('D') }, + K(E) = { L('e'), 'E', A('e'), A('e'), A('E'), C('E') }, + K(F) = { L('f'), 'F', A('f'), A('f'), A('F'), C('F') }, + K(G) = { L('g'), 'G', A('g'), A('g'), A('G'), C('G') }, + K(H) = { L('h'), 'H', A('h'), A('h'), A('H'), C('H') }, + K(I) = { L('i'), 'I', A('i'), A('i'), A('I'), C('I') }, + K(J) = { L('j'), 'J', A('j'), A('j'), A('J'), C('J') }, + K(K) = { L('k'), 'K', A('k'), A('k'), A('K'), C('K') }, + K(L) = { L('l'), 'L', A('l'), A('l'), A('L'), C('L') }, + K(M) = { L('m'), 'M', A('m'), A('m'), A('M'), C('M') }, + K(N) = { L('n'), 'N', A('n'), A('n'), A('N'), C('N') }, + K(O) = { L('o'), 'O', A('o'), A('o'), A('O'), C('O') }, + K(P) = { L('p'), 'P', A('p'), A('p'), A('P'), C('P') }, + K(Q) = { L('q'), 'Q', A('q'), A('q'), A('Q'), C('Q') }, + K(R) = { L('r'), 'R', A('r'), A('r'), A('R'), C('R') }, + K(S) = { L('s'), 'S', A('s'), A('s'), A('S'), C('S') }, + K(T) = { L('t'), 'T', A('t'), A('t'), A('T'), C('T') }, + K(U) = { L('u'), 'U', A('u'), A('u'), A('U'), C('U') }, + K(V) = { L('v'), 'V', A('v'), A('v'), A('V'), C('V') }, + K(W) = { L('w'), 'W', A('w'), A('w'), A('W'), C('W') }, + K(X) = { L('x'), 'X', A('x'), A('x'), A('X'), C('X') }, + K(Y) = { L('y'), 'Y', A('y'), A('y'), A('Y'), C('Y') }, + K(Z) = { L('z'), 'Z', A('z'), A('z'), A('Z'), C('Z') }, + K(1) = { '1', '!', A('1'), A('1'), A('!'), C('A') }, + K(2) = { '2', '@', A('2'), A('2'), A('@'), C('@') }, + K(3) = { '3', '#', A('3'), A('3'), A('#'), C('C') }, + K(4) = { '4', '$', A('4'), A('4'), A('$'), C('D') }, + K(5) = { '5', '%', A('5'), A('5'), A('%'), C('E') }, + K(6) = { '6', '^', A('6'), A('6'), A('^'), C('^') }, + K(7) = { '7', '&', A('7'), A('7'), A('&'), C('G') }, + K(8) = { '8', '*', A('8'), A('8'), A('*'), C('H') }, + K(9) = { '9', '(', A('9'), A('9'), A('('), C('I') }, + K(0) = { '0', ')', A('0'), A('0'), A(')'), C('@') }, + K(ENTER) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') }, + K(ESCAPE) = { C('['), C('['), CA('['),CA('['),CA('['),C('[') }, + K(BACKSPACE) = { C('H'), C('H'), CA('H'),CA('H'),CA('H'),DEL }, + K(TAB) = { C('I'), C('I'), CA('I'),CA('I'),CA('I'),C('I') }, + K(SPACEBAR) = { ' ', ' ', A(' '), A(' '), A(' '), C('@') }, + K(DASH) = { '-', '_', A('-'), A('-'), A('_'), C('_') }, + K(EQUAL) = { '=', '+', A('='), A('='), A('+'), C('@') }, + K(OPEN_BRACKET) = { '[', '{', A('['), A('['), A('{'), C('[') }, + K(CLOSE_BRACKET) = { ']', '}', A(']'), A(']'), A('}'), C(']') }, + K(BACKSLASH) = { '\\', '|', A('\\'),A('\\'),A('|'), C('\\') }, + K(SEMICOLON) = { ';', ':', A(';'), A(';'), A(':'), C('@') }, + K(APOSTROPH) = { '\'', '"', A('\''),A('\''),A('"'), C('@') }, + K(GRAVE_ACCENT) = { '`', '~', A('`'), A('`'), A('~'), C('@') }, + K(COMMA) = { ',', '<', A(','), A(','), A('<'), C('@') }, + K(PERIOD) = { '.', '>', A('.'), A('.'), A('>'), C('@') }, + K(SLASH) = { '/', '?', A('/'), A('/'), A('?'), C('@') }, + K(CAPS_LOCK) = { CALOCK, CALOCK, CALOCK, CALOCK, CALOCK, CALOCK }, + K(F1) = { F1, SF1, AF1, AF1, ASF1, CF1 }, + K(F2) = { F2, SF2, AF2, AF2, ASF2, CF2 }, + K(F3) = { F3, SF3, AF3, AF3, ASF3, CF3 }, + K(F4) = { F4, SF4, AF4, AF4, ASF4, CF4 }, + K(F5) = { F5, SF5, AF5, AF5, ASF5, CF5 }, + K(F6) = { F6, SF6, AF6, AF6, ASF6, CF6 }, + K(F7) = { F7, SF7, AF7, AF7, ASF7, CF7 }, + K(F8) = { F8, SF8, AF8, AF8, ASF8, CF8 }, + K(F9) = { F9, SF9, AF9, AF9, ASF9, CF9 }, + K(F10) = { F10, SF10, AF10, AF10, ASF10, CF10 }, + K(F11) = { F11, SF11, AF11, AF11, ASF11, CF11 }, + K(F12) = { F12, SF12, AF12, AF12, ASF12, CF12 }, + K(SCROLL_LOCK) = { SLOCK, SLOCK, SLOCK, SLOCK, SLOCK, SLOCK }, + K(INSERT) = { INSRT, INSRT, AINSRT, AINSRT, AINSRT, CINSRT }, + K(HOME) = { HOME, HOME, AHOME, AHOME, AHOME, CHOME }, + K(PAGE_UP) = { PGUP, PGUP, APGUP, APGUP, APGUP, CPGUP }, + K(DELETE) = { DEL, DEL, A(DEL), A(DEL), A(DEL), DEL }, + K(END) = { END, END, AEND, AEND, AEND, CEND }, + K(PAGE_DOWN) = { PGDN, PGDN, APGDN, APGDN, APGDN, CPGDN }, + K(RIGHT_ARROW) = { RIGHT, RIGHT, ARIGHT, ARIGHT, ARIGHT, CRIGHT }, + K(LEFT_ARROW) = { LEFT, LEFT, ALEFT, ALEFT, ALEFT, CLEFT }, + K(DOWN_ARROW) = { DOWN, DOWN, ADOWN, ADOWN, ADOWN, CDOWN }, + K(UP_ARROW) = { UP, UP, AUP, AUP, AUP, CUP }, + K(NUM_LOCK) = { NLOCK, NLOCK, NLOCK, NLOCK, NLOCK, NLOCK }, + K(KP_SLASH) = { '/', '/', A('/'), A('/'), A('/'), C('@') }, + K(KP_STAR) = { '*', '*', A('*'), A('*'), A('*'), C('@') }, + K(KP_DASH) = { '-', '-', AMIN, AMIN, A('-'), CNMIN }, + K(KP_PLUS) = { '+', '+', APLUS, APLUS, A('+'), CPLUS }, + K(KP_ENTER) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') }, + K(KP_1) = { NEND, '1', AEND, AEND, A('1'), CEND }, + K(KP_2) = { NDOWN, '2', ADOWN, ADOWN, A('2'), CDOWN }, + K(KP_3) = { NPGDN, '3', APGDN, APGDN, A('3'), CPGDN }, + K(KP_4) = { NLEFT, '4', ALEFT, ALEFT, A('4'), CLEFT }, + K(KP_5) = { NMID, '5', AMID, AMID, A('5'), CMID }, + K(KP_6) = { NRIGHT, '6', ARIGHT, ARIGHT, A('6'), CRIGHT }, + K(KP_7) = { NHOME, '7', AHOME, AHOME, A('7'), CHOME }, + K(KP_8) = { NUP, '8', AUP, AUP, A('8'), CUP }, + K(KP_9) = { NPGUP, '9', APGUP, APGUP, A('9'), CPGUP }, + K(KP_0) = { NINSRT, '0', AINSRT, AINSRT, A('0'), CINSRT }, + K(KP_PERIOD) = { NDEL, '.', A(DEL), A(DEL), A('.'), DEL }, + K(EUROPE_2) = { '<', '>', A('<'), A('|'), A('>'), C('@') }, + K(APPLICATION) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') }, + K(SYSREQ) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') }, + K(LEFT_CTRL) = { LCTRL, LCTRL, LCTRL, LCTRL, LCTRL, LCTRL }, + K(LEFT_SHIFT) = { LSHIFT, LSHIFT, LSHIFT, LSHIFT, LSHIFT, LSHIFT }, + K(LEFT_ALT) = { LALT, LALT, LALT, LALT, LALT, LALT }, + K(LEFT_GUI) = { LEFT, '<', ALEFT, ALEFT, A('<'), CLEFT }, + K(RIGHT_CTRL) = { RCTRL, RCTRL, RCTRL, RCTRL, RCTRL, RCTRL }, + K(RIGHT_SHIFT) = { RSHIFT, RSHIFT, RSHIFT, RSHIFT, RSHIFT, RSHIFT }, + K(RIGHT_ALT) = { RALT, RALT, RALT, RALT, RALT, RALT }, + K(RIGHT_GUI) = { RIGHT, '>', ARIGHT, ARIGHT, A('>'), CRIGHT } +}; +#endif \ No newline at end of file diff --git a/include/tty.h b/include/tty.h index 8b532eb..9d69934 100644 --- a/include/tty.h +++ b/include/tty.h @@ -77,8 +77,10 @@ typedef struct vga_buf { typedef struct keyboard_buf { void* buf; // 1d array, buffer input virtual line, works as a ldisc - int max_buf; int tail; + int head; + int len; + int readable; } keyboard_buf; #include "console.h" @@ -95,5 +97,15 @@ void write_serial(char a); void vga_tty_init(NTTY* tty); void vga_tty_write(NTTY* tty, char ch); void vga_tty_flush(NTTY* tty); +void vga_tty_backspace(NTTY* tty); +void ps2_tty_init(NTTY* tty); +int ps2_tty_read(NTTY* tty, u8* buf, int nr); + +#define CYCLE_SUB(head, tail, _max) ((head) < (tail) ? (tail)-(head) : (tail) + (_max) - (head)) +#define NEXT(x, _max) (((x) + 1) % (_max)) +#define LAST(x, _max) (((x) - 1) >= 0 ? ((x) - 1) % (_max) : (_max) - 1) +#define DEBUGNEW +extern int cur_ntty; +extern NTTY ntty_table[3]; #endif /* _ORANGES_TTY_H_ */ \ No newline at end of file diff --git a/kernel/keyboard.c b/kernel/keyboard.c index e4a5330..bf5af5e 100644 --- a/kernel/keyboard.c +++ b/kernel/keyboard.c @@ -8,10 +8,11 @@ #include "global.h" #include "proto.h" #include "keyboard.h" -#include "keymap.h" +// #include "keymap.h" #include "x86.h" #include "stdio.h" #include "assert.h" +#include "minix_keymap.h" static KB_INPUT kb_in; @@ -30,10 +31,13 @@ static int num_lock; /* Num Lock */ static int scroll_lock; /* Scroll Lock */ static int column; -static u8 get_byte_from_kb_buf(); +static u8 get_byte_from_kb_buf(); static void set_leds(); static void set_mouse_leds(); static void kb_wait(); +static void ps2_push(NTTY* tty, u16 key); +static void kbd_process(unsigned char scode); + // static void kb_ack(); /* * Helper Procedures for PS/2 Mouse Operation @@ -83,6 +87,9 @@ static u8 mouse_get_id() { void kb_handler(int irq){ u8 scan_code = inb(PS2_PORT_DATA); +#ifdef DEBUGNEW + kbd_process(scan_code); +#else if(kb_in.count < KB_IN_BYTES){ *(kb_in.p_head) = scan_code; kb_in.p_head++; @@ -91,7 +98,7 @@ void kb_handler(int irq){ } kb_in.count++; } - +#endif }; #define TTY_FIRST (tty_table) @@ -190,7 +197,7 @@ void init_kb(){ set_mouse_leds(); } - +#ifndef DEBUGNEW void keyboard_read(TTY* p_tty) { u8 scan_code; @@ -407,12 +414,108 @@ void keyboard_read(TTY* p_tty) key |= alt_l ? FLAG_ALT_L : 0; key |= alt_r ? FLAG_ALT_R : 0; key |= pad ? FLAG_PAD : 0; - in_process(p_tty,key); } } } +#endif +static u16 map_key(int code) { + int caps, column; + int shift = shift_l | shift_r; + int alt = alt_l | alt_r; + int ctrl = ctrl_l | ctrl_r; + u16 *keyrow = minix_keymap[code]; + caps = shift_l | shift_r; + if (num_lock&& (keyrow[0] & HASNUM)) caps = !caps; + if (caps_lock && (keyrow[0] & HASCAPS)) caps = !caps; + + if (alt) { + column = 2; + if (ctrl || alt_r) column = 3; /* Ctrl + Alt == AltGr */ + if (caps) column = 4; + } else { + // if (sticky_alt_mode && (lk & ALT_LOCK)) { + // column = 2; + // if (caps) column = 4; + // } else { + column = 0; + if (caps) column = 1; + if (ctrl) column = 5; + // } + } + return keyrow[column] & ~(HASNUM | HASCAPS); +} + +static void kbd_process(unsigned char scode) +{ + int press, index, page, code; + static int kbd_state = 0; + + press = !(scode & SCAN_RELEASE) ? INPUT_PRESS : INPUT_RELEASE; + index = scode & ~SCAN_RELEASE; + + switch (kbd_state) { + case 1: + page = scanmap_escaped[index].page; + code = scanmap_escaped[index].code; + break; + case 2: + kbd_state = (index == SCAN_CTRL) ? 3 : 0; + return; + case 3: + if (index == SCAN_NUMLOCK) { + page = INPUT_PAGE_KEY; + code = INPUT_KEY_PAUSE; + break; + } + /* FALLTHROUGH */ + default: + switch (scode) { + case SCAN_EXT0: + kbd_state = 1; + return; + case SCAN_EXT1: + kbd_state = 2; + return; + } + page = scanmap_normal[index].page; + code = scanmap_normal[index].code; + break; + } + + if (page) { + switch (code) + { + case INPUT_KEY_LEFT_SHIFT: + shift_l = press; break; + case INPUT_KEY_RIGHT_SHIFT: + shift_r = press; break; + case INPUT_KEY_LEFT_CTRL: + ctrl_l = press; break; + case INPUT_KEY_RIGHT_CTRL: + ctrl_r = press; break; + case INPUT_KEY_LEFT_ALT: + alt_l = press; break; + case INPUT_KEY_RIGHT_ALT: + alt_r = press; break; + case INPUT_KEY_NUM_LOCK: + if (press) num_lock = !num_lock; + break; + case INPUT_KEY_CAPS_LOCK: + if (press) caps_lock = !caps_lock; + break; + case INPUT_KEY_SCROLL_LOCK: + if (press) scroll_lock = !scroll_lock; + break; + } + + // inputdriver_send_event(FALSE /*mouse*/, page, code, press, 0); + if (press) ps2_push(&ntty_table[cur_ntty], map_key(code)); + } + + kbd_state = 0; +} /***************************************************************************** @@ -460,23 +563,6 @@ static void kb_wait() /* 等待 8042 的输入缓冲区空 */ } -/***************************************************************************** - * kb_ack - *****************************************************************************/ -/** - * Read from the keyboard controller until a KB_ACK is received. - * - *****************************************************************************/ -// static void kb_ack() -// { -// u8 kb_read; - -// do { -// kb_read = inb(KB_DATA); -// } while (kb_read != KB_ACK); -// } - - /***************************************************************************** * set_leds *****************************************************************************/ @@ -505,3 +591,81 @@ static void set_mouse_leds(){ outb(KB_DATA, KBC_MODE); } + +#define LASTKEY(x) LAST(x, TTY_IN_BYTES) +#define NEXTKEY(x) NEXT(x, TTY_IN_BYTES) + +static u8 keybuf[3][TTY_IN_BYTES]; +void ps2_tty_init(NTTY* tty) { + static int _cnt = 0; + assert(tty->driver_type == 1); + assert(tty->input_buf); + keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; + kbd->buf = (void*)keybuf[_cnt ++]; + kbd->head = kbd->tail = kbd->readable = 0; + kbd->len = 0; +} + +int ps2_tty_read(NTTY* tty, u8* buf, int nr) { + keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; + int i = 0; + while (kbd->readable == 0); + for (; i < nr && i < kbd->readable; ++ i) { + buf[i] = ((int*)kbd->buf)[kbd->head]; + kbd->head = NEXTKEY(kbd->head); + } + kbd->readable -= i; + kbd->len -= i; + return i; +} + +void ps2_tty_flush(NTTY* tty) { + +} + +static void ps2_push(NTTY* tty, u16 key) { + // kprintf("%x\n", key); + keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; + if (key & EXT) { + switch (key) + { + case F1: case F2: case F3: case F4: case F5: case F6: + case F7: case F8: case F9: case F10: case F11: case F12: + // select_console((key & 0xff) - (F1 & 0xff)); // TODO + kprintf("select console %d\n", (key & 0xff) - (F1 & 0xff)); + break; + default: + break; + } + } + else { + switch (key) + { + case '\r': case '\n': // escape ENTER + vga_tty_write(tty, '\n'); + ((int*)kbd->buf)[kbd->tail] = '\n'; + kbd->len ++; + kbd->tail = NEXTKEY(kbd->tail); + kbd->readable = CYCLE_SUB(kbd->head, kbd->tail, TTY_IN_BYTES); + break; + case '\b': + if (kbd->len > kbd->readable) { + vga_tty_backspace(tty); + kbd->len --; + kbd->tail = LASTKEY(kbd->tail); + } + break; + + default: + if ((key & 0xff) == 0) return; + if (kbd->len == TTY_IN_BYTES - 1) return; // leave one space for ctrl ascii + vga_tty_write(tty, key); + ((int*)kbd->buf)[kbd->tail] = key & 0xff; + kbd->len ++; + kbd->tail = NEXTKEY(kbd->tail); + break; + } + } +} + +//TODO: 1. 修改键盘驱动 2. 添加测试代码 3. 添加鼠标并调试滚动 \ No newline at end of file diff --git a/kernel/ktest.c b/kernel/ktest.c index 97a70ef..37c9ad6 100644 --- a/kernel/ktest.c +++ b/kernel/ktest.c @@ -127,7 +127,7 @@ void initial() do_vclose(stdout); do_vclose(stderr); - exec("orange/test.bin"); + exec("orange/shell_0.bin"); while(1); } \ No newline at end of file diff --git a/kernel/tty.c b/kernel/tty.c index cf5cf43..177c36e 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -12,7 +12,6 @@ #include "memman.h" #include "stdio.h" -#define DEBUGNEW int current_console; //当前显示在屏幕上的console void tty_write(TTY *tty, char *buf, int len); @@ -26,8 +25,8 @@ static void put_key(TTY *tty, u32 key); #ifdef DEBUGNEW -static NTTY ntty_table[3]; -static int cur_ntty = 0; +NTTY ntty_table[3]; +int cur_ntty = 0; static keyboard_buf keyboardbuf[3]; static vga_buf vgabuf[3]; @@ -41,10 +40,13 @@ void init_tty_main() { tty->input_buf = &keyboardbuf[i]; tty->output_buf = &vgabuf[i]; vga_tty_init(tty); + ps2_tty_init(tty); } } #endif + +#ifndef DEBUGNEW void in_process(TTY *p_tty, u32 key) { int real_line = p_tty->console->orig / SCR_WIDTH; @@ -106,6 +108,7 @@ void in_process(TTY *p_tty, u32 key) } } } +#endif #define TTY_FIRST (tty_table) #define TTY_END (tty_table + NR_CONSOLES) @@ -119,7 +122,7 @@ void task_tty() // } while(1) { - // vga_tty_flush(&ntty_table[cur_ntty]); + vga_tty_flush(&ntty_table[cur_ntty]); } #else @@ -223,7 +226,7 @@ static void tty_mouse(TTY *tty) } } } - +#ifndef DEBUGNEW static void tty_dev_read(TTY *tty) { if (is_current_console(tty->console)) @@ -273,7 +276,7 @@ static void tty_dev_write(TTY *tty) out_char(tty->console, ch); } } - +#endif static void put_key(TTY *tty, u32 key) { if (tty->ibuf_cnt < TTY_IN_BYTES) @@ -299,7 +302,7 @@ void tty_write(TTY *tty, char *buf, int len) while (--len >= 0) { vga_tty_write(&ntty_table[cur_ntty], *buf++); } - vga_tty_flush(&ntty_table[cur_ntty]); + // vga_tty_flush(&ntty_table[cur_ntty]); #else while (--len >= 0) out_char(tty->console, *buf++); @@ -314,6 +317,9 @@ void tty_write(TTY *tty, char *buf, int len) *****************************************************************************/ int tty_read(TTY *tty, char *buf, int len) { +#ifdef DEBUGNEW + return ps2_tty_read(&ntty_table[cur_ntty], (u8*)buf, len); +#else int i = 0; if (!tty->ibuf_read_cnt) { @@ -336,4 +342,5 @@ int tty_read(TTY *tty, char *buf, int len) } return i; +#endif } \ No newline at end of file diff --git a/kernel/vga.c b/kernel/vga.c index 86376cf..304f43b 100644 --- a/kernel/vga.c +++ b/kernel/vga.c @@ -118,11 +118,12 @@ static inline void vga_flush_blankline(int line_no) { static u16 pagebuf[3][SCR_BUFSIZE]; void vga_tty_init(NTTY* tty) { + static int _cnt = 0; assert(tty->driver_type == 1); assert(tty->output_buf); vga_buf* vga = tty->output_buf; // vga->buf = (void*)do_kmalloc(sizeof(u16) * SCR_BUFSIZE); - vga->buf = (void*)pagebuf[0]; + vga->buf = (void*)pagebuf[_cnt ++]; // kprintf("malloced %p %p %p\n", vga->buf, &vga->buf, &vga->scr_top_line); vga->cur_col = vga->cur_row = 0; // buf->max_line = SCR_BUFSIZE / SCR_WIDTH; @@ -137,22 +138,22 @@ void vga_tty_init(NTTY* tty) { } #define INDEX(row, col) ((row) * SCR_WIDTH + (col)) -#define NEXTLINE(row) (((row) + 1) % SCR_MAXLINE) -#define LASTLINE(row) (((row) - 1) >= 0 ? ((row) - 1) % SCR_MAXLINE : SCR_MAXLINE) +#define NEXTLINE(row) NEXT(row, SCR_MAXLINE) +#define LASTLINE(row) LAST(row, SCR_MAXLINE) -static void newline(vga_buf* vgabuf) { - vgabuf->cur_col = 0; +static void newline(vga_buf* vga) { + vga->cur_col = 0; // kprintf("bf %x\n", vgabuf->scr_cur_line); - vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line); + vga->scr_cur_line = NEXTLINE(vga->scr_cur_line); // kprintf("af %x\n", vgabuf->scr_cur_line); - vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line); - if (vgabuf->cur_row == SCR_HEIGHT) { + vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); + if (vga->cur_row == SCR_HEIGHT) { // auto scroll - vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); - if(vgabuf->scr_cur_line == vgabuf->head_line) { - vgabuf->head_line = NEXTLINE(vgabuf->head_line); + vga->scr_top_line = NEXTLINE(vga->scr_top_line); + if(vga->scr_cur_line == vga->head_line) { + vga->head_line = NEXTLINE(vga->head_line); // remember to fill blank the old line - u32* ptr_buf = (u32*) (vgabuf->buf + sizeof(u16) * vgabuf->head_line * SCR_WIDTH); + u32* ptr_buf = (u32*) (vga->buf + sizeof(u16) * vga->head_line * SCR_WIDTH); for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) { *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space } @@ -189,10 +190,23 @@ void vga_tty_write(NTTY* tty, char ch) { } break; } - vga->cur_row = abs(vga->scr_cur_line - vga->scr_top_line); + vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); // kprintf("row: %d; ", vga->cur_row); } +void vga_tty_backspace(NTTY* tty) { + vga_buf* vga = tty->output_buf; + u16* buf = vga->buf; + if (vga->cur_col == 0) { + vga->cur_col = SCR_WIDTH - 1; + vga->scr_cur_line = LASTLINE(vga->scr_cur_line); + } else { + vga->cur_col --; + } + buf[INDEX(vga->scr_cur_line, vga->cur_col)] = BLANK; + vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); +} + void vga_tty_flush(NTTY* tty) { vga_buf* vga = tty->output_buf; u16* buf = vga->buf;