#include #include #include #include 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]); } }