user: Converte this assembly snippet into its equivalent C code:

```asm
<ParseOpcodes>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x20,%rsp
  mov    %edi,-0x14(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %edx,-0x18(%rbp)
  mov    -0x20(%rbp),%rdx
  mov    -0x14(%rbp),%eax
  mov    %rdx,%rsi
  mov    %eax,%edi
  call   <OpcodeLen@plt>
  mov    %eax,-0x4(%rbp)
  mov    -0x18(%rbp),%eax
  cmp    -0x4(%rbp),%eax
  jge    L126
  mov    $0x0,%eax
  jmp    L70
L126:
  mov    -0x4(%rbp),%eax
  mov    %eax,-0x18(%rbp)
  mov    -0x18(%rbp),%edx
  mov    -0x14(%rbp),%eax
  add    %edx,%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x14(%rbp),%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  cmp    $0x38,%eax
  jg     L108
  cmp    $0x10,%eax
  jge    L36
  jmp    L124
L147:
  sub    $0xc0,%eax
  cmp    $0x3f,%eax
  ja     L124
  mov    %eax,%eax
  lea    0x0(,%rax,4),%rdx
  lea    D1(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D1(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
L36:
  mov    $0x1,%edx
  mov    %eax,%ecx
  shl    %cl,%rdx
  mov    %rdx,%rax
  movabs $0x101010100000000,%rdx
  and    %rax,%rdx
  test   %rdx,%rdx
  setne  %dl
  test   %dl,%dl
  jne    L251
  mov    %rax,%rdx
  and    $0x1000000,%edx
  test   %rdx,%rdx
  setne  %dl
  test   %dl,%dl
  jne    L302
  and    $0x10000,%eax
  test   %rax,%rax
  setne  %al
  test   %al,%al
  jne    L34
  jmp    L124
L108:
  cmp    $0xff,%eax
  jg     L124
  cmp    $0xc0,%eax
  jge    L147
  jmp    L124
  mov    -0x14(%rbp),%eax
  add    $0x2,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%ecx
  mov    -0x20(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    %edx,%eax
  mov    %eax,%ecx
  mov    -0x18(%rbp),%edx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  mov    %ecx,%edi
  call   <ParseOpcodes>
  jmp    L124
L251:
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%edx
  mov    -0x14(%rbp),%eax
  add    %edx,%eax
  lea    0x2(%rax),%ecx
  mov    -0x18(%rbp),%edx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  mov    %ecx,%edi
  call   <ParseOpcodes>
  jmp    L124
  mov    -0x14(%rbp),%eax
  add    $0x2,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%ecx
  mov    -0x20(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    %edx,%eax
  mov    %eax,%ecx
  mov    -0x18(%rbp),%edx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  mov    %ecx,%edi
  call   <ParseOpcodes>
  jmp    L124
  mov    -0x14(%rbp),%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x38,%eax
  mov    %eax,%ecx
  mov    -0x18(%rbp),%edx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  mov    %ecx,%edi
  call   <ParseOpcodes>
  jmp    L124
L34:
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%edx
  mov    -0x14(%rbp),%eax
  add    %edx,%eax
  lea    0x2(%rax),%ecx
  mov    -0x18(%rbp),%edx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  mov    %ecx,%edi
  call   <ParseOpcodes>
  jmp    L124
  mov    -0x14(%rbp),%eax
  add    $0x2,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%ecx
  mov    -0x20(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    %edx,%eax
  mov    %eax,-0x8(%rbp)
  jmp    L124
L302:
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%edx
  mov    -0x14(%rbp),%eax
  add    %edx,%eax
  add    $0x2,%eax
  mov    %eax,-0x8(%rbp)
  jmp    L124
  mov    -0x14(%rbp),%eax
  add    $0x2,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%ecx
  mov    -0x20(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    %edx,%eax
  mov    %eax,%ecx
  mov    -0x18(%rbp),%edx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  mov    %ecx,%edi
  call   <ParseOpcodes>
  jmp    L124
  mov    $0x1,%eax
  jmp    L70
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xe9,%al
  jne    L93
  lea    D21(%rip),%rax
  mov    %rax,%rdi
  call   <printf@plt>
  jmp    L93
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xe9,%al
  jne    L40
  lea    D15(%rip),%rax
  mov    %rax,%rdi
  call   <printf@plt>
  jmp    L40
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x4d,%al
  jne    L111
  mov    $0x2,%eax
  jmp    L70
L111:
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x45,%al
  jne    L274
  mov    $0x2,%eax
  jmp    L70
L93:
  nop
  jmp    L124
L40:
  nop
  jmp    L124
L274:
  nop
L124:
  mov    -0x8(%rbp),%eax
L70:
  leave
  ret
```

tool_calls: name: disassemble_data
arguments: data_label: D21
datatype: string
name: disassemble_data
arguments: data_label: D15
datatype: string

tool: D21: 	JP (IX) gefunden

tool: D15: 	JP (IY) gefunden

assistant: ```c
unsigned int ParseOpcodes(unsigned int adr, unsigned char *Opcodes, int len) {
  int i;
  unsigned int next;
  i = OpcodeLen(adr, Opcodes);
  if (len < i)
    return 0;
  len = i;
  next = adr + len;
  switch (Opcodes[adr]) {
  case 0xCA:
  case 0xC2:
  case 0xDA:
  case 0xD2:
  case 0xEA:
  case 0xE2:
  case 0xFA:
  case 0xF2:
    ParseOpcodes((Opcodes[adr + 2] << 8) + Opcodes[adr + 1], Opcodes, len);
    break;
  case 0x28:
  case 0x20:
  case 0x38:
  case 0x30:
    ParseOpcodes(adr + 2 + (char)Opcodes[adr + 1], Opcodes, len);
    break;
  case 0xCC:
  case 0xC4:
  case 0xDC:
  case 0xD4:
  case 0xEC:
  case 0xE4:
  case 0xFC:
  case 0xF4:
    ParseOpcodes((Opcodes[adr + 2] << 8) + Opcodes[adr + 1], Opcodes, len);
    break;
  case 0xC8:
  case 0xC0:
  case 0xD8:
  case 0xD0:
  case 0xE8:
  case 0xE0:
  case 0xF8:
  case 0xF0:
    break;
  case 0xC7:
  case 0xCF:
  case 0xD7:
  case 0xDF:
  case 0xE7:
  case 0xEF:
  case 0xF7:
  case 0xFF:
    ParseOpcodes(Opcodes[adr] & 0x38, Opcodes, len);
    break;
  case 0x10:
    ParseOpcodes(adr + 2 + (char)Opcodes[adr + 1], Opcodes, len);
    break;
  case 0xC3:
    next = (Opcodes[adr + 2] << 8) + Opcodes[adr + 1];
    break;
  case 0x18:
    next = adr + 2 + (char)Opcodes[adr + 1];
    break;
  case 0xCD:
    ParseOpcodes((Opcodes[adr + 2] << 8) + Opcodes[adr + 1], Opcodes, len);
    break;
  case 0xC9:
    return 1;
  case 0xE9:
    break;
  case 0xDD:
    if (Opcodes[adr + 1] == 0xE9) {
      printf("\tJP (IX) gefunden");
    }
    break;
  case 0xFD:
    if (Opcodes[adr + 1] == 0xE9) {
      printf("\tJP (IY) gefunden");
    }
    break;
  case 0xED:
    if (Opcodes[adr + 1] == 0x4D) {
      return 2;
    } else if (Opcodes[adr + 1] == 0x45) {
      return 2;
    }
    break;
  }
  return next;
}
```