// File: atsidaev[P]trx2x/DiskImage.cpp
// Function: TDiskImage::writeFDI(int)
void TDiskImage::writeFDI(int hfile)
{
   unsigned char *ptr = (unsigned char*)new char[(MaxTrack+1)*(MaxSide+1)*6250+524288];
   unsigned short *headptr = (unsigned short*)(ptr+4);
   memcpy(ptr, "FDI", 3);
   ptr[3]  = 0x00;                                      // write enabled
   headptr[0] = ((unsigned short)MaxTrack) + 1;         // Cyl count
   headptr[1] = ((unsigned short)MaxSide) + 1;          // Head count
   headptr[4] = 0;                                      // extension length

   unsigned int trk, side;
   VGFIND_SECTOR vgfs;
   VGFIND_ADM vgfa;

   unsigned char *htrkSectorCount;
   unsigned int fdiOFF = 0x0E;
   unsigned int trackOFF = 0;
   unsigned int SectorCount;
   unsigned int sectOFF;

   for(trk=0; trk <= unsigned(MaxTrack); trk++)
      for(side=0; side <= unsigned(MaxSide); side++)
      {
         *((uint32_t*)(ptr+fdiOFF)) = trackOFF;
         fdiOFF += 4;
         *((uint16_t*)(ptr+fdiOFF)) = 0;  // Всегда содержит 0 (резерв)
         fdiOFF += 2;
         htrkSectorCount = ptr+fdiOFF;
         fdiOFF++;
         SectorCount=0;
         sectOFF = 0;

         unsigned int TrackPtr=0;
         bool FirstFindAD = true;
         unsigned int FirstOffset;
         for(;;)
         {
            if(!FindADMark(trk, side, TrackPtr, &vgfa)) break;
            if(!FirstFindAD) 
            {
               if(vgfa.OffsetADM == FirstOffset) break;
            }
            else
            {
               FirstOffset = vgfa.OffsetADM;
               FirstFindAD = false;
            }
            TrackPtr = vgfa.OffsetEndADM;

            SectorCount++;

            memcpy(ptr+fdiOFF, vgfa.ADMPointer, 4);
            fdiOFF+=4;
            unsigned char flags=0x00;
            if(!FindSector(trk, side, vgfa.ADMPointer[2], &vgfs, vgfa.MarkedOffsetADM))
               flags |= 0x40;
            else
            {
               if(vgfs.DataMarker==0xF8) flags |= 0x80;
               if(vgfs.CRCOK) flags |= (vgfs.SectorLength>>7)&0x3F;
            }
            ptr[fdiOFF++] = flags;
            *((unsigned short*)(ptr+fdiOFF)) = sectOFF;
            fdiOFF+=2;

            if(!(flags&0x40)) sectOFF += vgfs.SectorLength;
         }
         *htrkSectorCount = (unsigned char)SectorCount;
         trackOFF += sectOFF;
      }
   headptr[2] = fdiOFF;                                 // Text offset
   memcpy(ptr+fdiOFF, fdicomment, sizeof(fdicomment));
   fdiOFF += sizeof(fdicomment);

   headptr[3] = fdiOFF;                                 // Data offset

   for(trk=0; trk <= unsigned(MaxTrack); trk++)
      for(side=0; side <= unsigned(MaxSide); side++)
      {
         unsigned int TrackPtr=0;
         bool FirstFindAD = true;
         unsigned int FirstOffset;
         for(;;)
         {
            if(!FindADMark(trk, side, TrackPtr, &vgfa)) break;
            if(!FirstFindAD) 
            {
               if(vgfa.OffsetADM == FirstOffset) break;
            }
            else
            {
               FirstOffset = vgfa.OffsetADM;
               FirstFindAD = false;
            }
            TrackPtr = vgfa.OffsetEndADM;

            if(FindSector(trk, side, vgfa.ADMPointer[2], &vgfs, vgfa.MarkedOffsetADM))
            {
               memcpy(ptr+fdiOFF, vgfs.SectorPointer, vgfs.SectorLength);
               fdiOFF+=vgfs.SectorLength;
            }
         }
      }

   write(hfile, ptr, fdiOFF);
   delete ptr;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0xf8(%rbp)
movzbl 0x145007(%rcx), %eax
addl $0x1, %eax
movzbl 0x145008(%rcx), %ecx
addl $0x1, %ecx
imull %ecx, %eax
imull $0x186a, %eax, %eax     # imm = 0x186A
addl $0x80000, %eax          # imm = 0x80000
movslq %eax, %rdi
callq 0x1030
movq %rax, %rcx
movq -0xf8(%rbp), %rax
movq %rcx, -0x18(%rbp)
movq -0x18(%rbp), %rcx
addq $0x4, %rcx
movq %rcx, -0x20(%rbp)
movq -0x18(%rbp), %rcx
movw 0xa9bb(%rip), %dx       # 0xe1c7
movw %dx, (%rcx)
movb 0xa9b4(%rip), %dl       # 0xe1c9
movb %dl, 0x2(%rcx)
movq -0x18(%rbp), %rcx
movb $0x0, 0x3(%rcx)
movzbl 0x145007(%rax), %ecx
movzwl %cx, %ecx
addl $0x1, %ecx
movw %cx, %dx
movq -0x20(%rbp), %rcx
movw %dx, (%rcx)
movzbl 0x145008(%rax), %eax
movzwl %ax, %eax
addl $0x1, %eax
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x20(%rbp), %rax
movw $0x0, 0x8(%rax)
movl $0xe, -0xc4(%rbp)
movl $0x0, -0xc8(%rbp)
movl $0x0, -0x24(%rbp)
movq -0xf8(%rbp), %rcx
movl -0x24(%rbp), %eax
movzbl 0x145007(%rcx), %ecx
cmpl %ecx, %eax
ja 0x3b0f
movl $0x0, -0x28(%rbp)
movq -0xf8(%rbp), %rcx
movl -0x28(%rbp), %eax
movzbl 0x145008(%rcx), %ecx
cmpl %ecx, %eax
ja 0x3aff
movl -0xc8(%rbp), %edx
movq -0x18(%rbp), %rax
movl -0xc4(%rbp), %ecx
movl %edx, (%rax,%rcx)
movl -0xc4(%rbp), %eax
addl $0x4, %eax
movl %eax, -0xc4(%rbp)
movq -0x18(%rbp), %rax
movl -0xc4(%rbp), %ecx
movw $0x0, (%rax,%rcx)
movl -0xc4(%rbp), %eax
addl $0x2, %eax
movl %eax, -0xc4(%rbp)
movq -0x18(%rbp), %rax
movl -0xc4(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0xc0(%rbp)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
movl $0x0, -0xcc(%rbp)
movl $0x0, -0xd0(%rbp)
movl $0x0, -0xd4(%rbp)
movb $0x1, -0xd5(%rbp)
movq -0xf8(%rbp), %rdi
movl -0x24(%rbp), %eax
movb %al, %dl
movl -0x28(%rbp), %eax
movl -0xd4(%rbp), %ecx
leaq -0xb8(%rbp), %r8
movzbl %dl, %esi
movzbl %al, %edx
callq 0x2220
testb $0x1, %al
jne 0x3966
jmp 0x3ace
testb $0x1, -0xd5(%rbp)
jne 0x3984
movl -0x90(%rbp), %eax
cmpl -0xdc(%rbp), %eax
jne 0x3982
jmp 0x3ace
jmp 0x3997
movl -0x90(%rbp), %eax
movl %eax, -0xdc(%rbp)
movb $0x0, -0xd5(%rbp)
movq -0xf8(%rbp), %rdi
movl -0x8c(%rbp), %eax
movl %eax, -0xd4(%rbp)
movl -0xcc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xcc(%rbp)
movq -0x18(%rbp), %rax
movl -0xc4(%rbp), %ecx
movq -0xa0(%rbp), %rdx
movl (%rdx), %edx
movl %edx, (%rax,%rcx)
movl -0xc4(%rbp), %eax
addl $0x4, %eax
movl %eax, -0xc4(%rbp)
movb $0x0, -0xdd(%rbp)
movl -0x24(%rbp), %eax
movb %al, %dl
movl -0x28(%rbp), %eax
movb %al, %cl
movq -0xa0(%rbp), %rax
movb 0x2(%rax), %al
movl -0x94(%rbp), %r9d
leaq -0x80(%rbp), %r8
movzbl %dl, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x25d0
testb $0x1, %al
jne 0x3a28
movzbl -0xdd(%rbp), %eax
orl $0x40, %eax
movb %al, -0xdd(%rbp)
jmp 0x3a65
movzbl -0x2e(%rbp), %eax
cmpl $0xf8, %eax
jne 0x3a45
movzbl -0xdd(%rbp), %eax
orl $0x80, %eax
movb %al, -0xdd(%rbp)
cmpb $0x0, -0x2f(%rbp)
je 0x3a63
movl -0x40(%rbp), %ecx
shrl $0x7, %ecx
andl $0x3f, %ecx
movzbl -0xdd(%rbp), %eax
orl %ecx, %eax
movb %al, -0xdd(%rbp)
jmp 0x3a65
movb -0xdd(%rbp), %dl
movq -0x18(%rbp), %rax
movl -0xc4(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0xc4(%rbp)
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movl -0xd0(%rbp), %eax
movw %ax, %dx
movq -0x18(%rbp), %rax
movl -0xc4(%rbp), %ecx
movw %dx, (%rax,%rcx)
movl -0xc4(%rbp), %eax
addl $0x2, %eax
movl %eax, -0xc4(%rbp)
movzbl -0xdd(%rbp), %eax
andl $0x40, %eax
cmpl $0x0, %eax
jne 0x3ac9
movl -0x40(%rbp), %eax
addl -0xd0(%rbp), %eax
movl %eax, -0xd0(%rbp)
jmp 0x3936
movl -0xcc(%rbp), %eax
movb %al, %cl
movq -0xc0(%rbp), %rax
movb %cl, (%rax)
movl -0xd0(%rbp), %eax
addl -0xc8(%rbp), %eax
movl %eax, -0xc8(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3894
jmp 0x3b01
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x3874
movl -0xc4(%rbp), %eax
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, 0x4(%rax)
movq -0x18(%rbp), %rdi
movl -0xc4(%rbp), %eax
addq %rax, %rdi
leaq 0xd63c(%rip), %rsi      # 0x11170
movl $0x4d, %edx
callq 0x10c0
movl -0xc4(%rbp), %eax
addq $0x4d, %rax
movl %eax, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, 0x6(%rax)
movl $0x0, -0x24(%rbp)
movq -0xf8(%rbp), %rcx
movl -0x24(%rbp), %eax
movzbl 0x145007(%rcx), %ecx
cmpl %ecx, %eax
ja 0x3ca6
movl $0x0, -0x28(%rbp)
movq -0xf8(%rbp), %rcx
movl -0x28(%rbp), %eax
movzbl 0x145008(%rcx), %ecx
cmpl %ecx, %eax
ja 0x3c96
movl $0x0, -0xe4(%rbp)
movb $0x1, -0xe5(%rbp)
movq -0xf8(%rbp), %rdi
movl -0x24(%rbp), %eax
movb %al, %dl
movl -0x28(%rbp), %eax
movl -0xe4(%rbp), %ecx
leaq -0xb8(%rbp), %r8
movzbl %dl, %esi
movzbl %al, %edx
callq 0x2220
testb $0x1, %al
jne 0x3be0
jmp 0x3c86
testb $0x1, -0xe5(%rbp)
jne 0x3bfe
movl -0x90(%rbp), %eax
cmpl -0xec(%rbp), %eax
jne 0x3bfc
jmp 0x3c86
jmp 0x3c11
movl -0x90(%rbp), %eax
movl %eax, -0xec(%rbp)
movb $0x0, -0xe5(%rbp)
movq -0xf8(%rbp), %rdi
movl -0x8c(%rbp), %eax
movl %eax, -0xe4(%rbp)
movl -0x24(%rbp), %eax
movb %al, %dl
movl -0x28(%rbp), %eax
movb %al, %cl
movq -0xa0(%rbp), %rax
movb 0x2(%rax), %al
movl -0x94(%rbp), %r9d
leaq -0x80(%rbp), %r8
movzbl %dl, %esi
movzbl %cl, %edx
movzbl %al, %ecx
callq 0x25d0
testb $0x1, %al
jne 0x3c57
jmp 0x3c81
movq -0x18(%rbp), %rdi
movl -0xc4(%rbp), %eax
addq %rax, %rdi
movq -0x48(%rbp), %rsi
movl -0x40(%rbp), %eax
movl %eax, %edx
callq 0x10c0
movl -0x40(%rbp), %eax
addl -0xc4(%rbp), %eax
movl %eax, -0xc4(%rbp)
jmp 0x3bb0
jmp 0x3c88
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3b86
jmp 0x3c98
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x3b66
movl -0xc(%rbp), %edi
movq -0x18(%rbp), %rsi
movl -0xc4(%rbp), %eax
movl %eax, %edx
callq 0x1050
movq -0x18(%rbp), %rax
movq %rax, -0x100(%rbp)
cmpq $0x0, %rax
je 0x3cdc
movq -0x100(%rbp), %rdi
movl $0x1, %esi
callq 0x1130
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)