// File: /workspace/github_c_makefile_star2_O1/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, %ebp
movq %rdi, %r12
movl %ebp, %eax
addw $-0x1, %ax
movw %ax, 0x8(%rsp)
movl $0x0, %r13d
sbbl %r13d, %r13d
movw $0x1, %r15w
movzbl %sil, %eax
movl %eax, 0xc(%rsp)
xorl %ebx, %ebx
movzwl %r15w, %edx
movq %r12, %rdi
movl 0xc(%rsp), %esi
callq 0xa037
testl %eax, %eax
je 0xa8b6
cmpq $0x0, 0x60(%rsp)
sete %cl
cmpw $0x1, %r15w
setne %dl
orb %cl, %dl
jne 0xa7ea
movzwl 0x476(%r12), %ecx
movl %ecx, %edx
incl %edx
cmpw %cx, 0x472(%r12)
movl $0x0, %ecx
cmovel %ecx, %edx
movq 0x60(%rsp), %rcx
movw %dx, (%rcx)
movzwl 0x478(%r12), %esi
movzwl 0x47c(%r12), %r9d
btl $0xb, %r9d
setae %cl
cmpl $0x3ea, %esi            # imm = 0x3EA
setb %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0xa8ad
shrl %esi
movl $0x1f9, %ecx            # imm = 0x1F9
subl %esi, %ecx
movl %esi, %edx
addl $0x7, %edx
movzwl 0x47a(%r12), %edi
movzwl %si, %r8d
addl $0xc, %r8d
movw $0x5, %si
movl $0x5, %r11d
movl %r11d, %r10d
movzwl 0x47a(%r12,%r10,2), %r10d
btl $0x9, %r9d
jae 0xa888
testw %bp, %bp
jne 0xa85f
cmpw %r13w, %r10w
ja 0xa87a
cmpw %r10w, 0x8(%rsp)
setb %r9b
cmpw %r13w, %r10w
setb %r11b
andb %r9b, %r11b
cmpb $0x1, %r11b
jne 0xa888
movl %r15d, %ebx
movw %si, 0xa(%rsp)
movl %edi, %r14d
movl %r10d, %r13d
movzwl %r8w, %r11d
movzwl 0x472(%r12,%r11,2), %r9d
btl $0xb, %r9d
jb 0xa8ad
addl %edi, %r10d
addl %edx, %esi
leal (%r11,%rdx), %r8d
movl %r10d, %edi
cmpl %r11d, %ecx
jge 0xa841
movzwl 0x474(%r12), %r15d
xorl %ecx, %ecx
testl %eax, %eax
je 0xa8ee
testw %r15w, %r15w
jne 0xa797
testw %bx, %bx
je 0xa8ee
movq 0x10(%rsp), %rax
movw %r14w, (%rax)
movq 0x18(%rsp), %rax
movw %bx, (%rax)
movq 0x20(%rsp), %rax
movzwl 0xa(%rsp), %ecx
movw %cx, (%rax)
movl $0x1, %ecx
movl %ecx, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq