// File: /workspace/github_cpp_makefile_star2_O3/donfreiday[P]gb/main.cpp
// Function: disassemble(CPU&, unsigned short&)
void disassemble(CPU& cpu, u16& pc) {
  g_disasm.address = pc;
  g_disasm.opcode = cpu.mmu.memory[pc];
  g_disasm.operandSize = 0;
  g_disasm.operand = 0;

  if (g_disasm.opcode == 0xCB) {
    g_disasm.operandSize = 1;
    g_disasm.operand = cpu.mmu.memory[++pc];
    g_disasm.str = cpu.instructions_CB[g_disasm.operand].disassembly;
  } else if (cpu.instructions[g_disasm.opcode].operandLength == 1) {
    g_disasm.operandSize = 1;
    g_disasm.operand = cpu.mmu.memory[++pc];
    g_disasm.str = cpu.instructions[g_disasm.opcode].disassembly;
  } else if (cpu.instructions[g_disasm.opcode].operandLength == 2) {
    g_disasm.operandSize = 2;
    g_disasm.operand = cpu.mmu.read16(++pc);
    g_disasm.str = cpu.instructions[g_disasm.opcode].disassembly;
    pc++;
  } else {
    ++pc;
    g_disasm.operandSize = 0;
    g_disasm.str = cpu.instructions[g_disasm.opcode].disassembly;
  }

  // Make sure we don't skip over any code entry points
  bool skippedEntry = false;
  for (u16 address : g_disasm.knownEntryPoints) {
    if (pc < address && pc + g_disasm.operandSize > address) {
      skippedEntry = true;
      pc = address;
    }
  }

  // Data sections are mixed in with code. So we need to make sure
  // that we don't skip right over the PC by blindly disassembling
  if (pc < g_cpu.reg.pc && pc + g_disasm.operandSize > g_cpu.reg.pc) {
    pc = g_cpu.reg.pc;
    g_disasm.knownEntryPoints.insert(pc);
    skippedEntry = true;
  }

  if (!skippedEntry) {
    pc += g_disasm.operandSize;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movzwl (%rsi), %eax
movw %ax, 0x3714e(%rip)      # 0x72ee8
movq 0x20(%rdi), %rcx
movzbl (%rcx,%rax), %eax
movb %al, 0x37142(%rip)      # 0x72eea
movw $0x0, 0x3713b(%rip)     # 0x72eec
cmpq $0xcb, %rax
jne 0x3bded
movb $0x1, 0x3712e(%rip)     # 0x72eee
leaq 0x37101(%rip), %r14     # 0x72ec8
movzwl (%rbx), %eax
incl %eax
movw %ax, (%rbx)
movzwl %ax, %eax
movzbl (%rcx,%rax), %eax
movw %ax, 0x3710f(%rip)      # 0x72eec
shll $0x4, %eax
movq 0x12a8(%rdi,%rax), %r15
jmp 0x3beab
leaq 0x2a8(%rdi), %r15
movl %eax, %edx
shll $0x4, %edx
movzbl 0x2b0(%rdi,%rdx), %edx
cmpl $0x2, %edx
je 0x3be35
cmpl $0x1, %edx
jne 0x3be93
movb $0x1, 0x370d8(%rip)     # 0x72eee
leaq 0x370ab(%rip), %r14     # 0x72ec8
movzwl (%rbx), %edx
incl %edx
movw %dx, (%rbx)
movzwl %dx, %edx
movzbl (%rcx,%rdx), %ecx
movw %cx, 0x370b9(%rip)      # 0x72eec
jmp 0x3bea4
addq $0x18, %rdi
movb $0x2, 0x370ae(%rip)     # 0x72eee
leaq 0x37081(%rip), %r14     # 0x72ec8
movzwl (%rbx), %eax
incl %eax
movw %ax, (%rbx)
movzwl %ax, %esi
callq 0x37a0c
movw %ax, 0x3708e(%rip)      # 0x72eec
movzbl 0x37085(%rip), %eax     # 0x72eea
shll $0x4, %eax
movq (%r15,%rax), %r15
movq 0x3705d(%rip), %r12     # 0x72ed0
movq %r15, %rdi
callq 0x72e0
movq %r14, %rdi
xorl %esi, %esi
movq %r12, %rdx
movq %r15, %rcx
movq %rax, %r8
callq 0x73b0
incw (%rbx)
jmp 0x3becd
incw (%rbx)
movb $0x0, 0x37051(%rip)     # 0x72eee
leaq 0x37024(%rip), %r14     # 0x72ec8
shll $0x4, %eax
movq (%r15,%rax), %r15
movq 0x3701e(%rip), %r12     # 0x72ed0
movq %r15, %rdi
callq 0x72e0
movq %r14, %rdi
xorl %esi, %esi
movq %r12, %rdx
movq %r15, %rcx
movq %rax, %r8
callq 0x73b0
movq 0x37034(%rip), %rax     # 0x72f08
leaq 0x3701d(%rip), %r12     # 0x72ef8
movzwl (%rbx), %r14d
cmpq %r12, %rax
je 0x3bf1f
movzbl 0x37002(%rip), %r13d    # 0x72eee
xorl %r15d, %r15d
movzwl 0x20(%rax), %ecx
cmpw %cx, %r14w
jae 0x3bf10
movzwl %cx, %edx
movzwl %r14w, %esi
addl %r13d, %esi
cmpl %edx, %esi
jbe 0x3bf10
movw %cx, (%rbx)
movb $0x1, %r15b
movl %ecx, %r14d
movq %rax, %rdi
callq 0x76b0
cmpq %r12, %rax
jne 0x3beef
jmp 0x3bf22
xorl %r15d, %r15d
movzwl 0x23ed7(%rip), %eax     # 0x5fe00
cmpw %ax, %r14w
jae 0x3bf63
movzwl %ax, %ecx
movzwl %r14w, %edx
movzbl 0x36fb1(%rip), %esi     # 0x72eee
addl %edx, %esi
cmpl %ecx, %esi
jbe 0x3bf63
movw %ax, (%rbx)
leaq 0x36fa3(%rip), %rdi     # 0x72ef0
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3c07c
testb $0x1, %r15b
jne 0x3bf77
movzbl 0x36f7e(%rip), %eax     # 0x72eee
addl %eax, %r14d
movw %r14w, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq