MIPS Input controller
What the Input controller is
The Input controller reports key presses and releases, held keys, mouse buttons, pointer position and wheel turns. Unlike the keyboard registers, which provide typed characters, it also reports keys such as the arrows, Shift and the function keys.
This editor adds the device to MARS, alongside the Synth. Its memory registers start at 0xffff0300, after the Synth's. In MARS these addresses read 0 and provide no input. Check the ID register before using the controller, as the first program below does.
Click the Screen panel to send keyboard and mouse input to the program. While the Screen has focus, keys go to the program, including Escape. Press Shift+Tab, or click outside the Screen, to return keyboard control to the editor. Losing focus releases all held keys and mouse buttons: their state bits clear and release events enter the queue. This also happens when the browser window loses focus.
A first program
This program prints a letter for each arrow key you press, R, L, D or U, and ends when you press Escape. Build it and press Run, then click the Screen and press the arrows.
.text
main: li $s0, 0xffff0300 # the Input controller
lw $t0, 0($s0) # ID: 0x494E5001 when it is there
srl $t0, $t0, 8
li $t1, 0x494E50 # "INP"
bne $t0, $t1, absent
poll: lw $t0, 8($s0) # Status: how many events wait
beqz $t0, idle
lw $t2, 12($s0) # Event: take the oldest one
srl $t3, $t2, 8
andi $t3, $t3, 7 # its kind
andi $t4, $t2, 0xff # its code
li $t5, 1 # kind 1: a key went down
bne $t3, $t5, poll
li $t5, 0x29 # Escape
beq $t4, $t5, done
addi $t5, $t4, -0x4F # the arrows are 0x4F to 0x52
sltiu $t6, $t5, 4
beqz $t6, poll # another key
la $t6, arrows
add $t6, $t6, $t5
lb $a0, 0($t6) # R, L, D or U
li $v0, 11
syscall
j poll
idle: li $a0, 16 # nothing waits: sleep a frame
li $v0, 32
syscall
j poll
absent: la $a0, missing
li $v0, 4
syscall
done: li $v0, 10
syscall
.data
arrows: .ascii "RLDU"
missing:.asciiz "This simulator has no Input controller.\n"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
The program uses three registers:
- It reads the ID register once, to make sure the Input controller is there.
- It reads Status, which says how many events are waiting. If there are none, it sleeps for 16 milliseconds and looks again.
- Each read of Event takes the oldest waiting event, one word. The program takes it apart: the kind in bits 10–8, and the code in bits 7–0.
The registers
Offsets below are from 0xffff0300. Each register is one 32-bit word, except Keys, which occupies 32 bytes. Read registers with lw. Read individual bytes of Keys with lbu.
| Offset | Register | In C | Access | What it holds |
|---|---|---|---|---|
0x00 | Id | SIM_INPUT_ID | read | Reads 0x494E5001 ("INP", version 1) when the Input controller is available. Reads 0 in MARS and RARS, which do not provide this device |
0x04 | Control | SIM_INPUT_CONTROL | write | Reads 0. Bit 1 is reserved: setting it stops the program because the Input controller does not support interrupts. Leave it clear and poll Status for events. Other bits are ignored |
0x08 | Status | SIM_INPUT_STATUS | read | Bits 6–0 hold the number of queued events, 0 to 127. Reading Status does not remove events |
0x0C | Event | SIM_INPUT_EVENT | read, takes an event | Reading removes and returns the oldest queued event, or 0 if the queue is empty. Read once with lw and keep the result |
0x10 | Pointer | SIM_INPUT_POINTER | read | Pointer position and held mouse buttons: y in bits 30–21, x in bits 20–11, buttons in bits 2–0 |
0x14–0x1F | Reserved | Reads 0 | ||
0x20 | Keys | SIM_INPUT_KEYS | read | 256 bits indicating held keys, one per HID usage code. For code u, test bit u & 7 of the byte at KEYS + (u >> 3) |
Status normally ranges from 0 to 64, the queue's capacity. Undo can restore additional events, so Status can exceed 64. It reports at most 127, even if more events are waiting.
Reading Event removes an event. Even a byte read with lbu removes it. Read it once with lw and keep the result. Reads of the other registers remove nothing.
Writes do not change the controller's state or the values later reads return. One write causes an error: setting bit 1 of Control stops the program, because this controller does not support interrupts. Leave that bit clear and poll Status.
Events
Key presses, repeats and releases, mouse button presses and releases, and wheel turns produce events, one word each. Events wait in a queue, oldest first. Two key presses between reads are both kept in order, unless the queue is full.
| Bits | Field | What it holds |
|---|---|---|
| 31 | always 0 | |
| 30–21 | y | the pointer’s row when the event happened, 0 to 1023 |
| 20–11 | x | the pointer’s column, 0 to 1023 |
| 10–8 | kind | what happened, from the table below |
| 7–0 | code | which key or button, or how far the wheel turned |
Bit 31 of an Event word is always 0. Logical and arithmetic right shifts therefore give the same result when extracting its fields.
| Kind | In C | Meaning |
|---|---|---|
| 0 | No event: the queue was empty | |
| 1 | SIM_INPUT_KEY_DOWN | A key went down; the code is its HID usage |
| 2 | SIM_INPUT_KEY_UP | A key came up; the code is its HID usage |
| 3 | SIM_INPUT_KEY_REPEAT | A held key repeats, as it does when typing; the code is its HID usage |
| 4 | SIM_INPUT_BUTTON_DOWN | A mouse button went down; the code is 1 left, 2 right or 3 middle |
| 5 | SIM_INPUT_BUTTON_UP | A mouse button came up; the code is 1 left, 2 right or 3 middle |
| 6 | SIM_INPUT_WHEEL | The wheel turned; the code is a signed count of notches, positive away from the user |
| 7 | SIM_INPUT_DROPPED | The queue was full and events were lost here: read the state registers again |
- A key's code is its USB HID number. It identifies a physical key position rather than its printed character. For example, the position labelled S on a US keyboard is
KeyS(0x16), regardless of the active layout. The table at the end lists the supported keys. - Holding a key sends one key-down event, then repeats at the keyboard's typing repeat rate, then one key-up event on release. To move something while a key is held, read the keys held now instead of counting repeats.
- A button's code is 1 for the left button, 2 for the right and 3 for the middle one.
- The wheel's code is a signed number of notches: positive away from you, negative towards you. Consecutive unread wheel turns in the same direction merge into one event while their sum fits from −127 to 127. The merged event uses the latest pointer position.
- Every event carries the pointer's position at the moment it happened, so a click event says where the click was.
Taking an event apart:
lw $t0, 12($s0) # one event
srl $t1, $t0, 8
andi $t1, $t1, 7 # kind, bits 10-8
andi $t2, $t0, 0xff # code, bits 7-0
srl $t3, $t0, 11
andi $t3, $t3, 0x3ff # x, bits 20-11
srl $t4, $t0, 21 # y, bits 30-21: bit 31 is 0
sll $t5, $t0, 24
sra $t5, $t5, 24 # a wheel's code as a signed number of notches1
2
3
4
5
6
7
8
9Keys held now
From offset 0x20, 32 bytes hold one bit per key code. A bit is 1 while its key is held. For code k, read byte 0x20 + k / 8, bit k % 8, using integer division. Reads with lbu or lw leave the state unchanged.
This checks whether the left arrow, code 0x50, is held. 0x50 / 8 is 10 and 0x50 % 8 is 0, so the bit is bit 0 of the byte at offset 0x20 + 10:
lbu $t0, 0x2a($s0) # keys 0x50 to 0x57
andi $t0, $t0, 1 # bit 0: the left arrow, 0x50
bnez $t0, left # held: move left this frame1
2
3
A game can read held keys once per frame and use events for single presses such as Escape. The two views answer different questions: a key pressed and released between frames is no longer held, but both events remain queued.
The pointer
The Pointer word holds y in bits 30–21, x in bits 20–11, and held buttons in bits 2–0: bit 0 left, bit 1 right and bit 2 middle.
x and y count words of the bitmap display, from 0 at the top left. The word under the pointer is y × columns + x, where columns is the display's width in words. Dragging past an edge keeps the coordinates at the last word. Pointer movement updates this register without queuing an event.
Waiting for input
To wait for input, sleep for a few milliseconds with service 32, then read Status again, as the first program does. Sleeping costs no instructions. Polling continuously uses instructions, fills the Undo history and can reach the instruction limit.
When the queue is full
The normal queue holds 64 events, including any dropped markers. When it is full, new events are lost. Once space becomes available, a later arriving event first adds a dropped marker, kind 7. If only one slot is free, the marker fills it and that arriving event is lost too. Reading events alone does not add a marker.
On receiving a dropped marker, read Keys and Pointer to recover the current state. Held-key and button state still updates when events are lost. Undo can temporarily restore more than 64 events, as explained below.
Typed characters and keys
A press that produces a character feeds both the keyboard registers at 0xffff0000 and the Input controller. Non-character keys, such as arrows and Shift, and key releases feed only the Input controller.
- Use the keyboard registers for text. They provide characters in the user's keyboard layout, including Shift and AltGr combinations, pasted text and Testcase input.
- Use the Input controller for keys. It provides physical key codes. A program using it for text must convert those codes into characters itself.
The two queues are separate. Reading the Input controller leaves typed characters waiting in the keyboard receiver. A later character read, including a read through a service, gets those old characters first. To discard them, read receiver data until the receiver's Ready bit is clear.
Escape types character 27 at the keyboard registers.
When the Input controller hears nothing
- Before the program starts and after it ends. Input is accepted from the program's first instruction until it ends. A click that focuses the Screen before Run is not queued. A key already held when the program starts appears at its next repeat as a key-down event.
- In a Testcase. A Testcase has no keyboard and no mouse: no events, no keys held, and the pointer at 0, 0. A Testcase's input still reaches the keyboard registers as typed lines.
- Under the bitmap display. A display whose base address is
0xffff0000, MARS's "memory map" base, can cover the Input controller's addresses. Its words are then pixels, and the Input controller writes none of them. Move the display, or make it smaller, to use both.
Undo
Undo restores events removed by the instruction being undone, at the front of the queue and in their original order. Running forward can read them again. Restored events are kept even if the queue grows past 64. Status reports at most 127.
Undo does not rewind held keys, held buttons or pointer position. Those registers show current input, so the restored queue may contain a key-down event for a key that is now released.
From C
<sim.h> names the Input controller's registers, the parts of an event and every key:
- Registers:
SIM_INPUT_ID,SIM_INPUT_CONTROL,SIM_INPUT_STATUS,SIM_INPUT_EVENTandSIM_INPUT_POINTERread a register, andSIM_INPUT_KEYSis the 32 bytes of keys held. - Helpers:
sim_input_present()says whether the Input controller is there,sim_input_pending()how many events wait,sim_input_event()takes the oldest event,sim_input_key_down(key)says whether a key is held, andsim_input_pointer()reads the Pointer register. - Parts of a word:
SIM_INPUT_KIND(event),SIM_INPUT_CODE(event)andSIM_INPUT_WHEEL_NOTCHES(event), which gives the wheel's notches as a signed number;SIM_INPUT_X(word)andSIM_INPUT_Y(word)for an event or the pointer, andSIM_INPUT_BUTTONS(pointer). - Kinds:
SIM_INPUT_KEY_DOWN,SIM_INPUT_KEY_UP,SIM_INPUT_KEY_REPEAT,SIM_INPUT_BUTTON_DOWN,SIM_INPUT_BUTTON_UP,SIM_INPUT_WHEELandSIM_INPUT_DROPPED. - Buttons, in two forms:
SIM_INPUT_BUTTON_LEFT,SIM_INPUT_BUTTON_RIGHTandSIM_INPUT_BUTTON_MIDDLE(1, 2 and 3) are a button event's code, whileSIM_INPUT_HELD_LEFT,SIM_INPUT_HELD_RIGHTandSIM_INPUT_HELD_MIDDLE(1, 2 and 4) are the Pointer register's bits. - Keys:
SIM_KEY_and the key's name from the table below, such asSIM_KEY_A,SIM_KEY_ARROW_LEFTandSIM_KEY_SPACE.
See Using C and C++ for compiling. This program moves a dot with the arrow keys, draws where you click, and ends on Escape:
#include <sim.h>
SIM_SCREEN(screen, 64, 64, 1);
int main(void) {
if (!sim_input_present()) {
sim_print_string("This simulator has no Input controller.\n");
return 1;
}
unsigned x = 32, y = 32;
for (;;) {
while (sim_input_pending()) {
unsigned event = sim_input_event();
unsigned kind = SIM_INPUT_KIND(event);
if (kind == SIM_INPUT_KEY_DOWN && SIM_INPUT_CODE(event) == SIM_KEY_ESCAPE)
return 0;
/* a left click paints the word under the pointer */
if (kind == SIM_INPUT_BUTTON_DOWN && SIM_INPUT_CODE(event) == SIM_INPUT_BUTTON_LEFT)
screen[SIM_INPUT_Y(event) * 64 + SIM_INPUT_X(event)] = sim_rgb(255, 255, 0);
}
screen[y * 64 + x] = 0;
if (sim_input_key_down(SIM_KEY_ARROW_LEFT) && x > 0) x--;
if (sim_input_key_down(SIM_KEY_ARROW_RIGHT) && x < 63) x++;
if (sim_input_key_down(SIM_KEY_ARROW_UP) && y > 0) y--;
if (sim_input_key_down(SIM_KEY_ARROW_DOWN) && y < 63) y++;
screen[y * 64 + x] = sim_rgb(0, 200, 255);
sim_sleep(16);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29Key codes
Each key is named after the browser's name for it, written in capitals with underscores: ArrowLeft is SIM_KEY_ARROW_LEFT in C. Left and right Shift, Control, Alt and Meta (the Windows or Command key) are different keys. The keypad's keys are their own and do not depend on Num Lock. Keys that a USB keyboard has no code for, such as volume and media keys and Fn, send nothing.
Letters and digits
| Key | Code | In C |
|---|---|---|
KeyA | 0x04 | SIM_KEY_A |
KeyB | 0x05 | SIM_KEY_B |
KeyC | 0x06 | SIM_KEY_C |
KeyD | 0x07 | SIM_KEY_D |
KeyE | 0x08 | SIM_KEY_E |
KeyF | 0x09 | SIM_KEY_F |
KeyG | 0x0A | SIM_KEY_G |
KeyH | 0x0B | SIM_KEY_H |
KeyI | 0x0C | SIM_KEY_I |
KeyJ | 0x0D | SIM_KEY_J |
KeyK | 0x0E | SIM_KEY_K |
KeyL | 0x0F | SIM_KEY_L |
KeyM | 0x10 | SIM_KEY_M |
KeyN | 0x11 | SIM_KEY_N |
KeyO | 0x12 | SIM_KEY_O |
KeyP | 0x13 | SIM_KEY_P |
KeyQ | 0x14 | SIM_KEY_Q |
KeyR | 0x15 | SIM_KEY_R |
KeyS | 0x16 | SIM_KEY_S |
KeyT | 0x17 | SIM_KEY_T |
KeyU | 0x18 | SIM_KEY_U |
KeyV | 0x19 | SIM_KEY_V |
KeyW | 0x1A | SIM_KEY_W |
KeyX | 0x1B | SIM_KEY_X |
KeyY | 0x1C | SIM_KEY_Y |
KeyZ | 0x1D | SIM_KEY_Z |
Digit1 | 0x1E | SIM_KEY_DIGIT_1 |
Digit2 | 0x1F | SIM_KEY_DIGIT_2 |
Digit3 | 0x20 | SIM_KEY_DIGIT_3 |
Digit4 | 0x21 | SIM_KEY_DIGIT_4 |
Digit5 | 0x22 | SIM_KEY_DIGIT_5 |
Digit6 | 0x23 | SIM_KEY_DIGIT_6 |
Digit7 | 0x24 | SIM_KEY_DIGIT_7 |
Digit8 | 0x25 | SIM_KEY_DIGIT_8 |
Digit9 | 0x26 | SIM_KEY_DIGIT_9 |
Digit0 | 0x27 | SIM_KEY_DIGIT_0 |
Typing keys
| Key | Code | In C |
|---|---|---|
Enter | 0x28 | SIM_KEY_ENTER |
Escape | 0x29 | SIM_KEY_ESCAPE |
Backspace | 0x2A | SIM_KEY_BACKSPACE |
Tab | 0x2B | SIM_KEY_TAB |
Space | 0x2C | SIM_KEY_SPACE |
Minus | 0x2D | SIM_KEY_MINUS |
Equal | 0x2E | SIM_KEY_EQUAL |
BracketLeft | 0x2F | SIM_KEY_BRACKET_LEFT |
BracketRight | 0x30 | SIM_KEY_BRACKET_RIGHT |
Backslash | 0x31 | SIM_KEY_BACKSLASH |
Semicolon | 0x33 | SIM_KEY_SEMICOLON |
Quote | 0x34 | SIM_KEY_QUOTE |
Backquote | 0x35 | SIM_KEY_BACKQUOTE |
Comma | 0x36 | SIM_KEY_COMMA |
Period | 0x37 | SIM_KEY_PERIOD |
Slash | 0x38 | SIM_KEY_SLASH |
CapsLock | 0x39 | SIM_KEY_CAPS_LOCK |
Function keys
| Key | Code | In C |
|---|---|---|
F1 | 0x3A | SIM_KEY_F1 |
F2 | 0x3B | SIM_KEY_F2 |
F3 | 0x3C | SIM_KEY_F3 |
F4 | 0x3D | SIM_KEY_F4 |
F5 | 0x3E | SIM_KEY_F5 |
F6 | 0x3F | SIM_KEY_F6 |
F7 | 0x40 | SIM_KEY_F7 |
F8 | 0x41 | SIM_KEY_F8 |
F9 | 0x42 | SIM_KEY_F9 |
F10 | 0x43 | SIM_KEY_F10 |
F11 | 0x44 | SIM_KEY_F11 |
F12 | 0x45 | SIM_KEY_F12 |
F13 | 0x68 | SIM_KEY_F13 |
F14 | 0x69 | SIM_KEY_F14 |
F15 | 0x6A | SIM_KEY_F15 |
F16 | 0x6B | SIM_KEY_F16 |
F17 | 0x6C | SIM_KEY_F17 |
F18 | 0x6D | SIM_KEY_F18 |
F19 | 0x6E | SIM_KEY_F19 |
F20 | 0x6F | SIM_KEY_F20 |
F21 | 0x70 | SIM_KEY_F21 |
F22 | 0x71 | SIM_KEY_F22 |
F23 | 0x72 | SIM_KEY_F23 |
F24 | 0x73 | SIM_KEY_F24 |
Navigation
| Key | Code | In C |
|---|---|---|
PrintScreen | 0x46 | SIM_KEY_PRINT_SCREEN |
ScrollLock | 0x47 | SIM_KEY_SCROLL_LOCK |
Pause | 0x48 | SIM_KEY_PAUSE |
Insert | 0x49 | SIM_KEY_INSERT |
Home | 0x4A | SIM_KEY_HOME |
PageUp | 0x4B | SIM_KEY_PAGE_UP |
Delete | 0x4C | SIM_KEY_DELETE |
End | 0x4D | SIM_KEY_END |
PageDown | 0x4E | SIM_KEY_PAGE_DOWN |
ArrowRight | 0x4F | SIM_KEY_ARROW_RIGHT |
ArrowLeft | 0x50 | SIM_KEY_ARROW_LEFT |
ArrowDown | 0x51 | SIM_KEY_ARROW_DOWN |
ArrowUp | 0x52 | SIM_KEY_ARROW_UP |
ContextMenu | 0x65 | SIM_KEY_CONTEXT_MENU |
Help | 0x75 | SIM_KEY_HELP |
Keypad
| Key | Code | In C |
|---|---|---|
NumLock | 0x53 | SIM_KEY_NUM_LOCK |
NumpadDivide | 0x54 | SIM_KEY_NUMPAD_DIVIDE |
NumpadMultiply | 0x55 | SIM_KEY_NUMPAD_MULTIPLY |
NumpadSubtract | 0x56 | SIM_KEY_NUMPAD_SUBTRACT |
NumpadAdd | 0x57 | SIM_KEY_NUMPAD_ADD |
NumpadEnter | 0x58 | SIM_KEY_NUMPAD_ENTER |
Numpad1 | 0x59 | SIM_KEY_NUMPAD_1 |
Numpad2 | 0x5A | SIM_KEY_NUMPAD_2 |
Numpad3 | 0x5B | SIM_KEY_NUMPAD_3 |
Numpad4 | 0x5C | SIM_KEY_NUMPAD_4 |
Numpad5 | 0x5D | SIM_KEY_NUMPAD_5 |
Numpad6 | 0x5E | SIM_KEY_NUMPAD_6 |
Numpad7 | 0x5F | SIM_KEY_NUMPAD_7 |
Numpad8 | 0x60 | SIM_KEY_NUMPAD_8 |
Numpad9 | 0x61 | SIM_KEY_NUMPAD_9 |
Numpad0 | 0x62 | SIM_KEY_NUMPAD_0 |
NumpadDecimal | 0x63 | SIM_KEY_NUMPAD_DECIMAL |
NumpadEqual | 0x67 | SIM_KEY_NUMPAD_EQUAL |
NumpadComma | 0x85 | SIM_KEY_NUMPAD_COMMA |
NumpadParenLeft | 0xB6 | SIM_KEY_NUMPAD_PAREN_LEFT |
NumpadParenRight | 0xB7 | SIM_KEY_NUMPAD_PAREN_RIGHT |
NumpadBackspace | 0xBB | SIM_KEY_NUMPAD_BACKSPACE |
Modifiers
| Key | Code | In C |
|---|---|---|
ControlLeft | 0xE0 | SIM_KEY_CONTROL_LEFT |
ShiftLeft | 0xE1 | SIM_KEY_SHIFT_LEFT |
AltLeft | 0xE2 | SIM_KEY_ALT_LEFT |
MetaLeft | 0xE3 | SIM_KEY_META_LEFT |
ControlRight | 0xE4 | SIM_KEY_CONTROL_RIGHT |
ShiftRight | 0xE5 | SIM_KEY_SHIFT_RIGHT |
AltRight | 0xE6 | SIM_KEY_ALT_RIGHT |
MetaRight | 0xE7 | SIM_KEY_META_RIGHT |
International
| Key | Code | In C |
|---|---|---|
IntlBackslash | 0x64 | SIM_KEY_INTL_BACKSLASH |
IntlRo | 0x87 | SIM_KEY_INTL_RO |
KanaMode | 0x88 | SIM_KEY_KANA_MODE |
IntlYen | 0x89 | SIM_KEY_INTL_YEN |
Convert | 0x8A | SIM_KEY_CONVERT |
NonConvert | 0x8B | SIM_KEY_NON_CONVERT |
Lang1 | 0x90 | SIM_KEY_LANG_1 |
Lang2 | 0x91 | SIM_KEY_LANG_2 |
Lang3 | 0x92 | SIM_KEY_LANG_3 |
Lang4 | 0x93 | SIM_KEY_LANG_4 |
Lang5 | 0x94 | SIM_KEY_LANG_5 |
On Windows, AltGr arrives as two keys at once: Control Left and Alt Right.
For assembly, these lines give the common keys names, ready to paste at the top of a program:
.eqv KEY_A 0x04
.eqv KEY_B 0x05
.eqv KEY_C 0x06
.eqv KEY_D 0x07
.eqv KEY_E 0x08
.eqv KEY_F 0x09
.eqv KEY_G 0x0A
.eqv KEY_H 0x0B
.eqv KEY_I 0x0C
.eqv KEY_J 0x0D
.eqv KEY_K 0x0E
.eqv KEY_L 0x0F
.eqv KEY_M 0x10
.eqv KEY_N 0x11
.eqv KEY_O 0x12
.eqv KEY_P 0x13
.eqv KEY_Q 0x14
.eqv KEY_R 0x15
.eqv KEY_S 0x16
.eqv KEY_T 0x17
.eqv KEY_U 0x18
.eqv KEY_V 0x19
.eqv KEY_W 0x1A
.eqv KEY_X 0x1B
.eqv KEY_Y 0x1C
.eqv KEY_Z 0x1D
.eqv KEY_DIGIT_1 0x1E
.eqv KEY_DIGIT_2 0x1F
.eqv KEY_DIGIT_3 0x20
.eqv KEY_DIGIT_4 0x21
.eqv KEY_DIGIT_5 0x22
.eqv KEY_DIGIT_6 0x23
.eqv KEY_DIGIT_7 0x24
.eqv KEY_DIGIT_8 0x25
.eqv KEY_DIGIT_9 0x26
.eqv KEY_DIGIT_0 0x27
.eqv KEY_ENTER 0x28
.eqv KEY_ESCAPE 0x29
.eqv KEY_BACKSPACE 0x2A
.eqv KEY_TAB 0x2B
.eqv KEY_SPACE 0x2C
.eqv KEY_MINUS 0x2D
.eqv KEY_EQUAL 0x2E
.eqv KEY_BRACKET_LEFT 0x2F
.eqv KEY_BRACKET_RIGHT 0x30
.eqv KEY_BACKSLASH 0x31
.eqv KEY_SEMICOLON 0x33
.eqv KEY_QUOTE 0x34
.eqv KEY_BACKQUOTE 0x35
.eqv KEY_COMMA 0x36
.eqv KEY_PERIOD 0x37
.eqv KEY_SLASH 0x38
.eqv KEY_CAPS_LOCK 0x39
.eqv KEY_F1 0x3A
.eqv KEY_F2 0x3B
.eqv KEY_F3 0x3C
.eqv KEY_F4 0x3D
.eqv KEY_F5 0x3E
.eqv KEY_F6 0x3F
.eqv KEY_F7 0x40
.eqv KEY_F8 0x41
.eqv KEY_F9 0x42
.eqv KEY_F10 0x43
.eqv KEY_F11 0x44
.eqv KEY_F12 0x45
.eqv KEY_PRINT_SCREEN 0x46
.eqv KEY_SCROLL_LOCK 0x47
.eqv KEY_PAUSE 0x48
.eqv KEY_INSERT 0x49
.eqv KEY_HOME 0x4A
.eqv KEY_PAGE_UP 0x4B
.eqv KEY_DELETE 0x4C
.eqv KEY_END 0x4D
.eqv KEY_PAGE_DOWN 0x4E
.eqv KEY_ARROW_RIGHT 0x4F
.eqv KEY_ARROW_LEFT 0x50
.eqv KEY_ARROW_DOWN 0x51
.eqv KEY_ARROW_UP 0x52
.eqv KEY_NUM_LOCK 0x53
.eqv KEY_NUMPAD_DIVIDE 0x54
.eqv KEY_NUMPAD_MULTIPLY 0x55
.eqv KEY_NUMPAD_SUBTRACT 0x56
.eqv KEY_NUMPAD_ADD 0x57
.eqv KEY_NUMPAD_ENTER 0x58
.eqv KEY_NUMPAD_1 0x59
.eqv KEY_NUMPAD_2 0x5A
.eqv KEY_NUMPAD_3 0x5B
.eqv KEY_NUMPAD_4 0x5C
.eqv KEY_NUMPAD_5 0x5D
.eqv KEY_NUMPAD_6 0x5E
.eqv KEY_NUMPAD_7 0x5F
.eqv KEY_NUMPAD_8 0x60
.eqv KEY_NUMPAD_9 0x61
.eqv KEY_NUMPAD_0 0x62
.eqv KEY_NUMPAD_DECIMAL 0x63
.eqv KEY_INTL_BACKSLASH 0x64
.eqv KEY_CONTEXT_MENU 0x65
.eqv KEY_NUMPAD_EQUAL 0x67
.eqv KEY_F13 0x68
.eqv KEY_F14 0x69
.eqv KEY_F15 0x6A
.eqv KEY_F16 0x6B
.eqv KEY_F17 0x6C
.eqv KEY_F18 0x6D
.eqv KEY_F19 0x6E
.eqv KEY_F20 0x6F
.eqv KEY_F21 0x70
.eqv KEY_F22 0x71
.eqv KEY_F23 0x72
.eqv KEY_F24 0x73
.eqv KEY_HELP 0x75
.eqv KEY_NUMPAD_COMMA 0x85
.eqv KEY_INTL_RO 0x87
.eqv KEY_KANA_MODE 0x88
.eqv KEY_INTL_YEN 0x89
.eqv KEY_CONVERT 0x8A
.eqv KEY_NON_CONVERT 0x8B
.eqv KEY_LANG_1 0x90
.eqv KEY_LANG_2 0x91
.eqv KEY_LANG_3 0x92
.eqv KEY_LANG_4 0x93
.eqv KEY_LANG_5 0x94
.eqv KEY_NUMPAD_PAREN_LEFT 0xB6
.eqv KEY_NUMPAD_PAREN_RIGHT 0xB7
.eqv KEY_NUMPAD_BACKSPACE 0xBB
.eqv KEY_CONTROL_LEFT 0xE0
.eqv KEY_SHIFT_LEFT 0xE1
.eqv KEY_ALT_LEFT 0xE2
.eqv KEY_META_LEFT 0xE3
.eqv KEY_CONTROL_RIGHT 0xE4
.eqv KEY_SHIFT_RIGHT 0xE5
.eqv KEY_ALT_RIGHT 0xE6
.eqv KEY_META_RIGHT 0xE71
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133