// File: /workspace/github_cpp_makefile_star2_O3/khedoros[P]khednes/cpu2.cpp
// Function: cpu::print_details(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void cpu::print_details(const std::string& filename) {
    int total=0;
    int count=0;

    for(int i=0;i<256;++i) {
        if(inst_counts[i]>0) {
            printf("Saw instruction #%02x  %d times.\n",i,inst_counts[i]);
            total+=inst_counts[i];
            count++;
        }
    }
    printf("Total of %d instructions invoked a total of %d times.\n",count,total);

    if(filename == "") return;
    ifstream rom(filename);
    bool print_insts = true;
    size_t filesize = 0;
    Vect<uint8_t> data;
    if(!rom.is_open()) {
        print_insts = false;
        cout<<"wtf couldn't open "<<filename<<" grrrr"<<endl;
    }
    else {
        cout<<"Opened "<<filename<<". ";
        rom.seekg(0,ios::end);
        filesize = rom.tellg() - streampos(16);
        cout<<"Going to read "<<dec<<filesize<<" bytes from it."<<endl;
        rom.seekg(16,ios::beg);
        if(filesize < 40 * 1024) {
            data.resize(filesize+PRG_PAGE_SIZE);
            rom.read(reinterpret_cast<char *>(&data[0]), filesize);
            rom.seekg(16,ios::beg);
            rom.read(reinterpret_cast<char *>(&data[PRG_PAGE_SIZE]), filesize);
        }
        else {
            data.resize(filesize);
            rom.read(reinterpret_cast<char *>(&data[0]), filesize);
        }
        rom.close();
        cout<<"Read the data. Closed the file."<<endl;
    }
    cout.flush();
    int addr_count = 0;
    for(int j=0;j<0x8000;++j) {
        if(addresses[16][j]) {
            if(print_insts) {
                printf("RAM:%04X (%04X)\t%s\n", j, addresses[16][j], util::inst_string(memory->read(j),memory->read(j+1),memory->read(j+2)).c_str());
            }
            else {
                printf("RAM:%04X (%04X)\n", j, addresses[16][j]);
            }
            addr_count++;
        }
    }
    for(int i=0;i<16;++i) {
        for(int j=0;j<PRG_PAGE_SIZE;++j) {
            if(addresses[i][j]) {
                if(print_insts) {
                    int base = i * PRG_PAGE_SIZE + j;
                    if(base < data.size()) {
                        printf("%02X:%04X (%04X)\t%s\n", i, j, addresses[i][j], (util::inst_string(data[base],data[base+1],data[base+2])).c_str());
                    }
                    else {
                        printf("%02X:%04X is outside the file.\n",i,j);
                    }
                }
                else {
                    printf("%02X:%04X (%04X)\n",i,j, addresses[i][j]);
                }
                addr_count++;
            }
        }
    }
    cout<<"The code visited "<<dec<<addr_count<<" addresses during execution."<<endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x258, %rsp            # imm = 0x258
movq %rsi, %r15
leaq 0x9e83(%rip), %r12      # 0x152d0
xorl %r13d, %r13d
xorl %ebx, %ebx
xorl %ebp, %ebp
movq %rdi, 0x8(%rsp)
movl 0x20(%rdi,%r13,4), %edx
testl %edx, %edx
jle 0xb47b
movq %r12, %rdi
movl %r13d, %esi
xorl %eax, %eax
callq 0x4050
movq 0x8(%rsp), %rdi
addl 0x20(%rdi,%r13,4), %ebx
incl %ebp
incq %r13
cmpq $0x100, %r13            # imm = 0x100
jne 0xb459
leaq 0x9e64(%rip), %rdi      # 0x152f2
movl %ebp, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x4050
leaq 0x8c99(%rip), %rsi      # 0x14139
movq %r15, %rdi
callq 0x4120
testl %eax, %eax
je 0xb93b
leaq 0x50(%rsp), %rdi
movq %r15, %rsi
movl $0x8, %edx
callq 0x4570
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x40e0
movb %al, 0x7(%rsp)
testb %al, %al
je 0xb62b
movq 0x10abd(%rip), %rdi     # 0x1bfb0
leaq 0x9e49(%rip), %rsi      # 0x15343
movl $0x7, %edx
callq 0x4410
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq 0x10a9e(%rip), %rdi     # 0x1bfb0
callq 0x4410
leaq 0x9e2d(%rip), %rsi      # 0x1534b
movl $0x2, %edx
movq %rax, %rdi
callq 0x4410
leaq 0x50(%rsp), %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x4480
leaq 0x50(%rsp), %rdi
callq 0x45f0
movq %rax, %r12
movq 0x10a60(%rip), %r14     # 0x1bfb0
leaq 0x9df7(%rip), %rsi      # 0x1534e
movl $0xe, %edx
movq %r14, %rdi
callq 0x4410
leaq -0x10(%r12), %r15
movq (%r14), %rax
movq -0x18(%rax), %rax
movl 0x18(%r14,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, 0x18(%r14,%rax)
movq %r14, %rdi
movq %r15, %rsi
callq 0x4280
movq %rax, %r13
leaq 0x9dc8(%rip), %rsi      # 0x1535d
movl $0xf, %edx
movq %rax, %rdi
callq 0x4410
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %r13, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
leaq 0x50(%rsp), %rdi
movl $0x10, %esi
xorl %edx, %edx
callq 0x4480
cmpq $0x9fff, %r15           # imm = 0x9FFF
ja 0xb683
addq $0x3ff0, %r12           # imm = 0x3FF0
leaq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0xa0bc
movq 0x10(%rsp), %rsi
leaq 0x50(%rsp), %rdi
movq %r15, %rdx
callq 0x4450
leaq 0x50(%rsp), %rdi
movl $0x10, %esi
xorl %edx, %edx
callq 0x4480
movl $0x4000, %esi           # imm = 0x4000
addq 0x10(%rsp), %rsi
jmp 0xb695
movq 0x1097e(%rip), %rdi     # 0x1bfb0
leaq 0x9cf0(%rip), %rsi      # 0x15329
movl $0x12, %edx
callq 0x4410
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq 0x1095f(%rip), %rdi     # 0x1bfb0
callq 0x4410
movq %rax, %r15
leaq 0x9cdc(%rip), %rsi      # 0x1533c
movl $0x6, %edx
movq %rax, %rdi
callq 0x4410
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4390
jmp 0xb6db
leaq 0x10(%rsp), %rdi
movq %r15, %rsi
callq 0xa0bc
movq 0x10(%rsp), %rsi
leaq 0x50(%rsp), %rdi
movq %r15, %rdx
callq 0x4450
leaq 0x50(%rsp), %rdi
callq 0x40c0
movq 0x108fd(%rip), %r15     # 0x1bfb0
leaq 0x9cb3(%rip), %rsi      # 0x1536d
movl $0x1f, %edx
movq %r15, %rdi
callq 0x4410
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %r15, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
movq 0x108bb(%rip), %rdi     # 0x1bfb0
callq 0x4290
leaq 0x30(%rsp), %rbx
xorl %r15d, %r15d
xorl %ebp, %ebp
movq 0x10c65(%rip), %rax     # 0x1c370
movq 0x180(%rax), %rax
movl (%rax,%r15,4), %r12d
testl %r12d, %r12d
je 0xb7b6
cmpb $0x0, 0x7(%rsp)
je 0xb7a0
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
movl %r15d, %esi
callq 0xa836
movl %eax, %r13d
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
leal 0x1(%r15), %esi
callq 0xa836
movl %eax, %r14d
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
leal 0x2(%r15), %esi
callq 0xa836
movq %rbx, %rdi
movl %r13d, %esi
movl %r14d, %edx
movl %eax, %ecx
callq 0xff6a
movq 0x30(%rsp), %rcx
leaq 0x9c10(%rip), %rdi      # 0x1538d
movl %r15d, %esi
movl %r12d, %edx
xorl %eax, %eax
callq 0x4050
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xb7b4
callq 0x4380
jmp 0xb7b4
leaq 0x9bfa(%rip), %rdi      # 0x153a1
movl %r15d, %esi
movl %r12d, %edx
xorl %eax, %eax
callq 0x4050
incl %ebp
incq %r15
cmpq $0x8000, %r15           # imm = 0x8000
jne 0xb704
xorl %ebx, %ebx
xorl %r14d, %r14d
leaq (%r14,%r14,2), %r13
xorl %r15d, %r15d
movq 0x10b97(%rip), %rax     # 0x1c370
movq (%rax,%r13,8), %rax
movl (%rax,%r15,4), %r12d
testl %r12d, %r12d
je 0xb886
cmpb $0x0, 0x7(%rsp)
je 0xb857
leaq (%rbx,%r15), %rcx
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rdx
subq %rax, %rdx
cmpq %rcx, %rdx
jbe 0xb870
addq %rbx, %rax
movzbl (%r15,%rax), %esi
movzbl 0x1(%r15,%rax), %edx
movzbl 0x2(%r15,%rax), %ecx
leaq 0x30(%rsp), %rdi
callq 0xff6a
movq 0x30(%rsp), %r8
leaq 0x9b81(%rip), %rdi      # 0x153b2
movl %r14d, %esi
movl %r15d, %edx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x4050
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xb884
callq 0x4380
jmp 0xb884
leaq 0x9b89(%rip), %rdi      # 0x153e7
movl %r14d, %esi
movl %r15d, %edx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x4050
jmp 0xb884
leaq 0x9b50(%rip), %rdi      # 0x153c7
movl %r14d, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x4050
incl %ebp
incq %r15
cmpq $0x4000, %r15           # imm = 0x4000
jne 0xb7d2
incq %r14
addq $0x4000, %rbx           # imm = 0x4000
cmpq $0x10, %r14
jne 0xb7cb
movq 0x106ff(%rip), %rbx     # 0x1bfb0
leaq 0x9b41(%rip), %rsi      # 0x153f9
movl $0x11, %edx
movq %rbx, %rdi
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rax
movl 0x18(%rbx,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, 0x18(%rbx,%rax)
movq %rbx, %rdi
movl %ebp, %esi
callq 0x45e0
movq %rax, %rbx
leaq 0x9b1d(%rip), %rsi      # 0x1540b
movl $0x1c, %edx
movq %rax, %rdi
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4290
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xb931
callq 0x4380
leaq 0x50(%rsp), %rdi
callq 0x40f0
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xb955
jmp 0xb955
jmp 0xb955
jmp 0xb955
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xb967
callq 0x4380
leaq 0x50(%rsp), %rdi
callq 0x40f0
movq %rbx, %rdi
callq 0x4610
nop