// File: /workspace/github_cpp_makefile_star2_O1/7shi[P]8086run/v1/main.cpp
// Function: bios(int)
void bios(int n) {
    void intr(int);
    static uint8_t buf[512];
    switch (n) {
        case 0x00: // #DE
            error("#DE: division exception");
            break;
        case 0x08: // timer
        {
            uint16_t low = read16(&mem[0x46c]);
            if (!++low) {
                uint16_t high = read16(&mem[0x46e]);
                if (++high >= 24) {
                    high %= 24;
                    mem[0x470] = 1;
                }
                write16(&mem[0x46e], high);
            }
            write16(&mem[0x46c], low);
            intr(0x1c);
            return;
        }
        case 0x09: // keyboard
            while (kbhit()) {
                int head = read16(&mem[0x41a]) - 0x1e;
                int tail = read16(&mem[0x41c]) - 0x1e;
                int next = (tail + 2) & 0x1f;
                if (next == head) break;
                int ch = getch();
                if (ch != EOF && kbscan[ch]) {
                    mem[0x41e + tail] = ch;
                    mem[0x41f + tail] = kbscan[ch];
                    write16(&mem[0x41c], 0x1e + next);
                }
            }
            return;
        case 0x10: // video
            switch (AH) {
                case 0x0e:
                    if (write(STDOUT_FILENO, &AL, 1));
                    return;
            }
            return; // ignore
        case 0x11: // get equipment list
            AX = disks[1].f ? 0x41 : 1;
            return;
        case 0x12: // get memory size
            AX = 640;
            return;
        case 0x13: // disk
        {
            if (DL > 1 || !disks[DL].f) {
                CF = 1; // error
                AH = 1; // invalid
                return;
            }
            Disk *d = &disks[DL];
            int c = CH | ((CL & 0xc0) << 2), s = (CL & 0x3f) - 1;
            int lba = d->s * (d->h * c + DH) + s;
            switch (AH) {
                case 0x00: // reset disk system
                    AH = CF = 0;
                    return;
                case 0x02: // read sectors
                case 0x03: // write sectors
                    if (c >= d->c || DH >= d->h
                            || s < 0 || s >= d->s) {
                        CF = 1; // error
                        AH = 4; // sector
                        return;
                    }
                    fseek(d->f, lba << 9, SEEK_SET);
                    if (AH == 2) {
                        if (fread(&ES[BX], 512, AL, d->f) < 1) {
                            memset(&ES[BX], 0, AL << 9);
                        }
                    } else {
                        fwrite(&ES[BX], 512, AL, d->f);
                    }
                    AH = CF = 0;
                    return;
                case 0x05: // format
                    fseek(d->f, (lba - s) << 9, SEEK_SET);
                    for (int i = 0; i < d->s; ++i) {
                        fwrite(&buf, 512, 1, d->f);
                    }
                    AH = CF = 0;
                    return;
                case 0x08: // get drive params
                    AX = 0;
                    BL = d->type;
                    CH = d->c - 1;
                    CL = d->s | ((d->c >> 2) & 0xc0);
                    DH = d->h - 1;
                    DL = 1;
                    ES = DI = 0;
                    CF = 0;
                    return;
                case 0x15: // get disk type
                    AH = 1;
                    CF = 0;
                    return;
                case 0x17: // set disk type
                    CF = 0; // ignore
                    return;
                case 0x18: // set media type
                    d->c = c + 1;
                    d->s = s + 1;
                    ES = DI = 0;
                    AH = CF = 0;
                    return;
            }
            CF = 1;
            return;
        }
        case 0x15: // system
            switch (AH) {
                case 0x88: // get extended memory size
                    CF = 0;
                    AX = 0;
                    return;
            }
            break;
        case 0x16: // keyboard
        {
            int head = read16(&mem[0x41a]);
            int tail = read16(&mem[0x41c]);
            switch (AH) {
                case 0x00: // get keystroke
                    while (head == tail) {
                        bios(9);
                        tail = read16(&mem[0x41c]);
                    }
                    AX = read16(&mem[0x400 + head]);
                    write16(&mem[0x41a], 0x1e + ((head - 0x1c) & 0x1f));
                    return;
                case 0x01: // check for keystroke
                    if ((ZF = head == tail)) {
                        AX = 0; // empty
                    } else {
                        AX = read16(&mem[0x400 + head]);
                    }
                    return;
            }
            break;
        }
        case 0x1a: // time
            switch (AH) {
                case 0x00: // get system time
                    AL = mem[0x470];
                    CX = read16(&mem[0x46e]);
                    DX = read16(&mem[0x46c]);
                    mem[0x470] = 0;
                    return;
                case 0x01: // set system time
                    write16(&mem[0x46e], CX);
                    write16(&mem[0x46c], DX);
                    mem[0x470] = 0;
                    return;
                case 0x02: // get RTC time
                case 0x04: // get RTC date
                {
                    time_t t = time(NULL);
                    tm *lt = localtime(&t);
                    if (AH == 2) {
                        CH = bcd(lt->tm_hour);
                        CL = bcd(lt->tm_min);
                        DH = bcd(lt->tm_sec);
                        DL = lt->tm_isdst == 1 ? 1 : 0;
                    } else {
                        CH = bcd(lt->tm_year / 100 + 19);
                        CL = bcd(lt->tm_year % 100);
                        DH = bcd(lt->tm_mon + 1);
                        DL = bcd(lt->tm_mday);
                    }
                    CF = 0;
                    return;
                }
                case 0x03: // set RTC time
                case 0x05: // set RTC date
                    return; // ignore
            }
            break;
        case 0x1c: // timer handler
            return;
    }
    error("not implemented: int %02x,%02x", n, AH);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edi, %esi
leal -0x8(%rsi), %eax
cmpl $0x14, %eax
ja 0x1f86
leaq 0x577c(%rip), %rcx      # 0x7004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzwl 0x7d84(%rip), %eax      # 0x961c
incw %ax
jne 0x18d4
movzwl 0x7d7a(%rip), %ecx      # 0x961e
incl %ecx
cmpw $0x18, %cx
jb 0x18c7
movzwl %cx, %edx
imull $0xaaab, %edx, %edx     # imm = 0xAAAB
shrl $0x11, %edx
andl $-0x8, %edx
leal (%rdx,%rdx,2), %edx
subl %edx, %ecx
movb $0x1, 0x7d59(%rip)      # 0x9620
movb %cl, 0x7d51(%rip)       # 0x961e
movb $0x0, 0x7d4b(%rip)      # 0x961f
movw %ax, 0x7d41(%rip)       # 0x961c
movl $0x1c, %edi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1fb0
movq 0x1278f6(%rip), %rax    # 0x1291f0
movzbl (%rax), %eax
cmpq $0x5, %rax
ja 0x1f98
leaq 0x574a(%rip), %rcx      # 0x7058
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %edi, %edi
callq 0x1090
movq %rsp, %rdi
movq %rax, (%rdi)
callq 0x1070
movq 0x1278c0(%rip), %rcx    # 0x1291f0
cmpb $0x2, (%rcx)
jne 0x1c7c
movslq 0x8(%rax), %rcx
imulq $0x66666667, %rcx, %rdx # imm = 0x66666667
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rdx
addl %esi, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
subl %edx, %ecx
orl %esi, %ecx
movq 0x127892(%rip), %rdx    # 0x1291f8
movb %cl, (%rdx)
movslq 0x4(%rax), %rcx
imulq $0x66666667, %rcx, %rdx # imm = 0x66666667
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rdx
addl %esi, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
subl %edx, %ecx
orl %esi, %ecx
movq 0x127843(%rip), %rdx    # 0x1291d8
movb %cl, (%rdx)
movslq (%rax), %rcx
imulq $0x66666667, %rcx, %rdx # imm = 0x66666667
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rdx
addl %esi, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
subl %edx, %ecx
orl %esi, %ecx
movq 0x12783d(%rip), %rdx    # 0x129200
movb %cl, (%rdx)
cmpl $0x1, 0x20(%rax)
sete %al
jmp 0x1d6e
movzbl 0x7bf2(%rip), %ebx      # 0x95ca
movzbl 0x7beb(%rip), %r14d     # 0x95cb
shll $0x8, %r14d
orq %rbx, %r14
movzwl 0x7bde(%rip), %eax      # 0x95cc
movq 0x1277fb(%rip), %rcx    # 0x1291f0
movzbl (%rcx), %ecx
cmpl $0x1, %ecx
je 0x1c53
testl %ecx, %ecx
jne 0x1f98
cmpw %ax, %r14w
jne 0x1a23
movl $0x9, %edi
callq 0x1868
cmpw 0x7bab(%rip), %r14w     # 0x95cc
je 0x1a0f
leaq 0x7786(%rip), %rax      # 0x91b0
movzwl 0x400(%r14,%rax), %eax
movw %ax, 0x127786(%rip)     # 0x1291c0
addb $0x4, %bl
andb $0x1f, %bl
addb $0x1e, %bl
movb %bl, 0x7b81(%rip)       # 0x95ca
movb $0x0, 0x7b7b(%rip)      # 0x95cb
jmp 0x1dc8
xorl %eax, %eax
cmpq $0x0, 0x127919(%rip)    # 0x129378
setne %al
shll $0x6, %eax
incl %eax
movw %ax, 0x127752(%rip)     # 0x1291c0
jmp 0x1dc8
movw $0x280, 0x127744(%rip)  # imm = 0x280
jmp 0x1dc8
leaq 0x7658(%rip), %rbx      # 0x90e0
leaq 0x7721(%rip), %r14      # 0x91b0
callq 0x12ed
testl %eax, %eax
je 0x1dc8
movzwl 0x7b27(%rip), %ebp      # 0x95ca
addl $-0x1e, %ebp
movzbl 0x7b1e(%rip), %r12d     # 0x95cc
leal 0x4(%r12), %r15d
andl $0x1f, %r15d
cmpl %ebp, %r15d
je 0x1dc8
movzbl 0x7b05(%rip), %r13d     # 0x95cd
callq 0x129c
cmpl $-0x1, %eax
je 0x1b04
movslq %eax, %rcx
movb (%rcx,%rbx), %cl
testb %cl, %cl
je 0x1b04
shll $0x8, %r13d
orl %r12d, %r13d
movb %al, 0x400(%r13,%r14)
movb %cl, 0x401(%r13,%r14)
leal 0x1e(%r15), %eax
movb %al, 0x7acf(%rip)       # 0x95cc
movb $0x0, 0x7ac9(%rip)      # 0x95cd
cmpl %ebp, %r15d
jne 0x1a8f
jmp 0x1dc8
movq 0x1276db(%rip), %rax    # 0x1291f0
cmpb $-0x78, (%rax)
jne 0x1f98
movb $0x0, 0x1276f3(%rip)    # 0x129218
movw $0x0, 0x127692(%rip)    # 0x1291c0
jmp 0x1dc8
movq 0x1276b6(%rip), %rax    # 0x1291f0
cmpb $0xe, (%rax)
jne 0x1dc8
movq 0x127686(%rip), %rsi    # 0x1291d0
movl $0x1, %edx
movl $0x1, %edi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1030
movq 0x127672(%rip), %rax    # 0x1291e0
movzbl (%rax), %eax
cmpq $0x1, %rax
ja 0x1c3d
leaq (%rax,%rax,2), %rax
leaq 0x1277da(%rip), %rcx    # 0x129360
movq (%rcx,%rax,8), %rdi
testq %rdi, %rdi
je 0x1c3d
leaq (%rcx,%rax,8), %r14
movq 0x12765a(%rip), %rax    # 0x1291f8
movq 0x127633(%rip), %rcx    # 0x1291d8
movzbl (%rcx), %ecx
leal (,%rcx,4), %edx
movb (%rax), %dl
andl $0x3f, %ecx
movq 0x127635(%rip), %rax    # 0x1291f0
movzbl (%rax), %r8d
cmpl $0x14, %r8d
jg 0x1dd7
cmpl $0x8, %r8d
ja 0x1eeb
movl 0x10(%r14), %r10d
movl 0x14(%r14), %r9d
movl %edx, %esi
imull %r10d, %esi
movq 0x127618(%rip), %r11    # 0x129200
movzbl (%r11), %r11d
addl %r11d, %esi
imull %r9d, %esi
movl %r8d, %r8d
leaq 0x5473(%rip), %rbx      # 0x7070
movslq (%rbx,%r8,4), %r8
addq %rbx, %r8
jmpq *%r8
cmpl 0xc(%r14), %edx
jge 0x1c2e
cmpl %r11d, %r10d
setle %dl
testl %ecx, %ecx
sete %r8b
orb %dl, %r8b
cmpl %r9d, %ecx
setg %dl
orb %r8b, %dl
cmpb $0x1, %dl
jne 0x1ef7
movb $0x1, 0x1275e3(%rip)    # 0x129218
movb $0x4, (%rax)
jmp 0x1dc8
movb $0x1, %al
movb %al, 0x1275d3(%rip)     # 0x129218
movq 0x1275a4(%rip), %rcx    # 0x1291f0
movb %al, (%rcx)
jmp 0x1dc8
cmpw %ax, %r14w
sete 0x1275b7(%rip)          # 0x129215
jne 0x1c67
xorl %eax, %eax
jmp 0x1a67
leaq 0x7542(%rip), %rax      # 0x91b0
movzwl 0x400(%r14,%rax), %eax
jmp 0x1a67
movslq 0x14(%rax), %rcx
imulq $0x51eb851f, %rcx, %rcx # imm = 0x51EB851F
movq %rcx, %rdx
sarq $0x25, %rdx
shrq $0x3f, %rcx
addl %edx, %ecx
addl $0x13, %ecx
movslq %ecx, %rcx
imulq $0x66666667, %rcx, %rdx # imm = 0x66666667
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rdx
addl %esi, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
subl %edx, %ecx
orl %esi, %ecx
movq 0x127535(%rip), %rdx    # 0x1291f8
movb %cl, (%rdx)
movslq 0x14(%rax), %rcx
imulq $0x51eb851f, %rcx, %rdx # imm = 0x51EB851F
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x25, %rdx
addl %esi, %edx
imull $0x64, %edx, %edx
subl %edx, %ecx
movslq %ecx, %rcx
imulq $0x66666667, %rcx, %rdx # imm = 0x66666667
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rdx
addl %esi, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
subl %edx, %ecx
orl %esi, %ecx
movq 0x1274ca(%rip), %rdx    # 0x1291d8
movb %cl, (%rdx)
movl 0x10(%rax), %ecx
leal 0x1(%rcx), %edx
movslq %edx, %rdx
imulq $0x66666667, %rdx, %rdx # imm = 0x66666667
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rdx
addl %esi, %edx
movl %edx, %esi
shll $0x4, %esi
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
negl %edx
addl %edx, %ecx
incl %ecx
orl %esi, %ecx
movq 0x1274ba(%rip), %rdx    # 0x129200
movb %cl, (%rdx)
movslq 0xc(%rax), %rax
imulq $0x66666667, %rax, %rcx # imm = 0x66666667
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x22, %rcx
addl %edx, %ecx
movl %ecx, %edx
shll $0x4, %edx
addl %ecx, %ecx
leal (%rcx,%rcx,4), %ecx
subl %ecx, %eax
orl %edx, %eax
movq 0x12746b(%rip), %rcx    # 0x1291e0
movb %al, (%rcx)
movb $0x0, 0x12749a(%rip)    # 0x129218
jmp 0x1dc8
movzwl 0x12743b(%rip), %eax    # 0x1291c2
movw %ax, 0x7890(%rip)       # 0x961e
movzwl 0x12742f(%rip), %eax    # 0x1291c4
movb %al, 0x7881(%rip)       # 0x961c
movb %ah, 0x787c(%rip)       # 0x961d
jmp 0x1dc1
movb 0x7877(%rip), %al       # 0x9620
movq 0x127420(%rip), %rcx    # 0x1291d0
movb %al, (%rcx)
movl 0x7864(%rip), %eax      # 0x961c
roll $0x10, %eax
movl %eax, 0x127401(%rip)    # 0x1291c2
movb $0x0, 0x7858(%rip)      # 0x9620
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x15, %r8d
je 0x1ee3
cmpl $0x17, %r8d
je 0x1d77
cmpl $0x18, %r8d
jne 0x1eeb
incl %edx
movl %edx, 0xc(%r14)
movl %ecx, 0x14(%r14)
xorl %ecx, %ecx
movw %cx, 0x1273ca(%rip)     # 0x1291ce
leaq 0x73a5(%rip), %rdx      # 0x91b0
movq %rdx, 0x12750e(%rip)    # 0x129320
movw %cx, 0x12750f(%rip)     # 0x129328
jmp 0x1e1d
xorl %ecx, %ecx
movb %cl, 0x1273f5(%rip)     # 0x129218
movb %cl, (%rax)
jmp 0x1dc8
shll $0x9, %esi
movslq %esi, %rsi
xorl %ebp, %ebp
xorl %edx, %edx
callq 0x10b0
cmpl $0x0, 0x14(%r14)
jle 0x1f70
leaq 0x127548(%rip), %rbx    # 0x129390
movq (%r14), %rcx
movl $0x200, %esi            # imm = 0x200
movl $0x1, %edx
movq %rbx, %rdi
callq 0x1170
incl %ebp
cmpl 0x14(%r14), %ebp
jl 0x1e48
jmp 0x1f70
xorl %eax, %eax
movw %ax, 0x12734d(%rip)     # 0x1291c0
movb 0x8(%r14), %cl
movq 0x12736a(%rip), %rdx    # 0x1291e8
movb %cl, (%rdx)
movb 0xc(%r14), %cl
decb %cl
movq 0x12736b(%rip), %rdx    # 0x1291f8
movb %cl, (%rdx)
movl 0xc(%r14), %ecx
shrl $0x2, %ecx
andl $0xc0, %ecx
orl 0x14(%r14), %ecx
movq 0x127331(%rip), %rdx    # 0x1291d8
movb %cl, (%rdx)
movb 0x10(%r14), %cl
decb %cl
movq 0x12734a(%rip), %rdx    # 0x129200
movb %cl, (%rdx)
movq 0x127321(%rip), %rcx    # 0x1291e0
movb $0x1, (%rcx)
movw %ax, 0x127305(%rip)     # 0x1291ce
leaq 0x72e0(%rip), %rcx      # 0x91b0
movq %rcx, 0x127449(%rip)    # 0x129320
movw %ax, 0x12744a(%rip)     # 0x129328
jmp 0x1d77
movb $0x1, (%rax)
jmp 0x1d77
movb $0x1, 0x127326(%rip)    # 0x129218
jmp 0x1dc8
leal (%rcx,%rsi), %eax
addl $0x7fffff, %eax         # imm = 0x7FFFFF
shll $0x9, %eax
movslq %eax, %rsi
xorl %edx, %edx
callq 0x10b0
movq 0x1272dd(%rip), %rax    # 0x1291f0
movzwl 0x1272ac(%rip), %edi    # 0x1291c6
movq 0x1272af(%rip), %rcx    # 0x1291d0
movzbl (%rcx), %edx
movq (%r14), %rcx
addq 0x1273f2(%rip), %rdi    # 0x129320
cmpb $0x2, (%rax)
jne 0x1f66
movl $0x200, %esi            # imm = 0x200
callq 0x1150
testq %rax, %rax
jne 0x1f70
movzwl 0x12727d(%rip), %edi    # 0x1291c6
addq 0x1273d0(%rip), %rdi    # 0x129320
movq 0x127279(%rip), %rax    # 0x1291d0
movzbl (%rax), %edx
shll $0x9, %edx
xorl %esi, %esi
callq 0x1040
jmp 0x1f70
movl $0x200, %esi            # imm = 0x200
callq 0x1170
xorl %eax, %eax
movb %al, 0x1272a0(%rip)     # 0x129218
movq 0x127271(%rip), %rcx    # 0x1291f0
movb %al, (%rcx)
jmp 0x1dc8
testl %esi, %esi
jne 0x1f98
leaq 0x572a(%rip), %rdi      # 0x76bb
xorl %eax, %eax
callq 0x16e5
movq 0x127251(%rip), %rax    # 0x1291f0
movzbl (%rax), %edx
leaq 0x572a(%rip), %rdi      # 0x76d3
xorl %eax, %eax
callq 0x16e5