// File: /workspace/github_c_makefile_star2_O3/simh[P]simtools/converters/fsio/rt11.c
// Function: rt11BestFit
static int rt11BestFit(
  struct mountedFS *mount,
  uint8_t unit,
  uint16_t rqsize,
  uint16_t *start,
  uint16_t *segment,
  uint16_t *offset,
  uint16_t *next
)
{
  struct RT11data *data = &mount->rt11data;
  uint16_t bestsize, beststart, bestsegment, bestoffset, dsseg = 1;

  bestsize = rqsize == 0 ? 0 : 0177777;
  bestsegment = 0;

  do {
    uint16_t entrysz, startblk, off = RT11_DH_SIZE;

    if (rt11ReadDirSegment(mount, unit, dsseg) == 0)
      return 0;

    /*
     * Return the next available directory segment or 0 if no more are
     * available.
     */
    if ((next != NULL) && (dsseg == 1)) {
      if (data->buf[RT11_DH_COUNT] != data->buf[RT11_DH_HIGHEST])
        *next = le16toh(data->buf[RT11_DH_HIGHEST]) + 1;
      else *next = 0;
    }

    entrysz = RT11_DI_SIZE + (le16toh(data->buf[RT11_DH_EXTRA]) >> 1);
    startblk = le16toh(data->buf[RT11_DH_START]);

    /*
     * Loop until we see and end-of-segment marker or there is no room for
     * another directory entry.
     */
    while (!RT11EOS(le16toh(data->buf[off + RT11_DI_STATUS])) &&
           ((RT11_DS_SIZE - off) >= entrysz)) {
      uint16_t status = le16toh(data->buf[off + RT11_DI_STATUS]);
      uint16_t length = le16toh(data->buf[off + RT11_DI_LENGTH]);

      if ((status & RT11_E_MPTY) != 0) {
        /*
         * Check for largest or best fit
         */
        if (((rqsize == 0) && (length > bestsize)) ||
            ((rqsize != 0) &&
             ((length >= rqsize) && (length < bestsize)))) {
          bestsize = length;
          beststart = startblk;
          bestsegment = dsseg;
          bestoffset = off;
        }
      }
      startblk += length;
      off += entrysz;
    }
    dsseg = le16toh(data->buf[RT11_DH_NEXT]);
  } while (dsseg != 0);

  if (bestsegment != 0) {
    *start = beststart;
    *segment = bestsegment;
    *offset = bestoffset;
    return 1;
  }
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, 0x20(%rsp)
movq %r8, 0x18(%rsp)
movq %rcx, 0x10(%rsp)
movl %edx, %r12d
movq %rdi, %r13
movl $0x0, 0x8(%rsp)
movl %r12d, %r11d
addw $-0x1, %r11w
movl $0x0, %ebx
sbbl %ebx, %ebx
movw $0x1, %r15w
movzbl %sil, %eax
movl %eax, 0xc(%rsp)
xorl %ebp, %ebp
movl %ebp, %r14d
movl %r11d, %ebp
movzwl %r15w, %edx
movq %r13, %rdi
movl 0xc(%rsp), %esi
callq 0x9d20
testl %eax, %eax
je 0xa5fc
cmpq $0x0, 0x60(%rsp)
sete %al
cmpw $0x1, %r15w
setne %cl
orb %al, %cl
jne 0xa4e1
movzwl 0x476(%r13), %eax
movl %eax, %ecx
incl %ecx
cmpw %ax, 0x472(%r13)
movl $0x0, %eax
cmovel %eax, %ecx
movq 0x60(%rsp), %rax
movw %cx, (%rax)
movzwl 0x478(%r13), %edx
movzwl 0x47c(%r13), %r8d
btl $0xb, %r8d
setae %al
cmpl $0x3ea, %edx            # imm = 0x3EA
setb %cl
andb %al, %cl
cmpb $0x1, %cl
movl %ebp, %r11d
jne 0xa5ac
shrl %edx
movl $0x1f9, %eax            # imm = 0x1F9
subl %edx, %eax
movl %edx, %ecx
addl $0x7, %ecx
movzwl 0x47a(%r13), %esi
movzwl %dx, %edi
addl $0xc, %edi
movw $0x5, %dx
movl $0x5, %r10d
movl %r14d, %ebp
movzwl 0x4(%rsp), %r14d
movl %r10d, %r9d
movzwl 0x47a(%r13,%r9,2), %r9d
btl $0x9, %r8d
jae 0xa585
testw %r12w, %r12w
jne 0xa55e
cmpw %bx, %r9w
ja 0xa577
cmpw %r9w, %r11w
setb %r8b
cmpw %bx, %r9w
setb %r10b
andb %r8b, %r10b
cmpb $0x1, %r10b
jne 0xa585
movl %r15d, %ebp
movl %edx, %r14d
movw %si, 0x6(%rsp)
movl %r9d, %ebx
movzwl %di, %r10d
movzwl 0x472(%r13,%r10,2), %r8d
btl $0xb, %r8d
jb 0xa5b5
addl %esi, %r9d
addl %ecx, %edx
leal (%r10,%rcx), %edi
movl %r9d, %esi
cmpl %r10d, %eax
jge 0xa53f
jmp 0xa5b5
movl %r14d, %ebp
movzwl 0x4(%rsp), %r14d
movw %r14w, 0x4(%rsp)
movzwl 0x474(%r13), %r15d
testw %r15w, %r15w
jne 0xa48a
testw %bp, %bp
je 0xa5fc
movq 0x10(%rsp), %rax
movzwl 0x6(%rsp), %ecx
movw %cx, (%rax)
movq 0x18(%rsp), %rax
movw %bp, (%rax)
movq 0x20(%rsp), %rax
movzwl 0x4(%rsp), %ecx
movw %cx, (%rax)
movl $0x1, 0x8(%rsp)
movl 0x8(%rsp), %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq