// File: /workspace/github_cpp_makefile_star2_O3/bloody76[P]Chip8-Disassembler/src/disassembler.cc
// Function: pretty_print()
void pretty_print()
{
    for (int i = 0; i < size; i += 2)
    {
        auto it = functions.find(i + 0x200);
        if (it != functions.end())
        {
            std::cout << "\t";
            if (it->first == 0x200)
                std::cout << "start";
            else
            {
                if (it->second == Type::SUB)
                    std::cout << "sub_";
                else
                    std::cout << "adr_";
                std::cout << it->first;
            }
            std::cout  << ":" << std::endl;
        }
        uint16 op = (mem[i] << 8) | mem[i + 1];
        {
            std::cout << "0x" << std::hex << op << std::dec << "|\t\t";
            switch ((op & 0xF000) >> 12)
            {
                case 0:
                    if ((op & 0x0FFF) == 0xE0)
                        std::cout << "CLS";
                    else if ((op & 0x0FFF) == 0xEE)
                        std::cout << "RET";
                    else
                        std::cout << "GOTO adr:" << (op & 0x0FFF);
                    break;
                case 1:
                    std::cout << "JP " << (op & 0x0FFF);
                    break;
                case 2:
                    std::cout << "CALL sub_" << (op & 0x0FFF);
                    break;
                case 3:
                    std::cout << "SE V" << ((op & 0x0F00) >> 8) << ", " << (op & 0x00FF);
                    break;
                case 4:
                    std::cout << "SNE V" << ((op & 0x0F00) >> 8) << ", " << (op & 0x00FF);
                    break;
                case 5:
                    std::cout << "SE V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                    break;
                case 6:
                    std::cout << "LD V" << ((op & 0x0F00) >> 8) << ", " << (op & 0x00FF);
                    break;
                case 7:
                    std::cout << "ADD V" << ((op & 0x0F00) >> 8) << ", " << (op & 0x00FF);
                    break;
                case 8:
                    switch (op & 0x000F)
                    {
                        case 0:
                            std::cout << "LD V" << ((op & 0x00F0) >> 4) << ", V" << ((op & 0x0F00) >> 8);
                            break;
                        case 1:
                            std::cout << "OR V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                            break;
                        case 2:
                            std::cout << "AND V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                            break;
                        case 3:
                            std::cout << "XOR V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                            break;
                        case 4:
                            std::cout << "ADD V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                            break;
                        case 5:
                            std::cout << "SUB V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                            break;
                        case 6:
                            std::cout << "SHR V" << ((op & 0x0F00) >> 8);
                            break;
                        case 7:
                            std::cout << "SUBN V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                            break;
                        case 0xE:
                            std::cout << "SHL V" << ((op & 0x0F00) >> 8);
                            break;
                    }
                    break;
                case 9:
                    std::cout << "SNE V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4);
                    break;
                case 0xA:
                    std::cout << "LD I, " << (op & 0x0FFF);
                    break;
                case 0xB:
                    std::cout << "JP V0, " << (op & 0x0FFF);
                    break;
                case 0xC:
                    std::cout << "RND V" << ((op & 0x0F00) >> 8) << ", " << (op & 0x00FF);
                    break;
                case 0xD:
                    std::cout << "DRW V" << ((op & 0x0F00) >> 8) << ", V" << ((op & 0x00F0) >> 4) << ", " << (op & 0x00FF);
                    break;
                case 0xE:
                    switch (op & 0x00FF)
                    {
                        case 0x9E:
                            std::cout << "SKP V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0xA1:
                            std::cout << "SKNP V" << ((op & 0x0F00) >> 8);
                            break;
                    }
                    break;
                case 0xF:
                    switch (op & 0x00FF)
                    {
                        case 0x07:
                            std::cout << "LD V" << ((op & 0x0F00) >> 8) << ", DT";
                            break;
                        case 0x0A:
                            std::cout << "LD V" << ((op & 0x0F00) >> 8) << ", K";
                            break;
                        case 0x15:
                            std::cout << "LD DT, V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0x18:
                            std::cout << "LD ST, V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0x1E:
                            std::cout << "ADD I, V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0x29:
                            std::cout << "LD F, V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0x33:
                            std::cout << "LD B, V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0x55:
                            std::cout << "LD [I], V" << ((op & 0x0F00) >> 8);
                            break;
                        case 0x65:
                            std::cout << "LD V" << ((op & 0x0F00) >> 8) << ", [i]";
                            break;
                    }
                    break;
                default:
                    std::cout << op;
                    break;
            }
            std::cout << std::endl;
        }
    }
}

// Assembly:
cmpq $0x0, 0x3c77(%rip)      # 0x6188
jle 0x2bd5
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
xorl %r12d, %r12d
movq 0x3aa4(%rip), %rbx      # 0x5fd0
leaq 0x1ad1(%rip), %r14      # 0x4004
leaq 0x3c1e(%rip), %r15      # 0x6158
movq 0x3c1f(%rip), %rax      # 0x6160
testq %rax, %rax
je 0x261f
leal 0x200(%r12), %ecx
movq %r15, %r13
xorl %edx, %edx
cmpw %cx, 0x20(%rax)
setb %dl
cmovaeq %rax, %r13
movq 0x10(%rax,%rdx,8), %rax
testq %rax, %rax
jne 0x2555
cmpq %r15, %r13
je 0x261f
cmpw 0x20(%r13), %cx
jb 0x261f
movl $0x1, %edx
movq %rbx, %rdi
leaq 0x1b1a(%rip), %rsi      # 0x40a9
callq 0x2180
cmpw $0x200, 0x20(%r13)      # imm = 0x200
jne 0x25b3
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1aed(%rip), %rsi      # 0x4099
callq 0x2180
jmp 0x25e4
cmpl $0x0, 0x24(%r13)
leaq 0x1ae0(%rip), %rsi      # 0x409f
leaq 0x1b00(%rip), %rax      # 0x40c6
cmoveq %rax, %rsi
movl $0x4, %edx
movq %rbx, %rdi
callq 0x2180
movzwl 0x20(%r13), %esi
movq %rbx, %rdi
callq 0x20d0
movl $0x1, %edx
movq %rbx, %rdi
leaq 0x1ac8(%rip), %rsi      # 0x40bb
callq 0x2180
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2130
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
movq 0x3b5a(%rip), %rax      # 0x6180
movzbl (%rax,%r12), %r13d
shll $0x8, %r13d
movzbl 0x1(%rax,%r12), %ebp
orq %rbp, %r13
movl $0x2, %edx
movq %rbx, %rdi
leaq 0x1a5d(%rip), %rsi      # 0x40a4
callq 0x2180
movq (%rbx), %rax
movq -0x18(%rax), %rax
movl 0x18(%rbx,%rax), %ecx
andl $-0x4b, %ecx
orl $0x8, %ecx
movl %ecx, 0x18(%rbx,%rax)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x20d0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
movl $0x3, %edx
movq %rax, %rdi
leaq 0x1a17(%rip), %rsi      # 0x40a7
callq 0x2180
movl %r13d, %eax
shrl $0xc, %eax
movslq (%r14,%rax,4), %rax
addq %r14, %rax
jmpq *%rax
andl $0xfff, %r13d           # imm = 0xFFF
cmpl $0xee, %r13d
je 0x29d9
cmpl $0xe0, %r13d
jne 0x29ed
movl $0x3, %edx
movq %rbx, %rdi
leaq 0x19d7(%rip), %rsi      # 0x40ab
jmp 0x2a9c
cmpl $0xa1, %ebp
je 0x29c5
cmpl $0x9e, %ebp
jne 0x2b8f
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1a21(%rip), %rsi      # 0x4121
jmp 0x2b77
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x19f9(%rip), %rsi      # 0x410d
jmp 0x28fa
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x19a8(%rip), %rsi      # 0x40d0
jmp 0x28b2
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x19d9(%rip), %rsi      # 0x4115
jmp 0x28b2
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1980(%rip), %rsi      # 0x40d0
jmp 0x281c
movl $0x9, %edx
movq %rbx, %rdi
leaq 0x195d(%rip), %rsi      # 0x40c1
jmp 0x28fa
cmpl $0x1d, %ebp
jle 0x296f
cmpl $0x32, %ebp
jle 0x2a2c
cmpl $0x33, %ebp
je 0x2ace
cmpl $0x55, %ebp
je 0x2b2f
cmpl $0x65, %ebp
jne 0x2b8f
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x1931(%rip), %rsi      # 0x40d6
callq 0x2180
shrl $0x8, %r13d
andl $0xf, %r13d
movq %rbx, %rdi
movl %r13d, %esi
callq 0x2210
movl $0x5, %edx
movq %rax, %rdi
leaq 0x19a0(%rip), %rsi      # 0x416c
jmp 0x2a9c
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x18eb(%rip), %rsi      # 0x40cb
jmp 0x28b2
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x18e7(%rip), %rsi      # 0x40db
jmp 0x28b2
movl $0x3, %edx
movq %rbx, %rdi
leaq 0x18b5(%rip), %rsi      # 0x40bd
jmp 0x28fa
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x18af(%rip), %rsi      # 0x40cb
callq 0x2180
movl %r13d, %esi
shrl $0x8, %esi
andl $0xf, %esi
movq %rbx, %rdi
callq 0x2210
movq %rax, %rbp
movl $0x3, %edx
movq %rax, %rdi
leaq 0x191a(%rip), %rsi      # 0x415e
callq 0x2180
shrl $0x4, %r13d
andl $0xf, %r13d
movq %rbp, %rdi
jmp 0x2b87
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x18b3(%rip), %rsi      # 0x411b
callq 0x2180
movl %r13d, %esi
shrl $0x8, %esi
andl $0xf, %esi
movq %rbx, %rdi
callq 0x2210
movq %rax, %rbp
movl $0x3, %edx
movq %rax, %rdi
leaq 0x18ce(%rip), %rsi      # 0x415e
callq 0x2180
movl %r13d, %esi
shrl $0x4, %esi
andl $0xf, %esi
movq %rbp, %rdi
jmp 0x28c3
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x1824(%rip), %rsi      # 0x40d6
callq 0x2180
movl %r13d, %esi
shrl $0x8, %esi
andl $0xf, %esi
movq %rbx, %rdi
callq 0x2210
movq %rax, %rbp
movl $0x2, %edx
movq %rax, %rdi
leaq 0x1838(%rip), %rsi      # 0x4112
callq 0x2180
movzbl %r13b, %esi
movq %rbp, %rdi
jmp 0x2b8a
movl $0x6, %edx
movq %rbx, %rdi
leaq 0x180c(%rip), %rsi      # 0x4106
callq 0x2180
andl $0xfff, %r13d           # imm = 0xFFF
jmp 0x2b84
movl %r13d, %eax
andl $0xf, %eax
cmpl $0xe, %eax
ja 0x2b8f
leaq 0x1723(%rip), %rcx      # 0x4044
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x179d(%rip), %rsi      # 0x40d6
callq 0x2180
movl %r13d, %esi
shrl $0x4, %esi
andl $0xf, %esi
movq %rbx, %rdi
callq 0x2210
movq %rax, %rbp
movl $0x3, %edx
movq %rax, %rdi
leaq 0x17fd(%rip), %rsi      # 0x415e
callq 0x2180
shrl $0x8, %r13d
jmp 0x284d
cmpl $0x14, %ebp
jg 0x2a06
cmpl $0x7, %ebp
je 0x2a66
cmpl $0xa, %ebp
jne 0x2b8f
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x173d(%rip), %rsi      # 0x40d6
callq 0x2180
shrl $0x8, %r13d
andl $0xf, %r13d
movq %rbx, %rdi
movl %r13d, %esi
callq 0x2210
movl $0x3, %edx
movq %rax, %rdi
leaq 0x1773(%rip), %rsi      # 0x4133
jmp 0x2a9c
movl $0x6, %edx
movq %rbx, %rdi
leaq 0x1753(%rip), %rsi      # 0x4127
jmp 0x2b77
movl $0x3, %edx
movq %rbx, %rdi
leaq 0x16c7(%rip), %rsi      # 0x40af
jmp 0x2a9c
movl $0x9, %edx
movq %rbx, %rdi
leaq 0x16b7(%rip), %rsi      # 0x40b3
callq 0x2180
jmp 0x2b84
cmpl $0x15, %ebp
je 0x2aa6
cmpl $0x18, %ebp
jne 0x2b8f
movl $0x8, %edx
movq %rbx, %rdi
leaq 0x1719(%rip), %rsi      # 0x4140
jmp 0x2b77
cmpl $0x1e, %ebp
je 0x2ae2
cmpl $0x29, %ebp
jne 0x2b8f
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x1705(%rip), %rsi      # 0x4152
jmp 0x2b77
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1680(%rip), %rsi      # 0x40e1
jmp 0x281c
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x1661(%rip), %rsi      # 0x40d6
callq 0x2180
shrl $0x8, %r13d
andl $0xf, %r13d
movq %rbx, %rdi
movl %r13d, %esi
callq 0x2210
movl $0x4, %edx
movq %rax, %rdi
leaq 0x1692(%rip), %rsi      # 0x412e
callq 0x2180
jmp 0x2b8f
movl $0x8, %edx
movq %rbx, %rdi
leaq 0x1682(%rip), %rsi      # 0x4137
jmp 0x2b77
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1624(%rip), %rsi      # 0x40ed
jmp 0x281c
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x167d(%rip), %rsi      # 0x415a
jmp 0x2b77
movl $0x8, %edx
movq %rbx, %rdi
leaq 0x1658(%rip), %rsi      # 0x4149
jmp 0x2b77
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x15e3(%rip), %rsi      # 0x40e8
jmp 0x281c
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x15da(%rip), %rsi      # 0x40f3
jmp 0x2b77
movl $0x6, %edx
movq %rbx, %rdi
leaq 0x15cf(%rip), %rsi      # 0x40f9
jmp 0x281c
movl $0x9, %edx
movq %rbx, %rdi
leaq 0x1624(%rip), %rsi      # 0x4162
jmp 0x2b77
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1598(%rip), %rsi      # 0x40e7
jmp 0x281c
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1578(%rip), %rsi      # 0x40db
jmp 0x281c
movl $0x5, %edx
movq %rbx, %rdi
leaq 0x1589(%rip), %rsi      # 0x4100
callq 0x2180
shrl $0x8, %r13d
andl $0xf, %r13d
movq %rbx, %rdi
movl %r13d, %esi
callq 0x2210
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2130
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
addq $0x2, %r12
cmpq %r12, 0x35c7(%rip)      # 0x6188
jg 0x253a
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq