LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/OHeapReadPathEviction.cpp
// Function: OHeapReadPathEviction::extractMin()
Block OHeapReadPathEviction::extractMin() {
  Block min_block = this->onlyFindMin();
  Block ret = this->onlyDeleteBlock(min_block.leaf_id, min_block.t);

  if (this->type_hiding_security) {
    this->insertDummyBlock();
  }

  this->t++;
  return ret;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x40, %rsp
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x3c22
movl (%r15), %edx
movq 0x8(%r15), %rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3cda
cmpb $0x1, 0x28(%rbx)
jne 0x3f6e
movq %rbx, %rdi
callq 0x407c
incq 0x20(%rbx)
movq %r14, %rax
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/OHeapReadPathEviction.cpp
// Function: OHeapReadPathEviction::decreaseKey(int, long)
std::pair<int, int> OHeapReadPathEviction::decreaseKey(int leaf, long t) {
  if (this->type_hiding_security) {
    this->onlyFindMin();
  }

  Block old_block = this->onlyDeleteBlock(leaf, t);
  auto ret = this->onlyInsertBlock(old_block.k - 1, old_block.v);

  this->t++;
  return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x78, %rsp
movq %rdx, %r14
movl %esi, %ebp
movq %rdi, %rbx
cmpb $0x1, 0x28(%rdi)
jne 0x3fa5
leaq 0x40(%rsp), %rdi
movq %rbx, %rsi
callq 0x3c22
leaq 0x40(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movl %ebp, %edx
movq %r14, %rcx
callq 0x3cda
movl 0x10(%r15), %esi
decl %esi
movups 0x14(%r15), %xmm0
movaps %xmm0, 0x20(%rsp)
movups 0x24(%r15), %xmm0
movaps %xmm0, 0x30(%rsp)
movaps 0x20(%rsp), %xmm0
movaps 0x30(%rsp), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x3eb6
incq 0x20(%rbx)
addq $0x78, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/OHeapReadPathEviction.cpp
// Function: OHeapReadPathEviction::evictAfterInsert()
void OHeapReadPathEviction::evictAfterInsert() {
  // two random paths non-overlapping except at the root
  // = random leaf_id in the first half and random leaf_id in the second half (over all leaf_ids)
  int random_leaf_one = this->rand_gen->getRandomLeaf()/2;
  int random_leaf_two = this->rand_gen->getRandomLeaf()/2 + this->num_leaves/2;

  this->evictAndUpdateMin(random_leaf_one);
  this->evictAndUpdateMin(random_leaf_two);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x38(%rdi), %rdi
movq (%rdi), %rax
callq *(%rax)
pushq $0x2
popq %r15
cltd
idivl %r15d
movl %eax, %ebp
movq 0x38(%rbx), %rdi
movq (%rdi), %rax
callq *(%rax)
cltd
idivl %r15d
movl %eax, %r14d
movl 0x10(%rbx), %eax
cltd
idivl %r15d
addl %eax, %r14d
movq %rbx, %rdi
movl %ebp, %esi
callq 0x40d2
movq %rbx, %rdi
movl %r14d, %esi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x40d2
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/OHeapReadPathEviction.cpp
// Function: OHeapReadPathEviction::readAndRemove(int, long)
Block OHeapReadPathEviction::readAndRemove(int leaf, long t) {
  if (leaf != -1 && t != -1) {
    Block ret;    
    for (int l = 0; l < this->num_levels; l++) {
      int p = this->P(leaf, l);
      Bucket bucket_on_path = this->storage->readBucket(p);
      std::optional<Block> possible_ret = bucket_on_path.removeBlock(t);
      if (possible_ret.has_value()) {
        ret = possible_ret.value();
        bucket_on_path.addBlock(Block());  // for obliviousness
      }
      this->storage->writeBucket(p, bucket_on_path);
    }
    return ret;
  } else {
    // dummy ops
    leaf = this->rand_gen->getRandomLeaf();
    for (int l = 0; l < num_levels; l++) {
      int p = this->P(leaf, l);
      Bucket b = this->storage->readBucket(p);
      this->storage->writeBucket(p, b);
    }
    return Block();
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, %r14
movq %rdi, %rbp
movl %edx, 0x4(%rsp)
cmpl $-0x1, %edx
sete %al
movq %rcx, 0x8(%rsp)
cmpq $-0x1, %rcx
sete %cl
orb %al, %cl
jne 0x4532
movq %rbp, %rdi
callq 0x24f8
xorl %r13d, %r13d
leaq 0xa0(%rsp), %rbx
cmpl 0xc(%r14), %r13d
jge 0x4599
movq (%r14), %rax
movq %r14, %rdi
movl 0x4(%rsp), %esi
movl %r13d, %edx
callq *0x30(%rax)
movl %eax, %r15d
movq 0x30(%r14), %rsi
movq (%rsi), %rax
leaq 0x10(%rsp), %r12
movq %r12, %rdi
movl %r15d, %edx
callq *0x8(%rax)
leaq 0x60(%rsp), %rdi
movq %r12, %rsi
movq 0x8(%rsp), %rdx
callq 0x26ee
cmpb $0x1, 0x98(%rsp)
jne 0x450e
movl %r13d, (%rsp)
movl 0x90(%rsp), %eax
movl %eax, 0x30(%rbp)
movups 0x60(%rsp), %xmm0
movups 0x70(%rsp), %xmm1
movups 0x80(%rsp), %xmm2
movups %xmm2, 0x20(%rbp)
movups %xmm1, 0x10(%rbp)
movq %rbp, %r12
movups %xmm0, (%rbp)
movq %rbx, %rbp
movq %rbx, %rdi
callq 0x24f8
leaq 0x10(%rsp), %rdi
movq %rbp, %rsi
callq 0x26c8
movq %r12, %rbp
movl (%rsp), %r13d
movq 0x30(%r14), %rdi
movq (%rdi), %rax
movl %r15d, %esi
leaq 0x10(%rsp), %rdx
callq *0x10(%rax)
leaq 0x48(%rsp), %rdi
callq 0x2898
incl %r13d
jmp 0x4472
movq %rbp, %rbx
movq 0x38(%r14), %rdi
movq (%rdi), %rax
callq *(%rax)
movl %eax, %ebp
xorl %r12d, %r12d
leaq 0x10(%rsp), %r13
cmpl 0xc(%r14), %r12d
jge 0x458e
movq (%r14), %rax
movq %r14, %rdi
movl %ebp, %esi
movl %r12d, %edx
callq *0x30(%rax)
movl %eax, %r15d
movq 0x30(%r14), %rsi
movq (%rsi), %rax
movq %r13, %rdi
movl %r15d, %edx
callq *0x8(%rax)
movq 0x30(%r14), %rdi
movq (%rdi), %rax
movl %r15d, %esi
movq %r13, %rdx
callq *0x10(%rax)
leaq 0x48(%rsp), %rdi
callq 0x2898
incl %r12d
jmp 0x4548
movq %rbx, %rbp
movq %rbx, %rdi
callq 0x24f8
movq %rbp, %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x45b2
jmp 0x45b2
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
callq 0x2898
movq %rbx, %rdi
callq 0x2240
nop
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/OHeapReadPathEviction.cpp
// Function: operator<<(std::ostream&, OHeapReadPathEviction const&)
std::ostream& operator<<(std::ostream& out, const OHeapReadPathEviction& oheap) {
  out << "==========" << std::endl;
  for (int i = 0; i < oheap.num_buckets; i++) {
    std::vector<Block> blocks = oheap.storage->readBucket(i).getBlocks();
    bool all_dummy = true;
    for (const Block& bl : blocks) {
      if (bl.leaf_id != -1) {
        all_dummy = false;
        break;
      }
    }
    if (!all_dummy) {
      out << "Bucket " << i << " contains:" << std::endl;
    
      for (int j = 0; j < oheap.bucket_size; j++) {
        const Block& bl = blocks.at(j);
        if (bl.leaf_id != -1) {
          out << bl << std::endl;
        }
      }

      out << std::endl;
    }
  }
  out << "==========" << std::endl;
  return out;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x2849(%rip), %rsi      # 0x7248
callq 0x2140
movq %rax, %rdi
callq 0x20b0
xorl %r12d, %r12d
leaq 0x18(%rsp), %r13
movq %rsp, %rbp
cmpl 0x18(%r14), %r12d
jge 0x4ae2
movq 0x30(%r14), %rsi
movq (%rsi), %rax
movq %r13, %rdi
movl %r12d, %edx
callq *0x8(%rax)
movq %r13, %rdi
callq 0x278c
movq %rbp, %rdi
movq %rax, %rsi
callq 0x4b56
leaq 0x50(%rsp), %rdi
callq 0x2898
movq (%rsp), %rcx
movq 0x8(%rsp), %rax
cmpq %rax, %rcx
je 0x4ad2
cmpl $-0x1, (%rcx)
leaq 0x38(%rcx), %rcx
je 0x4a57
movq %rbx, %rdi
leaq 0x2993(%rip), %rsi      # 0x7402
callq 0x2140
movq %rax, %rdi
movl %r12d, %esi
callq 0x2230
movq %rax, %rdi
leaq 0x27ca(%rip), %rsi      # 0x7253
callq 0x2140
movq %rax, %rdi
callq 0x20b0
xorl %r15d, %r15d
movslq 0x8(%r14), %rax
cmpq %rax, %r15
jge 0x4aca
movq %rbp, %rdi
movq %r15, %rsi
callq 0x2836
cmpl $-0x1, (%rax)
je 0x4ac5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2562
movq %rax, %rdi
callq 0x20b0
incq %r15
jmp 0x4a99
movq %rbx, %rdi
callq 0x20b0
movq %rbp, %rdi
callq 0x2898
incl %r12d
jmp 0x4a17
leaq 0x275f(%rip), %rsi      # 0x7248
movq %rbx, %rdi
callq 0x2140
movq %rax, %rdi
callq 0x20b0
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
jmp 0x4b1d
jmp 0x4b17
movq %rax, %rbx
movq %rsp, %rdi
callq 0x2898
movq %rbx, %rdi
callq 0x2240
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/RandomForOHeap.cpp
// Function: RandomForOHeap::RandomForOHeap()
RandomForOHeap::RandomForOHeap() {
  if (RandomForOHeap::is_initialized) {
    throw std::runtime_error("Only one random instance can be used at a time!");
  }

  this->bound = -1;
  rnd_generator.seed(0L);
  this->seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
  RandomForOHeap::is_initialized  = true;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
leaq 0x54d9(%rip), %rax      # 0xad20
movq %rax, (%rdi)
movq $0x1, 0x10(%rdi)
andq $0x0, 0x18(%rdi)
cmpb $0x1, 0x590b(%rip)      # 0xb169
je 0x5886
orl $-0x1, 0x8(%rdi)
andq $0x0, 0x10(%rdi)
movabsq $0x5deece66d, %rax      # imm = 0x5DEECE66D
movq %rax, 0x18(%rdi)
movb $0x1, 0x58eb(%rip)      # 0xb169
addq $0x8, %rsp
popq %rbx
popq %r14
retq
pushq $0x10
popq %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x1a39(%rip), %rsi      # 0x72d1
movq %rax, %rdi
callq 0x2080
movq 0x5749(%rip), %rsi      # 0xaff0
movq 0x571a(%rip), %rdx      # 0xafc8
movq %rbx, %rdi
callq 0x2220
movq %rax, %r14
movq %rbx, %rdi
callq 0x2100
movq %r14, %rdi
callq 0x2240
nop
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/RandomForOHeap.cpp
// Function: RandomForOHeap::getRandomLeaf()
int RandomForOHeap::getRandomLeaf() {
  if (this->bound == -1) {
    throw std::runtime_error("Bound is not set.");
  }

  long next = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
  this->seed = next;
  int bits = next >> (48 - 31);
  if ((this->bound & -this->bound) == this->bound) {  // if bound is a power of 2
    return (int)((this->bound * (long)bits) >> 31);
  }
  int val = bits % this->bound;
  while (bits - val + (this->bound-1) < 0) {
    next = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
    this->seed = next;
    bits = next >> (48 - 31);
    val = bits % this->bound;
  }
  return val;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movslq 0x8(%rdi), %rsi
cmpq $-0x1, %rsi
je 0x5946
movabsq $0xffffffffffff, %r8    # imm = 0xFFFFFFFFFFFF
movabsq $0x5deece66d, %r9       # imm = 0x5DEECE66D
movq 0x18(%rdi), %r10
imulq %r9, %r10
addq $0xb, %r10
andq %r8, %r10
movq %r10, 0x18(%rdi)
movq %r10, %rcx
shrq $0x11, %rcx
leal -0x1(%rsi), %eax
testl %eax, %esi
jne 0x5917
imulq %rsi, %rcx
shrq $0x1f, %rcx
jmp 0x593c
movl %ecx, %eax
cltd
idivl %esi
addl %esi, %ecx
cmpl %ecx, %edx
js 0x593a
imulq %r9, %r10
addq $0xb, %r10
andq %r8, %r10
movq %r10, 0x18(%rdi)
movq %r10, %rcx
shrq $0x11, %rcx
jmp 0x5917
movl %edx, %ecx
movl %ecx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
pushq $0x10
popq %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x19a9(%rip), %rsi      # 0x7301
movq %rax, %rdi
callq 0x2080
movq 0x5689(%rip), %rsi      # 0xaff0
movq 0x565a(%rip), %rdx      # 0xafc8
movq %rbx, %rdi
callq 0x2220
movq %rax, %r14
movq %rbx, %rdi
callq 0x2100
movq %r14, %rdi
callq 0x2240
nop
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/ServerStorage.cpp
// Function: ServerStorage::setCapacity(int)
void ServerStorage::setCapacity(int total_num_of_buckets) {
  if (this->is_capacity_set) {
    throw std::runtime_error("Capacity of ServerStorage cannot be changed");
  }
  this->is_capacity_set = true;
  this->capacity = total_num_of_buckets;
  this->buckets.assign(total_num_of_buckets, Bucket());
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x50, %rsp
cmpb $0x1, 0x5744(%rip)      # 0xb16c
je 0x5a6b
movq %rdi, %rbx
movb $0x1, 0x5738(%rip)      # 0xb16c
movl %esi, 0x8(%rdi)
addq $0x10, %rbx
movslq %esi, %r14
movq %rsp, %r15
movq %r15, %rdi
callq 0x264c
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x5fcc
leaq 0x38(%rsp), %rdi
callq 0x2898
addq $0x50, %rsp
popq %rbx
popq %r14
popq %r15
retq
pushq $0x10
popq %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x1904(%rip), %rsi      # 0x7381
movq %rax, %rdi
callq 0x2080
movq 0x5564(%rip), %rsi      # 0xaff0
movq 0x5535(%rip), %rdx      # 0xafc8
movq %rbx, %rdi
callq 0x2220
movq %rax, %r14
movq %rbx, %rdi
callq 0x2100
jmp 0x5ab5
movq %rax, %r14
leaq 0x38(%rsp), %rdi
callq 0x2898
movq %r14, %rdi
callq 0x2240
nop
// File: /workspace/github_cpp_makefile_star2_O2/obliviousram[P]PathOHeap/src/ServerStorage.cpp
// Function: ServerStorage::checkRWValid(int)
void ServerStorage::checkRWValid(int position) {
  if (!this->is_capacity_set) {
    throw std::runtime_error("Please call setCapacity before reading or writing any block");
  }
  if (position >= this->capacity || position < 0) {
    throw std::runtime_error("You are trying to access Bucket " + std::to_string(position) +
        ", but this Server contains only " + std::to_string(this->capacity) + " buckets.");
  }
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0xc0, %rsp
cmpb $0x0, 0x569c(%rip)      # 0xb16c
je 0x5aed
movl %esi, %ebp
movq %rdi, %r14
testl %esi, %esi
js 0x5b1d
cmpl %ebp, 0x8(%r14)
jle 0x5b1d
addq $0xc0, %rsp
popq %rbx
popq %r14
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x18ae(%rip), %rsi      # 0x73ad
movq %rax, %rdi
callq 0x2080
movq 0x54e2(%rip), %rsi      # 0xaff0
movq 0x54b3(%rip), %rdx      # 0xafc8
movq %rbx, %rdi
callq 0x2220
pushq $0x10
popq %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
movl %ebp, %esi
callq 0x5d63
leaq 0x18ae(%rip), %rsi      # 0x73e9
leaq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x5d3f
leaq 0x18b9(%rip), %rdx      # 0x740a
leaq 0x60(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x5cb9
movl 0x8(%r14), %esi
movq %rsp, %rdi
callq 0x5d63
leaq 0x80(%rsp), %rdi
leaq 0x60(%rsp), %rsi
movq %rsp, %rdx
callq 0x5cd8
leaq 0x18a3(%rip), %rdx      # 0x742b
leaq 0xa0(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x5cb9
movb $0x1, %bpl
leaq 0xa0(%rsp), %rsi
movq %rbx, %rdi
callq 0x21f0
xorl %ebp, %ebp
movq 0x5437(%rip), %rsi      # 0xaff0
movq 0x5408(%rip), %rdx      # 0xafc8
movq %rbx, %rdi
callq 0x2220
movq %rax, %r14
leaq 0xa0(%rsp), %rdi
callq 0x20a0
jmp 0x5be0
movq %rax, %r14
movb $0x1, %bpl
leaq 0x80(%rsp), %rdi
callq 0x20a0
jmp 0x5bf5
movq %rax, %r14
movb $0x1, %bpl
movq %rsp, %rdi
callq 0x20a0
jmp 0x5c05
movq %rax, %r14
movb $0x1, %bpl
leaq 0x60(%rsp), %rdi
callq 0x20a0
jmp 0x5c17
movq %rax, %r14
movb $0x1, %bpl
leaq 0x40(%rsp), %rdi
callq 0x20a0
jmp 0x5c29
movq %rax, %r14
movb $0x1, %bpl
leaq 0x20(%rsp), %rdi
callq 0x20a0
testb %bpl, %bpl
jne 0x5c3f
jmp 0x5c47
jmp 0x5c3c
movq %rax, %r14
movq %rbx, %rdi
callq 0x2100
movq %r14, %rdi
callq 0x2240
nop
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::Cpu()
Cpu::Cpu() {
    regX = regY = regA = 0x00;
    regPC = mem.read_word(0xFFFC);
    regSP = 0x01ff;
    regP.C = regP.Z = regP.I = regP.D = regP.B = regP.V = regP.N = 0;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x8(%rdi), %r14
movq %r14, %rdi
callq 0x2b2c
andw $0x0, 0x10020(%rbx)
movb $0x0, 0x10022(%rbx)
movq %r14, %rdi
movl $0xfffc, %esi           # imm = 0xFFFC
callq 0x2c9c
movw %ax, 0x10024(%rbx)
movw $0x1ff, 0x10026(%rbx)   # imm = 0x1FF
andl $0x0, 0x10028(%rbx)
andl $0x0, 0x1002b(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::ASL_mem_execute(unsigned short, unsigned char)
void Cpu::ASL_mem_execute(uint16_t address, uint8_t operand) {
    // Arithmetic shift left (Memory content)
    // M,Z,C,N = M*2

    uint8_t result = operand << 1;

    mem.write_byte(address, result);

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

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movl %edx, %ebx
movq %rdi, %r14
leal (%rbx,%rbx), %eax
addq $0x8, %rdi
movzbl %al, %ebp
movl %ebp, %edx
callq 0x2cee
testb %bpl, %bpl
sete 0x10029(%r14)
shrb $0x7, %bl
movb %bl, 0x10028(%r14)
shrb $0x7, %bpl
movb %bpl, 0x1002e(%r14)
popq %rbx
popq %r14
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::BRK_execute()
void Cpu::BRK_execute() {
    // Force 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 and the Break command
    regPC = mem.read_word(BRK_INT_VECTOR_ADDR);
    regP.B = 1;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
movzwl 0x10024(%rdi), %ebp
movl %ebp, %esi
shrl $0x8, %esi
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), %r14b
movb 0x1002a(%rdi), %al
shlb $0x2, %al
orb %cl, %al
addb %r14b, %r14b
orb %al, %r14b
orb 0x10028(%rdi), %r14b
callq 0x27d4
movzbl %bpl, %esi
movq %rbx, %rdi
callq 0x27d4
movzbl %r14b, %esi
movq %rbx, %rdi
callq 0x27d4
leaq 0x8(%rbx), %rdi
movl $0xfffe, %esi           # imm = 0xFFFE
callq 0x2c9c
movw %ax, 0x10024(%rbx)
movb $0x1, 0x1002c(%rbx)
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::DEC_execute(unsigned short, unsigned char)
void Cpu::DEC_execute(uint16_t address, uint8_t operand) {
    //Decrement memory
    //M,Z,N = M-1

    int8_t result = operand-1;
    mem.write_byte(address, result);

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

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
decb %dl
addq $0x8, %rdi
movzbl %dl, %ebp
movl %ebp, %edx
callq 0x2cee
testb %bpl, %bpl
sete 0x10029(%rbx)
shrb $0x7, %bpl
movb %bpl, 0x1002e(%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::INC_execute(unsigned short, unsigned char)
void Cpu::INC_execute(uint16_t address, uint8_t operand) {
    //Increment memory
    //M,Z,N = M+1

    uint8_t result = operand + 1;
    mem.write_byte(address, result);

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

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebx
movq %rdi, %r14
leal 0x1(%rbx), %eax
addq $0x8, %rdi
movzbl %al, %edx
callq 0x2cee
incb %bl
sete 0x10029(%r14)
shrb $0x7, %bl
movb %bl, 0x1002e(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::JSR_execute(unsigned short)
void Cpu::JSR_execute(uint16_t address) {
    //Jump to subroutine

    uint16_t returnAddr = regPC - 1; //Last byte of the instruction
    pushStack((returnAddr >> 8) & 0x00ff); //high
    pushStack(returnAddr & 0x00ff); //low
    regPC = address;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movl %esi, %ebp
movq %rdi, %r14
movl 0x10024(%rdi), %ebx
decl %ebx
movzbl %bh, %esi
callq 0x27d4
movzbl %bl, %esi
movq %r14, %rdi
callq 0x27d4
movw %bp, 0x10024(%r14)
popq %rbx
popq %r14
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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:
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
movzbl %al, %esi
jmp 0x27d4
nop
// File: /workspace/github_cpp_makefile_star2_O2/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
callq 0x27f4
movb %al, 0x10020(%rbx)
testb %al, %al
sete 0x10029(%rbx)
shrb $0x7, %al
movb %al, 0x1002e(%rbx)
popq %rbx
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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
callq 0x27f4
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
// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
pushq %rax
movq %rdi, %rbx
callq 0x27f4
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)
movq %rbx, %rdi
callq 0x27f4
movl %eax, %ebp
movq %rbx, %rdi
callq 0x27f4
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ecx
orl %eax, %ecx
movw %cx, 0x10024(%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
pushq %rax
movq %rdi, %rbx
callq 0x27f4
movl %eax, %ebp
movq %rbx, %rdi
callq 0x27f4
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ecx
addl %ecx, %eax
incl %eax
movw %ax, 0x10024(%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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 0x2be2
movl %eax, %ebp
movl 0x10024(%r12), %esi
addl $0x2, %esi
andl %r13d, %esi
movq %rbx, %rdi
callq 0x2be2
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %ebp
orl %eax, %ebp
addw $0x3, 0x10024(%r12)
movl $0x3, (%r15)
xorl %eax, %eax
leal -0x8c(%r14), %ecx
cmpl $0x3, %ecx
jb 0x2434
cmpl $0xc, %r14d
je 0x2434
cmpl $0x20, %r14d
je 0x2434
cmpl $0x4c, %r14d
je 0x2434
movzwl %bp, %esi
movq %rbx, %rdi
callq 0x2be2
movzbl %al, %eax
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_O2/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 0x2be2
addw $0x2, 0x10024(%r14)
andl $0x0, (%rbx)
movzbl %al, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_cpp_makefile_star2_O2/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 0x2be2
movzbl %al, %ebp
movb 0x10021(%r14), %al
addb %bpl, %al
movzbl %al, %esi
movq %r15, %rdi
callq 0x2c9c
movzwl %ax, %esi
movq %r15, %rdi
callq 0x2be2
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_O2/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 0x2be2
movzbl %al, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x2be2
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_O2/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 0x2be2
movl %eax, %ebp
movl 0x10024(%r14), %esi
addl $0x2, %esi
andl %r12d, %esi
movq %r15, %rdi
callq 0x2be2
movzbl %al, %eax
shll $0x8, %eax
movzbl %bpl, %esi
orl %eax, %esi
andl %r12d, %esi
movq %r15, %rdi
callq 0x2c9c
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_O2/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 0x2be2
movzbl %al, %esi
movq %r15, %rdi
callq 0x2c9c
movl %eax, %r12d
movzbl 0x10022(%r14), %eax
addl %eax, %r12d
andl %r12d, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x2be2
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_O2/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 0x2be2
addb 0x10021(%r14), %al
movzbl %al, %ebp
movq %r15, %rdi
movl %ebp, %esi
callq 0x2be2
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_O2/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 0x2be2
movl %eax, %r12d
movl 0x10024(%r14), %esi
addl $0x2, %esi
andl %ebp, %esi
movq %r15, %rdi
callq 0x2be2
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 0x2be2
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_O2/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 %r14
pushq %rbx
movq %rdi, %rbx
movzwl 0x10024(%rdi), %ebp
movl %ebp, %esi
shrl $0x8, %esi
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), %r14b
movb 0x1002a(%rdi), %al
shlb $0x2, %al
orb %cl, %al
addb %r14b, %r14b
orb %al, %r14b
orb 0x10028(%rdi), %r14b
callq 0x27d4
movzbl %bpl, %esi
movq %rbx, %rdi
callq 0x27d4
movzbl %r14b, %esi
movq %rbx, %rdi
callq 0x27d4
leaq 0x8(%rbx), %rdi
movl $0xfffa, %esi           # imm = 0xFFFA
callq 0x2c9c
movw %ax, 0x10024(%rbx)
popq %rbx
popq %r14
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/mem.cpp
// Function: Mem::Mem()
Mem::Mem() {
    //Mem init with 0s
    for (int i = 0; i<=RAM_SIZE; ++i) {
	ram[i] = 0x00;
    }
    
    load_rom("smb.nes");
}

// Assembly:
xorl %eax, %eax
cmpq $0x10001, %rax          # imm = 0x10001
je 0x2b3f
movb $0x0, (%rdi,%rax)
incq %rax
jmp 0x2b2e
leaq 0x1a72(%rip), %rsi      # 0x45b8
jmp 0x2b4c
nop
// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/mem.cpp
// Function: Mem::load_rom(char*)
void Mem::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
    */
    rom.read((char *)ram, HEADER_SIZE);
    
    int x = ram[4];
    //int y = ram[5];

    /* 3. PRG ROM data */
    rom.read((char *)ram+0x8000, PRG_ROM_SIZE*x);

    ram[0xfffc] = 0x00;
    ram[0xfffd] = 0x80;

    rom.close();
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x210, %rsp            # imm = 0x210
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x1130
pushq $0x4
popq %rdx
movq %r15, %rdi
movq %r14, %rsi
callq 0x10b0
leaq 0x8(%rsp), %rdi
pushq $0x10
popq %rdx
movq %rbx, %rsi
callq 0x1150
movzbl 0x4(%rbx), %edx
leaq 0x8000(%rbx), %rsi
shll $0xe, %edx
leaq 0x8(%rsp), %rdi
callq 0x1150
movw $0x8000, 0xfffc(%rbx)   # imm = 0x8000
leaq 0x8(%rsp), %rdi
callq 0x1030
leaq 0x8(%rsp), %rdi
callq 0x1050
addq $0x210, %rsp            # imm = 0x210
popq %rbx
popq %r14
popq %r15
retq
jmp 0x2bcd
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x1050
movq %rbx, %rdi
callq 0x11c0
// File: /workspace/github_cpp_makefile_star2_O2/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:
cmpw $0x800, %si             # imm = 0x800
jb 0x2c17
cmpw $0xfff, %si             # imm = 0xFFF
ja 0x2bf8
addl $0xfffff800, %esi       # imm = 0xFFFFF800
jmp 0x2c17
cmpw $0x17ff, %si            # imm = 0x17FF
ja 0x2c07
addl $0xfffff000, %esi       # imm = 0xFFFFF000
jmp 0x2c17
leal -0x1800(%rsi), %eax
cmpw $0x2000, %si            # imm = 0x2000
cmovael %esi, %eax
movl %eax, %esi
leal -0x2008(%rsi), %eax
movl %esi, %ecx
andl $0x2007, %ecx           # imm = 0x2007
cmpw $0x1ff8, %ax            # imm = 0x1FF8
cmovael %esi, %ecx
movzwl %cx, %eax
leal -0x2000(%rax), %ecx
cmpl $0x7, %ecx
ja 0x2c56
leaq 0x1907(%rip), %rdx      # 0x4548
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq 0x10000(%rdi), %rdi
jmp 0x3240
cmpl $0x4016, %eax           # imm = 0x4016
jne 0x2c73
movb 0x10008(%rdi), %cl
movl %ecx, %eax
andb $0x1, %al
shrb %cl
orb $-0x80, %cl
movb %cl, 0x10008(%rdi)
retq
movb (%rdi,%rax), %al
retq
movq 0x10000(%rdi), %rdi
jmp 0x32ae
movq 0x10000(%rdi), %rdi
jmp 0x32e0
movq 0x10000(%rdi), %rdi
jmp 0x3428
nop
// File: /workspace/github_cpp_makefile_star2_O2/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:
cmpw $0x800, %si             # imm = 0x800
jb 0x2cd1
cmpw $0xfff, %si             # imm = 0xFFF
ja 0x2cb2
addl $0xfffff800, %esi       # imm = 0xFFFFF800
jmp 0x2cd1
cmpw $0x17ff, %si            # imm = 0x17FF
ja 0x2cc1
addl $0xfffff000, %esi       # imm = 0xFFFFF000
jmp 0x2cd1
leal -0x1800(%rsi), %eax
cmpw $0x2000, %si            # imm = 0x2000
cmovael %esi, %eax
movl %eax, %esi
leal -0x2008(%rsi), %eax
movl %esi, %ecx
andl $0x2007, %ecx           # imm = 0x2007
cmpw $0x1ff8, %ax            # imm = 0x1FF8
cmovael %esi, %ecx
movzwl %cx, %eax
movzwl (%rdi,%rax), %eax
retq
// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
movq %rdi, %rbx
movb $0x0, 0x3c010(%rdi)
movl $0x4000, %edi           # imm = 0x4000
callq 0x1160
andl $0x0, 0x3c012(%rbx)
andl $0x0, 0x3c015(%rbx)
movq %rax, (%rbx)
movl $0x100, %edi            # imm = 0x100
callq 0x1160
movq %rax, 0x8(%rbx)
andl $0x0, 0x3c01c(%rbx)
popq %rbx
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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
cmpw $0xeff, %ax             # imm = 0xEFF
ja 0x3073
leal -0x1000(%rsi), %eax
jmp 0x3084
leal -0x3f20(%rsi), %ecx
leal -0x20(%rsi), %eax
cmpw $0xe0, %cx
cmovael %esi, %eax
cmpw $0x3f10, %ax            # imm = 0x3F10
je 0x30a9
movzwl %ax, %eax
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x30a2
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x30ae
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x30ae
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x30ae
movl $0x3f00, %eax           # imm = 0x3F00
movq (%rdi), %rcx
movb (%rcx,%rax), %al
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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
cmpw $0xeff, %ax             # imm = 0xEFF
ja 0x30cb
leal -0x1000(%rsi), %eax
jmp 0x30dc
leal -0x3f20(%rsi), %ecx
leal -0x20(%rsi), %eax
cmpw $0xe0, %cx
cmovael %esi, %eax
cmpw $0x3f10, %ax            # imm = 0x3F10
je 0x3101
movzwl %ax, %eax
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x30fa
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x3106
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x3106
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x3106
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
// File: /workspace/github_cpp_makefile_star2_O2/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
cmpw $0xeff, %ax             # imm = 0xEFF
ja 0x3137
leal -0x1000(%rsi), %eax
jmp 0x3148
leal -0x3f20(%rsi), %ecx
leal -0x20(%rsi), %eax
cmpw $0xe0, %cx
cmovael %esi, %eax
cmpw $0x3f10, %ax            # imm = 0x3F10
je 0x316d
movzwl %ax, %eax
cmpl $0x3f18, %eax           # imm = 0x3F18
je 0x3166
cmpl $0x3f14, %eax           # imm = 0x3F14
jne 0x3172
movl $0x3f04, %eax           # imm = 0x3F04
jmp 0x3172
movl $0x3f08, %eax           # imm = 0x3F08
jmp 0x3172
movl $0x3f00, %eax           # imm = 0x3F00
movq (%rdi), %rcx
movb %dl, (%rcx,%rax)
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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 0x1130
pushq $0x4
popq %rdx
movq %r15, %rdi
movq %r14, %rsi
callq 0x10b0
leaq -0x238(%rbp), %rdi
leaq -0x30(%rbp), %rsi
pushq $0x10
popq %rdx
callq 0x1150
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 0x1150
movq (%rbx), %rsi
shlq $0xd, %r14
leaq -0x238(%rbp), %rdi
movq %r14, %rdx
callq 0x1150
leaq -0x238(%rbp), %rdi
callq 0x1030
movq %r15, %rsp
leaq -0x238(%rbp), %rdi
callq 0x1050
leaq -0x18(%rbp), %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3228
jmp 0x3228
movq %rax, %rbx
leaq -0x238(%rbp), %rdi
callq 0x1050
movq %rbx, %rdi
callq 0x11c0
nop
// File: /workspace/github_cpp_makefile_star2_O2/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 0x327e
movzbl %sil, %eax
orw %ax, 0x3c012(%rdi)
xorl %eax, %eax
jmp 0x3291
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_O2/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
cmpw $0x3f00, %r14w          # imm = 0x3F00
jb 0x3307
movzwl %r14w, %esi
movq %rbx, %rdi
callq 0x305e
movl %eax, %ebp
jmp 0x331a
movb 0x3c014(%rbx), %bpl
movzwl %r14w, %esi
movq %rbx, %rdi
callq 0x305e
movb %al, 0x3c014(%rbx)
leal 0x20(%r14), %eax
incl %r14d
testb $0x4, 0x3c010(%rbx)
cmovnel %eax, %r14d
movw %r14w, 0x3c012(%rbx)
movl %ebp, %eax
popq %rbx
popq %r14
popq %rbp
retq
nop
// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %r14
pushq %rbx
pushq %rax
movl %esi, %ebx
movq %rdi, %r14
movzwl 0x3c012(%rdi), %esi
movl %ebx, %edx
callq 0x3122
testb $0x4, 0x3c010(%r14)
pushq $0x1
popq %rax
pushq $0x20
popq %rcx
cmovel %eax, %ecx
addw %cx, 0x3c012(%r14)
movb 0x3c015(%r14), %al
andb $-0x20, %al
andb $0x1f, %bl
orb %al, %bl
movb %bl, 0x3c015(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
nop