LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::LSR_mem_execute(unsigned short, unsigned char)
void Cpu::LSR_mem_execute(uint16_t address, uint8_t operand) {
    // Logical shift right (Memory content)
    // M,Z,C,N = M/2

    uint8_t result = (operand >> 1) & 0x7f;

    mem.write_byte(address, result);

    regP.Z = result == 0;
    regP.C = operand & 1;
    regP.N = (result >> 7) & 1;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebx
movq %rdi, %r14
movl %ebx, %eax
shrb %al
addq $0x8, %rdi
movzbl %al, %edx
callq 0x43dc
cmpb $0x2, %bl
setb 0x10029(%r14)
andb $0x1, %bl
movb %bl, 0x10028(%r14)
movb $0x0, 0x1002e(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::LSR_A_execute()
void Cpu::LSR_A_execute() {
    // Logical shift right (Accumulator content)
    // A,Z,C,N = A/2

    uint8_t result = (regA >> 1) & 0x7f;

    regP.Z = result == 0;
    regP.C = regA & 1;
    regP.N = (result >> 7) & 1;

    regA = result;
}

// Assembly:
movb 0x10020(%rdi), %al
movl %eax, %ecx
shrb %cl
cmpb $0x2, %al
setb 0x10029(%rdi)
andb $0x1, %al
movb %al, 0x10028(%rdi)
movb $0x0, 0x1002e(%rdi)
movb %cl, 0x10020(%rdi)
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::PHP_execute()
void Cpu::PHP_execute() {
    // Push processor status
    
    uint8_t procStat;
    procStat =  (regP.N) << 6 |
		(regP.V) << 5 |
		(regP.B) << 4 |
		(regP.D) << 3 |
		(regP.I) << 2 |
		(regP.Z) << 1 |
		(regP.C);
    pushStack(procStat);
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movb 0x1002e(%rdi), %al
shlb $0x6, %al
movb 0x1002d(%rdi), %cl
shlb $0x5, %cl
orb %al, %cl
movb 0x1002c(%rdi), %al
shlb $0x4, %al
orb %cl, %al
movb 0x1002b(%rdi), %cl
shlb $0x3, %cl
orb %al, %cl
movb 0x10029(%rdi), %al
movb 0x1002a(%rdi), %dl
shlb $0x2, %dl
orb %cl, %dl
addb %al, %al
orb %dl, %al
orb 0x10028(%rdi), %al
addq $0x8, %rdi
movzwl 0x10026(%rbx), %esi
movzbl %al, %edx
callq 0x43dc
decw 0x10026(%rbx)
popq %rbx
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::PLA_execute()
void Cpu::PLA_execute() {
    // Pull accumulator

    regA = pullStack();

    regP.Z = regA == 0;
    regP.N = regA >> 7;
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movzwl 0x10026(%rdi), %eax
incl %eax
movw %ax, 0x10026(%rdi)
addq $0x8, %rdi
movzwl %ax, %esi
callq 0x42ba
movb %al, 0x10020(%rbx)
testb %al, %al
sete 0x10029(%rbx)
shrb $0x7, %al
movb %al, 0x1002e(%rbx)
popq %rbx
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::PLP_execute()
void Cpu::PLP_execute() {
    // Pull processor status

    uint8_t procStat = pullStack();
    regP.N = (procStat >> 6) & 1;
    regP.V = (procStat >> 5) & 1;
    regP.B = (procStat >> 4) & 1;
    regP.D = (procStat >> 3) & 1;
    regP.I = (procStat >> 2) & 1;
    regP.Z = (procStat >> 1) & 1;
    regP.C = procStat & 1;
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movzwl 0x10026(%rdi), %eax
incl %eax
movw %ax, 0x10026(%rdi)
addq $0x8, %rdi
movzwl %ax, %esi
callq 0x42ba
movl %eax, %ecx
shrb $0x6, %cl
andb $0x1, %cl
movb %cl, 0x1002e(%rbx)
movl %eax, %ecx
shrb $0x5, %cl
andb $0x1, %cl
movb %cl, 0x1002d(%rbx)
movl %eax, %ecx
shrb $0x4, %cl
andb $0x1, %cl
movb %cl, 0x1002c(%rbx)
movl %eax, %ecx
shrb $0x3, %cl
andb $0x1, %cl
movb %cl, 0x1002b(%rbx)
movl %eax, %ecx
shrb $0x2, %cl
andb $0x1, %cl
movb %cl, 0x1002a(%rbx)
movl %eax, %ecx
shrb %cl
andb $0x1, %cl
movb %cl, 0x10029(%rbx)
andb $0x1, %al
movb %al, 0x10028(%rbx)
popq %rbx
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::ROL_mem_execute(unsigned short, unsigned char)
void Cpu::ROL_mem_execute(uint16_t address, uint8_t operand) {
    // Rotate left (memory contents)

    uint8_t result = (operand << 1) | regP.C;
    mem.write_byte(address, result);

    regP.C = (operand >> 7) & 1;
    regP.Z = result == 0;
    regP.N = (result >> 7) & 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebx
movq %rdi, %r14
leal (%rbx,%rbx), %r15d
movb 0x10028(%rdi), %al
orb %r15b, %al
addq $0x8, %rdi
movzbl %al, %ebp
movl %ebp, %edx
callq 0x43dc
shrb $0x7, %bl
movb %bl, 0x10028(%r14)
testb %bpl, %bpl
sete 0x10029(%r14)
shrb $0x7, %r15b
movb %r15b, 0x1002e(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::ROL_A_execute()
void Cpu::ROL_A_execute() {
    // Rotate Left (accumulator)

    uint8_t result = (regA << 1) | regP.C;

    regP.C = (regA >> 7) & 1;
    regP.Z = result == 0;
    regP.N = (result >> 7) & 1;
    
    regA = result;
}

// Assembly:
movb 0x10020(%rdi), %al
leal (%rax,%rax), %ecx
shrb $0x7, %al
movb 0x10028(%rdi), %dl
orb %cl, %dl
movb %al, 0x10028(%rdi)
sete 0x10029(%rdi)
shrb $0x7, %cl
movb %cl, 0x1002e(%rdi)
movb %dl, 0x10020(%rdi)
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::ROR_mem_execute(unsigned short, unsigned char)
void Cpu::ROR_mem_execute(uint16_t address, uint8_t operand) {
    // Rotate right (memory contents)

    uint8_t result = ((operand >> 1) & 0x7f) | (regP.C << 7);
    mem.write_byte(address, result);

    regP.C = operand & 1;
    regP.Z = result == 0;
    regP.N = (result >> 7) & 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebx
movq %rdi, %r14
movb 0x10028(%rdi), %r15b
movl %ebx, %eax
shrb %al
movl %r15d, %ecx
shlb $0x7, %cl
orb %al, %cl
addq $0x8, %rdi
movzbl %cl, %ebp
movl %ebp, %edx
callq 0x43dc
andb $0x1, %bl
movb %bl, 0x10028(%r14)
testb %bpl, %bpl
sete 0x10029(%r14)
movb %r15b, 0x1002e(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::ROR_A_execute()
void Cpu::ROR_A_execute() {
    // Rotate right (accumulator)

    uint8_t result = ((regA >> 1) & 0x7f) | (regP.C << 7);

    regP.C = regA & 1;
    regP.Z = result == 0;
    regP.N = (result >> 7) & 1;

    regA = result;
}

// Assembly:
movb 0x10020(%rdi), %al
movb 0x10028(%rdi), %cl
movl %eax, %edx
shrb %dl
movl %ecx, %esi
shlb $0x7, %sil
orb %dl, %sil
andb $0x1, %al
movb %al, 0x10028(%rdi)
testb %sil, %sil
sete 0x10029(%rdi)
movb %cl, 0x1002e(%rdi)
movb %sil, 0x10020(%rdi)
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::RTI_execute()
void Cpu::RTI_execute() {
    // Return from interrupt

    uint8_t procStat = pullStack();
    regP.N = (procStat >> 6) & 1;
    regP.V = (procStat >> 5) & 1;
    regP.B = (procStat >> 4) & 1;
    regP.D = (procStat >> 3) & 1;
    regP.I = (procStat >> 2) & 1;
    regP.Z = (procStat >> 1) & 1;
    regP.C = procStat & 1;

    uint8_t PC_low = pullStack();
    uint8_t PC_high = pullStack();
    regPC = (PC_high << 8) | PC_low;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movzwl 0x10026(%rdi), %esi
incl %esi
movw %si, 0x10026(%rdi)
leaq 0x8(%rdi), %r14
movl $0xffff, %r15d          # imm = 0xFFFF
andl %r15d, %esi
movq %r14, %rdi
callq 0x42ba
movl %eax, %ecx
shrb $0x6, %cl
andb $0x1, %cl
movb %cl, 0x1002e(%rbx)
movl %eax, %ecx
shrb $0x5, %cl
andb $0x1, %cl
movb %cl, 0x1002d(%rbx)
movl %eax, %ecx
shrb $0x4, %cl
andb $0x1, %cl
movb %cl, 0x1002c(%rbx)
movl %eax, %ecx
shrb $0x3, %cl
andb $0x1, %cl
movb %cl, 0x1002b(%rbx)
movl %eax, %ecx
shrb $0x2, %cl
andb $0x1, %cl
movb %cl, 0x1002a(%rbx)
movl %eax, %ecx
shrb %cl
andb $0x1, %cl
movb %cl, 0x10029(%rbx)
andb $0x1, %al
movb %al, 0x10028(%rbx)
movzwl 0x10026(%rbx), %esi
incl %esi
movw %si, 0x10026(%rbx)
andl %r15d, %esi
movq %r14, %rdi
callq 0x42ba
movl %eax, %ebp
movzwl 0x10026(%rbx), %esi
incl %esi
movw %si, 0x10026(%rbx)
andl %r15d, %esi
movq %r14, %rdi
callq 0x42ba
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ecx
orl %eax, %ecx
movw %cx, 0x10024(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::RTS_execute()
void Cpu::RTS_execute() {
    // Return from subroutine

    uint8_t PC_low = pullStack();
    uint8_t PC_high = pullStack();
    uint16_t PC = (PC_high << 8) | PC_low;
    regPC = PC + 1; //It had the last byte of the last instr
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movzwl 0x10026(%rdi), %esi
incl %esi
movw %si, 0x10026(%rdi)
leaq 0x8(%rdi), %r14
movl $0xffff, %r15d          # imm = 0xFFFF
andl %r15d, %esi
movq %r14, %rdi
callq 0x42ba
movl %eax, %ebp
movzwl 0x10026(%rbx), %esi
incl %esi
movw %si, 0x10026(%rbx)
andl %r15d, %esi
movq %r14, %rdi
callq 0x42ba
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ecx
addl %ecx, %eax
incl %eax
movw %ax, 0x10024(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_absolute(addr_mode_t*, unsigned char)
uint32_t Cpu::read_operand_absolute(addr_mode_t *addr_mode, uint8_t opcode) {
    uint8_t operand;
    uint8_t high, low;
    low = mem.read_byte(regPC + 0x0001);
    high = mem.read_byte(regPC + 0x0002);
    uint16_t address = (high << 8) | low;
    regPC += 0x03;
    *addr_mode = ABSOLUTE;
    //These opcodes don't need an operand
    //We avoid lateral effects on ppu regs reads
    if (!(opcode == 0x20 || opcode == 0x8c || opcode == 0x4c || opcode == 0x0c || opcode ==
	0x8d || opcode == 0x8e))
	operand = mem.read_byte(address);
    else
	operand = 0;
    return (address << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %r14d
movq %rsi, %r15
movq %rdi, %r12
leaq 0x8(%rdi), %rbx
movl 0x10024(%rdi), %esi
incl %esi
movl $0xffff, %r13d          # imm = 0xFFFF
andl %r13d, %esi
movq %rbx, %rdi
callq 0x42ba
movl %eax, %ebp
movl 0x10024(%r12), %esi
addl $0x2, %esi
andl %r13d, %esi
movq %rbx, %rdi
callq 0x42ba
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ebp
addw $0x3, 0x10024(%r12)
orl %eax, %ebp
movl $0x3, (%r15)
xorl %eax, %eax
cmpl $0x8b, %r14d
jg 0x3921
cmpl $0xc, %r14d
je 0x392e
cmpl $0x20, %r14d
je 0x392e
cmpl $0x4c, %r14d
je 0x392e
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x42ba
movzbl %al, %eax
jmp 0x392e
addl $0xffffff74, %r14d      # imm = 0xFFFFFF74
cmpl $0x3, %r14d
jae 0x3911
shll $0x10, %ebp
orl %eax, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_imm(addr_mode_t*)
uint32_t Cpu::read_operand_imm(addr_mode_t *addr_mode) {
    uint8_t operand;
    operand = mem.read_byte(regPC + 0x0001);
    regPC += 0x02;
    *addr_mode = IMMEDIATE;
    return operand;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
addq $0x8, %rdi
movl 0x10024(%r14), %eax
incl %eax
movzwl %ax, %esi
callq 0x42ba
addw $0x2, 0x10024(%r14)
movl $0x0, (%rbx)
movzbl %al, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_indexed_indirect(addr_mode_t*)
uint32_t Cpu::read_operand_indexed_indirect(addr_mode_t *addr_mode) {
    uint8_t operand;
    uint16_t address;
    uint8_t d = mem.read_byte(regPC + 0x0001);
    address = mem.read_word(uint16_t (0x00FF & (d+regX)));
    operand = mem.read_byte(address);
    regPC += 0x02;
    *addr_mode = INDIRECT_X;
    return (d << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rdi), %r15
movl 0x10024(%rdi), %eax
incl %eax
movzwl %ax, %esi
movq %r15, %rdi
callq 0x42ba
movzbl %al, %ebp
movb 0x10021(%r14), %al
addb %bpl, %al
movzbl %al, %esi
movq %r15, %rdi
callq 0x4380
movzwl %ax, %esi
movq %r15, %rdi
callq 0x42ba
addw $0x2, 0x10024(%r14)
movl $0x6, (%rbx)
shll $0x10, %ebp
movzbl %al, %eax
orl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_zero_page(addr_mode_t*)
uint32_t Cpu::read_operand_zero_page(addr_mode_t *addr_mode) {
    uint8_t operand;
    uint16_t address = 0;
    uint8_t d = mem.read_byte(regPC + 0x0001);
    address = address | (0x00ff & d);
    operand = mem.read_byte(address);
    regPC += 0x02;
    *addr_mode = ZERO_PAGE;
    return (address << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rdi), %r15
movl 0x10024(%rdi), %eax
incl %eax
movzwl %ax, %esi
movq %r15, %rdi
callq 0x42ba
movzbl %al, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x42ba
addw $0x2, 0x10024(%r14)
movl $0x1, (%rbx)
shll $0x10, %ebp
movzbl %al, %eax
orl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_indirect(addr_mode_t*)
uint32_t Cpu::read_operand_indirect(addr_mode_t *addr_mode) {
    uint16_t pointer;
    uint16_t address;
    uint8_t high, low, operand;
    operand = 0;
    low = mem.read_byte(regPC + 0x0001);
    high = mem.read_byte(regPC + 0x0002);
    pointer = (high << 8) | low;
    address = mem.read_word(pointer);
    regPC += 0x03;
    *addr_mode = INDIRECT;
    return (address << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rdi), %r15
movl 0x10024(%rdi), %esi
incl %esi
movl $0xffff, %r12d          # imm = 0xFFFF
andl %r12d, %esi
movq %r15, %rdi
callq 0x42ba
movl %eax, %ebp
movl 0x10024(%r14), %esi
addl $0x2, %esi
andl %r12d, %esi
movq %r15, %rdi
callq 0x42ba
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %esi
orl %eax, %esi
andl %r12d, %esi
movq %r15, %rdi
callq 0x4380
addw $0x3, 0x10024(%r14)
movl $0x9, (%rbx)
shll $0x10, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_relative(addr_mode_t*)
uint32_t Cpu::read_operand_relative(addr_mode_t *addr_mode) {
    int8_t operand;
    operand = mem.read_byte(regPC+ 0x0001);
    int16_t signExtOperand = (operand << 8) >> 8;
    regPC += 0x02;
    signExtOperand += regPC;
    *addr_mode = RELATIVE;
    return signExtOperand << 16;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
addq $0x8, %rdi
movl 0x10024(%r14), %eax
incl %eax
movzwl %ax, %esi
callq 0x42ba
movl 0x10024(%r14), %ecx
leal 0x2(%rcx), %edx
movw %dx, 0x10024(%r14)
movsbl %al, %eax
addl %ecx, %eax
addl $0x2, %eax
movl $0x8, (%rbx)
shll $0x10, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_indirect_indexed(addr_mode_t*)
uint32_t Cpu::read_operand_indirect_indexed(addr_mode_t *addr_mode) {
    uint16_t address;
    uint8_t operand;
    uint8_t high, low;
    low = mem.read_byte(regPC + 0x0001);
    high = 0x00;
    address = mem.read_word((high << 8) | low);
    address += (uint16_t) regY;
    operand = mem.read_byte(address);
    regPC += 0x02;
    *addr_mode = INDIRECT_Y;
    return (address << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rdi), %r15
movl 0x10024(%rdi), %esi
incl %esi
movl $0xffff, %ebp           # imm = 0xFFFF
andl %ebp, %esi
movq %r15, %rdi
callq 0x42ba
movzbl %al, %esi
movq %r15, %rdi
callq 0x4380
movl %eax, %r12d
movzbl 0x10022(%r14), %eax
addl %eax, %r12d
andl %r12d, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x42ba
addw $0x2, 0x10024(%r14)
movl $0x7, (%rbx)
shll $0x10, %r12d
movzbl %al, %eax
orl %r12d, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_zero_page_indexed_x(addr_mode_t*)
uint32_t Cpu::read_operand_zero_page_indexed_x(addr_mode_t *addr_mode) {
    uint8_t operand;
    uint16_t address;
    uint8_t d = mem.read_byte(regPC + 0x0001);
    address = (0x0FF & (d+regX));
    operand = mem.read_byte(address);
    regPC += 0x02;
    *addr_mode = ZERO_PAGE_X;
    return (address << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rdi), %r15
movl 0x10024(%rdi), %eax
incl %eax
movzwl %ax, %esi
movq %r15, %rdi
callq 0x42ba
addb 0x10021(%r14), %al
movzbl %al, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x42ba
addw $0x2, 0x10024(%r14)
movl $0x2, (%rbx)
shll $0x10, %ebp
movzbl %al, %eax
orl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::read_operand_absolute_indexed_y(addr_mode_t*)
uint32_t Cpu::read_operand_absolute_indexed_y(addr_mode_t *addr_mode) {
    uint16_t address;
    uint8_t operand;
    uint8_t high, low;
    low = mem.read_byte(regPC + 0x0001);
    high = mem.read_byte(regPC + 0x0002);
    address = (high << 8) | low;
    address += regY;
    operand = mem.read_byte(address);
    regPC += 0x03;
    *addr_mode = ABSOLUTE_Y;
    return (address << 16) | operand;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rdi), %r15
movl 0x10024(%rdi), %esi
incl %esi
movl $0xffff, %ebp           # imm = 0xFFFF
andl %ebp, %esi
movq %r15, %rdi
callq 0x42ba
movl %eax, %r12d
movl 0x10024(%r14), %esi
addl $0x2, %esi
andl %ebp, %esi
movq %r15, %rdi
callq 0x42ba
movzbl %al, %eax
shll $0x8, %eax
movzbl %r12b, %ecx
orl %eax, %ecx
movzbl 0x10022(%r14), %r12d
addl %ecx, %r12d
andl %r12d, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x42ba
addw $0x3, 0x10024(%r14)
movl $0x5, (%rbx)
shll $0x10, %r12d
movzbl %al, %eax
orl %r12d, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::NMI_execute()
void Cpu::NMI_execute() {
    // Non-Maskable interrupt

    uint8_t lowPC, highPC;
    lowPC = regPC;
    highPC = (regPC >> 8);
    
    uint8_t procStat;
    procStat =  (regP.N) << 6 |
		(regP.V) << 5 |
		(regP.B) << 4 |
		(regP.D) << 3 |
		(regP.I) << 2 |
		(regP.Z) << 1 |
		(regP.C);
    
    //We push the PC and Processor Status into the stack
    pushStack(highPC);
    pushStack(lowPC);
    pushStack(procStat);

    //We set the PC to the interrupt vector
    regPC = mem.read_word(NMI_INT_VECTOR_ADDR);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
movzwl 0x10024(%rdi), %ebp
movl %ebp, %edx
shrl $0x8, %edx
movb 0x1002e(%rdi), %al
shlb $0x6, %al
movb 0x1002d(%rdi), %cl
shlb $0x5, %cl
orb %al, %cl
movb 0x1002c(%rdi), %al
shlb $0x4, %al
orb %cl, %al
movb 0x1002b(%rdi), %cl
shlb $0x3, %cl
orb %al, %cl
movb 0x10029(%rdi), %r15b
movb 0x1002a(%rdi), %al
shlb $0x2, %al
orb %cl, %al
addb %r15b, %r15b
orb %al, %r15b
orb 0x10028(%rdi), %r15b
leaq 0x8(%rdi), %r14
movzwl 0x10026(%rdi), %esi
movq %r14, %rdi
callq 0x43dc
movzwl 0x10026(%rbx), %esi
decl %esi
movw %si, 0x10026(%rbx)
movl $0xffff, %r12d          # imm = 0xFFFF
andl %r12d, %esi
movzbl %bpl, %edx
movq %r14, %rdi
callq 0x43dc
movzwl 0x10026(%rbx), %esi
decl %esi
movw %si, 0x10026(%rbx)
andl %r12d, %esi
movzbl %r15b, %edx
movq %r14, %rdi
callq 0x43dc
decw 0x10026(%rbx)
movq %r14, %rdi
movl $0xfffa, %esi           # imm = 0xFFFA
callq 0x4380
movw %ax, 0x10024(%rbx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem.cpp
// Function: Mem::read_byte(unsigned short)
uint8_t Mem::read_byte(uint16_t addr) {
    //Mirroring
    if (addr > 0x07FF) {
	if (addr < 0x1000)
	    addr -= 0x0800;
	else if (addr < 0x1800)
	    addr -= 0x1000;
	else if (addr < 0x2000)
	    addr -= 0x1800;
    }
    //PPU regs mirroring
    if (addr > 0x2007 && addr < 0x4000) {
	addr = (addr & 7) + 0x2000;
    }

    if (addr == 0x2000)
	return mem_ppu->read_PPUCTRL();
    else if (addr == 0x2001)
	return mem_ppu->read_PPUMASK();
    else if (addr == 0x2002)
	return mem_ppu->read_PPUSTATUS();
    else if (addr == 0x2007)
        return mem_ppu->read_PPUDATA();
    else if (addr == 0x4016) {
	uint8_t result = controller_latch & 1;
	controller_latch = controller_latch >> 1;
	controller_latch |= 0x80;
	return result;
    }
    else
        return ram[addr];
}

// Assembly:
cmpl $0x800, %esi            # imm = 0x800
jb 0x42f1
movzwl %si, %eax
cmpl $0xfff, %eax            # imm = 0xFFF
ja 0x42d4
addl $0xfffff800, %esi       # imm = 0xFFFFF800
jmp 0x42f1
cmpl $0x17ff, %eax           # imm = 0x17FF
ja 0x42e3
addl $0xfffff000, %esi       # imm = 0xFFFFF000
jmp 0x42f1
leal -0x1800(%rax), %esi
cmpl $0x2000, %eax           # imm = 0x2000
cmovael %eax, %esi
leal -0x2008(%rsi), %edx
movl $0xffff, %ecx           # imm = 0xFFFF
andl %ecx, %edx
movl %esi, %eax
andl $0x2007, %eax           # imm = 0x2007
cmpl $0x1ff8, %edx           # imm = 0x1FF8
cmovael %esi, %eax
andl %eax, %ecx
leal -0x2000(%rcx), %edx
cmpl $0x7, %edx
ja 0x4337
leaq 0x2226(%rip), %rcx      # 0x6548
movslq (%rcx,%rdx,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
movq 0x10000(%rdi), %rdi
jmp 0x48fc
cmpl $0x4016, %ecx           # imm = 0x4016
jne 0x4355
movb 0x10008(%rdi), %cl
movl %ecx, %eax
andb $0x1, %al
shrb %cl
orb $-0x80, %cl
movb %cl, 0x10008(%rdi)
retq
movzwl %ax, %eax
movb (%rdi,%rax), %al
retq
movq 0x10000(%rdi), %rdi
jmp 0x496a
movq 0x10000(%rdi), %rdi
jmp 0x499c
movq 0x10000(%rdi), %rdi
jmp 0x4b30
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem.cpp
// Function: Mem::read_word(unsigned short)
uint16_t Mem::read_word(uint16_t addr) {
    //Mirroring
    if (addr > 0x07FF) {
	if (addr < 0x1000)
	    addr -= 0x0800;
	else if (addr < 0x1800)
	    addr -= 0x1000;
	else if (addr < 0x2000)
	    addr -= 0x1800;
    }
    //PPU regs mirroring
    if (addr > 0x2007 && addr < 0x4000) {
	addr = (addr & 7) + 0x2000;
    }
    uint16_t result;
    uint8_t lower, upper;
    lower = ram[addr];
    upper = ram[addr+1];
    result = ((uint16_t) upper << 8) | (uint16_t) lower; //$HHLL
    return result;
}

// Assembly:
cmpl $0x800, %esi            # imm = 0x800
jb 0x43b7
movzwl %si, %eax
cmpl $0xfff, %eax            # imm = 0xFFF
ja 0x439a
addl $0xfffff800, %esi       # imm = 0xFFFFF800
jmp 0x43b7
cmpl $0x17ff, %eax           # imm = 0x17FF
ja 0x43a9
addl $0xfffff000, %esi       # imm = 0xFFFFF000
jmp 0x43b7
leal -0x1800(%rax), %esi
cmpl $0x2000, %eax           # imm = 0x2000
cmovael %eax, %esi
leal -0x2008(%rsi), %eax
movl $0xffff, %ecx           # imm = 0xFFFF
andl %ecx, %eax
movl %esi, %edx
andl $0x2007, %edx           # imm = 0x2007
cmpl $0x1ff8, %eax           # imm = 0x1FF8
cmovael %esi, %edx
andl %ecx, %edx
movzwl (%rdi,%rdx), %eax
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::Mem_ppu()
Mem_ppu::Mem_ppu() {
    PPUCTRL = 0;
    PPUADDR = 0;
    PPUDATA = 0;
    PPUSTATUS = 0;
    OAMADDR = 0;
    OAMDATA = 0;
    ram = (unsigned char*) malloc(PPU_RAM_SIZE);
    oam = (unsigned char*) malloc(256);
    ppuaddr_ptr_hl = 0;
    oamaddr_ptr_hl = 0;
    ppuscroll_ptr_hl = 0;
    in_vblank = false;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movb $0x0, 0x3c010(%rdi)
movl $0x4000, %edi           # imm = 0x4000
callq 0x21a0
xorl %ebp, %ebp
movl %ebp, 0x3c012(%rbx)
movl %ebp, 0x3c015(%rbx)
movq %rax, (%rbx)
movl $0x100, %edi            # imm = 0x100
callq 0x21a0
movq %rax, 0x8(%rbx)
movl %ebp, 0x3c01c(%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::read_byte(unsigned short)
uint8_t Mem_ppu::read_byte(uint16_t addr) {
    //Mirroring
    if (addr > 0x2fff && addr < 0x3f00)
	addr = addr - 0x1000;
    else if (addr > 0x3f1f && addr < 0x4000)
	addr = addr - 0x0020;
    //Pallette mirroring
    if (addr == 0x3f10)
	addr = 0x3f00;
    else if (addr == 0x3f14)
	addr = 0x3f04;
    else if (addr == 0x3f18)
	addr = 0x3f08;
    else if (addr == 0x3f1c)
	addr = 0x3f1c;

    return ram[addr];
}

// Assembly:
movl %esi, %eax
addl $0xffffd000, %eax       # imm = 0xFFFFD000
movzwl %ax, %eax
cmpl $0xeff, %eax            # imm = 0xEFF
ja 0x4715
leal -0x1000(%rsi), %eax
jmp 0x472a
leal -0x3f20(%rsi), %eax
movzwl %ax, %ecx
leal -0x20(%rsi), %eax
cmpl $0xe0, %ecx
cmovael %esi, %eax
movzwl %ax, %eax
cmpl $0x3f10, %eax           # imm = 0x3F10
je 0x4750
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x4749
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x4755
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x4755
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x4755
movl $0x3f00, %eax           # imm = 0x3F00
movq (%rdi), %rcx
movb (%rcx,%rax), %al
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::read_word(unsigned short)
uint16_t Mem_ppu::read_word(uint16_t addr) {
    //Mirroring
    if (addr > 0x2fff && addr < 0x3f00)
	addr = addr - 0x1000;
    else if (addr > 0x3f1f && addr < 0x4000)
	addr = addr - 0x0020;
    //Pallette mirroring
    if (addr == 0x3f10)
	addr = 0x3f00;
    else if (addr == 0x3f14)
	addr = 0x3f04;
    else if (addr == 0x3f18)
	addr = 0x3f08;
    else if (addr == 0x3f1c)
	addr = 0x3f1c;
    uint16_t result;
    uint8_t lower, upper;
    lower = ram[addr&0xFFFE];
    upper = ram[addr|0x0001];
    result = ((uint16_t) upper << 8) | (uint16_t) lower; //$HHLL
    return result;
}

// Assembly:
movl %esi, %eax
addl $0xffffd000, %eax       # imm = 0xFFFFD000
movzwl %ax, %eax
cmpl $0xeff, %eax            # imm = 0xEFF
ja 0x4775
leal -0x1000(%rsi), %eax
jmp 0x478a
leal -0x3f20(%rsi), %eax
movzwl %ax, %ecx
leal -0x20(%rsi), %eax
cmpl $0xe0, %ecx
cmovael %esi, %eax
movzwl %ax, %eax
cmpl $0x3f10, %eax           # imm = 0x3F10
je 0x47b0
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x47a9
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x47b5
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x47b5
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x47b5
movl $0x3f00, %eax           # imm = 0x3F00
movq (%rdi), %rcx
movl %eax, %eax
movl %eax, %edx
andl $-0x2, %edx
movzbl (%rcx,%rdx), %edx
orq $0x1, %rax
movzbl (%rcx,%rax), %eax
shll $0x8, %eax
orl %edx, %eax
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::write_byte(unsigned short, unsigned char)
void Mem_ppu::write_byte(uint16_t addr, uint8_t data) {
    //Mirroring
    if (addr > 0x2fff && addr < 0x3f00)
	addr = addr - 0x1000;
    else if (addr > 0x3f1f && addr < 0x4000)
	addr = addr - 0x0020;
    //Pallette mirroring
    if (addr == 0x3f10)
	addr = 0x3f00;
    else if (addr == 0x3f14)
	addr = 0x3f04;
    else if (addr == 0x3f18)
	addr = 0x3f08;
    else if (addr == 0x3f1c)
	addr = 0x3f1c;
    ram[addr] = data;
}

// Assembly:
movl %esi, %eax
addl $0xffffd000, %eax       # imm = 0xFFFFD000
movzwl %ax, %eax
cmpl $0xeff, %eax            # imm = 0xEFF
ja 0x47eb
leal -0x1000(%rsi), %eax
jmp 0x4800
leal -0x3f20(%rsi), %eax
movzwl %ax, %ecx
leal -0x20(%rsi), %eax
cmpl $0xe0, %ecx
cmovael %esi, %eax
movzwl %ax, %eax
cmpl $0x3f10, %eax           # imm = 0x3F10
je 0x4826
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x481f
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x482b
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x482b
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x482b
movl $0x3f00, %eax           # imm = 0x3F00
movq (%rdi), %rcx
movb %dl, (%rcx,%rax)
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::load_rom(char*)
void Mem_ppu::load_rom(char *name) {
    /*This rom loads .nes roms in iNES file format
    The iNES file format follows the following sections:
    
    1. Header (16 bytes)
    2. Trainer, if present(0 or 512 bytes)
    3. PRG ROM data (16384 * x bytes)
    4. CHR ROM data, if present (8192 * y bytes)
    5. PlayChoice INST-ROM, if present (0 or 8192 bytes)
    6. PlayChoice PROM, if present (16 bytes Data, 16 CounterOut)
    */

    ifstream rom;
    rom.open((char *)name, std::ios_base::binary);

    /* 1. HEADER
    The header format is as follows:
    0-3: Constant $4E $45 $53 $1A
    4:  Size of PRG ROM in 16KB units (x)
    5:  Size of CHR ROM in 8KB units (y)
    6:  Flags 6  - Mapper, mirroring, battery, trainer
    7:  Flags 7  - Mapper, VS/Playchoice, NES 2.0
    8:  Flags 8  - PRG-RAM size
    9:  Flags 9  - TV system
    10: Flags 10 - TV system, PRG-RAM presence
    11-15: unused padding
    */
    char header[HEADER_SIZE];
    rom.read(header, HEADER_SIZE);
    
    int x = header[4];
    int y = header[5];

    /* 3. PRG ROM data */
    char prg_rom[PRG_ROM_SIZE*x];
    rom.read(prg_rom, PRG_ROM_SIZE*x);

    /* 4. CHR ROM data */
    rom.read((char *)ram, CHR_ROM_SIZE*y);
    rom.close();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x228, %rsp            # imm = 0x228
movq %rsi, %r14
movq %rdi, %rbx
leaq -0x238(%rbp), %r15
movq %r15, %rdi
callq 0x2160
movq %r15, %rdi
movq %r14, %rsi
movl $0x4, %edx
callq 0x20c0
leaq -0x238(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x10, %edx
callq 0x2190
movq %rsp, %r15
movsbq -0x2c(%rbp), %rdx
movsbq -0x2b(%rbp), %r14
shlq $0xe, %rdx
movq %rsp, %rsi
movl %edx, %eax
subq %rax, %rsi
movq %rsi, %rsp
leaq -0x238(%rbp), %rdi
callq 0x2190
movq (%rbx), %rsi
shlq $0xd, %r14
leaq -0x238(%rbp), %rdi
movq %r14, %rdx
callq 0x2190
leaq -0x238(%rbp), %rdi
callq 0x2040
movq %r15, %rsp
leaq -0x238(%rbp), %rdi
callq 0x2060
leaq -0x18(%rbp), %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x48e4
jmp 0x48e4
movq %rax, %rbx
leaq -0x238(%rbp), %rdi
callq 0x2060
movq %rbx, %rdi
callq 0x2200
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::write_PPUADDR(unsigned char)
void Mem_ppu::write_PPUADDR(uint8_t addr) {
    if (ppuaddr_ptr_hl == 0) {
	//Writing high byte
	PPUADDR = (addr << 8);
	PPUADDR &= 0x3FFF; //Upper adddresses are mirrored
	ppuaddr_ptr_hl = 1;
    }
    else {
	//Writing low byte
	PPUADDR |= (addr & 0x00FF);
	ppuaddr_ptr_hl = 0;
    }
    //Lower bits of ppustatus are the last written bits
    PPUSTATUS = (PPUSTATUS & 0xe0) | (addr & 0x1f);
}

// Assembly:
cmpb $0x0, 0x3c01c(%rdi)
je 0x493a
movzbl %sil, %eax
orw %ax, 0x3c012(%rdi)
xorl %eax, %eax
jmp 0x494d
movzbl %sil, %eax
andl $0x3f, %eax
shll $0x8, %eax
movw %ax, 0x3c012(%rdi)
movb $0x1, %al
movb %al, 0x3c01c(%rdi)
movb 0x3c015(%rdi), %al
andb $-0x20, %al
andb $0x1f, %sil
orb %al, %sil
movb %sil, 0x3c015(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::read_PPUSTATUS()
uint8_t Mem_ppu::read_PPUSTATUS() {
    uint8_t result = PPUSTATUS;
    //Clear the vblank status bit if we are not in vblank
    if (!in_vblank)
	PPUSTATUS = PPUSTATUS & 0x7f;
    //Clear the address latch
    PPUADDR = 0;
    ppuaddr_ptr_hl = 0;
    ppuscroll_ptr_hl = 0;
    oamaddr_ptr_hl = 0;
    return result;
}

// Assembly:
movb 0x3c015(%rdi), %al
cmpb $0x0, 0x3c01f(%rdi)
jne 0x4984
movl %eax, %ecx
andb $0x7f, %cl
movb %cl, 0x3c015(%rdi)
xorl %ecx, %ecx
movw %cx, 0x3c012(%rdi)
movw %cx, 0x3c01c(%rdi)
movb $0x0, 0x3c01e(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::read_PPUDATA()
uint8_t Mem_ppu::read_PPUDATA() {
    uint8_t result;
    if (PPUADDR > 0x3eff) {
	//When ppuaddr is at the pallettes, read normally
	result = read_byte(PPUADDR);
	PPUDATA = result;
    }
    else {
	//If not, then read the internal buffer
	result = PPUDATA;
	PPUDATA = read_byte(PPUADDR);
    }
    //The internal buffer updates anyways

    if (((PPUCTRL >> 2) & 1) == 0) {
	    PPUADDR += 1;
    }
    else {
	    PPUADDR += 32;
    }
    return result;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
movzwl 0x3c012(%rdi), %r14d
cmpl $0x3f00, %r14d          # imm = 0x3F00
jb 0x49c4
movzwl %r14w, %esi
movq %rbx, %rdi
callq 0x46fc
movl %eax, %ebp
jmp 0x49d7
movb 0x3c014(%rbx), %bpl
movzwl %r14w, %esi
movq %rbx, %rdi
callq 0x46fc
movb %al, 0x3c014(%rbx)
leal 0x20(%r14), %eax
leal 0x1(%r14), %ecx
testb $0x4, 0x3c010(%rbx)
cmovnel %eax, %ecx
movw %cx, 0x3c012(%rbx)
movl %ebp, %eax
popq %rbx
popq %r14
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::write_PPUDATA(unsigned char)
void Mem_ppu::write_PPUDATA(uint8_t data) {
    write_byte(PPUADDR, data);
    if (((PPUCTRL >> 2) & 1) == 0) {
	    PPUADDR += 1;
    }
    else {
	    PPUADDR += 32;
    }
    //Lower bits of ppustatus are the last written bits
    PPUSTATUS = (PPUSTATUS & 0xe0) | (data & 0x1f);
}

// Assembly:
movzwl 0x3c012(%rdi), %eax
movl %eax, %ecx
addl $0xffffd000, %ecx       # imm = 0xFFFFD000
movzwl %cx, %ecx
cmpl $0xeff, %ecx            # imm = 0xEFF
ja 0x4a20
leal -0x1000(%rax), %ecx
jmp 0x4a35
leal -0x3f20(%rax), %ecx
movzwl %cx, %edx
leal -0x20(%rax), %ecx
cmpl $0xe0, %edx
cmovael %eax, %ecx
movzwl %cx, %eax
cmpl $0x3f10, %eax           # imm = 0x3F10
je 0x4a5b
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x4a54
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x4a60
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x4a60
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x4a60
movl $0x3f00, %eax           # imm = 0x3F00
movq (%rdi), %rcx
movb %sil, (%rcx,%rax)
testb $0x4, 0x3c010(%rdi)
movl $0x1, %eax
movl $0x20, %ecx
cmovel %eax, %ecx
addw %cx, 0x3c012(%rdi)
movb 0x3c015(%rdi), %al
andb $-0x20, %al
andb $0x1f, %sil
orb %al, %sil
movb %sil, 0x3c015(%rdi)
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::write_OAMADDR(unsigned char)
void Mem_ppu::write_OAMADDR(uint8_t addr) {
    if (oamaddr_ptr_hl == 0) {
	//Writing high byte
	OAMADDR = (addr << 8);
	OAMADDR &= 0x3FFF; //Upper adddresses are mirrored
	oamaddr_ptr_hl = 1;
    }
    else {
	//Writing low byte
	OAMADDR |= (addr & 0x00FF);
	oamaddr_ptr_hl = 0;
    }
    //Lower bits of ppustatus are the last written bits
    PPUSTATUS = (PPUSTATUS & 0xe0) | (addr & 0x1f);
}

// Assembly:
cmpb $0x0, 0x3c01d(%rdi)
je 0x4ab2
movzbl %sil, %eax
orw %ax, 0x3c016(%rdi)
xorl %eax, %eax
jmp 0x4ac5
movzbl %sil, %eax
andl $0x3f, %eax
shll $0x8, %eax
movw %ax, 0x3c016(%rdi)
movb $0x1, %al
movb %al, 0x3c01d(%rdi)
movb 0x3c015(%rdi), %al
andb $-0x20, %al
andb $0x1f, %sil
orb %al, %sil
movb %sil, 0x3c015(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::read_OAMDATA()
uint8_t Mem_ppu::read_OAMDATA() {
    uint8_t result = ram[OAMADDR];
    if (!in_vblank)
	OAMADDR = OAMADDR+1;
    return result;
}

// Assembly:
movq (%rdi), %rax
movzwl 0x3c016(%rdi), %ecx
movb (%rax,%rcx), %al
cmpb $0x0, 0x3c01f(%rdi)
jne 0x4b01
incl %ecx
movw %cx, 0x3c016(%rdi)
retq
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/mem_ppu.cpp
// Function: Mem_ppu::write_PPUSCROLL(unsigned char)
void Mem_ppu::write_PPUSCROLL(uint8_t data) {
    if (ppuscroll_ptr_hl == 0) {
	//Writing high byte
	PPUSCROLL = (data << 8);
	ppuscroll_ptr_hl = 1;
    }
    else {
	//Writing low byte
	PPUSCROLL |= (data & 0x00FF);
	ppuscroll_ptr_hl = 0;
    }
    //Lower bits of ppustatus are the last written bits
    PPUSTATUS = (PPUSTATUS & 0xe0) | (data & 0x1f);
}

// Assembly:
cmpb $0x0, 0x3c01e(%rdi)
je 0x4b58
movzbl %sil, %eax
orw %ax, 0x3c01a(%rdi)
xorl %eax, %eax
jmp 0x4b68
movzbl %sil, %eax
shll $0x8, %eax
movw %ax, 0x3c01a(%rdi)
movb $0x1, %al
movb %al, 0x3c01e(%rdi)
movb 0x3c015(%rdi), %al
andb $-0x20, %al
andb $0x1f, %sil
orb %al, %sil
movb %sil, 0x3c015(%rdi)
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/ppu.cpp
// Function: Ppu::Ppu()
Ppu::Ppu() {
    di = XOpenDisplay(getenv("DISPLAY"));
    //Create window
    int x = 0, y = 0, width = 256, height = 240, border_width = 1;
    sc = DefaultScreen(di);
    ro = DefaultRootWindow(di);
    wi = XCreateSimpleWindow(di, ro, x, y, width, height, border_width, BlackPixel(di, sc), WhitePixel(di, sc));
    XSelectInput(di, wi, KeyPressMask | KeyReleaseMask | ExposureMask);
    XAutoRepeatOff(di);
    gc = XCreateGC(di, ro, 0, NULL);
    XMapWindow(di, wi); //Make window visible
    XStoreName(di, wi, "NEScutre");
    initColors();
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
leaq 0x1b25(%rip), %rdi      # 0x66c8
callq 0x2180
movq %rax, %rdi
callq 0x21b0
movq %rax, 0x10(%rbx)
movslq 0xe0(%rax), %r10
movl %r10d, 0x18(%rbx)
movq 0xe8(%rax), %r11
shlq $0x7, %r10
movq 0x10(%r11,%r10), %rsi
movq %rsi, 0x20(%rbx)
subq $0x8, %rsp
movq %rax, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
movl $0x100, %r8d            # imm = 0x100
movl $0xf0, %r9d
pushq 0x58(%r11,%r10)
pushq 0x60(%r11,%r10)
pushq $0x1
callq 0x2070
addq $0x20, %rsp
movq %rax, 0x28(%rbx)
movq 0x10(%rbx), %rdi
movl $0x8003, %edx           # imm = 0x8003
movq %rax, %rsi
callq 0x20b0
movq 0x10(%rbx), %rdi
callq 0x20d0
movq 0x10(%rbx), %rdi
movq 0x20(%rbx), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2090
movq %rax, 0x30(%rbx)
movq 0x10(%rbx), %rdi
movq 0x28(%rbx), %rsi
callq 0x2150
movq 0x10(%rbx), %rdi
movq 0x28(%rbx), %rsi
leaq 0x1a82(%rip), %rdx      # 0x66d0
callq 0x2050
movq %rbx, %rdi
popq %rbx
jmp 0x4c5c
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/src/ppu.cpp
// Function: Ppu::vblank()
void Ppu::vblank() {
    //Set the vblank bit
    mem_ppu->PPUSTATUS = mem_ppu->PPUSTATUS | 0x80;
    mem_ppu->in_vblank = true;
    if ((mem_ppu->PPUCTRL >> 7) & 1)
	cpu->NMI_execute();
}

// Assembly:
movq 0x8(%rdi), %rax
orb $-0x80, 0x3c015(%rax)
movb $0x1, 0x3c01f(%rax)
cmpb $0x0, 0x3c010(%rax)
js 0x52c2
retq
movq (%rdi), %rdi
jmp 0x3d0e
nop
// File: /workspace/github_cpp_makefile_star2_O1/NGageMegaman[P]NEScutre/main.cpp
// Function: main
int main() {
    int count = 0, n_scanline;
    unsigned int next_vblank = 89342;
    unsigned int next_vblank_end = 89342 + 7746;
    unsigned int next_sprite = 89342 + 7746 + 340;
    Clock nes_clock;
    Mem_ppu nes_mem_ppu;
    nes_mem_ppu.load_rom("smb.nes");
    Cpu nes_cpu;
    nes_cpu.clock = &nes_clock;
    nes_cpu.mem.mem_ppu = &nes_mem_ppu;
    Ppu nes_ppu;
    nes_ppu.cpu = &nes_cpu;
    nes_ppu.mem_ppu = &nes_mem_ppu;
    nes_cpu.mem.di = nes_ppu.di;
    while(1) {
	    nes_cpu.execute();
	    if (nes_clock.cycles >= next_vblank) {
		//usleep(400000);
		for (int i = 0; i<240; ++i)
		    nes_ppu.drawSprites(i);
		nes_ppu.drawScreen();
		count++;
		n_scanline = 0;
	        next_vblank += 89342;
		next_sprite = next_vblank_end + 340;
	        nes_ppu.vblank();
	    }
	    if (nes_clock.cycles >= next_vblank_end) {
		next_vblank_end = next_vblank + 7746;
		nes_mem_ppu.vblank_end();
		nes_mem_ppu.PPUSTATUS = nes_mem_ppu.PPUSTATUS & 0xbf;
	    }
	    //Draw for each scanline
	    //We assume the first sprite always does s0h
	    if (n_scanline != 0xee && nes_clock.cycles >= next_sprite) {
		nes_ppu.draw(n_scanline);
		nes_ppu.checkSprite0Hit(n_scanline);
		next_sprite = next_sprite + 340;
		n_scanline++;
	    }
	   
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4c198, %rsp          # imm = 0x4C198
leaq 0xc(%rsp), %r15
movq %r15, %rdi
callq 0x23dc
leaq 0x10178(%rsp), %rbx
movq %rbx, %rdi
callq 0x46b8
leaq 0x12b7(%rip), %rsi      # 0x65b8
movq %rbx, %rdi
callq 0x4832
leaq 0x148(%rsp), %r14
movq %r14, %rdi
callq 0x23e4
movq %r15, (%r14)
movq %rbx, 0x10008(%r14)
leaq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0x4b98
movq %r14, (%r15)
movq %rbx, 0x8(%r15)
movq 0x10(%r15), %rax
movq %rax, 0x10018(%r14)
movl $0x17c94, %ebx          # imm = 0x17C94
movl $0x17b40, %r13d         # imm = 0x17B40
movl $0x15cfe, %r12d         # imm = 0x15CFE
leaq 0x148(%rsp), %rdi
callq 0x243a
cmpl %r12d, 0xc(%rsp)
jae 0x536c
movl %r14d, %ebp
jmp 0x53a2
xorl %ebp, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x4d4a
incl %ebp
cmpl $0xf0, %ebp
jne 0x536e
movq %r15, %rdi
callq 0x5256
addl $0x15cfe, %r12d         # imm = 0x15CFE
leal 0x154(%r13), %ebx
movq %r15, %rdi
callq 0x52a6
xorl %ebp, %ebp
cmpl %r13d, 0xc(%rsp)
jb 0x53c6
leal 0x1e42(%r12), %r13d
leaq 0x10178(%rsp), %rdi
callq 0x4b86
andb $-0x41, 0x4c18d(%rsp)
movl $0xee, %r14d
cmpl $0xee, %ebp
je 0x5353
movl %ebp, %r14d
cmpl %ebx, 0xc(%rsp)
jb 0x5353
movq %r15, %rdi
movl %ebp, %esi
callq 0x5070
movq %r15, %rdi
movl %ebp, %esi
callq 0x4d32
addl $0x154, %ebx            # imm = 0x154
incl %ebp
movl %ebp, %r14d
jmp 0x5353
// File: /workspace/github_cpp_makefile_star2_O1/araujoigor[P]ipp-compiler/./src/include/IMath.hpp
// Function: IMath::isNumber(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
static bool isNumber(std::string numberStr){
		try{
			std::string::size_type sz;
			std::stof(numberStr, &sz);
			return true;
		}catch(std::invalid_argument& e){
			return false;
		}catch(std::out_of_range& ex){
			std::cout << "Erro ao avaliar string " << numberStr << std::endl;
			return false;
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq (%rdi), %r15
callq 0x8060
movq %rax, %r14
movl (%rax), %r13d
movl $0x0, (%rax)
leaq -0x30(%rbp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x8590
cmpq %r15, (%r12)
je 0xb2ba
movl (%r14), %eax
testl %eax, %eax
je 0xb2a6
cmpl $0x22, %eax
jne 0xb2a9
leaq 0x20dca(%rip), %rdi     # 0x2c06b
callq 0x85f0
movl %r13d, (%r14)
movb $0x1, %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x20daa(%rip), %rdi     # 0x2c06b
callq 0x8260
movq %rax, %r15
cmpl $0x0, (%r14)
jne 0xb2d2
movl %r13d, (%r14)
cmpl $0x2, %edx
jne 0xb2e1
movq %r15, %rdi
callq 0x8190
jmp 0xb321
cmpl $0x1, %edx
jne 0xb332
movq %r15, %rdi
callq 0x8190
movq 0x31cd3(%rip), %rdi     # 0x3cfc8
leaq 0x20d57(%rip), %rsi     # 0x2c053
movl $0x17, %edx
callq 0x8460
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq 0x31cb4(%rip), %rdi     # 0x3cfc8
callq 0x8460
movq %rax, %rdi
callq 0x81e0
callq 0x8700
xorl %eax, %eax
jmp 0xb2ab
movq %rax, %r15
callq 0x8700
movq %r15, %rdi
callq 0x87b0
movq %rax, %rdi
callq 0xc37e
// File: /workspace/github_cpp_makefile_star2_O1/araujoigor[P]ipp-compiler/./src/include/IDefinition.hpp
// Function: IDefinition::addVar(IData*)
void addVar(IData *var){
		vars.push_back(var);

		if(ownerBlock == NULL)
			scheduledVariableRegister = true;
		else
			ownerBlock->registerLocalVariable(var, myLine);
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rsi, %rax
movq %rdi, %rbx
movq %rsi, -0x10(%rbp)
movq 0x40(%rdi), %rsi
cmpq 0x48(%rdi), %rsi
je 0xb6aa
movq %rax, (%rsi)
addq $0x8, 0x40(%rbx)
jmp 0xb6b7
leaq 0x38(%rbx), %rdi
leaq -0x10(%rbp), %rdx
callq 0xeea8
movq 0x10(%rbx), %rdi
testq %rdi, %rdi
je 0xb6ce
movq -0x10(%rbp), %rsi
movl 0x8(%rbx), %edx
callq 0xed48
jmp 0xb6d5
movb $0x1, 0xb0(%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/araujoigor[P]ipp-compiler/./src/include/IDefinition.hpp
// Function: IDefinition::addVar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*)
void addVar(std::string *leftVar, std::string *rightVar){
		varEqualsVarMapping[*leftVar] = *rightVar;

		if(ownerBlock == NULL)
			scheduledVariableRegister = true;
		else
			ownerBlock->registerLocalVariable(generateVariable(&type, leftVar), myLine);
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
addq $0x50, %rdi
callq 0xefe2
movq %rax, %rdi
movq %r15, %rsi
callq 0x8230
movq 0x10(%rbx), %r15
testq %r15, %r15
je 0xb730
leaq 0x18(%rbx), %rdi
movq %r14, %rsi
callq 0x91ae
movl 0x8(%rbx), %edx
movq %r15, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0xed48
movb $0x1, 0xb0(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O1/araujoigor[P]ipp-compiler/./src/include/IMath.hpp
// Function: IMath::IMath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*)
IMath(std::string *newExpression){
		expression.clear();
		expression.push_back('(');
		expression.append(*newExpression);
		expression.push_back(')');
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x10(%rdi), %r12
movq %r12, (%rdi)
movq $0x0, 0x8(%rdi)
movb $0x0, 0x10(%rdi)
leaq 0x20(%rdi), %r14
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rdi)
movups %xmm0, 0x2c(%rdi)
movl $0x1, 0x3c(%rdi)
movl $0x28, %esi
callq 0x8310
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %rbx, %rdi
callq 0x8120
movq %rbx, %rdi
movl $0x29, %esi
callq 0x8310
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r15
movq %r14, %rdi
callq 0xf39a
movq (%rbx), %rdi
cmpq %r12, %rdi
je 0xb7c3
callq 0x8350
movq %r15, %rdi
callq 0x87b0
nop
// File: /workspace/github_cpp_makefile_star2_O1/araujoigor[P]ipp-compiler/./src/include/IDefinition.hpp
// Function: IDefinition::addVar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, IMath*)
void addVar(std::string *leftValue, IMath *rightVar){
		varEqualsMathMapping[*leftValue] = rightVar;

		if(ownerBlock == NULL)
			scheduledVariableRegister = true;
		else
			ownerBlock->registerLocalVariable(generateVariable(&type, leftValue), myLine);
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
addq $0x80, %rdi
callq 0xf3e8
movq %r15, (%rax)
movq 0x10(%rbx), %r15
testq %r15, %r15
je 0xb81b
leaq 0x18(%rbx), %rdi
movq %r14, %rsi
callq 0x91ae
movl 0x8(%rbx), %edx
movq %r15, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0xed48
movb $0x1, 0xb0(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O1/araujoigor[P]ipp-compiler/./src/include/IMath.hpp
// Function: IMath::isInteger(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
static bool isInteger(std::string numberStr){
		if(isNumber(numberStr)){
			if(numberStr.find(".") != std::string::npos || numberStr.find("e") != std::string::npos ||
					numberStr.find("E") != std::string::npos)
				return false;

			return true;
		}

		return false;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
leaq -0x28(%rbp), %r15
movq %r15, -0x10(%r15)
movq (%rdi), %rsi
movq 0x8(%rdi), %rdx
addq %rsi, %rdx
leaq -0x38(%rbp), %r14
movq %r14, %rdi
callq 0x10d2a
movq %r14, %rdi
callq 0xb254
movl %eax, %r14d
movq -0x38(%rbp), %rdi
cmpq %r15, %rdi
je 0xb92d
callq 0x8350
testb %r14b, %r14b
je 0xb990
leaq 0x24e6e(%rip), %rsi     # 0x307a7
xorl %r14d, %r14d
movl $0x1, %ecx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x8790
cmpq $-0x1, %rax
jne 0xb993
leaq 0x209b5(%rip), %rsi     # 0x2c30d
xorl %r14d, %r14d
movl $0x1, %ecx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x8790
cmpq $-0x1, %rax
jne 0xb993
leaq 0x207d1(%rip), %rsi     # 0x2c148
movl $0x1, %ecx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x8790
cmpq $-0x1, %rax
sete %r14b
jmp 0xb993
xorl %r14d, %r14d
movl %r14d, %eax
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq -0x38(%rbp), %rdi
cmpq %r15, %rdi
je 0xb9b2
callq 0x8350
movq %rbx, %rdi
callq 0x87b0