// File: /workspace/github_cpp_makefile_star2_O2/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 0xa0f5
movss 0x4(%rax), %xmm0
leaq -0x3c(%rbp), %rbx
movl $0x43960000, (%rbx)     # imm = 0x43960000
movss %xmm0, 0x4(%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0xb0b1
andq $0x0, (%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11aa5
leaq 0xe24f(%rip), %rdi      # 0x42fd7
pushq $0x6
popq %rdx
xorl %esi, %esi
callq 0xb0d4
leaq 0xe24a(%rip), %rax      # 0x42fe3
leaq 0xe24c(%rip), %rdi      # 0x42fec
cmpb $0x0, 0x21873(%rip)     # 0x5661a
cmovneq %rax, %rdi
andq $0x0, (%rbx)
leaq -0x3c(%rbp), %rsi
callq 0x129b2
testb %al, %al
je 0x34dd0
movb 0x21858(%rip), %al      # 0x5661a
movb %al, 0x21853(%rip)      # 0x5661b
xorb $0x1, %al
movb %al, 0x2184a(%rip)      # 0x5661a
movss 0x15c4(%rip), %xmm1     # 0x3639c
xorps %xmm0, %xmm0
callq 0x1254d
leaq -0x3c(%rbp), %rsi
andq $0x0, (%rsi)
leaq 0xe206(%rip), %rdi      # 0x42ff5
callq 0x129b2
testb %al, %al
je 0x34e08
cmpb $0x0, 0x2181b(%rip)     # 0x5661a
jne 0x34e08
movb $0x1, 0x39149(%rip)     # 0x6df51
movss 0x158c(%rip), %xmm1     # 0x3639c
xorps %xmm0, %xmm0
callq 0x1254d
leaq -0x3c(%rbp), %rsi
andq $0x0, (%rsi)
leaq 0xe1d6(%rip), %rdi      # 0x42ffd
callq 0x129b2
testb %al, %al
je 0x34e37
movb $0x1, 0x217e4(%rip)     # 0x5661b
andq $0x0, (%rbx)
leaq 0xe1c6(%rip), %rdi      # 0x43008
movq %rbx, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0xfc8c
andq $0x0, (%rbx)
pushq $0x5
popq %rdi
leaq -0x3c(%rbp), %rsi
callq 0x116b2
callq 0x11d3a
movq %rbx, %rdi
movl $0x7fff, %esi           # imm = 0x7FFF
callq 0x1f524
movl 0x8(%rbx), %eax
addl %eax, %eax
leaq -0x2a(%rbp), %rbx
movw %ax, (%rbx)
pushq $0x1
popq %r12
leaq -0x50(%rbp), %r13
leaq 0x25f6d(%rip), %r15     # 0x5adf8
movzwl %ax, %eax
movl -0x30(%rbp), %ecx
addl %ecx, %ecx
cmpl %eax, %ecx
jle 0x3506a
leaq 0x3907e(%rip), %rdi     # 0x6df20
movq %rbx, %rsi
callq 0x35870
movq %rax, %r14
movzwl -0x2a(%rbp), %edi
callq 0x13d85
andq $0x0, -0x50(%rbp)
leaq 0xe14d(%rip), %rdi      # 0x4300f
movl %r12d, %esi
xorl %edx, %edx
movq %r13, %rcx
callq 0x1ab4d
testb %al, %al
je 0x34eff
leaq 0x3904e(%rip), %rax     # 0x6df28
cmpq %rax, %r14
je 0x34ef0
leaq 0x3903a(%rip), %rdi     # 0x6df20
movq %rbx, %rsi
callq 0x358cc
jmp 0x34eff
leaq 0x39029(%rip), %rdi     # 0x6df20
movq %rbx, %rsi
callq 0x356da
callq 0x12ea2
movzwl -0x2a(%rbp), %eax
xorps %xmm0, %xmm0
cmpw 0x25eee(%rip), %ax      # 0x5ae00
je 0x34f1c
movss 0x1474(%rip), %xmm0     # 0x36390
movl $0x3f800000, -0x50(%rbp) # imm = 0x3F800000
movss %xmm0, -0x4c(%rbp)
movabsq $0x3f8000003f800000, %rax # imm = 0x3F8000003F800000
movq %rax, -0x48(%rbp)
andq $0x0, -0x58(%rbp)
pushq $0x7
popq %rdi
leaq -0x58(%rbp), %rsi
callq 0x116b2
xorps %xmm0, %xmm0
movss 0x144a(%rip), %xmm1     # 0x3639c
callq 0x1254d
leaq 0xe0f1(%rip), %rdi      # 0x4304f
leaq 0x38fc3(%rip), %rax     # 0x6df28
cmpq %rax, %r14
je 0x34f71
leaq 0x26d5(%rip), %rdi      # 0x37646
xorl %eax, %eax
callq 0x1227e
movl %r12d, %edi
callq 0xfb23
movzwl -0x2a(%rbp), %r14d
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3540f
movzwl 0x25e69(%rip), %eax     # 0x5ae00
cmpw %ax, %r14w
jae 0x34fcc
cmpw %ax, -0x2a(%rbp)
jbe 0x34fcc
movw %ax, -0x2a(%rbp)
leaq 0x38f42(%rip), %rdi     # 0x6def0
movq %rbx, %rsi
callq 0x356da
movaps 0x13b3(%rip), %xmm0     # 0x36370
movups %xmm0, -0x50(%rbp)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3540f
xorps %xmm0, %xmm0
movss 0x13c5(%rip), %xmm1     # 0x3639c
callq 0x1254d
movzbl 0x38f0b(%rip), %eax     # 0x6deee
movzwl 0x38efe(%rip), %edx     # 0x6dee8
movzbl 0x38ef9(%rip), %ecx     # 0x6deea
testl %eax, %eax
je 0x3500a
cmpl $0x1, %eax
jne 0x3501d
movzbl 0x38eeb(%rip), %eax     # 0x6deec
leaq 0xe014(%rip), %rsi      # 0x4301c
jmp 0x3502b
movq %r13, %rdi
leaq 0xe02c(%rip), %rsi      # 0x43040
xorl %eax, %eax
callq 0x12327
jmp 0x35039
movzwl 0x38ec8(%rip), %eax     # 0x6deec
leaq 0xe004(%rip), %rsi      # 0x4302f
movzwl %ax, %r8d
movq %r13, %rdi
xorl %eax, %eax
callq 0x12327
xorps %xmm0, %xmm0
movss 0x1358(%rip), %xmm1     # 0x3639c
callq 0x1254d
movq 0x38e78(%rip), %rsi     # 0x6dec8
movzwl 0x38e95(%rip), %edx     # 0x6deec
movq %r13, %rdi
xorl %eax, %eax
callq 0x12327
movzwl -0x2a(%rbp), %eax
jmp 0x34e8b
cmpb $0x0, 0x215a9(%rip)     # 0x5661a
jne 0x350d0
cmpb $0x1, 0x215a1(%rip)     # 0x5661b
jne 0x350d0
movzwl 0x25d7d(%rip), %ebx     # 0x5ae00
callq 0x11d3a
movss %xmm0, -0x40(%rbp)
callq 0x12028
addl $-0x14, %ebx
cvtsi2ss %ebx, %xmm1
movss -0x40(%rbp), %xmm3
mulss %xmm1, %xmm3
mulss 0x1326(%rip), %xmm3     # 0x363d0
movaps %xmm3, %xmm1
subss %xmm0, %xmm1
andps 0x1228(%rip), %xmm1     # 0x362e0
ucomiss 0x3805(%rip), %xmm1     # 0x388c4
jbe 0x350c9
movaps %xmm3, %xmm0
callq 0x120a8
movb $0x0, 0x2154b(%rip)     # 0x5661b
leaq -0x3c(%rbp), %rdi
callq 0x1f532
pushq $0x1
popq %rdi
callq 0xfb23
callq 0xfe6f
callq 0xb516
leaq -0x3c(%rbp), %rdi
callq 0x1f588
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x35111
jmp 0x35111
jmp 0x35111
jmp 0x35111
jmp 0x35111
jmp 0x35111
jmp 0x35111
movq %rax, %rbx
leaq -0x3c(%rbp), %rdi
callq 0x1f588
movq %rbx, %rdi
callq 0x74b0