user: Please show me the C implementation that matches the assembly code listed below:

```asm
<block_write>:
  endbr64
  push   %r12
  push   %rbp
  push   %rbx
  mov    %edi,%ebp
  mov    %rsi,%r12
  call   <unlock_block_for_writes@plt>
  mov    $0xe8,%esi
  mov    %ebp,%edi
  call   <flash_write@plt>
  mov    %ebp,%edi
  call   <flash_read@plt>
  test   $0x80,%al
  je     L11
L84:
  mov    $0x1f,%esi
  mov    %ebp,%edi
  call   <flash_write@plt>
  mov    $0x0,%ebx
L98:
  mov    (%r12,%rbx,4),%esi
  lea    0x0(%rbp,%rbx,1),%edi
  call   <flash_write@plt>
  add    $0x1,%rbx
  cmp    $0x20,%rbx
  jne    L98
  mov    $0xd0,%esi
  mov    %ebp,%edi
  call   <flash_write@plt>
  mov    %ebp,%edi
  call   <flash_read@plt>
  and    $0x80,%eax
  mov    %eax,%ebx
  jne    L108
L138:
  mov    %ebp,%edi
  call   <flash_read@plt>
  add    $0x1,%ebx
  and    $0x80,%eax
  cmp    $0xffe,%ebx
  jg     L106
  test   %eax,%eax
  je     L138
L106:
  test   %eax,%eax
  je     L46
L108:
  mov    %ebp,%edi
  call   <flash_read_status@plt>
  mov    %eax,%ebx
  test   $0x8,%al
  jne    L117
L78:
  test   $0x30,%bl
  jne    L103
L113:
  test   $0x2,%bl
  jne    L158
L80:
  test   $0x20,%bl
  jne    L51
L42:
  mov    %ebp,%edi
  call   <lock_block_to_prevent_writes@plt>
  mov    %ebp,%edi
  call   <flash_read_mode@plt>
  pop    %rbx
  pop    %rbp
  pop    %r12
  ret
L11:
  lea    D16(%rip),%rdi
  mov    $0x0,%eax
  call   <warnx@plt>
  jmp    L84
L46:
  mov    %ebx,%esi
  lea    D51(%rip),%rdi
  call   <warnx@plt>
  jmp    L108
L117:
  mov    %eax,%esi
  lea    D53(%rip),%rdi
  mov    $0x0,%eax
  call   <warnx@plt>
  jmp    L78
L103:
  mov    %ebx,%esi
  lea    D48(%rip),%rdi
  mov    $0x0,%eax
  call   <warnx@plt>
  jmp    L113
L158:
  mov    %ebx,%esi
  lea    D35(%rip),%rdi
  mov    $0x0,%eax
  call   <warnx@plt>
  jmp    L80
L51:
  lea    0x0(%rbp,%rbp,1),%esi
  mov    %ebx,%edx
  lea    D23(%rip),%rdi
  mov    $0x0,%eax
  call   <warnx@plt>
  jmp    L42
```

tool_calls: name: unpack_data
arguments: tag: D16
type_infered: string
name: unpack_data
arguments: tag: D51
type_infered: string
name: unpack_data
arguments: tag: D53
type_infered: string
name: unpack_data
arguments: tag: D48
type_infered: string
name: unpack_data
arguments: tag: D35
type_infered: string
name: unpack_data
arguments: tag: D23
type_infered: string

tool: D16: block_write to flash failed - block write not supported by device?

tool: D51: ERROR on block-write - flash is busy even after 0x%x checks


tool: D53: Vpp voltage droop error during block-write, aborted, status=0x%02x


tool: D48: Command sequence error during block-write, aborted, status=0x%02x


tool: D35: Block locked during block-write process, aborted, status=0x%02x


tool: D23: Block-write failed at offset 0x%08x, status=0x%02x


assistant: ```c
void block_write(int addr16b, int *data) {
  int j, f, status;
  unlock_block_for_writes(addr16b);
  flash_write(addr16b, 0xe8);
  if ((flash_read(addr16b) & 0x80) == 0)
    warnx("block_write to flash failed - block write not supported by device?");
  flash_write(addr16b, 0x1f);
  for (j = 0; j < 0x20; j++)
    flash_write(addr16b + j, data[j]);
  flash_write(addr16b, 0xd0);
  status = flash_read(addr16b);
  for (j = 0; ((status & 0x80) == 0) && (j < 0xfff); j++)
    status = flash_read(addr16b);
  if ((status & 0x80) == 0)
    warnx("ERROR on block-write - flash is busy even after 0x%x checks\n", j);
  status = flash_read_status(addr16b);
  if ((status & (1 << 3)) != 0)
    warnx("Vpp voltage droop error during block-write, aborted, status=0x%02x\n", status);
  if ((status & (3 << 4)) != 0)
    warnx("Command sequence error during block-write, aborted, status=0x%02x\n", status);
  if ((status & (1 << 1)) != 0)
    warnx("Block locked during block-write process, aborted, status=0x%02x\n", status);
  if ((status & (1 << 5)) != 0)
    warnx("Block-write failed at offset 0x%08x, status=0x%02x\n", addr16b << 1, status);
  lock_block_to_prevent_writes(addr16b);
  flash_read_mode(addr16b);
}
```