x86keyboardnasmosdevscancodes

Convert Scancodes to ASCII


So I got IRQ1 working correctly but it turns out that it prints the scan code read from port 0x60. I know I have to convert these to the actual characters but I can't seem to get my head around it. I am trying to do this in nasm. I know I can use key maps but it raises questions about make or break codes (which should I use and what should I do with the other?). Is there no mathematical formula to convert them to ASCII? I already read a lot about it online but it didn't help much. Any help as to how convert scan codes to character in nasm is appreciated.


Solution

  • There is no such mathematical formula. In fact, the mapping differs a bit between keyboard layouts. This is a pretty hard problem. Usually you'd provide a way for users to select their keyboard layout and load a map based on that. So to answer your question: I'd suggest you to make an array mapping each scancode to the correct character. I assume you run it in qemu or another emulator, and the keymap in that is pretty constant for all intents and purposes. Then once your kernel gets farther in development, you provide multiple of these keymapping arrays that can be swapped out by the user. Though I'd put that pretty low on the list of tasks that need to be implemented in your os.

    An example of such an array (for a standard US keyboard layout like you get in qemu):

    char kbd_US [128] =
    {
        0,  27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',   
      '\t', /* <-- Tab */
      'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',     
        0, /* <-- control key */
      'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',  0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',   0,
      '*',
        0,  /* Alt */
      ' ',  /* Space bar */
        0,  /* Caps lock */
        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 */
      '-',
        0,  /* Left Arrow */
        0,
        0,  /* Right Arrow */
      '+',
        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,  /* All other keys are undefined */
    };
    

    Please note that this map is not entirely complete, won't work for all keyboards, and you might want to redefine the mapping for modifier keys like control, alt and shift. You will need to do some testing for that.