https://github.com/akkartik/mu/blob/main/102keyboard.subx

     1 # check keyboard for a key
     2 # return 0 on no keypress or unrecognized key
     3 #
     4 # We need to do this in machine code because Mu doesn't have global variables
     5 # yet (for the keyboard buffer).
     6
     7 == code
     8
     9 # Most keys correspond to their ASCII/Unicode values.
    10 # TODO: Support for international keyboards and multi-byte Unicode.
    11 #
    12 # However there are some exceptions that have no assigned place in Unicode
    13 # (and with good reason):
    14 #   0x80 = left arrow ←
    15 #   0x81 = down arrow ↓
    16 #   0x82 = up arrow ↑
    17 #   0x83 = right arrow →
    18 # These code points are not used by Unicode and their semantics are agreed to
    19 # be context-sensitive: https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C1_controls.
    20 # Mu cannibalizes them in yet another non-standard way.
    21 read-key:  # kbd: (addr keyboard) -> result/eax: byte
    22     # . prologue
    23     55/push-ebp
    24     89/<- %ebp 4/r32/esp
    25     # . save registers
    26     51/push-ecx
    27     # result = 0
    28     b8/copy-to-eax 0/imm32
    29     # ecx = keyboard
    30     8b/-> *(ebp+8) 1/r32/ecx
    31     81 7/subop/compare %ecx 0/imm32
    32     {
    33       75/jump-if-!= break/disp8
    34       # var buffer-byte-addr/ecx: (addr byte)
    35       8b/-> *Keyboard-buffer:read 1/r32/CL
    36       81 0/subop/add %ecx Keyboard-buffer:data/imm32
    37       # var next-key/eax: byte = *buffer-byte-addr
    38       8a/byte-> *ecx 0/r32/AL
    39       # if (next-key != 0) lock and remove from keyboard buffer
    40       3d/compare-eax-with 0/imm32
    41       {
    42         74/jump-if-= break/disp8
    43         fa/disable-interrupts
    44         c6 0/subop/copy-byte *ecx 0/imm8
    45         ff 0/subop/increment *Keyboard-buffer:read
    46         81 4/subop/and *Keyboard-buffer:read 0x0f/imm32
    47         fb/enable-interrupts
    48       }
    49       # return
    50       eb $read-key:end/disp8
    51     }
    52     # TODO: fake keyboard
    53 $read-key:end:
    54     # . restore registers
    55     59/pop-to-ecx
    56     # . epilogue
    57     89/<- %esp 5/r32/ebp
    58     5d/pop-to-ebp
    59     c3/return