// File: 7shi[P]8086run/v2/keyboard.cpp
// Function: decodeKey(int)
uint16_t decodeKey(int ch) {
    if (ch == EOF) return 0;
#ifdef _WIN32
    static int stroke = -1;
    if (stroke == 0xe0 || stroke == 0) {
        stroke = EOF;
        return ch << 8;
    }
    if (ch == 0xe0 || ch == 0) {
        stroke = ch;
        return 0;
    }
    stroke = EOF;
#else
    static std::string stroke;
    if (!stroke.empty()) {
        stroke += ch;
        if (stroke == "\x1bO") { // NumLock
            return 0;
        } else if (stroke == "\x1bOP") { // NumLock (ignore)
            stroke.clear();
            return 0;
        } else if (stroke == "\x1b[") {
            return 0;
        } else if (stroke == "\x1b[A") { // up
            stroke.clear();
            return 'H' << 8;
        } else if (stroke == "\x1b[B") { // down
            stroke.clear();
            return 'P' << 8;
        } else if (stroke == "\x1b[C") { // right
            stroke.clear();
            return 'M' << 8;
        } else if (stroke == "\x1b[D") { // left
            stroke.clear();
            return 'K' << 8;
        } else if (stroke.length() > 2 && isdigit(ch)) { // F*
            return 0;
        } else if (stroke.length() > 3 && ch == '~') { // F*
            int num = atoi(&stroke[2]);
            stroke.clear();
            if (11 <= num && num <= 15) return (0x3b + (num - 11)) << 8;
            if (17 <= num && num <= 21) return (0x40 + (num - 17)) << 8;
            if (23 <= num && num <= 24) return (0x85 + (num - 23)) << 8;
            return 0;
        }
    }
    if (ch == 0x1b) {
        stroke = "\x1b";
        return 0;
    }
    stroke.clear();
#endif
    if (ch < 128 && kbscan[ch]) {
        return (kbscan[ch] << 8) | ch;
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movl %edi, -0x8(%rbp)
cmpl $-0x1, -0x8(%rbp)
jne 0x858c
movw $0x0, -0x2(%rbp)
jmp 0x889b
cmpb $0x0, 0x12508d(%rip)    # 0x12d620
jne 0x85d8
leaq 0x125084(%rip), %rdi    # 0x12d620
callq 0x2270
cmpl $0x0, %eax
je 0x85d8
leaq 0x125053(%rip), %rdi    # 0x12d600
callq 0x21d0
movq 0x4a17(%rip), %rdi      # 0xcfd0
leaq 0x125040(%rip), %rsi    # 0x12d600
leaq 0x4b91(%rip), %rdx      # 0xd158
callq 0x20d0
leaq 0x12504d(%rip), %rdi    # 0x12d620
callq 0x20a0
leaq 0x125021(%rip), %rdi    # 0x12d600
callq 0x2250
testb $0x1, %al
jne 0x8833
movl -0x8(%rbp), %eax
leaq 0x12500a(%rip), %rdi    # 0x12d600
movsbl %al, %esi
callq 0x2090
leaq 0x124ffb(%rip), %rdi    # 0x12d600
leaq 0x21f8(%rip), %rsi      # 0xa804
callq 0x88b0
testb $0x1, %al
jne 0x8617
jmp 0x8622
movw $0x0, -0x2(%rbp)
jmp 0x889b
leaq 0x124fd7(%rip), %rdi    # 0x12d600
leaq 0x21d7(%rip), %rsi      # 0xa807
callq 0x88b0
testb $0x1, %al
jne 0x863b
jmp 0x8652
leaq 0x124fbe(%rip), %rdi    # 0x12d600
callq 0x21a0
movw $0x0, -0x2(%rbp)
jmp 0x889b
leaq 0x124fa7(%rip), %rdi    # 0x12d600
leaq 0x21ab(%rip), %rsi      # 0xa80b
callq 0x88b0
testb $0x1, %al
jne 0x866b
jmp 0x8676
movw $0x0, -0x2(%rbp)
jmp 0x889b
leaq 0x124f83(%rip), %rdi    # 0x12d600
leaq 0x218a(%rip), %rsi      # 0xa80e
callq 0x88b0
testb $0x1, %al
jne 0x868f
jmp 0x86a6
leaq 0x124f6a(%rip), %rdi    # 0x12d600
callq 0x21a0
movw $0x4800, -0x2(%rbp)     # imm = 0x4800
jmp 0x889b
leaq 0x124f53(%rip), %rdi    # 0x12d600
leaq 0x215e(%rip), %rsi      # 0xa812
callq 0x88b0
testb $0x1, %al
jne 0x86bf
jmp 0x86d6
leaq 0x124f3a(%rip), %rdi    # 0x12d600
callq 0x21a0
movw $0x5000, -0x2(%rbp)     # imm = 0x5000
jmp 0x889b
leaq 0x124f23(%rip), %rdi    # 0x12d600
leaq 0x2132(%rip), %rsi      # 0xa816
callq 0x88b0
testb $0x1, %al
jne 0x86ef
jmp 0x8706
leaq 0x124f0a(%rip), %rdi    # 0x12d600
callq 0x21a0
movw $0x4d00, -0x2(%rbp)     # imm = 0x4D00
jmp 0x889b
leaq 0x124ef3(%rip), %rdi    # 0x12d600
leaq 0x2106(%rip), %rsi      # 0xa81a
callq 0x88b0
testb $0x1, %al
jne 0x871f
jmp 0x8736
leaq 0x124eda(%rip), %rdi    # 0x12d600
callq 0x21a0
movw $0x4b00, -0x2(%rbp)     # imm = 0x4B00
jmp 0x889b
leaq 0x124ec3(%rip), %rdi    # 0x12d600
callq 0x2220
cmpq $0x2, %rax
jbe 0x8760
movl -0x8(%rbp), %edi
callq 0x20e0
cmpl $0x0, %eax
je 0x8760
movw $0x0, -0x2(%rbp)
jmp 0x889b
leaq 0x124e99(%rip), %rdi    # 0x12d600
callq 0x2220
cmpq $0x3, %rax
jbe 0x8821
cmpl $0x7e, -0x8(%rbp)
jne 0x8821
leaq 0x124e79(%rip), %rdi    # 0x12d600
movl $0x2, %esi
callq 0x2290
movq %rax, %rdi
callq 0x2230
movl %eax, -0xc(%rbp)
leaq 0x124e5d(%rip), %rdi    # 0x12d600
callq 0x21a0
movl $0xb, %eax
cmpl -0xc(%rbp), %eax
jg 0x87cd
cmpl $0xf, -0xc(%rbp)
jg 0x87cd
movl -0xc(%rbp), %eax
subl $0xb, %eax
addl $0x3b, %eax
shll $0x8, %eax
movw %ax, -0x2(%rbp)
jmp 0x889b
movl $0x11, %eax
cmpl -0xc(%rbp), %eax
jg 0x87f2
cmpl $0x15, -0xc(%rbp)
jg 0x87f2
movl -0xc(%rbp), %eax
subl $0x11, %eax
addl $0x40, %eax
shll $0x8, %eax
movw %ax, -0x2(%rbp)
jmp 0x889b
movl $0x17, %eax
cmpl -0xc(%rbp), %eax
jg 0x8819
cmpl $0x18, -0xc(%rbp)
jg 0x8819
movl -0xc(%rbp), %eax
subl $0x17, %eax
addl $0x85, %eax
shll $0x8, %eax
movw %ax, -0x2(%rbp)
jmp 0x889b
movw $0x0, -0x2(%rbp)
jmp 0x889b
jmp 0x8823
jmp 0x8825
jmp 0x8827
jmp 0x8829
jmp 0x882b
jmp 0x882d
jmp 0x882f
jmp 0x8831
jmp 0x8833
cmpl $0x1b, -0x8(%rbp)
jne 0x8854
leaq 0x124dc0(%rip), %rdi    # 0x12d600
leaq 0x1fd7(%rip), %rsi      # 0xa81e
callq 0x21c0
movw $0x0, -0x2(%rbp)
jmp 0x889b
leaq 0x124da5(%rip), %rdi    # 0x12d600
callq 0x21a0
cmpl $0x80, -0x8(%rbp)
jge 0x8895
movslq -0x8(%rbp), %rcx
leaq 0x48ec(%rip), %rax      # 0xd160
cmpb $0x0, (%rax,%rcx)
je 0x8895
movslq -0x8(%rbp), %rcx
leaq 0x48db(%rip), %rax      # 0xd160
movzbl (%rax,%rcx), %eax
shll $0x8, %eax
orl -0x8(%rbp), %eax
movw %ax, -0x2(%rbp)
jmp 0x889b
movw $0x0, -0x2(%rbp)
movw -0x2(%rbp), %ax
addq $0x10, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop