443 lines
12 KiB
C
443 lines
12 KiB
C
#include <kernel/ps2.h>
|
|
#include <kernel/io.h>
|
|
#include <kernel/pic8259.h>
|
|
#include <kernel/vga.h>
|
|
#include <kernel/printf.h>
|
|
#include <kernel/strcmp.h>
|
|
#include <kernel/ide.h>
|
|
#include <kernel/mem.h>
|
|
|
|
#define cpu_relax asm volatile ("pause" ::);
|
|
|
|
char shell_buffer[512];
|
|
int shell_index;
|
|
|
|
// TODO: Support dual ports
|
|
void initialize_8042ps2() {
|
|
// disable ps/2 ports so nothing gets messed up
|
|
outportb(PS2_8042_COMMAND, 0xAD);
|
|
outportb(PS2_8042_COMMAND, 0xA7);
|
|
|
|
// flush output buffer
|
|
inportb(PS2_8042_DATA);
|
|
|
|
// get config byte
|
|
outportb(PS2_8042_COMMAND, 0x20);
|
|
uint8_t config = inportb(0x60);
|
|
// disable IRQs and translation, also make sure 0 vals are 0
|
|
config &= 0b00110100;
|
|
// write our config byte back
|
|
outportb(PS2_8042_COMMAND, 0x60);
|
|
while (inportb(PS2_8042_STATUS) & 0x2) cpu_relax;
|
|
outportb(PS2_8042_DATA, config);
|
|
|
|
// perform self test
|
|
outportb(PS2_8042_COMMAND, 0xAA);
|
|
while (!(inportb(PS2_8042_STATUS) & 0x1)) cpu_relax;
|
|
uint8_t result = inportb(PS2_8042_DATA);
|
|
if (result == 0x55) printf("Passed PS/2 self test\n");
|
|
else printf("Failed!\n");
|
|
|
|
// perform port test
|
|
outportb(PS2_8042_COMMAND, 0xAB);
|
|
while (!(inportb(PS2_8042_STATUS) & 0x1)) cpu_relax;
|
|
result = inportb(PS2_8042_DATA);
|
|
if (!result) printf("Passed PS/2 port 1 test\n");
|
|
else printf("Failed!\n");
|
|
|
|
// enable ps/2 port
|
|
outportb(PS2_8042_COMMAND, 0xAE);
|
|
|
|
// enable IRQ 1
|
|
config = 0b01100101;
|
|
outportb(PS2_8042_COMMAND, 0x60);
|
|
while (inportb(PS2_8042_STATUS) & 0x2) cpu_relax;
|
|
outportb(PS2_8042_DATA, config);
|
|
}
|
|
|
|
extern linked_mem_t stdin;
|
|
|
|
void ps2_handler() {
|
|
uint8_t scancode = inportb(0x60);
|
|
|
|
if (scancode > 0x80) goto eoi;
|
|
|
|
switch(scancode) {
|
|
case KBD_ESC:
|
|
break;
|
|
case KBD_1:
|
|
_putchar('1');
|
|
shell_buffer[shell_index++] = '1';
|
|
break;
|
|
case KBD_2:
|
|
_putchar('2');
|
|
shell_buffer[shell_index++] = '2';
|
|
break;
|
|
case KBD_3:
|
|
_putchar('3');
|
|
shell_buffer[shell_index++] = '3';
|
|
break;
|
|
case KBD_4:
|
|
_putchar('4');
|
|
shell_buffer[shell_index++] = '4';
|
|
break;
|
|
case KBD_5:
|
|
_putchar('5');
|
|
shell_buffer[shell_index++] = '5';
|
|
break;
|
|
case KBD_6:
|
|
_putchar('6');
|
|
shell_buffer[shell_index++] = '6';
|
|
break;
|
|
case KBD_7:
|
|
_putchar('7');
|
|
shell_buffer[shell_index++] = '7';
|
|
break;
|
|
case KBD_8:
|
|
_putchar('8');
|
|
shell_buffer[shell_index++] = '8';
|
|
break;
|
|
case KBD_9:
|
|
_putchar('9');
|
|
shell_buffer[shell_index++] = '9';
|
|
break;
|
|
case KBD_0:
|
|
_putchar('0');
|
|
shell_buffer[shell_index++] = '0';
|
|
break;
|
|
case KBD_MINUS:
|
|
_putchar('-');
|
|
shell_buffer[shell_index++] = '-';
|
|
break;
|
|
case KBD_EQUALS:
|
|
_putchar('=');
|
|
shell_buffer[shell_index++] = '=';
|
|
break;
|
|
case KBD_BACKSPACE:
|
|
if (shell_index > 0) {
|
|
popchar();
|
|
shell_buffer[--shell_index] = 0;
|
|
}
|
|
break;
|
|
case KBD_TAB:
|
|
break;
|
|
case KBD_Q:
|
|
_putchar('Q');
|
|
shell_buffer[shell_index++] = 'Q';
|
|
break;
|
|
case KBD_W:
|
|
_putchar('W');
|
|
shell_buffer[shell_index++] = 'W';
|
|
break;
|
|
case KBD_E:
|
|
_putchar('E');
|
|
shell_buffer[shell_index++] = 'E';
|
|
break;
|
|
case KBD_R:
|
|
_putchar('R');
|
|
shell_buffer[shell_index++] = 'R';
|
|
break;
|
|
case KBD_T:
|
|
_putchar('T');
|
|
shell_buffer[shell_index++] = 'T';
|
|
break;
|
|
case KBD_Y:
|
|
_putchar('Y');
|
|
shell_buffer[shell_index++] = 'Y';
|
|
break;
|
|
case KBD_U:
|
|
_putchar('U');
|
|
shell_buffer[shell_index++] = 'U';
|
|
break;
|
|
case KBD_I:
|
|
_putchar('I');
|
|
shell_buffer[shell_index++] = 'I';
|
|
break;
|
|
case KBD_O:
|
|
_putchar('O');
|
|
shell_buffer[shell_index++] = 'O';
|
|
break;
|
|
case KBD_P:
|
|
_putchar('P');
|
|
shell_buffer[shell_index++] = 'P';
|
|
break;
|
|
case KBD_LBRACKET:
|
|
_putchar('[');
|
|
shell_buffer[shell_index++] = '[';
|
|
break;
|
|
case KBD_RBRACKET:
|
|
_putchar(']');
|
|
shell_buffer[shell_index++] = ']';
|
|
break;
|
|
case KBD_ENTER:
|
|
printf("\n");
|
|
if (strcmp(shell_buffer, "PINGAS") == 0) {
|
|
printf("andew pingas detected");
|
|
} else if (strcmp(shell_buffer, "HELLO") == 0) {
|
|
printf("hi");
|
|
} else if (strcmp(shell_buffer, "READ") == 0) {
|
|
uint8_t sector[512] = {0};
|
|
ata_read_sector(ATA_PRIMARY, ATA_MASTER, 0, sector);
|
|
for (int i = 0; i < 512; i++) {
|
|
_putchar(sector[i]);
|
|
}
|
|
} else {
|
|
printf("unknown command '%s' idiot", shell_buffer);
|
|
}
|
|
for (int i = 0; i < 512; i++) {
|
|
shell_buffer[i] = 0;
|
|
}
|
|
shell_index = 0;
|
|
printf("\n$ ");
|
|
break;
|
|
case KBD_LCTRL:
|
|
// Handle left control key
|
|
break;
|
|
case KBD_A:
|
|
_putchar('A');
|
|
shell_buffer[shell_index++] = 'A';
|
|
break;
|
|
case KBD_S:
|
|
_putchar('S');
|
|
shell_buffer[shell_index++] = 'S';
|
|
break;
|
|
case KBD_D:
|
|
_putchar('D');
|
|
shell_buffer[shell_index++] = 'D';
|
|
break;
|
|
case KBD_F:
|
|
_putchar('F');
|
|
shell_buffer[shell_index++] = 'F';
|
|
break;
|
|
case KBD_G:
|
|
_putchar('G');
|
|
shell_buffer[shell_index++] = 'G';
|
|
break;
|
|
case KBD_H:
|
|
_putchar('H');
|
|
shell_buffer[shell_index++] = 'H';
|
|
break;
|
|
case KBD_J:
|
|
_putchar('J');
|
|
shell_buffer[shell_index++] = 'J';
|
|
break;
|
|
case KBD_K:
|
|
_putchar('K');
|
|
shell_buffer[shell_index++] = 'K';
|
|
break;
|
|
case KBD_L:
|
|
_putchar('L');
|
|
shell_buffer[shell_index++] = 'L';
|
|
break;
|
|
case KBD_SEMICOLON:
|
|
_putchar(';');
|
|
shell_buffer[shell_index++] = ';';
|
|
break;
|
|
case KBD_APOSTROPHE:
|
|
_putchar('\'');
|
|
shell_buffer[shell_index++] = '\'';
|
|
break;
|
|
case KBD_GRAVE:
|
|
_putchar('`');
|
|
shell_buffer[shell_index++] = '`';
|
|
break;
|
|
case KBD_LSHIFT:
|
|
// Handle left shift key
|
|
break;
|
|
case KBD_BACKSLASH:
|
|
_putchar('\\');
|
|
shell_buffer[shell_index++] = '\\';
|
|
break;
|
|
case KBD_Z:
|
|
_putchar('Z');
|
|
shell_buffer[shell_index++] = 'Z';
|
|
break;
|
|
case KBD_X:
|
|
_putchar('X');
|
|
shell_buffer[shell_index++] = 'X';
|
|
break;
|
|
case KBD_C:
|
|
_putchar('C');
|
|
shell_buffer[shell_index++] = 'C';
|
|
break;
|
|
case KBD_V:
|
|
_putchar('V');
|
|
shell_buffer[shell_index++] = 'V';
|
|
break;
|
|
case KBD_B:
|
|
_putchar('B');
|
|
shell_buffer[shell_index++] = 'B';
|
|
break;
|
|
case KBD_N:
|
|
_putchar('N');
|
|
shell_buffer[shell_index++] = 'N';
|
|
break;
|
|
case KBD_M:
|
|
_putchar('M');
|
|
shell_buffer[shell_index++] = 'M';
|
|
break;
|
|
case KBD_COMMA:
|
|
_putchar(',');
|
|
shell_buffer[shell_index++] = ',';
|
|
break;
|
|
case KBD_PERIOD:
|
|
_putchar('.');
|
|
shell_buffer[shell_index++] = '.';
|
|
break;
|
|
case KBD_SLASH:
|
|
_putchar('/');
|
|
shell_buffer[shell_index++] = '/';
|
|
break;
|
|
case KBD_RSHIFT:
|
|
// Handle right shift key
|
|
break;
|
|
case KBD_PRINTSCREEN:
|
|
// Handle print screen key
|
|
break;
|
|
case KBD_LALT:
|
|
// Handle left alt key
|
|
break;
|
|
case KBD_SPACE:
|
|
_putchar(' ');
|
|
shell_buffer[shell_index++] = ' ';
|
|
break;
|
|
case KBD_CAPSLOCK:
|
|
// Handle caps lock key
|
|
break;
|
|
case KBD_F1:
|
|
// Handle F1 key
|
|
break;
|
|
case KBD_F2:
|
|
// Handle F2 key
|
|
break;
|
|
case KBD_F3:
|
|
// Handle F3 key
|
|
break;
|
|
case KBD_F4:
|
|
// Handle F4 key
|
|
break;
|
|
case KBD_F5:
|
|
// Handle F5 key
|
|
break;
|
|
case KBD_F6:
|
|
// Handle F6 key
|
|
break;
|
|
case KBD_F7:
|
|
// Handle F7 key
|
|
break;
|
|
case KBD_F8:
|
|
// Handle F8 key
|
|
break;
|
|
case KBD_F9:
|
|
// Handle F9 key
|
|
break;
|
|
case KBD_F10:
|
|
// Handle F10 key
|
|
break;
|
|
case KBD_NUMLOCK:
|
|
// Handle num lock key
|
|
break;
|
|
case KBD_SCROLLLOCK:
|
|
// Handle scroll lock key
|
|
break;
|
|
case KBD_HOME:
|
|
// Handle home key
|
|
break;
|
|
case KBD_UP:
|
|
// Handle up arrow key
|
|
break;
|
|
case KBD_PAGEUP:
|
|
// Handle page up key
|
|
break;
|
|
case KBD_KP_MINUS:
|
|
// Handle keypad minus key
|
|
break;
|
|
case KBD_LEFT:
|
|
// Handle left arrow key
|
|
break;
|
|
case KBD_KP_5:
|
|
// Handle keypad 5 key
|
|
break;
|
|
case KBD_RIGHT:
|
|
// Handle right arrow key
|
|
break;
|
|
case KBD_KP_PLUS:
|
|
// Handle keypad plus key
|
|
break;
|
|
case KBD_END:
|
|
// Handle end key
|
|
break;
|
|
case KBD_DOWN:
|
|
// Handle down arrow key
|
|
break;
|
|
case KBD_PAGEDOWN:
|
|
// Handle page down key
|
|
break;
|
|
case KBD_INSERT:
|
|
// Handle insert key
|
|
break;
|
|
case KBD_DELETE:
|
|
// Handle delete key
|
|
break;
|
|
case KBD_SYSRQ:
|
|
// Handle system request key
|
|
break;
|
|
case KBD_F11:
|
|
// Handle F11 key
|
|
break;
|
|
case KBD_F12:
|
|
// Handle F12 key
|
|
break;
|
|
case KBD_KP_ENTER:
|
|
break;
|
|
case KBD_RCTRL:
|
|
// Handle right control key
|
|
break;
|
|
case KBD_KP_DIVIDE:
|
|
// Handle keypad divide key
|
|
break;
|
|
case KBD_PRINTSCREEN2:
|
|
// Handle print screen key (alternate)
|
|
break;
|
|
case KBD_RALT:
|
|
// Handle right alt key
|
|
break;
|
|
case KBD_HOME2:
|
|
// Handle home key (alternate)
|
|
break;
|
|
case KBD_UP2:
|
|
// Handle up arrow key (alternate)
|
|
break;
|
|
case KBD_PAGEUP2:
|
|
// Handle page up key (alternate)
|
|
break;
|
|
case KBD_LEFT2:
|
|
// Handle left arrow key (alternate)
|
|
break;
|
|
case KBD_RIGHT2:
|
|
// Handle right arrow key (alternate)
|
|
break;
|
|
case KBD_END2:
|
|
// Handle end key (alternate)
|
|
break;
|
|
case KBD_DOWN2:
|
|
// Handle down arrow key (alternate)
|
|
break;
|
|
case KBD_PAGEDOWN2:
|
|
// Handle page down key (alternate)
|
|
break;
|
|
case KBD_INSERT2:
|
|
// Handle insert key (alternate)
|
|
break;
|
|
case KBD_DELETE2:
|
|
// Handle delete key (alternate)
|
|
break;
|
|
default:
|
|
// Handle unknown scan codes
|
|
printf("Unknown scan code\n");
|
|
break;
|
|
}
|
|
eoi:
|
|
pic_send_eoi(1);
|
|
}
|