159 lines
3.1 KiB
C
159 lines
3.1 KiB
C
#include <kernel/tty.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <strlib.h>
|
|
|
|
static inline uint8_t inb(uint16_t port)
|
|
{
|
|
uint8_t ret;
|
|
__asm__ volatile ( "inb %w1, %b0"
|
|
: "=a"(ret)
|
|
: "Nd"(port)
|
|
: "memory");
|
|
return ret;
|
|
}
|
|
|
|
static bool is_in_shift;
|
|
|
|
static unsigned char keyboard_char(unsigned char scancode)
|
|
{
|
|
if (0x01 < scancode && scancode < 0x0B) {
|
|
return scancode - 2 + '1';
|
|
}
|
|
|
|
if (scancode == 0x0B) {
|
|
return '0';
|
|
}
|
|
|
|
switch (scancode) {
|
|
case 0x10:
|
|
return 'Q';
|
|
case 0x11:
|
|
return 'W';
|
|
case 0x12:
|
|
return 'E';
|
|
case 0x13:
|
|
return 'R';
|
|
case 0x14:
|
|
return 'T';
|
|
case 0x15:
|
|
return 'Y';
|
|
case 0x16:
|
|
return 'U';
|
|
case 0x17:
|
|
return 'I';
|
|
case 0x18:
|
|
return 'O';
|
|
case 0x19:
|
|
return 'P';
|
|
case 0x1a:
|
|
return '[';
|
|
case 0x1b:
|
|
return ']';
|
|
case 0x1c:
|
|
return '\n';
|
|
case 0x1d:
|
|
return '\b';
|
|
case 0x1e:
|
|
return 'A';
|
|
case 0x1f:
|
|
return 'S';
|
|
case 0x20:
|
|
return 'D';
|
|
case 0x21:
|
|
return 'F';
|
|
case 0x22:
|
|
return 'G';
|
|
case 0x23:
|
|
return 'H';
|
|
case 0x24:
|
|
return 'J';
|
|
case 0x25:
|
|
return 'K';
|
|
case 0x26:
|
|
return 'L';
|
|
case 0x27:
|
|
return ';';
|
|
case 0x28:
|
|
return '\'';
|
|
case 0x29:
|
|
return '`';
|
|
case 0x2a:
|
|
is_in_shift = true;
|
|
break;
|
|
case 0x2b:
|
|
return '\\';
|
|
case 0x2c:
|
|
return 'Z';
|
|
case 0x2d:
|
|
return 'X';
|
|
case 0x2e:
|
|
return 'C';
|
|
case 0x2f:
|
|
return 'V';
|
|
case 0x30:
|
|
return 'B';
|
|
case 0x31:
|
|
return 'N';
|
|
case 0x32:
|
|
return 'M';
|
|
case 0x33:
|
|
return ',';
|
|
case 0x34:
|
|
return '.';
|
|
case 0x35:
|
|
return '/';
|
|
case 0x36:
|
|
is_in_shift = true;
|
|
break;
|
|
case 0x39:
|
|
return ' ';
|
|
case 0xaa:
|
|
is_in_shift = false;
|
|
break;
|
|
case 0xb6:
|
|
is_in_shift = false;
|
|
break;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
char get_last_key_pressed()
|
|
{
|
|
char scancode = inb(0x60);
|
|
|
|
if (is_in_shift) {
|
|
return keyboard_char(scancode);
|
|
}
|
|
|
|
return to_lower_char(keyboard_char(scancode));
|
|
}
|
|
|
|
void print_hex_digit(uint8_t digit)
|
|
{
|
|
digit = digit & 0xf;
|
|
if (digit < 0xA) {
|
|
terminal_putchar(digit + 0x30);
|
|
} else {
|
|
terminal_putchar(digit + 0x41 - 0xA);
|
|
}
|
|
}
|
|
|
|
void print_hex_byte(uint8_t byte)
|
|
{
|
|
int upper = byte >> 4;
|
|
int lower = byte & 0x0F;
|
|
|
|
print_hex_digit(upper);
|
|
print_hex_digit(lower);
|
|
}
|
|
|
|
void print_hex_bytes(void* bytes, size_t len)
|
|
{
|
|
uint8_t* value = bytes;
|
|
for (size_t i = len; i > 0; i--) {
|
|
print_hex_byte(value[i - 1]);
|
|
}
|
|
}
|