// File: /workspace/github_cpp_makefile_star2_O1/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 0xb1e1
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 0xc578
movq %r14, (%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x15803
leaq 0xe017(%rip), %rdi      # 0x49d9f
xorl %esi, %esi
movl $0x6, %edx
callq 0xc59b
leaq 0xe010(%rip), %rax      # 0x49dab
cmpb $0x0, 0x1f888(%rip)     # 0x5b62a
leaq 0xe00b(%rip), %rdi      # 0x49db4
cmovneq %rax, %rdi
movq %r14, (%rbx)
leaq -0x3c(%rbp), %rsi
callq 0x168d6
testb %al, %al
je 0x3bdd1
movb 0x1f867(%rip), %al      # 0x5b62a
movb %al, 0x1f862(%rip)      # 0x5b62b
xorb $0x1, %al
movb %al, 0x1f859(%rip)      # 0x5b62a
movss 0x15b3(%rip), %xmm1     # 0x3d38c
xorps %xmm0, %xmm0
callq 0x163f1
leaq -0x3c(%rbp), %rsi
movq $0x0, (%rsi)
leaq 0xdfca(%rip), %rdi      # 0x49dbd
callq 0x168d6
testb %al, %al
je 0x3be0c
cmpb $0x0, 0x1f827(%rip)     # 0x5b62a
jne 0x3be0c
movb $0x1, 0x37155(%rip)     # 0x72f61
movss 0x1578(%rip), %xmm1     # 0x3d38c
xorps %xmm0, %xmm0
callq 0x163f1
leaq -0x3c(%rbp), %rsi
movq $0x0, (%rsi)
leaq 0xdf97(%rip), %rdi      # 0x49dc5
callq 0x168d6
testb %al, %al
je 0x3be3e
movb $0x1, 0x1f7ed(%rip)     # 0x5b62b
xorl %r14d, %r14d
movq %r14, (%rbx)
leaq 0xdf85(%rip), %rdi      # 0x49dd0
movq %rbx, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x132b9
movq %r14, (%rbx)
movl $0x5, %edi
movq %rbx, %rsi
callq 0x15319
callq 0x15afc
movl $0xffffffff, 0x4(%rbx)  # imm = 0xFFFFFFFF
movq %rbx, %rdi
movl $0x7fff, %esi           # imm = 0x7FFF
callq 0x24ee4
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 0x3c0c5
leaq 0x37098(%rip), %rbx     # 0x72f38
leaq -0x50(%rbp), %r14
leaq -0x2a(%rbp), %r12
leaq 0x23f59(%rip), %r15     # 0x5fe08
movq 0x3708a(%rip), %rdx     # 0x72f40
movq %rbx, %rcx
testq %rdx, %rdx
je 0x3bed9
movq %rbx, %rcx
xorl %esi, %esi
cmpw %ax, 0x20(%rdx)
setb %sil
cmovaeq %rdx, %rcx
movq 0x10(%rdx,%rsi,8), %rdx
testq %rdx, %rdx
jne 0x3bec1
cmpq %rbx, %rcx
je 0x3bee8
cmpw 0x20(%rcx), %ax
setb %r13b
jmp 0x3beeb
movb $0x1, %r13b
callq 0x18358
movq $0x0, -0x50(%rbp)
leaq 0xded8(%rip), %rdi      # 0x49dd7
movl $0x1, %esi
xorl %edx, %edx
movq %r14, %rcx
callq 0x20486
testb %al, %al
je 0x3bf46
testb %r13b, %r13b
je 0x3bf28
leaq 0x37012(%rip), %rdi     # 0x72f30
movq %r12, %rsi
callq 0x3c794
jmp 0x3bf46
leaq 0x37001(%rip), %rdi     # 0x72f30
movq %r12, %rsi
callq 0x3c8c4
leaq 0x36ff2(%rip), %rdi     # 0x72f30
movq %rax, %rsi
callq 0x3c946
callq 0x16fc0
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
movzwl -0x2a(%rbp), %eax
movl $0x3f800000, -0x50(%rbp) # imm = 0x3F800000
cmpw 0x23eac(%rip), %ax      # 0x5fe10
jne 0x3bf6f
movl $0x0, -0x4c(%rbp)
jmp 0x3bf76
movl $0x3f800000, -0x4c(%rbp) # imm = 0x3F800000
movabsq $0x3f8000003f800000, %rax # imm = 0x3F8000003F800000
movq %rax, -0x48(%rbp)
movq $0x0, -0x5c(%rbp)
movl $0x7, %edi
leaq -0x5c(%rbp), %rsi
callq 0x15319
xorps %xmm0, %xmm0
movss 0x13e7(%rip), %xmm1     # 0x3d38c
callq 0x163f1
testb %r13b, %r13b
leaq 0x26aa(%rip), %rdi      # 0x3e65e
leaq 0xde5c(%rip), %rax      # 0x49e17
cmovneq %rax, %rdi
xorl %eax, %eax
callq 0x1609c
movl $0x1, %edi
callq 0x12ffd
movzwl -0x2a(%rbp), %r13d
movq %r15, %rdi
movq %r12, %rsi
callq 0x3c49f
movzwl 0x23e29(%rip), %eax     # 0x5fe10
cmpw %ax, %r13w
jae 0x3c01c
cmpw %ax, -0x2a(%rbp)
jbe 0x3c01c
movw %ax, -0x2a(%rbp)
leaq 0x36f02(%rip), %rdi     # 0x72f00
movq %r12, %rsi
callq 0x3c794
movaps 0x1353(%rip), %xmm0     # 0x3d360
movaps %xmm0, -0x50(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x3c49f
xorps %xmm0, %xmm0
movss 0x1365(%rip), %xmm1     # 0x3d38c
callq 0x163f1
movzbl 0x36ecb(%rip), %eax     # 0x72efe
movzwl 0x36ebe(%rip), %edx     # 0x72ef8
movzbl 0x36eb9(%rip), %ecx     # 0x72efa
testl %eax, %eax
je 0x3c05a
cmpl $0x1, %eax
jne 0x3c06d
movzbl 0x36eab(%rip), %eax     # 0x72efc
leaq 0xdd8c(%rip), %rsi      # 0x49de4
jmp 0x3c07b
movq %r14, %rdi
leaq 0xdda4(%rip), %rsi      # 0x49e08
xorl %eax, %eax
callq 0x16147
jmp 0x3c089
movzwl 0x36e88(%rip), %eax     # 0x72efc
leaq 0xdd7c(%rip), %rsi      # 0x49df7
movzwl %ax, %r8d
movq %r14, %rdi
xorl %eax, %eax
callq 0x16147
xorps %xmm0, %xmm0
movss 0x12f8(%rip), %xmm1     # 0x3d38c
callq 0x163f1
movq 0x36e38(%rip), %rsi     # 0x72ed8
movzwl 0x36e55(%rip), %edx     # 0x72efc
movq %r14, %rdi
xorl %eax, %eax
callq 0x16147
movzwl -0x2a(%rbp), %eax
movzwl %ax, %edi
movl -0x30(%rbp), %ecx
addl %ecx, %ecx
cmpl %edi, %ecx
jg 0x3beaf
cmpb $0x0, 0x1f55e(%rip)     # 0x5b62a
jne 0x3c12e
cmpb $0x1, 0x1f556(%rip)     # 0x5b62b
jne 0x3c12e
movzwl 0x23d32(%rip), %ebx     # 0x5fe10
callq 0x15afc
movss %xmm0, -0x54(%rbp)
callq 0x15e15
addl $-0x14, %ebx
xorps %xmm1, %xmm1
cvtsi2ss %ebx, %xmm1
movss -0x54(%rbp), %xmm3
mulss %xmm1, %xmm3
mulss 0x12b4(%rip), %xmm3     # 0x3d3bc
movaps %xmm3, %xmm1
subss %xmm0, %xmm1
andps 0x11ba(%rip), %xmm1     # 0x3d2d0
ucomiss 0x3643(%rip), %xmm1     # 0x3f760
jbe 0x3c127
movaps %xmm3, %xmm0
callq 0x15e98
movb $0x0, 0x1f4fd(%rip)     # 0x5b62b
leaq -0x3c(%rbp), %rdi
callq 0x24b20
movl $0x1, %edi
callq 0x12ffd
callq 0x134d7
callq 0xcdc7
cmpl $-0x1, -0x38(%rbp)
jne 0x3c17a
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3c16c
jmp 0x3c16c
jmp 0x3c16c
jmp 0x3c16c
jmp 0x3c16c
jmp 0x3c16c
cmpl $-0x1, -0x38(%rbp)
jne 0x3c17a
movq %rax, %rdi
callq 0x74d0
leaq 0x2cda(%rip), %rdi      # 0x3ee5b
leaq 0x290b(%rip), %rsi      # 0x3ea93
leaq 0x2d33(%rip), %rcx      # 0x3eec2
movl $0x3e2, %edx            # imm = 0x3E2
callq 0x7140