// File: /workspace/github_cpp_makefile_star2_O2/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, 0x38abe(%rip)      # 0x6dee8
movq 0x20(%rdi), %rcx
movzbl (%rcx,%rax), %eax
andw $0x0, 0x38ab2(%rip)     # 0x6deec
movb %al, 0x38aaa(%rip)      # 0x6deea
cmpq $0xcb, %rax
jne 0x3547f
movb $0x1, 0x38a9f(%rip)     # 0x6deee
leaq 0x38a72(%rip), %rax     # 0x6dec8
movzwl (%rbx), %edx
incl %edx
movw %dx, (%rbx)
movzwl %dx, %edx
movzbl (%rcx,%rdx), %ecx
movw %cx, 0x38a80(%rip)      # 0x6deec
shll $0x4, %ecx
movq 0x12a8(%rdi,%rcx), %rsi
movq %rax, %rdi
jmp 0x3551f
leaq 0x2a8(%rdi), %r15
movl %eax, %edx
shll $0x4, %edx
movzbl 0x2b0(%rdi,%rdx), %edx
cmpl $0x2, %edx
je 0x354c3
cmpl $0x1, %edx
jne 0x35507
movb $0x1, 0x38a4a(%rip)     # 0x6deee
leaq 0x38a1d(%rip), %rdi     # 0x6dec8
movzwl (%rbx), %edx
incl %edx
movw %dx, (%rbx)
movzwl %dx, %edx
movzbl (%rcx,%rdx), %ecx
movw %cx, 0x38a2b(%rip)      # 0x6deec
jmp 0x35518
addq $0x18, %rdi
movb $0x2, 0x38a20(%rip)     # 0x6deee
leaq 0x389f3(%rip), %r14     # 0x6dec8
movzwl (%rbx), %eax
incl %eax
movw %ax, (%rbx)
movzwl %ax, %esi
callq 0x31708
movw %ax, 0x38a00(%rip)      # 0x6deec
movzbl 0x389f7(%rip), %eax     # 0x6deea
shll $0x4, %eax
movq (%r15,%rax), %rsi
movq %r14, %rdi
callq 0x7890
incw (%rbx)
jmp 0x35524
incw (%rbx)
movb $0x0, 0x389dd(%rip)     # 0x6deee
leaq 0x389b0(%rip), %rdi     # 0x6dec8
shll $0x4, %eax
movq (%r15,%rax), %rsi
callq 0x7890
movq 0x389dd(%rip), %rax     # 0x6df08
movzwl (%rbx), %r14d
movzbl 0x389b7(%rip), %r12d    # 0x6deee
xorl %r15d, %r15d
leaq 0x389b7(%rip), %r13     # 0x6def8
movzwl %r14w, %ecx
cmpq %r13, %rax
je 0x35571
movzwl 0x20(%rax), %edx
cmpw %dx, %r14w
jae 0x35567
movzwl %dx, %esi
addl %r12d, %ecx
cmpl %esi, %ecx
jbe 0x35567
movw %dx, (%rbx)
movb $0x1, %r15b
movl %edx, %r14d
movq %rax, %rdi
callq 0x7690
jmp 0x35541
movzwl 0x25888(%rip), %eax     # 0x5ae00
cmpw %ax, %r14w
jae 0x355ae
movzwl %ax, %edx
movzbl 0x38966(%rip), %esi     # 0x6deee
addl %ecx, %esi
cmpl %edx, %esi
jbe 0x355ae
movw %ax, (%rbx)
leaq 0x38958(%rip), %rdi     # 0x6def0
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x356da
testb $0x1, %r15b
jne 0x355c2
movzbl 0x38933(%rip), %eax     # 0x6deee
addl %eax, %r14d
movw %r14w, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq