# check keyboard for a key # return 0 on no keypress or unrecognized key # # We need to do this in machine code because Mu doesn't have global variables # yet (for the keyboard buffer). == code # Most keys correspond to their ASCII/Unicode values. # TODO: Support for international keyboards and multi-byte Unicode. # # However there are some exceptions that have no assigned place in Unicode # (and with good reason): # 0x80 = left arrow ← # 0x81 = down arrow ↓ # 0x82 = up arrow ↑ # 0x83 = right arrow → # These code points are not used by Unicode and their semantics are agreed to # be context-sensitive: https://en.wikipedia.org/wiki/C0_and_C1_control_codes#C1_controls. # Mu cannibalizes them in yet another non-standard way. read-key: # kbd: (addr keyboard) -> result/eax: byte # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx # result = 0 b8/copy-to-eax 0/imm32 # ecx = keyboard 8b/-> *(ebp+8) 1/r32/ecx 81 7/subop/compare %ecx 0/imm32 { 75/jump-if-!= break/disp8 # var buffer-byte-addr/ecx: (addr byte) 8b/-> *Keyboard-buffer:read 1/r32/CL 81 0/subop/add %ecx Keyboard-buffer:data/imm32 # var next-key/eax: byte = *buffer-byte-addr 8a/byte-> *ecx 0/r32/AL # if (next-key != 0) lock and remove from keyboard buffer 3d/compare-eax-with 0/imm32 { 74/jump-if-= break/disp8 fa/disable-interrupts c6 0/subop/copy-byte *ecx 0/imm8 ff 0/subop/increment *Keyboard-buffer:read 81 4/subop/and *Keyboard-buffer:read 0x0f/imm32 fb/enable-interrupts } # return eb $read-key:end/disp8 } # TODO: fake keyboard $read-key:end: # . restore registers 59/pop-to-ecx # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return