// File: /workspace/github_cpp_makefile_star2_O3/donfreiday[P]gb/main.cpp
// Function: imguiDisassembly()
void imguiDisassembly() {
  // Get window dimensions
  ImGui::SetNextWindowSize(
      ImVec2(DISASM_WINDOW_WIDTH, ImGui::GetIO().DisplaySize.y));

  // Position in top left corner
  ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));

  ImGui::Begin("disassembly", nullptr,
               ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);

  // Button to run or pause emulator
  if (ImGui::Button(g_running ? "Pause(r)" : " Run(r) ")) {
    g_scrollDisasmToPC = g_running;
    g_running = !g_running;
  }

  // Button for step. Only works when emulation is paused
  ImGui::SameLine();
  if (ImGui::Button("Step(s)")) {
    if (!g_running) {
      g_stepping = true;
    }
  }

  // Button for jump to PC
  ImGui::SameLine();
  if (ImGui::Button("Goto PC(p)")) {
    g_scrollDisasmToPC = true;
  }

  ImGui::BeginChild("disasm", ImVec2(0.0f, 0.0f));
  ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));

  ImGuiListClipper clipper(0x7FFF, ImGui::GetTextLineHeight());
  u16 index = clipper.DisplayStart * 2;

  while (index < clipper.DisplayEnd * 2) {
    // Is the current index a breakpoint?
    bool breakpoint = g_breakpoints.find(index) != g_breakpoints.end();

    // Clicking a line sets or removes a breakpoint
    ImGui::PushID(index);
    if (ImGui::Selectable("##breakpoint",
                          ImGuiSelectableFlags_SpanAllColumns)) {
      if (breakpoint) {
        g_breakpoints.erase(index);
      } else {
        g_breakpoints.insert(index);
      }
    }
    ImGui::PopID();

    // Color currently executing line
    ImVec4 color;
    if (index == g_cpu.reg.pc) {
      color = ImVec4(1.0f, 0.0f, 1.0f, 1.0f);
    } else {
      color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
    }

    // Mark breakpoints
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
    ImGui::SameLine();
    if (breakpoint) {
      ImGui::Text("*");
    } else {
      ImGui::Text(" ");
    }
    ImGui::PopStyleVar();

    // This will increment index by size of opcode+operand
    int prevIndex = index;
    disassemble(g_cpu, index);

    // Don't skip the current PC
    if (prevIndex < g_cpu.reg.pc && index > g_cpu.reg.pc) {
      index = g_cpu.reg.pc;
      g_disasm.knownEntryPoints.insert(index);
      color = ImVec4(1.0f, 0.0f, 1.0f, 1.0f);
      disassemble(g_cpu, index);
    }

    // Display current address, opcode, and operand (if any)
    ImGui::SameLine();
    if (g_disasm.operandSize > 0) {
      // One byte operand
      if (g_disasm.operandSize == 1) {
        ImGui::TextColored(color, "%04X:%02X %02X    ", g_disasm.address,
                           g_disasm.opcode, (u8)g_disasm.operand);
      }
      // Two byte operand
      else {
        ImGui::TextColored(color, "%04X:%02X %04X  ", g_disasm.address,
                           g_disasm.opcode, g_disasm.operand);
      }
    }
    // No operand
    else {
      ImGui::TextColored(color, "%04X:%02X       ", g_disasm.address,
                         g_disasm.opcode);
    }

    // Display disassembly
    ImGui::SameLine();
    ImGui::TextColored(color, g_disasm.str.c_str(), g_disasm.operand);
  }

  // Scroll to current PC if warranted
  if (!g_running && g_scrollDisasmToPC) {
    float target = (g_cpu.reg.pc - 20) * ImGui::GetTextLineHeight() * 0.5f;
    if (fabsf(target - ImGui::GetScrollY()) > 20) {
      ImGui::SetScrollY(target);
    }
    g_scrollDisasmToPC = false;
  }

  clipper.End();
  ImGui::PopStyleVar();
  ImGui::EndChild();
  ImGui::End();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
callq 0xb0ca
movss 0x4(%rax), %xmm0
leaq -0x3c(%rbp), %rbx
movl $0x43960000, (%rbx)     # imm = 0x43960000
movss %xmm0, 0x4(%rbx)
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xc42a
movq %r14, (%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x153a7
leaq 0xe6cd(%rip), %rdi      # 0x49d47
xorl %esi, %esi
movl $0x6, %edx
callq 0xc44d
leaq 0xe6c6(%rip), %rax      # 0x49d53
cmpb $0x0, 0x1ff86(%rip)     # 0x5b61a
leaq 0xe6c1(%rip), %rdi      # 0x49d5c
cmovneq %rax, %rdi
movq %r14, (%rbx)
leaq -0x3c(%rbp), %rsi
callq 0x1642f
testb %al, %al
je 0x3b6c3
movb 0x1ff65(%rip), %al      # 0x5b61a
movb %al, 0x1ff60(%rip)      # 0x5b61b
xorb $0x1, %al
movb %al, 0x1ff57(%rip)      # 0x5b61a
movss 0x1cd1(%rip), %xmm1     # 0x3d39c
xorps %xmm0, %xmm0
callq 0x15f5f
leaq -0x3c(%rbp), %rsi
movq $0x0, (%rsi)
leaq 0xe680(%rip), %rdi      # 0x49d65
callq 0x1642f
testb %al, %al
je 0x3b6fe
cmpb $0x0, 0x1ff25(%rip)     # 0x5b61a
jne 0x3b6fe
movb $0x1, 0x37853(%rip)     # 0x72f51
movss 0x1c96(%rip), %xmm1     # 0x3d39c
xorps %xmm0, %xmm0
callq 0x15f5f
leaq -0x3c(%rbp), %rsi
movq $0x0, (%rsi)
leaq 0xe64d(%rip), %rdi      # 0x49d6d
callq 0x1642f
testb %al, %al
je 0x3b730
movb $0x1, 0x1feeb(%rip)     # 0x5b61b
xorl %r14d, %r14d
movq %r14, (%rbx)
leaq 0xe63b(%rip), %rdi      # 0x49d78
movq %rbx, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x12f21
movq %r14, (%rbx)
movl $0x5, %edi
movq %rbx, %rsi
callq 0x14ee8
callq 0x15671
movl $0xffffffff, 0x4(%rbx)  # imm = 0xFFFFFFFF
movq %rbx, %rdi
movl $0x7fff, %esi           # imm = 0x7FFF
callq 0x24ad2
movl 0x8(%rbx), %eax
movl 0xc(%rbx), %ecx
addl %eax, %eax
movw %ax, -0x2a(%rbp)
movzwl %ax, %edi
addl %ecx, %ecx
cmpl %edi, %ecx
jle 0x3b9a5
leaq -0x50(%rbp), %r14
leaq -0x2a(%rbp), %r12
leaq 0x2465e(%rip), %r15     # 0x5fdf8
leaq 0x37787(%rip), %r13     # 0x72f28
movq 0x37788(%rip), %rdx     # 0x72f30
movb $0x1, %bl
testq %rdx, %rdx
je 0x3b7d6
movq %r13, %rcx
xorl %esi, %esi
cmpw %ax, 0x20(%rdx)
setb %sil
cmovaeq %rdx, %rcx
movq 0x10(%rdx,%rsi,8), %rdx
testq %rdx, %rdx
jne 0x3b7b2
cmpq %r13, %rcx
je 0x3b7d6
cmpw 0x20(%rcx), %ax
setb %bl
callq 0x17e36
movq $0x0, -0x50(%rbp)
leaq 0xe595(%rip), %rdi      # 0x49d7f
movl $0x1, %esi
xorl %edx, %edx
movq %r14, %rcx
callq 0x201b9
testb %al, %al
je 0x3b830
testb %bl, %bl
je 0x3b812
leaq 0x37718(%rip), %rdi     # 0x72f20
movq %r12, %rsi
callq 0x3c07c
jmp 0x3b830
leaq 0x37707(%rip), %rdi     # 0x72f20
movq %r12, %rsi
callq 0x3c1a2
leaq 0x376f8(%rip), %rdi     # 0x72f20
movq %rax, %rsi
callq 0x3c22a
callq 0x16b19
movzwl -0x2a(%rbp), %eax
xorps %xmm0, %xmm0
cmpw 0x245bd(%rip), %ax      # 0x5fe00
je 0x3b84d
movss 0x1b43(%rip), %xmm0     # 0x3d390
movl $0x3f800000, -0x50(%rbp) # imm = 0x3F800000
movss %xmm0, -0x4c(%rbp)
movabsq $0x3f8000003f800000, %rax # imm = 0x3F8000003F800000
movq %rax, -0x48(%rbp)
movq $0x0, -0x58(%rbp)
movl $0x7, %edi
leaq -0x58(%rbp), %rsi
callq 0x14ee8
xorps %xmm0, %xmm0
movss 0x1b14(%rip), %xmm1     # 0x3d39c
callq 0x15f5f
testb %bl, %bl
leaq 0x2df8(%rip), %rdi      # 0x3e68e
leaq 0xe522(%rip), %rax      # 0x49dbf
cmovneq %rax, %rdi
xorl %eax, %eax
callq 0x15c0a
movl $0x1, %edi
callq 0x12c6e
movzwl -0x2a(%rbp), %ebx
movq %r15, %rdi
movq %r12, %rsi
callq 0x3bd7f
movzwl 0x24538(%rip), %eax     # 0x5fe00
cmpw %ax, %bx
jae 0x3b8fc
cmpw %ax, -0x2a(%rbp)
jbe 0x3b8fc
movw %ax, -0x2a(%rbp)
leaq 0x37612(%rip), %rdi     # 0x72ef0
movq %r12, %rsi
callq 0x3c07c
movaps 0x1a83(%rip), %xmm0     # 0x3d370
movups %xmm0, -0x50(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x3bd7f
xorps %xmm0, %xmm0
movss 0x1a95(%rip), %xmm1     # 0x3d39c
callq 0x15f5f
movzbl 0x375db(%rip), %eax     # 0x72eee
movzwl 0x375ce(%rip), %edx     # 0x72ee8
movzbl 0x375c9(%rip), %ecx     # 0x72eea
testl %eax, %eax
je 0x3b93a
cmpl $0x1, %eax
jne 0x3b94d
movzbl 0x375bb(%rip), %eax     # 0x72eec
leaq 0xe454(%rip), %rsi      # 0x49d8c
jmp 0x3b95b
movq %r14, %rdi
leaq 0xe46c(%rip), %rsi      # 0x49db0
xorl %eax, %eax
callq 0x15cb5
jmp 0x3b969
movzwl 0x37598(%rip), %eax     # 0x72eec
leaq 0xe444(%rip), %rsi      # 0x49d9f
movzwl %ax, %r8d
movq %r14, %rdi
xorl %eax, %eax
callq 0x15cb5
xorps %xmm0, %xmm0
movss 0x1a28(%rip), %xmm1     # 0x3d39c
callq 0x15f5f
movq 0x37548(%rip), %rsi     # 0x72ec8
movzwl 0x37565(%rip), %edx     # 0x72eec
movq %r14, %rdi
xorl %eax, %eax
callq 0x15cb5
movzwl -0x2a(%rbp), %eax
movzwl %ax, %edi
movl -0x30(%rbp), %ecx
addl %ecx, %ecx
cmpl %edi, %ecx
jg 0x3b7a1
cmpb $0x0, 0x1fc6e(%rip)     # 0x5b61a
jne 0x3ba0e
cmpb $0x1, 0x1fc66(%rip)     # 0x5b61b
jne 0x3ba0e
movzwl 0x24442(%rip), %ebx     # 0x5fe00
callq 0x15671
movss %xmm0, -0x40(%rbp)
callq 0x15983
addl $-0x14, %ebx
xorps %xmm1, %xmm1
cvtsi2ss %ebx, %xmm1
movss -0x40(%rbp), %xmm3
mulss %xmm1, %xmm3
mulss 0x19e4(%rip), %xmm3     # 0x3d3cc
movaps %xmm3, %xmm1
subss %xmm0, %xmm1
andps 0x18ea(%rip), %xmm1     # 0x3d2e0
ucomiss 0x3cc7(%rip), %xmm1     # 0x3f6c4
jbe 0x3ba07
movaps %xmm3, %xmm0
callq 0x15a06
movb $0x0, 0x1fc0d(%rip)     # 0x5b61b
leaq -0x3c(%rbp), %rdi
callq 0x24712
movl $0x1, %edi
callq 0x12c6e
callq 0x13129
callq 0xcc43
cmpl $-0x1, -0x38(%rbp)
jne 0x3ba5a
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3ba4c
jmp 0x3ba4c
jmp 0x3ba4c
jmp 0x3ba4c
jmp 0x3ba4c
jmp 0x3ba4c
cmpl $-0x1, -0x38(%rbp)
jne 0x3ba5a
movq %rax, %rdi
callq 0x74c0
leaq 0x342a(%rip), %rdi      # 0x3ee8b
leaq 0x305b(%rip), %rsi      # 0x3eac3
leaq 0x3483(%rip), %rcx      # 0x3eef2
movl $0x3e2, %edx            # imm = 0x3E2
callq 0x7140