LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: donfreiday[P]gb/./imgui/imgui_impl_sdl.cpp
// Function: ImGui_ImplSdl_Init(SDL_Window*)
bool ImGui_ImplSdl_Init(SDL_Window *window)
{
    ImGuiIO& io = ImGui::GetIO();
    io.KeyMap[ImGuiKey_Tab] = SDLK_TAB;                     // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
    io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
    io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
    io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
    io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
    io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
    io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
    io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
    io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
    io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE;
    io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE;
    io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN;
    io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE;
    io.KeyMap[ImGuiKey_A] = SDLK_a;
    io.KeyMap[ImGuiKey_C] = SDLK_c;
    io.KeyMap[ImGuiKey_V] = SDLK_v;
    io.KeyMap[ImGuiKey_X] = SDLK_x;
    io.KeyMap[ImGuiKey_Y] = SDLK_y;
    io.KeyMap[ImGuiKey_Z] = SDLK_z;
	
    io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists;   // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
    io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText;
    io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText;
	
#ifdef _WIN32
    SDL_SysWMinfo wmInfo;
    SDL_VERSION(&wmInfo.version);
    SDL_GetWindowWMInfo(window, &wmInfo);
    io.ImeWindowHandle = wmInfo.info.win.window;
#endif

    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movq %rdi, -0x8(%rbp)
callq 0xca90
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl $0x9, 0x2c(%rax)
movq -0x10(%rbp), %rax
movl $0x50, 0x30(%rax)
movq -0x10(%rbp), %rax
movl $0x4f, 0x34(%rax)
movq -0x10(%rbp), %rax
movl $0x52, 0x38(%rax)
movq -0x10(%rbp), %rax
movl $0x51, 0x3c(%rax)
movq -0x10(%rbp), %rax
movl $0x4b, 0x40(%rax)
movq -0x10(%rbp), %rax
movl $0x4e, 0x44(%rax)
movq -0x10(%rbp), %rax
movl $0x4a, 0x48(%rax)
movq -0x10(%rbp), %rax
movl $0x4d, 0x4c(%rax)
movq -0x10(%rbp), %rax
movl $0x7f, 0x50(%rax)
movq -0x10(%rbp), %rax
movl $0x8, 0x54(%rax)
movq -0x10(%rbp), %rax
movl $0xd, 0x58(%rax)
movq -0x10(%rbp), %rax
movl $0x1b, 0x5c(%rax)
movq -0x10(%rbp), %rax
movl $0x61, 0x60(%rax)
movq -0x10(%rbp), %rax
movl $0x63, 0x64(%rax)
movq -0x10(%rbp), %rax
movl $0x76, 0x68(%rax)
movq -0x10(%rbp), %rax
movl $0x78, 0x6c(%rax)
movq -0x10(%rbp), %rax
movl $0x79, 0x70(%rax)
movq -0x10(%rbp), %rax
movl $0x7a, 0x74(%rax)
movq -0x10(%rbp), %rax
leaq -0xac1(%rip), %rcx      # 0x4d5b0
movq %rcx, 0xb0(%rax)
movq -0x10(%rbp), %rax
leaq 0x2d(%rip), %rcx        # 0x4e0b0
movq %rcx, 0xc0(%rax)
movq -0x10(%rbp), %rax
leaq 0x3b(%rip), %rcx        # 0x4e0d0
movq %rcx, 0xb8(%rax)
movb $0x1, %al
andb $0x1, %al
addq $0x10, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: donfreiday[P]gb/joypad.cpp
// Function: Joypad::read(unsigned char)
u8 Joypad::read(u8 request) {
  // Directions
  if (!bitTest(request, 5)) {
    return directions;
  }

  // Buttons
  else if (!bitTest(request, 4)) {
    return buttons;
  }

  return 0xFF;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x10(%rbp)
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x5, %esi
movzbl -0x11(%rbp), %edi
callq 0x4e910
testb $0x1, %al
jne 0x4e878
movq -0x20(%rbp), %rax
movb 0x1(%rax), %al
movb %al, -0x1(%rbp)
jmp 0x4e89b
movl $0x4, %esi
movzbl -0x11(%rbp), %edi
callq 0x4e910
testb $0x1, %al
jne 0x4e895
movq -0x20(%rbp), %rax
movb (%rax), %al
movb %al, -0x1(%rbp)
jmp 0x4e89b
jmp 0x4e897
movb $-0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop
// File: donfreiday[P]gb/mmu.cpp
// Function: MMU::reset()
void MMU::reset() {
  memory.resize(0x10000, 0);
  ram.resize(0x2000, 0);  // external RAM

  // Setup MBC info
  mbc.romOffset = 0x4000;
  mbc.romBank = 0;
  mbc.mode = 0;
  mbc.ramOffset = 0;
  mbc.type = 0;  // this will be determined in load()
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x18(%rbp)
addq $0x8, %rdi
movb $0x0, -0x9(%rbp)
movl $0x10000, %esi          # imm = 0x10000
leaq -0x9(%rbp), %rdx
callq 0x4f300
movq -0x18(%rbp), %rdi
addq $0x50, %rdi
movb $0x0, -0xa(%rbp)
movl $0x2000, %esi           # imm = 0x2000
leaq -0xa(%rbp), %rdx
callq 0x4f300
movq -0x18(%rbp), %rax
movw $0x4000, 0x2(%rax)      # imm = 0x4000
movb $0x0, 0x1(%rax)
movb $0x0, 0x6(%rax)
movw $0x0, 0x4(%rax)
movb $0x0, (%rax)
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: donfreiday[P]gb/mmu.cpp
// Function: MMU::read8(unsigned short)
u8 MMU::read8(u16 addr) {
  // ROM, switched bank
  if (addr >= 0x4000 && addr <= 0x7FFF) {
    return rom[mbc.romOffset + (addr & 0x3FFF)];
  }

  // RAM, switched bank
  else if (addr >= 0xA000 && addr <= 0x8FFF) {
    return ram[mbc.ramOffset + (addr & 0x1FFF)];
  }

  // Shadow of working RAM, less final 512 bytes
  else if (addr >= 0xE000 && addr <= 0xFDFF) {
    return memory[addr - 0x1000];
  }

  // Joypad
  else if (addr == 0xFF00) {
    return joypad->read(memory[0xFF00]);
  }

  // Default
  else {
    return memory[addr];
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movw %si, %ax
movq %rdi, -0x10(%rbp)
movw %ax, -0x12(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movzwl -0x12(%rbp), %eax
cmpl $0x4000, %eax           # imm = 0x4000
jl 0x4ed4e
movzwl -0x12(%rbp), %eax
cmpl $0x7fff, %eax           # imm = 0x7FFF
jg 0x4ed4e
movq -0x20(%rbp), %rax
movq %rax, %rdi
addq $0x38, %rdi
movzwl 0x2(%rax), %eax
movzwl -0x12(%rbp), %ecx
andl $0x3fff, %ecx           # imm = 0x3FFF
addl %ecx, %eax
movslq %eax, %rsi
callq 0x4f3d0
movb (%rax), %al
movb %al, -0x1(%rbp)
jmp 0x4ee15
movzwl -0x12(%rbp), %eax
cmpl $0xa000, %eax           # imm = 0xA000
jl 0x4ed91
movzwl -0x12(%rbp), %eax
cmpl $0x8fff, %eax           # imm = 0x8FFF
jg 0x4ed91
movq -0x20(%rbp), %rax
movq %rax, %rdi
addq $0x50, %rdi
movzwl 0x4(%rax), %eax
movzwl -0x12(%rbp), %ecx
andl $0x1fff, %ecx           # imm = 0x1FFF
addl %ecx, %eax
movslq %eax, %rsi
callq 0x4f3d0
movb (%rax), %al
movb %al, -0x1(%rbp)
jmp 0x4ee15
movzwl -0x12(%rbp), %eax
cmpl $0xe000, %eax           # imm = 0xE000
jl 0x4edc7
movzwl -0x12(%rbp), %eax
cmpl $0xfdff, %eax           # imm = 0xFDFF
jg 0x4edc7
movq -0x20(%rbp), %rdi
addq $0x8, %rdi
movzwl -0x12(%rbp), %eax
subl $0x1000, %eax           # imm = 0x1000
movslq %eax, %rsi
callq 0x4f3d0
movb (%rax), %al
movb %al, -0x1(%rbp)
jmp 0x4ee15
movzwl -0x12(%rbp), %eax
cmpl $0xff00, %eax           # imm = 0xFF00
jne 0x4edfd
movq -0x20(%rbp), %rdi
movq 0x70(%rdi), %rax
movq %rax, -0x28(%rbp)
addq $0x8, %rdi
movl $0xff00, %esi           # imm = 0xFF00
callq 0x4f3d0
movq -0x28(%rbp), %rdi
movzbl (%rax), %esi
callq 0x4e840
movb %al, -0x1(%rbp)
jmp 0x4ee15
movq -0x20(%rbp), %rdi
addq $0x8, %rdi
movzwl -0x12(%rbp), %eax
movl %eax, %esi
callq 0x4f3d0
movb (%rax), %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x30, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/gpu.cpp
// Function: GPU::reset()
void GPU::reset() {
  width = 160;
  height = 144;
  scanline = 0;
  mmu->memory[LY] = scanline;
  mmu->memory[STAT] = 0x84;
  modeclock = 0;
  memset(screenData, 0xFF, sizeof(screenData));
  vsync = false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movl $0xa0, 0x14(%rax)
movl $0x90, 0x18(%rax)
movb $0x0, 0x10(%rax)
movb 0x10(%rax), %cl
movb %cl, -0x11(%rbp)
movq (%rax), %rdi
addq $0x8, %rdi
movl $0xff44, %esi           # imm = 0xFF44
callq 0x4f3d0
movb -0x11(%rbp), %dl
movq %rax, %rcx
movq -0x10(%rbp), %rax
movb %dl, (%rcx)
movq (%rax), %rdi
addq $0x8, %rdi
movl $0xff41, %esi           # imm = 0xFF41
callq 0x4f3d0
movq -0x10(%rbp), %rdi
movb $-0x7c, (%rax)
movl $0x0, 0x8(%rdi)
addq $0x1d, %rdi
movl $0xff, %esi
movl $0x10e00, %edx          # imm = 0x10E00
callq 0x7240
movq -0x10(%rbp), %rax
movb $0x0, 0x1c(%rax)
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)
// File: donfreiday[P]gb/gpu.cpp
// Function: GPU::renderScanline()
void GPU::renderScanline() {
  u8 control = mmu->memory[LCDC];
  if (bitTest(control, LCDC_BG_ENABLE)) {
    renderBackground();
  }
  if (bitTest(control, LCDC_OBJ_ENABLE)) {
    renderSprites();
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq (%rax), %rdi
addq $0x8, %rdi
movl $0xff40, %esi           # imm = 0xFF40
callq 0x4f3d0
movb (%rax), %al
movb %al, -0x9(%rbp)
xorl %esi, %esi
movzbl -0x9(%rbp), %edi
callq 0x4e910
testb $0x1, %al
jne 0x5164b
jmp 0x51654
movq -0x18(%rbp), %rdi
callq 0x51700
movl $0x1, %esi
movzbl -0x9(%rbp), %edi
callq 0x4e910
testb $0x1, %al
jne 0x51668
jmp 0x51671
movq -0x18(%rbp), %rdi
callq 0x51a80
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: donfreiday[P]gb/gpu.cpp
// Function: GPU::paletteLookup(unsigned char, unsigned short)
GPU::COLOR GPU::paletteLookup(u8 colorID, u16 address) {
  COLOR result = WHITE;
  u8 palette = mmu->memory[address];
  u8 high = 0;
  u8 low = 0;
  switch (colorID) {
    case 0:
      high = 1;
      low = 0;
      break;
    case 1:
      high = 3;
      low = 2;
      break;
    case 2:
      high = 5;
      low = 4;
      break;
    case 3:
      high = 7;
      low = 6;
      break;
  }
  u8 color = 0;
  if (palette & (1 << high)) {
    color |= 2;
  }
  if (palette & (1 << low)) {
    color |= 1;
  }

  switch (color) {
    case 0:
      result = WHITE;
      break;
    case 1:
      result = LIGHT_GRAY;
      break;
    case 2:
      result = DARK_GRAY;
      break;
    case 3:
      result = BLACK;
      break;
  }
  return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movw %dx, %ax
movb %sil, %cl
movq %rdi, -0x8(%rbp)
movb %cl, -0x9(%rbp)
movw %ax, -0xc(%rbp)
movq -0x8(%rbp), %rax
movl $0x0, -0x10(%rbp)
movq (%rax), %rdi
addq $0x8, %rdi
movzwl -0xc(%rbp), %eax
movl %eax, %esi
callq 0x4f3d0
movb (%rax), %al
movb %al, -0x11(%rbp)
movb $0x0, -0x12(%rbp)
movb $0x0, -0x13(%rbp)
movzbl -0x9(%rbp), %eax
movq %rax, -0x20(%rbp)
subq $0x3, %rax
ja 0x51edb
movq -0x20(%rbp), %rax
leaq 0x141e8(%rip), %rcx     # 0x66094
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, -0x12(%rbp)
movb $0x0, -0x13(%rbp)
jmp 0x51edb
movb $0x3, -0x12(%rbp)
movb $0x2, -0x13(%rbp)
jmp 0x51edb
movb $0x5, -0x12(%rbp)
movb $0x4, -0x13(%rbp)
jmp 0x51edb
movb $0x7, -0x12(%rbp)
movb $0x6, -0x13(%rbp)
movb $0x0, -0x14(%rbp)
movzbl -0x11(%rbp), %eax
movzbl -0x12(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x51f01
movzbl -0x14(%rbp), %eax
orl $0x2, %eax
movb %al, -0x14(%rbp)
movzbl -0x11(%rbp), %eax
movzbl -0x13(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x51f23
movzbl -0x14(%rbp), %eax
orl $0x1, %eax
movb %al, -0x14(%rbp)
movzbl -0x14(%rbp), %eax
movq %rax, -0x28(%rbp)
subq $0x3, %rax
ja 0x51f67
movq -0x28(%rbp), %rax
leaq 0x14168(%rip), %rcx     # 0x660a4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, -0x10(%rbp)
jmp 0x51f67
movl $0x1, -0x10(%rbp)
jmp 0x51f67
movl $0x2, -0x10(%rbp)
jmp 0x51f67
movl $0x3, -0x10(%rbp)
movl -0x10(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
// File: donfreiday[P]gb/cpu.cpp
// Function: CPU::reset()
void CPU::reset() {
  // These values would ordinarily be set by the boot ROM
  reg.a = 0x01;
  reg.b = 0x00;
  reg.c = 0x13;
  reg.d = 0x00;
  reg.e = 0xD8;
  reg.h = 0x01;
  reg.l = 0x4D;
  reg.f = 0xB0;
  reg.pc = 0x100;
  reg.sp = 0xFFFE;
  cpu_clock_t = 0;
  ime = false;
  eiDelay = false;
  dividerCounter = 0;
  timerCounter = 0;
  timerMode = 0;       // Clock rate determined by lowest 2 bits of TAC register
  timerCycles = 1024;  // Initial TAC 00 so GB-Z80 clock speed / inc rate ==
                       // 4194304÷4096 == 1024 cycles
  
  mmu.reset();
  mmu.memory[IF] = 0xE1;

  debugToFile = false;
  if (debugToFile) {
    fout.open("debug.txt");
    fout.clear();
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x10(%rbp)
movb $0x1, 0x1(%rdi)
movb $0x0, 0x3(%rdi)
movb $0x13, 0x2(%rdi)
movb $0x0, 0x5(%rdi)
movb $-0x28, 0x4(%rdi)
movb $0x1, 0x7(%rdi)
movb $0x4d, 0x6(%rdi)
movb $-0x50, (%rdi)
movw $0x100, 0x8(%rdi)       # imm = 0x100
movw $0xfffe, 0xa(%rdi)      # imm = 0xFFFE
movl $0x0, 0xc(%rdi)
movb $0x0, 0x10(%rdi)
movb $0x0, 0x11(%rdi)
movl $0x0, 0x298(%rdi)
movl $0x0, 0x2a4(%rdi)
movl $0x0, 0x29c(%rdi)
movl $0x400, 0x2a0(%rdi)     # imm = 0x400
addq $0x18, %rdi
callq 0x4e9e0
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff0f, %esi           # imm = 0xFF0F
callq 0x4f3d0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movb $-0x1f, (%rcx)
movb $0x0, 0x90(%rax)
testb $0x1, 0x90(%rax)
je 0x5211b
movq -0x10(%rbp), %rdi
addq $0x98, %rdi
leaq 0x15806(%rip), %rsi     # 0x678f7
movl $0x10, %edx
callq 0x7800
movq -0x10(%rbp), %rax
movq %rax, %rdi
addq $0x98, %rdi
movq 0x98(%rax), %rax
addq -0x18(%rax), %rdi
xorl %esi, %esi
callq 0x7880
addq $0x10, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: CPU::updateDivider(unsigned char)
void CPU::updateDivider(u8 cycles) {
  timerCounter += cycles;
  if (timerCounter >= 256) {
    timerCounter = 0;
    mmu.memory[DIV] = 0;
  } else {
    mmu.memory[DIV]++;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movzbl -0x9(%rbp), %ecx
addl 0x2a4(%rax), %ecx
movl %ecx, 0x2a4(%rax)
cmpl $0x100, 0x2a4(%rax)     # imm = 0x100
jl 0x55f1b
movq -0x18(%rbp), %rdi
movl $0x0, 0x2a4(%rdi)
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff04, %esi           # imm = 0xFF04
callq 0x4f3d0
movb $0x0, (%rax)
jmp 0x55f38
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff04, %esi           # imm = 0xFF04
callq 0x4f3d0
movb (%rax), %cl
addb $0x1, %cl
movb %cl, (%rax)
addq $0x20, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/cpu.cpp
// Function: CPU::updateTimer(unsigned char)
void CPU::updateTimer(u8 cycles) {
  // Return if timer disabled
  if (!bitTest(mmu.memory[TAC], 2)) {
    return;
  }

  // Handle timer input clock selection changes
  if (timerMode != (mmu.memory[TAC] & 0x3)) {
    timerMode = mmu.memory[TAC] & 0x3;
    switch (timerMode) {
      case 0:
        timerCycles = 1024;  // clock / inc rate == 4194304÷4096 == 1024 cycles
        break;
      case 1:
        timerCycles = 16;
        break;
      case 2:
        timerCycles = 64;
        break;
      case 3:
        timerCycles = 256;
        break;
      default:
        break;
    }
  }

  timerCounter += cycles;

  if (timerCounter >= timerCycles) {
    timerCounter = 0;
    // Check for timer overflow
    if (mmu.memory[TIMA] >= 0xFF) {
      mmu.memory[TIMA] = 0;
      // Request interrupt
      // todo: I think there is a 4 cycle delay here
      bitSet(mmu.memory[IF], 2);
    } else {
      mmu.memory[TIMA]++;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x18(%rbp)
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff07, %esi           # imm = 0xFF07
callq 0x4f3d0
movl $0x2, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x55f82
jmp 0x560ef
movq -0x18(%rbp), %rdi
movl 0x29c(%rdi), %eax
movl %eax, -0x1c(%rbp)
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff07, %esi           # imm = 0xFF07
callq 0x4f3d0
movq %rax, %rcx
movl -0x1c(%rbp), %eax
movzbl (%rcx), %ecx
andl $0x3, %ecx
cmpl %ecx, %eax
je 0x56042
movq -0x18(%rbp), %rdi
addq $0x20, %rdi
movl $0xff07, %esi           # imm = 0xFF07
callq 0x4f3d0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movzbl (%rcx), %ecx
andl $0x3, %ecx
movl %ecx, 0x29c(%rax)
movl 0x29c(%rax), %eax
movq %rax, -0x28(%rbp)
subq $0x3, %rax
ja 0x5603e
movq -0x28(%rbp), %rax
leaq 0x108bf(%rip), %rcx     # 0x668b4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x18(%rbp), %rax
movl $0x400, 0x2a0(%rax)     # imm = 0x400
jmp 0x56040
movq -0x18(%rbp), %rax
movl $0x10, 0x2a0(%rax)
jmp 0x56040
movq -0x18(%rbp), %rax
movl $0x40, 0x2a0(%rax)
jmp 0x56040
movq -0x18(%rbp), %rax
movl $0x100, 0x2a0(%rax)     # imm = 0x100
jmp 0x56040
jmp 0x56040
jmp 0x56042
movq -0x18(%rbp), %rcx
movzbl -0x9(%rbp), %eax
addl 0x2a4(%rcx), %eax
movl %eax, 0x2a4(%rcx)
movl 0x2a4(%rcx), %eax
cmpl 0x2a0(%rcx), %eax
jl 0x560ef
movq -0x18(%rbp), %rdi
movl $0x0, 0x2a4(%rdi)
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff05, %esi           # imm = 0xFF05
callq 0x4f3d0
movzbl (%rax), %eax
cmpl $0xff, %eax
jl 0x560d0
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff05, %esi           # imm = 0xFF05
callq 0x4f3d0
movq -0x18(%rbp), %rdi
movb $0x0, (%rax)
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff0f, %esi           # imm = 0xFF0F
callq 0x4f3d0
movq %rax, %rdi
movl $0x2, %esi
callq 0x4e8e0
jmp 0x560ed
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
addq $0x8, %rdi
movl $0xff05, %esi           # imm = 0xFF05
callq 0x4f3d0
movb (%rax), %cl
addb $0x1, %cl
movb %cl, (%rax)
jmp 0x560ef
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: CPU::checkInterrupts()
void CPU::checkInterrupts() {
  if (!ime || eiDelay) {  // IME disabled or the last instruction was EI
    eiDelay = false;
    return;
  }
  u8 requested = mmu.read8(IF);
  if (requested > 0) {
    u8 enabled = mmu.read8(IE);
    for (u8 i = 0; i < 5; i++) {
      if (bitTest(requested, i)) {
        if (bitTest(enabled, i)) {
          doInterrupt(i);
        }
      }
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
testb $0x1, 0x10(%rax)
je 0x56124
movq -0x18(%rbp), %rax
testb $0x1, 0x11(%rax)
je 0x56131
movq -0x18(%rbp), %rax
movb $0x0, 0x11(%rax)
jmp 0x561b8
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
movl $0xff0f, %esi           # imm = 0xFF0F
callq 0x4ecf0
movb %al, -0x9(%rbp)
movzbl -0x9(%rbp), %eax
cmpl $0x0, %eax
jle 0x561b8
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x4ecf0
movb %al, -0xa(%rbp)
movb $0x0, -0xb(%rbp)
movzbl -0xb(%rbp), %eax
cmpl $0x5, %eax
jge 0x561b6
movb -0x9(%rbp), %al
movzbl %al, %edi
movzbl -0xb(%rbp), %esi
callq 0x4e910
testb $0x1, %al
jne 0x56186
jmp 0x561aa
movb -0xa(%rbp), %al
movzbl %al, %edi
movzbl -0xb(%rbp), %esi
callq 0x4e910
testb $0x1, %al
jne 0x5619b
jmp 0x561a8
movq -0x18(%rbp), %rdi
movzbl -0xb(%rbp), %esi
callq 0x561c0
jmp 0x561aa
jmp 0x561ac
movb -0xb(%rbp), %al
addb $0x1, %al
movb %al, -0xb(%rbp)
jmp 0x56168
jmp 0x561b8
addq $0x20, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/cpu.cpp
// Function: CPU::doInterrupt(unsigned char)
void CPU::doInterrupt(u8 interrupt) {
  ime = false;  // IME = disabled

  // Reset bit in Interrupt Request Register
  u8 flags = mmu.memory[IF];
  bitClear(flags, interrupt);
  mmu.memory[IF] = flags;

  reg.sp -= 2;
  mmu.write16(reg.sp, reg.pc);  // Push PC to the stack

  // Interrupts have specific service routines at defined memory locations
  switch (interrupt) {
    case 0:
      reg.pc = 0x40;
      break;

    case 1:
      reg.pc = 0x48;
      break;

    case 2:
      reg.pc = 0x50;
      break;

    case 4:
      reg.pc = 0x60;
      break;

    default:
      break;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x20(%rbp)
movb $0x0, 0x10(%rdi)
movq %rdi, %rax
addq $0x18, %rax
movq %rax, -0x28(%rbp)
addq $0x20, %rdi
movq %rdi, -0x40(%rbp)
movl $0xff0f, %esi           # imm = 0xFF0F
movq %rsi, -0x38(%rbp)
callq 0x4f3d0
movb (%rax), %al
movb %al, -0xa(%rbp)
movzbl -0x9(%rbp), %esi
leaq -0xa(%rbp), %rdi
callq 0x4e8b0
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rsi
movb -0xa(%rbp), %al
movb %al, -0x29(%rbp)
callq 0x4f3d0
movb -0x29(%rbp), %dl
movq -0x28(%rbp), %rdi
movq %rax, %rcx
movq -0x20(%rbp), %rax
movb %dl, (%rcx)
movw 0xa(%rax), %cx
addw $-0x2, %cx
movw %cx, 0xa(%rax)
movzwl 0xa(%rax), %esi
movzwl 0x8(%rax), %edx
callq 0x4f210
movzbl -0x9(%rbp), %eax
movq %rax, -0x18(%rbp)
subq $0x4, %rax
ja 0x5629f
movq -0x18(%rbp), %rax
leaq 0x1065e(%rip), %rcx     # 0x668c4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x20(%rbp), %rax
movw $0x40, 0x8(%rax)
jmp 0x562a1
movq -0x20(%rbp), %rax
movw $0x48, 0x8(%rax)
jmp 0x562a1
movq -0x20(%rbp), %rax
movw $0x50, 0x8(%rax)
jmp 0x562a1
movq -0x20(%rbp), %rax
movw $0x60, 0x8(%rax)
jmp 0x562a1
jmp 0x562a1
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::incrementReg<unsigned char>(unsigned char&)
void CPU::incrementReg(t &reg1) {
  reg1++;
  bool carry = bitTest(reg.f, FLAG_CARRY);
  reg.f = 0;
  if (carry) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
  if ((reg1 & 0xF) == 0) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movb (%rcx), %dl
addb $0x1, %dl
movb %dl, (%rcx)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x20(%rbp), %rax
andb $0x1, %cl
movb %cl, -0x11(%rbp)
movb $0x0, (%rax)
testb $0x1, -0x11(%rbp)
je 0x563c3
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x563dd
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0xf, %eax
cmpl $0x0, %eax
jne 0x563fa
movq -0x20(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::decrementReg<unsigned char>(unsigned char&)
void CPU::decrementReg(t &reg1) {
  reg1--;
  bool carry = bitTest(reg.f, FLAG_CARRY);
  reg.f = 0;
  bitSet(reg.f, FLAG_SUBTRACT);
  if (carry) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
  if ((reg1 & 0xF) == 0xF) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movb (%rcx), %dl
addb $-0x1, %dl
movb %dl, (%rcx)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movq -0x20(%rbp), %rdi
andb $0x1, %al
movb %al, -0x11(%rbp)
movb $0x0, (%rdi)
movl $0x6, %esi
callq 0x4e8e0
testb $0x1, -0x11(%rbp)
je 0x5645a
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x56474
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
andl $0xf, %eax
cmpl $0xf, %eax
jne 0x56491
movq -0x20(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::rotateLeftCarry<unsigned short>(unsigned short&)
void CPU::rotateLeftCarry(t &reg1) {
  reg.f = 0;
  // High bit is shifted into carry flag
  if (bitTest(reg1, 7)) {
    bitSet(reg.f, FLAG_CARRY);
  }
  reg.a <<= 1;  // Shift register left, low bit becomes 0
  if (bitTest(reg.f, FLAG_CARRY)) {
    reg1++;
  }
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movl $0x7, %esi
movzwl (%rax), %edi
callq 0x574a0
testb $0x1, %al
jne 0x564d2
jmp 0x564e0
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %ecx
shll %ecx
movb %cl, 0x1(%rax)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x56500
jmp 0x5650e
movq -0x10(%rbp), %rax
movw (%rax), %cx
addw $0x1, %cx
movw %cx, (%rax)
movq -0x10(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x0, %eax
jne 0x56528
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::add16<unsigned short>(unsigned short&, unsigned short)
void CPU::add16(t &reg1, t n) {
  bool zero = bitTest(reg.f, FLAG_ZERO);
  reg.f = 0;
  if ((reg1 + n) > 0xFFFF) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if ((reg1 & 0x0FFF) + (n & 0x0FFF) > 0x0FFF) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
  bitClear(reg.f, FLAG_SUBTRACT);
  reg1 += n;
  if (zero) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movw %dx, %ax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movw %ax, -0x12(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x7, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x20(%rbp), %rax
andb $0x1, %cl
movb %cl, -0x13(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movzwl (%rax), %eax
movzwl -0x12(%rbp), %ecx
addl %ecx, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jle 0x5658d
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzwl (%rax), %eax
andl $0xfff, %eax            # imm = 0xFFF
movzwl -0x12(%rbp), %ecx
andl $0xfff, %ecx            # imm = 0xFFF
addl %ecx, %eax
cmpl $0xfff, %eax            # imm = 0xFFF
jle 0x565ba
movq -0x20(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
movq -0x20(%rbp), %rdi
movl $0x6, %esi
callq 0x4e8b0
movzwl -0x12(%rbp), %edx
movq -0x10(%rbp), %rax
movzwl (%rax), %ecx
addl %edx, %ecx
movw %cx, (%rax)
testb $0x1, -0x13(%rbp)
je 0x565ec
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::rotateRightCarry<unsigned char>(unsigned char&)
void CPU::rotateRightCarry(t &reg1) {
  reg.f = 0;
  // Low bit of register is shifted into carry flag
  if (bitTest(reg1, 1)) {
    bitSet(reg.f, FLAG_CARRY);
  }
  reg1 >>= 1;  // Shift register right, high bit becomes 0
  if (bitTest(reg.f, FLAG_CARRY)) {
    bitSet(reg1, 7);  // Carry flag shifts into high bit of register
  }
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movl $0x1, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x56632
jmp 0x56640
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movzbl (%rcx), %edx
sarl %edx
movb %dl, (%rcx)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x56662
jmp 0x56670
movq -0x10(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x5668a
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::rotateLeft<unsigned char>(unsigned char&)
void CPU::rotateLeft(t &reg1) {
  bool prevCarry = bitTest(reg.f, FLAG_CARRY);
  reg.f = 0;
  bool carry = bitTest(reg1, 7);
  reg1 <<= 1;
  reg1 += prevCarry;
  if (carry) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x20(%rbp), %rax
andb $0x1, %cl
movb %cl, -0x11(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movl $0x7, %esi
movzbl (%rax), %edi
callq 0x4e910
andb $0x1, %al
movb %al, -0x12(%rbp)
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
shll %ecx
movb %cl, (%rax)
movb -0x11(%rbp), %al
andb $0x1, %al
movzbl %al, %edx
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
addl %edx, %ecx
movb %cl, (%rax)
testb $0x1, -0x12(%rbp)
je 0x5670c
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x56726
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::rotateRight<unsigned char>(unsigned char&)
void CPU::rotateRight(t &reg1) {
  bool prevCarry = bitTest(reg.f, FLAG_CARRY);
  reg.f = 0;
  bool carry = bitTest(reg1, 0);
  reg1 >>= 1;
  reg1 += (prevCarry << 7);
  if (carry) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x20(%rbp), %rax
andb $0x1, %cl
movb %cl, -0x11(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
xorl %esi, %esi
movzbl (%rax), %edi
callq 0x4e910
andb $0x1, %al
movb %al, -0x12(%rbp)
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
sarl %ecx
movb %cl, (%rax)
movb -0x11(%rbp), %al
andb $0x1, %al
movzbl %al, %edx
shll $0x7, %edx
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
addl %edx, %ecx
movb %cl, (%rax)
testb $0x1, -0x12(%rbp)
je 0x567ac
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x567c6
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::add<unsigned char>(unsigned char)
void CPU::add(t n) {
  reg.f = 0;
  if ((reg.a + n) > 0xFF) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if ((reg.a & 0xF) + (n & 0xF) > 0xF) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
  bitClear(reg.f, FLAG_SUBTRACT);
  reg.a += n;
  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
movzbl -0x9(%rbp), %ecx
addl %ecx, %eax
cmpl $0xff, %eax
jle 0x5680c
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0xf, %eax
movzbl -0x9(%rbp), %ecx
andl $0xf, %ecx
addl %ecx, %eax
cmpl $0xf, %eax
jle 0x56833
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rdi
movl $0x6, %esi
callq 0x4e8b0
movq -0x18(%rbp), %rax
movzbl -0x9(%rbp), %edx
movzbl 0x1(%rax), %ecx
addl %edx, %ecx
movb %cl, 0x1(%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x56869
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::addCarry<unsigned char>(unsigned char)
void CPU::addCarry(t n) {
  u8 prevCarry = bitTest(reg.f, FLAG_CARRY);
  reg.f = 0;

  if (reg.a + n + prevCarry > 0xFF) {
    bitSet(reg.f, FLAG_CARRY);
  }

  if ((reg.a & 0x0F) + (n & 0x0F) + prevCarry > 0x0F) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }

  reg.a += n + prevCarry;

  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x18(%rbp), %rax
andb $0x1, %cl
movb %cl, -0xa(%rbp)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
movzbl -0x9(%rbp), %ecx
addl %ecx, %eax
movzbl -0xa(%rbp), %ecx
addl %ecx, %eax
cmpl $0xff, %eax
jle 0x568cb
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0xf, %eax
movzbl -0x9(%rbp), %ecx
andl $0xf, %ecx
addl %ecx, %eax
movzbl -0xa(%rbp), %ecx
addl %ecx, %eax
cmpl $0xf, %eax
jle 0x568f8
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl -0x9(%rbp), %edx
movzbl -0xa(%rbp), %ecx
addl %ecx, %edx
movzbl 0x1(%rax), %ecx
addl %edx, %ecx
movb %cl, 0x1(%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x56926
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::subtract<unsigned char>(unsigned char)
void CPU::subtract(t n) {
  reg.f = 0;
  if (reg.a < n) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if ((reg.a & 0xF) < (n & 0xF)) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
  bitSet(reg.f, FLAG_SUBTRACT);
  reg.a -= n;
  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
movzbl -0x9(%rbp), %ecx
cmpl %ecx, %eax
jge 0x56967
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0xf, %eax
movzbl -0x9(%rbp), %ecx
andl $0xf, %ecx
cmpl %ecx, %eax
jge 0x5698b
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rdi
movl $0x6, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl -0x9(%rbp), %edx
movzbl 0x1(%rax), %ecx
subl %edx, %ecx
movb %cl, 0x1(%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x569c1
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::subtractCarry<unsigned char>(unsigned char)
void CPU::subtractCarry(t n) {
  u8 prevCarry = bitTest(reg.f, FLAG_CARRY);
  if (reg.a < n + prevCarry) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if ((reg.a & 0x0F) < ((n + prevCarry) & 0x0F)) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
  bitSet(reg.f, FLAG_SUBTRACT);
  reg.a -= (n + prevCarry);
  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x18(%rbp), %rax
andb $0x1, %cl
movb %cl, -0xa(%rbp)
movzbl 0x1(%rax), %eax
movzbl -0x9(%rbp), %ecx
movzbl -0xa(%rbp), %edx
addl %edx, %ecx
cmpl %ecx, %eax
jge 0x56a23
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0xf, %eax
movzbl -0x9(%rbp), %ecx
movzbl -0xa(%rbp), %edx
addl %edx, %ecx
andl $0xf, %ecx
cmpl %ecx, %eax
jge 0x56a4d
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rdi
movl $0x6, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl -0x9(%rbp), %edx
movzbl -0xa(%rbp), %ecx
addl %ecx, %edx
movzbl 0x1(%rax), %ecx
subl %edx, %ecx
movb %cl, 0x1(%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x56a89
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::andReg<unsigned char>(unsigned char)
void CPU::andReg(t reg1) {
  reg.a &= reg1;
  reg.f = 0;
  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
  bitSet(reg.f, FLAG_HALF_CARRY);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movzbl -0x9(%rbp), %edx
movzbl 0x1(%rax), %ecx
andl %edx, %ecx
movb %cl, 0x1(%rax)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x56ad1
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::xorReg<unsigned char>(unsigned char)
void CPU::xorReg(t reg1) {
  reg.a ^= reg1;
  reg.f = 0;
  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movzbl -0x9(%rbp), %edx
movzbl 0x1(%rax), %ecx
xorl %edx, %ecx
movb %cl, 0x1(%rax)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x56b31
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::orReg<unsigned char>(unsigned char)
void CPU::orReg(t reg1) {
  reg.a |= reg1;
  reg.f = 0;
  if (reg.a == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movzbl -0x9(%rbp), %edx
movzbl 0x1(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x1(%rax)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x56b81
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::compare<unsigned char>(unsigned char)
void CPU::compare(t num) {
  reg.f = 0;
  if (reg.a < num) {
    bitSet(reg.f, FLAG_CARRY);
  }
  if ((reg.a & 0xF) < (num & 0xF)) {
    bitSet(reg.f, FLAG_HALF_CARRY);
  }
  bitSet(reg.f, FLAG_SUBTRACT);
  if (reg.a - num == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movzbl 0x1(%rax), %eax
movzbl -0x9(%rbp), %ecx
cmpl %ecx, %eax
jge 0x56bc7
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
andl $0xf, %eax
movzbl -0x9(%rbp), %ecx
andl $0xf, %ecx
cmpl %ecx, %eax
jge 0x56beb
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rdi
movl $0x6, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rax
movzbl 0x1(%rax), %eax
movzbl -0x9(%rbp), %ecx
subl %ecx, %eax
cmpl $0x0, %eax
jne 0x56c1a
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::sla<unsigned char>(unsigned char&)
void CPU::sla(t &reg1) {
  reg.f = 0;
  if (bitTest(reg1, 7)) {
    bitSet(reg.f, FLAG_CARRY);
  }
  reg1 <<= 1;
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movl $0x7, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x57142
jmp 0x57150
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
shll %ecx
movb %cl, (%rax)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x57175
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::sra<unsigned char>(unsigned char&)
void CPU::sra(t &reg1) {
  reg.f = 0;
  u8 msb = bitTest(reg1, 7);
  if (bitTest(reg1, 0)) {
    bitSet(reg.f, FLAG_CARRY);
  }
  reg1 >>= 1;
  reg1 += (msb << 7);
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movl $0x7, %esi
movzbl (%rax), %edi
callq 0x4e910
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
xorl %esi, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x571c5
jmp 0x571d3
movq -0x20(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
sarl %ecx
movb %cl, (%rax)
movzbl -0x11(%rbp), %edx
shll $0x7, %edx
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
addl %edx, %ecx
movb %cl, (%rax)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x5720a
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::swapReg<unsigned char>(unsigned char&)
void CPU::swapReg(t &reg1) {
  t lowerNibble = reg1 >> 4;
  reg1 <<= 4;
  reg1 |= lowerNibble;
  reg.f = 0;
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movzbl (%rcx), %ecx
sarl $0x4, %ecx
movb %cl, -0x11(%rbp)
movq -0x10(%rbp), %rcx
movzbl (%rcx), %edx
shll $0x4, %edx
movb %dl, (%rcx)
movzbl -0x11(%rbp), %esi
movq -0x10(%rbp), %rcx
movzbl (%rcx), %edx
orl %esi, %edx
movb %dl, (%rcx)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x5726d
movq -0x20(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::srl<unsigned char>(unsigned char&)
void CPU::srl(t &reg1) {
  reg.f = 0;
  if (bitTest(reg1, 0)) {
    bitSet(reg.f, FLAG_CARRY);
  }
  reg1 >>= 1;
  if (reg1 == 0) {
    bitSet(reg.f, FLAG_ZERO);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movb $0x0, (%rax)
movq -0x10(%rbp), %rax
xorl %esi, %esi
movzbl (%rax), %edi
callq 0x4e910
testb $0x1, %al
jne 0x572af
jmp 0x572bd
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
movq -0x10(%rbp), %rax
movzbl (%rax), %ecx
sarl %ecx
movb %cl, (%rax)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x572e2
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax,%rax)
// File: donfreiday[P]gb/cpu.cpp
// Function: void CPU::bit<unsigned char>(unsigned char, unsigned char)
void CPU::bit(u8 bit, t reg1) {
  u8 prevCarry = bitTest(reg.f, FLAG_CARRY);
  reg.f = 0;
  if (!bitTest(reg1, bit)) {
    bitSet(reg.f, FLAG_ZERO);
  }
  bitClear(reg.f, FLAG_SUBTRACT);
  bitSet(reg.f, FLAG_HALF_CARRY);
  if (prevCarry) {
    bitSet(reg.f, FLAG_CARRY);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %dl, %al
movb %sil, %cl
movq %rdi, -0x8(%rbp)
movb %cl, -0x9(%rbp)
movb %al, -0xa(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movl $0x4, %esi
movzbl (%rax), %edi
callq 0x4e910
movb %al, %cl
movq -0x18(%rbp), %rax
andb $0x1, %cl
movb %cl, -0xb(%rbp)
movb $0x0, (%rax)
movb -0xa(%rbp), %al
movzbl %al, %edi
movzbl -0x9(%rbp), %esi
callq 0x4e910
testb $0x1, %al
jne 0x5734c
movq -0x18(%rbp), %rdi
movl $0x7, %esi
callq 0x4e8e0
movq -0x18(%rbp), %rdi
movl $0x6, %esi
callq 0x4e8b0
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x4e8e0
cmpb $0x0, -0xb(%rbp)
je 0x5737c
movq -0x18(%rbp), %rdi
movl $0x4, %esi
callq 0x4e8e0
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)
// File: donfreiday[P]gb/main.cpp
// Function: handleSdlEvents()
void handleSdlEvents() {
  // Handle keydown, window close, etc
  SDL_Event event;
  while (SDL_PollEvent(&event)) {
    ImGui_ImplSdl_ProcessEvent(&event);
    switch (event.type) {
      case SDL_KEYDOWN:
        handleKeyPress(event.key.keysym.sym);
      case SDL_CONTROLLERBUTTONDOWN:
      case SDL_KEYUP:
      case SDL_CONTROLLERBUTTONUP:
        g_joypad.handleEvent(event);
        break;

      case SDL_CONTROLLERDEVICEADDED:
        // todo
        break;

      case SDL_CONTROLLERDEVICEREMOVED:
        // todo
        break;

      case SDL_QUIT:
        g_quit = true;
        break;

      default:
        break;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
leaq -0x38(%rbp), %rdi
callq 0x7860
cmpl $0x0, %eax
je 0x578b6
leaq -0x38(%rbp), %rdi
callq 0x4da80
movl -0x38(%rbp), %eax
movl %eax, -0x74(%rbp)
subl $0x100, %eax            # imm = 0x100
je 0x578a6
jmp 0x57819
movl -0x74(%rbp), %eax
subl $0x300, %eax            # imm = 0x300
je 0x57858
jmp 0x57825
movl -0x74(%rbp), %eax
subl $0x301, %eax            # imm = 0x301
je 0x57860
jmp 0x57831
movl -0x74(%rbp), %eax
addl $0xfffff9af, %eax       # imm = 0xFFFFF9AF
subl $0x2, %eax
jb 0x57860
jmp 0x57840
movl -0x74(%rbp), %eax
subl $0x653, %eax            # imm = 0x653
je 0x578a2
jmp 0x5784c
movl -0x74(%rbp), %eax
subl $0x654, %eax            # imm = 0x654
je 0x578a4
jmp 0x578af
movl -0x24(%rbp), %edi
callq 0x58bc0
leaq -0x70(%rbp), %rdi
leaq -0x38(%rbp), %rsi
movl $0x38, %edx
callq 0x7080
movq -0x40(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x30(%rax)
movups -0x70(%rbp), %xmm0
movups -0x60(%rbp), %xmm1
movups -0x50(%rbp), %xmm2
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq 0x3f665(%rip), %rdi     # 0x96f00
callq 0x4e430
jmp 0x578b1
jmp 0x578b1
jmp 0x578b1
movb $0x1, 0x3f6e3(%rip)     # 0x96f90
jmp 0x578b1
jmp 0x578b1
jmp 0x577eb
addq $0xb0, %rsp
popq %rbp
retq
nop
// File: donfreiday[P]gb/main.cpp
// Function: imguiRegisters()
void imguiRegisters() {
  // Position to the right of disassembly window
  ImGui::SetNextWindowPos(ImVec2(DISASM_WINDOW_WIDTH, 0.0f));
  ImGui::SetNextWindowSize(ImVec2(REG_WINDOW_WIDTH, REG_WINDOW_HEIGHT));
  ImGui::Begin("reg", nullptr,
               ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
  ImGui::Text(
      "af = %04X\nbc = %04X\nde = %04X\nhl = %04X\nsp = %04X\npc = %04X",
      g_cpu.reg.af, g_cpu.reg.bc, g_cpu.reg.de, g_cpu.reg.hl, g_cpu.reg.sp,
      g_cpu.reg.pc);
  ImGui::End();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
leaq -0x8(%rbp), %rdi
movss 0x5a30(%rip), %xmm0     # 0x5d5a4
xorps %xmm1, %xmm1
callq 0x2d280
leaq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x19450
leaq -0x10(%rbp), %rdi
movss 0x3595(%rip), %xmm0     # 0x5b128
movss 0x3511(%rip), %xmm1     # 0x5b0ac
callq 0x2d280
leaq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0xe790
leaq 0xff36(%rip), %rdi      # 0x67ae8
xorl %eax, %eax
movl %eax, %esi
movl $0x6, %edx
callq 0xe7e0
movzwl 0x2c271(%rip), %esi     # 0x83e38
movzwl 0x2c26c(%rip), %edx     # 0x83e3a
movzwl 0x2c267(%rip), %ecx     # 0x83e3c
movzwl 0x2c261(%rip), %r8d     # 0x83e3e
movzwl 0x2c25d(%rip), %r9d     # 0x83e42
movzwl 0x2c254(%rip), %eax     # 0x83e40
leaq 0xfef9(%rip), %rdi      # 0x67aec
movl %eax, (%rsp)
movb $0x0, %al
callq 0x1a220
callq 0xee30
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax,%rax)
// File: donfreiday[P]gb/main.cpp
// Function: imguiHelp()
void imguiHelp() {
  ImGui::SetNextWindowPos(ImVec2(DISASM_WINDOW_WIDTH+REG_WINDOW_WIDTH, 0.0f));
  ImGui::Begin("controls", nullptr,
               ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
  ImGui::Text(
      "A: z\n"
      "B: x\n"
      "Select: space\n"
      "Start: enter\n"
      "Directions: arrows\n"
      "Fullscreen: f\n");
  ImGui::End();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
leaq -0x8(%rbp), %rdi
movss 0x2bd0(%rip), %xmm0     # 0x5b0b4
xorps %xmm1, %xmm1
callq 0x2d280
leaq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x19450
leaq 0xf757(%rip), %rdi      # 0x67c55
xorl %eax, %eax
movl %eax, %esi
movl $0x6, %edx
callq 0xe7e0
leaq 0xf74b(%rip), %rdi      # 0x67c5e
movb $0x0, %al
callq 0x1a220
callq 0xee30
addq $0x10, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: donfreiday[P]gb/main.cpp
// Function: handleKeyPress(int)
void handleKeyPress(SDL_Keycode key) {
  switch (key) {
    // Fullscreen
    case SDLK_f:
      g_fullscreenLcd = !g_fullscreenLcd;
      break;

    // Step
    case SDLK_s:
      if (!g_running) {
        g_stepping = true;
      }
      break;

    // Toggle running state
    case SDLK_r:
      g_scrollDisasmToPC = g_running;
      g_running = !g_running;
      break;

    // Scroll to PC
    case SDLK_p:
      g_scrollDisasmToPC = true;
      break;

    default:
      break;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movl %edi, -0x4(%rbp)
movl -0x4(%rbp), %eax
addl $-0x66, %eax
movl %eax, %ecx
movq %rcx, -0x10(%rbp)
subl $0xd, %eax
ja 0x58c39
movq -0x10(%rbp), %rax
leaq 0xee25(%rip), %rcx      # 0x67a08
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb 0x3e3a0(%rip), %al      # 0x96f92
xorb $-0x1, %al
andb $0x1, %al
movb %al, 0x3e396(%rip)      # 0x96f92
jmp 0x58c3b
testb $0x1, 0x26a45(%rip)     # 0x7f64a
jne 0x58c0e
movb $0x1, 0x3e383(%rip)     # 0x96f91
jmp 0x58c3b
movb 0x26a34(%rip), %al      # 0x7f64a
andb $0x1, %al
movb %al, 0x26a2d(%rip)      # 0x7f64b
movb 0x26a26(%rip), %al      # 0x7f64a
xorb $-0x1, %al
andb $0x1, %al
movb %al, 0x26a1c(%rip)      # 0x7f64a
jmp 0x58c3b
movb $0x1, 0x26a14(%rip)     # 0x7f64b
jmp 0x58c3b
jmp 0x58c3b
popq %rbp
retq
nopl (%rax)