// File: /workspace/github_c_makefile_star2_O2/simh[P]simtools/converters/fsio/dos11.c
// Function: dos11CreateFile
int dos11CreateFile(
  struct mountedFS *mount,
  struct dos11FileSpec *spec,
  struct dos11OpenFile *file,
  unsigned long contig
)
{
  struct DOS11data *data = &mount->dos11data;
  uint16_t mfdblk, ufdblk, ufdblk2;
  unsigned int i, j;
  struct tm tm;
  time_t now = time(NULL);
  uint16_t today;

  /*
   * Compute a suitable year for file creation date. This year will have
   * the same calendar as the current year but will be in the 20th century
   * so that DOS/BATCH-11 will be able to enter the date successfully (It is
   * not Y2K compliant!).
   */
  localtime_r(&now, &tm);
  tm.tm_year -= 28;

  today = ((tm.tm_year - 70) * 1000) + tm.tm_yday + 1;
  
  if (dos11ReadBlock(mount, MFD1_BLOCK, NULL) == 0)
    return 0;

  /*
   * Search the MFD for the specified UIC.
   */
  mfdblk = le16toh(data->buf[MFD1_MFD2BLOCK]);
  do {
    if (dos11ReadBlock(mount, mfdblk, NULL) == 0)
      return 0;

    for (i = MFD2_HEADER; i < EODIR(mount, MFD2_SIZE); i += MFD2_SIZE) {
      uint16_t uic = le16toh(data->buf[i + MFD2_UFDUIC]);
      uint16_t entrysz = le16toh(data->buf[i + MFD2_UFDSIZE]);

      if (uic != 0) {
        if (uic == ((spec->group << 8) | spec->user)) {
          ufdblk = le16toh(data->buf[i + MFD2_UFDSTART]);

          if (ufdblk == 0) {
            if ((ufdblk = dos11XtndDirectory(mount)) == 0) {
              ERROR("%s: Unable to create initial directory block\n",
                    mount->name);
              return 0;
            }

            data->buf[i + MFD2_UFDSTART] = htole16(ufdblk);
            if (dos11WriteBlock(mount, mfdblk, NULL) == 0)
              return 0;
          }
          for (;;) {
            if (dos11ReadBlock(mount, ufdblk, NULL) == 0)
              return 0;
            
            for (j = 1; j < EODIR(mount, entrysz); j += entrysz) {
              if ((le16toh(data->buf[j + UFD_FILENAME]) == 0) &&
                  (le16toh(data->buf[j + UFD_FILENAME + 1]) == 0) &&
                  (le16toh(data->buf[j + UFD_EXTENSION]) == 0)) {
                data->buf[j + UFD_FILENAME] =
                  file->name[0] = htole16(spec->name[0]);
                data->buf[j + UFD_FILENAME + 1] =
                  file->name[1] = htole16(spec->name[1]);
                data->buf[j + UFD_EXTENSION] = file->ext = htole16(spec->ext);
                data->buf[j + UFD_CREATION] =
                  file->creation =
                    htole16(today | (SWISSET('c') ? UFD_TYPECONTIGUOUS : 0));
                data->buf[j + UFD_NEXTFREEBYTE] = file->nfb = 0;
                data->buf[j + UFD_FILESTART] = file->start = 0;
                data->buf[j + UFD_FILELENGTH] = file->length = 0;
                data->buf[j + UFD_LASTBLOCKWRITTEN] = file->last = 0;
                data->buf[j + UFD_LUP] = file->lup = htole16(UFD_LOCK + 0233);

                file->ufdblk = ufdblk;
                file->ufdoffset = j;

                file-> mount = mount;

                if (SWISSET('c')) {
                  /*
                   * Allocate contiguous disk space for the file.
                   */
                  uint16_t base = bitmapAllocContiguous(mount, contig);

                  if (base == 0) {
                    ERROR("%s: Unable to allocate contiguous space\n",
                          mount->name);
                    return 0;
                  }

                  data->buf[j + UFD_FILESTART] = 
                    file->start = htole16(base);
                  data->buf[j + UFD_FILELENGTH] = 
                    file->length = htole16(contig);
                }

                /*
                 * Write the UFD block back to disk. The file will be marked
                 * as "locked" indicating that it is being written and the
                 * directory entry may not be accurate.
                 */
                if (dos11WriteBlock(mount, ufdblk, NULL) == 0)
                  return 0;

                return 1;
              }
            }

            if ((ufdblk = le16toh(data->buf[UFD_LINK])) == 0) {
              if ((ufdblk2 = dos11XtndDirectory(mount)) == 0) {
                ERROR("%s: Unable to extend UFD\n", mount->name);
                return 0;
              }

              data->buf[UFD_LINK] = htole16(ufdblk2);
              if (dos11WriteBlock(mount, ufdblk, NULL) == 0)
                return 0;
              ufdblk = ufdblk2;
            }
          }
        }
      }
    }
    mfdblk = le16toh(data->buf[MFD2_LINK]);
  } while (mfdblk != 0);

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rcx, 0x18(%rsp)
movq %rdx, 0x28(%rsp)
movq %rsi, %r12
movq %rdi, %rbx
xorl %r13d, %r13d
xorl %edi, %edi
callq 0x3200
leaq 0x58(%rsp), %rdi
movq %rax, (%rdi)
leaq 0x60(%rsp), %r14
movq %r14, %rsi
callq 0x30b0
movl 0x14(%r14), %ebp
movl 0x1c(%r14), %r15d
leal -0x1c(%rbp), %eax
movl %eax, 0x14(%r14)
pushq $0x1
popq %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x5ffa
testl %eax, %eax
je 0x5eb6
imull $0x3e8, %ebp, %eax      # imm = 0x3E8
addl %r15d, %eax
addl $0x8131, %eax           # imm = 0x8131
movl %eax, 0x10(%rsp)
movzwl 0x554(%rbx), %eax
pushq $0x3
popq %r14
movzwl %ax, %r15d
xorl %r13d, %r13d
movq %rbx, %rdi
movl %r15d, %esi
xorl %edx, %edx
callq 0x5ffa
testl %eax, %eax
je 0x5eb6
movq 0x28(%rbx), %rax
shrq %rax
addq $-0x3, %rax
movl %r14d, %ebp
leal -0x2(%rbp), %ecx
cmpq %rcx, %rax
jbe 0x5a6c
movzwl 0x554(%rbx,%rcx,2), %ecx
testw %cx, %cx
je 0x5a67
cmpw %cx, 0x8(%r12)
je 0x5a7d
addl $0x4, %ebp
jmp 0x5a4a
movzwl 0x554(%rbx), %eax
testw %ax, %ax
jne 0x5a20
jmp 0x5eb6
movl %r15d, 0x14(%rsp)
movl %ebp, %eax
movzwl 0x554(%rbx,%rax,2), %r15d
decl %ebp
movzwl 0x554(%rbx,%rbp,2), %r14d
testw %r14w, %r14w
jne 0x5ad3
movq %rbx, %rdi
callq 0x6113
testw %ax, %ax
je 0x5ecb
movl %eax, %r14d
movw %ax, 0x554(%rbx,%rbp,2)
xorl %r13d, %r13d
movq %rbx, %rdi
movl 0x14(%rsp), %esi
xorl %edx, %edx
callq 0x616b
testl %eax, %eax
je 0x5eb6
leaq -0x1(%r15), %rbp
movzwl %r14w, %esi
xorl %r13d, %r13d
movq %rbx, %rdi
movl %esi, 0x14(%rsp)
xorl %edx, %edx
callq 0x5ffa
testl %eax, %eax
je 0x5eb6
movq 0x28(%rbx), %rdx
shrq %rdx
subq %rbp, %rdx
pushq $0x9
popq %rax
leal -0x8(%rax), %ecx
cmpq %rcx, %rdx
jbe 0x5b35
cmpw $0x0, 0x554(%rbx,%rcx,2)
jne 0x5b30
leal -0x7(%rax), %esi
cmpw $0x0, 0x554(%rbx,%rsi,2)
jne 0x5b30
leal -0x6(%rax), %edi
cmpw $0x0, 0x554(%rbx,%rdi,2)
je 0x5b7a
addl %r15d, %eax
jmp 0x5b01
movzwl 0x554(%rbx), %r14d
testw %r14w, %r14w
jne 0x5ad7
movq %rbx, %rdi
callq 0x6113
testw %ax, %ax
je 0x5f14
movl %eax, %r14d
movw %ax, 0x554(%rbx)
xorl %r13d, %r13d
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x616b
testl %eax, %eax
jne 0x5ad7
jmp 0x5eb6
movzwl 0x2(%r12), %edx
movq 0x28(%rsp), %r8
movw %dx, (%r8)
movw %dx, 0x554(%rbx,%rcx,2)
movzwl 0x4(%r12), %edx
movw %dx, 0x2(%r8)
movw %dx, 0x554(%rbx,%rsi,2)
movzwl 0x6(%r12), %edx
movw %dx, 0x4(%r8)
movw %dx, 0x554(%rbx,%rdi,2)
leaq 0x1241a(%rip), %rdx     # 0x17fd8
movl (%rdx), %edx
andl $0x4, %edx
movl %edx, %esi
shll $0xd, %esi
orl 0x10(%rsp), %esi
movw %si, 0x6(%r8)
leal -0x5(%rax), %edi
movw %si, 0x554(%rbx,%rdi,2)
andw $0x0, 0x8(%r8)
leal -0x4(%rax), %esi
andw $0x0, 0x554(%rbx,%rsi,2)
andw $0x0, 0xa(%r8)
leal -0x3(%rax), %edi
andw $0x0, 0x554(%rbx,%rdi,2)
andw $0x0, 0xc(%r8)
leal -0x2(%rax), %r9d
andw $0x0, 0x554(%rbx,%r9,2)
andw $0x0, 0xe(%r8)
leal -0x1(%rax), %esi
andw $0x0, 0x554(%rbx,%rsi,2)
movw $0x809b, %si            # imm = 0x809B
movw %si, 0x10(%r8)
movl %eax, %eax
movw %si, 0x554(%rbx,%rax,2)
movw %r14w, 0x12(%r8)
movw %cx, 0x14(%r8)
movq %rbx, 0x20(%r8)
testl %edx, %edx
je 0x5e9f
movq %r9, 0x40(%rsp)
movq %rdi, 0x48(%rsp)
movzwl 0x18(%rsp), %ebp
movl 0x48(%rbx), %eax
cmpl %ebp, %eax
jbe 0x5f9c
movzwl 0x150(%rbx), %r11d
leal -0x1(%rbp), %ecx
movslq %ecx, %r9
pushq $0x11
popq %rcx
subl 0x18(%rsp), %ecx
movzwl %cx, %r13d
movb $0x1, %r14b
movw $0x3c0, %si             # imm = 0x3C0
movq %r9, 0x50(%rsp)
movzwl %r11w, %ecx
notl %ecx
addl %eax, %ecx
cmpl %ebp, %ecx
jb 0x5f9c
movl %r11d, %eax
xorl %edx, %edx
divw %si
movl %edx, 0x20(%rsp)
movl %eax, %r12d
cmpw 0x4c(%rbx), %r12w
jae 0x5f9c
movzwl %r12w, %esi
movq %rbx, %rdi
movl %r11d, %r15d
callq 0x8129
leaq 0x11812(%rip), %r10     # 0x174e0
movq 0x50(%rsp), %r9
testl %eax, %eax
je 0x5f9c
movl %r15d, %r11d
imull $0x3c0, %r12d, %eax     # imm = 0x3C0
movl 0x20(%rsp), %ecx
movzwl %cx, %r15d
shrl $0x4, %r15d
andl $-0x10, %ecx
leal (%rcx,%rax), %edi
addl $0x10, %edi
addl %eax, %ecx
negl %ecx
movzwl %cx, %edx
cmpq $0x3b, %r15
ja 0x5d73
movzwl 0x15c(%rbx,%r15,2), %esi
cmpl $0xffff, %esi           # imm = 0xFFFF
je 0x5d68
movl %edi, 0x10(%rsp)
testb %r14b, %r14b
je 0x5d30
movl %r15d, %ecx
shll $0x4, %ecx
addl %eax, %ecx
movw %cx, 0x150(%rbx)
cmpw $0x10, 0x18(%rsp)
ja 0x5d5c
movzwl (%r10,%r9,2), %edi
xorl %r14d, %r14d
cmpl %r14d, %r13d
je 0x5d5c
movl %edi, %r8d
movl %r14d, %ecx
shll %cl, %r8d
testl %esi, %r8d
je 0x5e51
incl %r14d
jmp 0x5d40
testw %si, %si
jns 0x5d83
xorl %r14d, %r14d
movl 0x10(%rsp), %edi
incq %r15
addl $0x10, %edi
addl $-0x10, %edx
jmp 0x5d01
incl %r12d
movl $0x0, 0x20(%rsp)
jmp 0x5e3b
movl %r15d, %ecx
shll $0x4, %ecx
pushq $0x1
popq %rdi
leaq 0x1176d(%rip), %rdx     # 0x17500
movq %rbp, 0x38(%rsp)
movl %r12d, 0x24(%rsp)
cmpq $0x11, %rdi
je 0x5dae
testw %si, (%rdx,%rdi,2)
jne 0x5db2
incq %rdi
jmp 0x5d9d
movw $0x11, %di
movq 0x18(%rsp), %rdx
movq %rdi, 0x30(%rsp)
subl %edi, %edx
leal (%rcx,%rax), %r14d
addl $0x10, %r14d
movzwl %dx, %ebp
movl %r14d, %r12d
movzwl %r12w, %esi
cmpw $0x10, %bp
jb 0x5df9
movq %rbx, %rdi
leaq 0xe(%rsp), %rdx
callq 0x824c
testl %eax, %eax
je 0x5e2b
cmpw $0x0, 0xe(%rsp)
jne 0x5e2b
addl $0x10, %r12d
addq $-0x10, %rbp
jmp 0x5dcc
testw %bp, %bp
je 0x5f65
movq %rbx, %rdi
leaq 0xe(%rsp), %rdx
callq 0x824c
testl %eax, %eax
je 0x5e2b
decl %ebp
leaq 0x116c4(%rip), %rax     # 0x174e0
movzwl (%rax,%rbp,2), %eax
testw %ax, 0xe(%rsp)
je 0x5f65
xorl %r14d, %r14d
movq 0x38(%rsp), %rbp
movl %r12d, %r11d
movl 0x24(%rsp), %r12d
cmpq $0x3b, %r15
movw $0x3c0, %si             # imm = 0x3C0
ja 0x5cad
movl 0x48(%rbx), %eax
jmp 0x5c8e
orl %r8d, %esi
movw %si, 0x15c(%rbx,%r15,2)
movb $0x1, 0x152(%rbx)
subl %edx, %r14d
testw %r14w, %r14w
je 0x5f9c
movq 0x28(%rsp), %rcx
movw %r14w, 0xa(%rcx)
movq 0x48(%rsp), %rax
movw %r14w, 0x554(%rbx,%rax,2)
movq 0x18(%rsp), %rax
movw %ax, 0xc(%rcx)
movq 0x40(%rsp), %rcx
movw %ax, 0x554(%rbx,%rcx,2)
movq %rbx, %rdi
movl 0x14(%rsp), %esi
xorl %edx, %edx
callq 0x616b
xorl %r13d, %r13d
testl %eax, %eax
setne %r13b
movl %r13d, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x11126(%rip), %rax     # 0x16ff8
movq (%rax), %rdi
addq $0x8, %rbx
leaq 0xa9b7(%rip), %rsi      # 0x10897
xorl %r13d, %r13d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x31e0
leaq 0x120d4(%rip), %rax     # 0x17fc8
movq (%rax), %rdi
testq %rdi, %rdi
je 0x5eb6
movq 0x110bd(%rip), %rax     # 0x16fc0
cmpq (%rax), %rdi
je 0x5eb6
leaq 0xa988(%rip), %rsi      # 0x10897
jmp 0x5fe8
movq 0x110dd(%rip), %rax     # 0x16ff8
movq (%rax), %rdi
addq $0x8, %rbx
leaq 0xa9c5(%rip), %rsi      # 0x108ee
xorl %r13d, %r13d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x31e0
leaq 0x1208b(%rip), %rax     # 0x17fc8
movq (%rax), %rdi
testq %rdi, %rdi
je 0x5eb6
movq 0x11070(%rip), %rax     # 0x16fc0
cmpq (%rax), %rdi
je 0x5eb6
leaq 0xa98e(%rip), %rsi      # 0x108ee
jmp 0x5fe8
movq 0x30(%rsp), %rax
subl %eax, %r14d
movl 0x10(%rsp), %r15d
subl %eax, %r15d
movq 0x18(%rsp), %rax
movl %eax, %ebp
subw $0x1, %bp
jb 0x5e67
movzwl %r15w, %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x81f5
incl %r15d
testl %eax, %eax
jne 0x5f7c
movq 0x11055(%rip), %rax     # 0x16ff8
movq (%rax), %rdi
addq $0x8, %rbx
leaq 0xa914(%rip), %rsi      # 0x108c5
xorl %r13d, %r13d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x31e0
leaq 0x12003(%rip), %rax     # 0x17fc8
movq (%rax), %rdi
testq %rdi, %rdi
je 0x5eb6
movq 0x10fe8(%rip), %rax     # 0x16fc0
cmpq (%rax), %rdi
je 0x5eb6
leaq 0xa8dd(%rip), %rsi      # 0x108c5
xorl %r13d, %r13d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x31e0
jmp 0x5eb6