// File: /workspace/github_c_makefile_star2_O2/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, %r10d
addw $-0x1, %r10w
movl $0x0, %ebx
sbbl %ebx, %ebx
movw $0x1, %r14w
movzbl %sil, %eax
movl %eax, 0xc(%rsp)
xorl %ebp, %ebp
movw %r10w, 0x6(%rsp)
movzwl %r14w, %edx
movq %r13, %rdi
movl 0xc(%rsp), %esi
callq 0x89c6
testl %eax, %eax
je 0x937e
cmpq $0x0, 0x60(%rsp)
sete %al
cmpw $0x1, %r14w
setne %cl
orb %al, %cl
jne 0x92b1
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), %eax
shrl %eax
movzwl 0x47a(%r13), %esi
movl $0x1f9, %ecx            # imm = 0x1F9
subl %eax, %ecx
addl $0x7, %eax
movw $0x5, %dx
movzwl 0x6(%rsp), %r10d
movzwl 0x4(%rsp), %r11d
movzwl %dx, %edi
movzwl 0x472(%r13,%rdi,2), %r8d
btl $0xb, %r8d
jb 0x933c
cmpl %edi, %ecx
jl 0x933c
movl %edi, %edi
movzwl 0x47a(%r13,%rdi,2), %edi
btl $0x9, %r8d
jae 0x9334
testw %r12w, %r12w
jne 0x9311
cmpw %bx, %di
ja 0x9329
cmpw %di, %r10w
setb %r8b
cmpw %bx, %di
setb %r9b
andb %r8b, %r9b
cmpb $0x1, %r9b
jne 0x9334
movl %r14d, %ebp
movl %edx, %r11d
movl %esi, %r15d
movl %edi, %ebx
addl %esi, %edi
addl %eax, %edx
movl %edi, %esi
jmp 0x92dd
movw %r11w, 0x4(%rsp)
movzwl 0x474(%r13), %r14d
testw %r14w, %r14w
jne 0x9260
testw %bp, %bp
je 0x937e
movq 0x10(%rsp), %rax
movw %r15w, (%rax)
movq 0x18(%rsp), %rax
movw %bp, (%rax)
movq 0x20(%rsp), %rax
movzwl 0x4(%rsp), %ecx
movw %cx, (%rax)
pushq $0x1
popq %rax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq