52bb2609ae
Added basic shell and fixed various bugs...now iceos should be "complete".
118 lines
3.7 KiB
C
118 lines
3.7 KiB
C
/* The keyboard driver works with a device called PS/2: to talk with this
|
|
* controller we can use serial communication(e.g. ports.h). The actual flow of
|
|
* data is made with "commands", each command is one byte and the keyboard's
|
|
* controller can send two type of response:
|
|
* ACK(Acknowledge): to acknowledge the previous command
|
|
* Resend: to resend the previous command due to an error.
|
|
* We have also to wait between the command, the data and the response of
|
|
* the PS/2 controller.
|
|
* This device should not exists anymore in any modern computer
|
|
* motherboard; however the CPU(or the motherboard?) should be able to
|
|
* simulate it even if we're using some USB keyboard.
|
|
* Apart of that the keyboard will be listen on IRQ1(33),
|
|
* so we have to register an ISR for that.
|
|
*/
|
|
|
|
#include "keyboard.h"
|
|
#include "isr.h"
|
|
#include "ports.h"
|
|
#include "tty.h"
|
|
#include "../shell/shell.h"
|
|
#include "../libc/stdio.h"
|
|
|
|
static void keyboard_callback();
|
|
|
|
/* Keyboard scan codes map , layout is: standard US keyboard */
|
|
uint8_t keyboard_scan_codes[] = {
|
|
0, (uint8_t)27, (uint8_t)'1', (uint8_t)'2', (uint8_t)'3', (uint8_t)'4', (uint8_t)'5', (uint8_t)'6', (uint8_t)'7', (uint8_t)'8',
|
|
(uint8_t)'0', (uint8_t)'0', (uint8_t)'-', (uint8_t)'=', (uint8_t)'\b',
|
|
(uint8_t)'\t',
|
|
(uint8_t)'q', (uint8_t)'w', (uint8_t)'e', (uint8_t)'r',
|
|
(uint8_t)'t', (uint8_t)'y', (uint8_t)'u', (uint8_t)'i', (uint8_t)'o', (uint8_t)'p', (uint8_t)'[', (uint8_t)']', (uint8_t)'\n',
|
|
0,
|
|
(uint8_t)'a', (uint8_t)'s', (uint8_t)'d', (uint8_t)'f', (uint8_t)'g', (uint8_t)'h', (uint8_t)'j', (uint8_t)'k', (uint8_t)'l', (uint8_t)';',
|
|
(uint8_t)'\'', (uint8_t)'`', 0,
|
|
(uint8_t)'\\', (uint8_t)'z', (uint8_t)'x', (uint8_t)'c', (uint8_t)'v', (uint8_t)'b', (uint8_t)'n',
|
|
(uint8_t)'m', (uint8_t)',', (uint8_t)'.', (uint8_t)'/', 0,
|
|
(uint8_t)'*',
|
|
|
|
0, // Alt
|
|
(uint8_t)' ', // Spacebar
|
|
0, // Caps lock
|
|
0, // 59 - F1 key
|
|
0, // 59 - F1 key
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, // F10
|
|
0, // 69 - Num lock
|
|
0, // Scroll lock
|
|
0, // Home key
|
|
0, // Up arrow
|
|
0, // Page up
|
|
(uint8_t)'-',
|
|
0, // Left arrow
|
|
0,
|
|
0, // Right arrow
|
|
(uint8_t)'+',
|
|
0, // 79 End key
|
|
0, // Down arrow
|
|
0, // Page down
|
|
0, // Insert key
|
|
0, // Delete key
|
|
0, 0, 0,
|
|
0, // F11 key
|
|
0, // F12 key
|
|
0 // Others key are undefined
|
|
};
|
|
|
|
uint8_t command[512]; // Max length of a single command
|
|
uint8_t temp[512];
|
|
uint32_t cmd_index = 0;
|
|
uint32_t shiftdown = 0;
|
|
|
|
void clear() {
|
|
for(uint16_t i = 0; i < 512; i++)
|
|
command[i] = 0;
|
|
}
|
|
|
|
void clear_tmp(void) {
|
|
for(uint16_t i = 0; i < 512; i++)
|
|
command[i] = 0;
|
|
}
|
|
|
|
static void keyboard_callback() {
|
|
uint8_t scan_code = inb(KB_DATA_PORT); // Read from keyboard
|
|
uint8_t keycode = keyboard_scan_codes[scan_code]; // Get ASCII value
|
|
|
|
if(scan_code & 0x80) {
|
|
if(scan_code == 0xAA || scan_code == 0x86)
|
|
shiftdown = 0;
|
|
} else {
|
|
// Handle backspace
|
|
if(keycode == 0x08) {
|
|
if(cmd_index <= 0) // If at start of the prompt
|
|
return; // Do not delete it.
|
|
cmd_index--; // Otherwise go back
|
|
|
|
for(uint32_t i = 0; i < cmd_index; ++i)
|
|
temp[i] = command[i];
|
|
clear();
|
|
for(uint32_t i = 0; i < cmd_index; ++i)
|
|
command[i] = temp[i];
|
|
clear_tmp();
|
|
backspace();
|
|
} else if(keycode == 0x0A) { // Handle Enter
|
|
processCommand(command);
|
|
cmd_index = 0;
|
|
clear();
|
|
init_prompt();
|
|
} else {
|
|
printf("%c", keycode);
|
|
command[cmd_index] = keycode;
|
|
cmd_index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void init_keyboard() {
|
|
register_interrupt_handler(IRQ1, &keyboard_callback);
|
|
} |