// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
xorl %ebx, %ebx
movq 0x2ae7(%rip), %r15      # 0x4fd0
leaq 0xb14(%rip), %r14       # 0x3004
cmpq %rbx, 0x2c89(%rip)      # 0x5180
jle 0x29e5
leal 0x200(%rbx), %eax
movw %ax, 0x6(%rsp)
leaq 0x2c39(%rip), %rdi      # 0x5148
leaq 0x6(%rsp), %rsi
callq 0x2e70
movq %rax, %rbp
leaq 0x2c2d(%rip), %rax      # 0x5150
cmpq %rax, %rbp
je 0x2591
movq %r15, %rdi
leaq 0xb77(%rip), %rsi       # 0x30a9
callq 0x2130
cmpw $0x200, 0x20(%rbp)      # imm = 0x200
jne 0x2550
movq %r15, %rdi
leaq 0xb50(%rip), %rsi       # 0x3099
callq 0x2130
jmp 0x257a
cmpl $0x0, 0x24(%rbp)
leaq 0xb44(%rip), %rsi       # 0x309f
leaq 0xb64(%rip), %rax       # 0x30c6
cmoveq %rax, %rsi
movq %r15, %rdi
callq 0x2130
movzwl 0x20(%rbp), %esi
movq %r15, %rdi
callq 0x21f0
movq %r15, %rdi
leaq 0xb37(%rip), %rsi       # 0x30bb
callq 0x2130
movq %rax, %rdi
callq 0x20d0
movq 0x2be0(%rip), %rax      # 0x5178
movzbl (%rax,%rbx), %r13d
shll $0x8, %r13d
movzbl 0x1(%rax,%rbx), %r12d
leal (%r12,%r13), %ebp
movq %r15, %rdi
leaq 0xaef(%rip), %rsi       # 0x30a4
callq 0x2130
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x8, %edx
movl %edx, 0x18(%rax,%rcx)
movq %rax, %rdi
movl %ebp, %esi
callq 0x21f0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
movq %rax, %rdi
leaq 0xaaf(%rip), %rsi       # 0x30a7
callq 0x2130
shrl $0xc, %r13d
movslq (%r14,%r13,4), %rax
addq %r14, %rax
jmpq *%rax
andl $0xfff, %ebp            # imm = 0xFFF
movq %r15, %rdi
cmpl $0xee, %ebp
je 0x287a
cmpl $0xe0, %ebp
jne 0x2886
leaq 0xa79(%rip), %rsi       # 0x30ab
jmp 0x2990
cmpl $0xa1, %r12d
je 0x286b
cmpl $0x9e, %r12d
jne 0x29d4
movq %r15, %rdi
leaq 0xac6(%rip), %rsi       # 0x3121
jmp 0x29bf
movq %r15, %rdi
leaq 0xaa3(%rip), %rsi       # 0x310d
jmp 0x280f
movq %r15, %rdi
leaq 0xa57(%rip), %rsi       # 0x30d0
jmp 0x27d5
movq %r15, %rdi
leaq 0xa8d(%rip), %rsi       # 0x3115
jmp 0x27d5
movq %r15, %rdi
leaq 0xa39(%rip), %rsi       # 0x30d0
jmp 0x276a
movq %r15, %rdi
leaq 0xa1b(%rip), %rsi       # 0x30c1
jmp 0x280f
cmpl $0x65, %r12d
je 0x28c4
cmpl $0xa, %r12d
je 0x2967
cmpl $0x15, %r12d
je 0x292e
cmpl $0x18, %r12d
je 0x2897
cmpl $0x1e, %r12d
je 0x28b5
cmpl $0x29, %r12d
je 0x291f
cmpl $0x33, %r12d
je 0x28f2
cmpl $0x55, %r12d
je 0x28a6
cmpl $0x7, %r12d
jne 0x29d4
movq %r15, %rdi
leaq 0x9c7(%rip), %rsi       # 0x30d6
callq 0x2130
shrl $0x8, %ebp
andl $0xf, %ebp
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
movq %rax, %rdi
leaq 0xa00(%rip), %rsi       # 0x312e
jmp 0x2990
movq %r15, %rdi
leaq 0x98e(%rip), %rsi       # 0x30cb
jmp 0x27d5
movq %r15, %rdi
leaq 0x98f(%rip), %rsi       # 0x30db
jmp 0x27d5
movq %r15, %rdi
leaq 0x962(%rip), %rsi       # 0x30bd
jmp 0x280f
movq %r15, %rdi
leaq 0x961(%rip), %rsi       # 0x30cb
callq 0x2130
movl %ebp, %esi
shrl $0x8, %esi
andl $0xf, %esi
movq %rax, %rdi
callq 0x2200
movq %rax, %rdi
leaq 0x9d5(%rip), %rsi       # 0x315e
callq 0x2130
shrl $0x4, %ebp
jmp 0x29c7
movq %r15, %rdi
leaq 0x97b(%rip), %rsi       # 0x311b
callq 0x2130
movl %ebp, %esi
shrl $0x8, %esi
andl $0xf, %esi
movq %rax, %rdi
callq 0x2200
movq %rax, %rdi
leaq 0x99f(%rip), %rsi       # 0x315e
callq 0x2130
movl %ebp, %esi
shrl $0x4, %esi
jmp 0x27df
movq %r15, %rdi
leaq 0x901(%rip), %rsi       # 0x30d6
callq 0x2130
movl %ebp, %esi
shrl $0x8, %esi
andl $0xf, %esi
movq %rax, %rdi
callq 0x2200
movq %rax, %rdi
leaq 0x91e(%rip), %rsi       # 0x3112
callq 0x2130
movzbl %bpl, %esi
movq %rax, %rdi
jmp 0x29cf
movq %r15, %rdi
leaq 0x8f7(%rip), %rsi       # 0x3106
callq 0x2130
andl $0xfff, %ebp            # imm = 0xFFF
jmp 0x29ca
movl %ebp, %eax
andl $0xf, %eax
cmpl $0xe, %eax
ja 0x29d4
leaq 0x810(%rip), %rcx       # 0x3044
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %r15, %rdi
leaq 0x88f(%rip), %rsi       # 0x30d6
callq 0x2130
movl %ebp, %esi
shrl $0x4, %esi
andl $0xf, %esi
movq %rax, %rdi
callq 0x2200
movq %rax, %rdi
leaq 0x8f8(%rip), %rsi       # 0x315e
jmp 0x29bf
movq %r15, %rdi
leaq 0x8b2(%rip), %rsi       # 0x3127
jmp 0x29bf
leaq 0x82e(%rip), %rsi       # 0x30af
jmp 0x2990
leaq 0x826(%rip), %rsi       # 0x30b3
callq 0x2130
jmp 0x29ca
movq %r15, %rdi
leaq 0x89f(%rip), %rsi       # 0x3140
jmp 0x29bf
movq %r15, %rdi
leaq 0x8b2(%rip), %rsi       # 0x3162
jmp 0x29bf
movq %r15, %rdi
leaq 0x88a(%rip), %rsi       # 0x3149
jmp 0x29bf
movq %r15, %rdi
leaq 0x808(%rip), %rsi       # 0x30d6
callq 0x2130
shrl $0x8, %ebp
andl $0xf, %ebp
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
movq %rax, %rdi
leaq 0x87f(%rip), %rsi       # 0x316c
jmp 0x2990
movq %r15, %rdi
leaq 0x85e(%rip), %rsi       # 0x315a
jmp 0x29bf
movq %r15, %rdi
leaq 0x7d6(%rip), %rsi       # 0x30e1
jmp 0x276a
movq %r15, %rdi
leaq 0x7d3(%rip), %rsi       # 0x30ed
jmp 0x276a
movq %r15, %rdi
leaq 0x829(%rip), %rsi       # 0x3152
jmp 0x29bf
movq %r15, %rdi
leaq 0x7ff(%rip), %rsi       # 0x3137
jmp 0x29bf
movq %r15, %rdi
leaq 0x7a1(%rip), %rsi       # 0x30e8
jmp 0x276a
movq %r15, %rdi
leaq 0x79d(%rip), %rsi       # 0x30f3
jmp 0x29bf
movq %r15, %rdi
leaq 0x797(%rip), %rsi       # 0x30f9
jmp 0x276a
movq %r15, %rdi
leaq 0x765(%rip), %rsi       # 0x30d6
callq 0x2130
shrl $0x8, %ebp
andl $0xf, %ebp
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
movq %rax, %rdi
leaq 0x7a3(%rip), %rsi       # 0x3133
callq 0x2130
jmp 0x29d4
movq %r15, %rdi
leaq 0x746(%rip), %rsi       # 0x30e7
jmp 0x276a
movq %r15, %rdi
leaq 0x72b(%rip), %rsi       # 0x30db
jmp 0x276a
movq %r15, %rdi
leaq 0x741(%rip), %rsi       # 0x3100
callq 0x2130
shrl $0x8, %ebp
andl $0xf, %ebp
movq %rax, %rdi
movl %ebp, %esi
callq 0x2200
movq %r15, %rdi
callq 0x20d0
addq $0x2, %rbx
jmp 0x24f0
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq