// File: /workspace/github_cpp_makefile_star2_O3/atsidaev[P]trx2x/DiskImage.cpp
// Function: TDiskImage::readUDI(int, bool)
void TDiskImage::readUDI(int hfile, bool ronly)
{
   long fsize = filelength(hfile);
   if(fsize < 0)
   {
      ShowError(ERR_GETLEN);
      return;
   }

   unsigned char *ptr = (unsigned char*)new char[fsize+1024*2048];
   if(!ptr)
   {
      ShowError(ERR_NOMEM);
      return;
   }

   unsigned long rsize = read(hfile, ptr, fsize+1024);
   if(rsize < 16+4)
   {
      delete ptr;
      ShowError(ERR_CORRUPT);
      return;
   }

   if(memcmp(ptr, "UDI!", 4) != 0) 
   {
      delete ptr;
      ShowError(ERR_FORMAT" UDI!");
      return;
   }

   UDI_HEADER *udi_hdr = (UDI_HEADER*)(ptr);

   if((udi_hdr->Version != 0x00)||(udi_hdr->_zero != 0x00)||(udi_hdr->ExtHdrLength != 0))
   {
      delete ptr;
      ShowError(ERR_FILEVER" UDI!");
      return;
   }
   if(rsize != (udi_hdr->UnpackedLength+4))
   {
      delete ptr;
      ShowError(ERR_CORRUPT);
      return;
   }

   MaxTrack = udi_hdr->MaxCylinder;
   MaxSide = udi_hdr->MaxSide;


// checking for corrupt...
   unsigned int udiOFF=0x10;

   unsigned int trk, side;

   for(trk=0; trk <= unsigned(MaxTrack); trk++)
      for(side=0; side <= unsigned(MaxSide); side++)
      {
         uint8_t frmt = ptr[udiOFF++];
         if(rsize < udiOFF+4)
         {
            delete ptr;
            ShowError(ERR_CORRUPT);
            return;
         }

         if(frmt)
         {
            udiOFF += *((uint32_t*)(ptr+udiOFF));
            udiOFF += 4;
            continue;
         }

         unsigned ccctlen = *((uint16_t*)(ptr+udiOFF));
         udiOFF += ccctlen;
         udiOFF += 2;
         if(rsize < udiOFF+4)
         {
            delete ptr;
            ShowError(ERR_CORRUPT);
            return;
         }

         udiOFF += ccctlen/8 + ((ccctlen-(ccctlen/8)*8)? 1:0);
         if(rsize < udiOFF+4)
         {
            delete ptr;
            ShowError(ERR_CORRUPT);
            return;
         }
      }


   udiOFF = 0x10;

   unsigned int trklen;

   for(trk=0; trk <= unsigned(MaxTrack); trk++)
      for(side=0; side <= unsigned(MaxSide); side++)
      {
         if(udiOFF >= rsize) break;

         if(ptr[udiOFF++] != 0)        // non MFM track?
         {
            FTrackLength[trk][side] = 6250;
// make unformatted track...
            FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side]+1024];      // trk img
            FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side]+1024];      // clk img
            for(unsigned ij=0; ij < 6250; ij++)   
            {
               FTracksPtr[trk][side][0][ij] = 0x00;
               FTracksPtr[trk][side][1][ij] = 0x00;         
            }

            udiOFF += *((unsigned long*)(ptr+udiOFF));
            udiOFF +=4;
            continue;
         }
         trklen = *((unsigned short*)(ptr+udiOFF));
         udiOFF += 2;
         FTrackLength[trk][side] = trklen;

// make unformatted track...
         FTracksPtr[trk][side][0] = (unsigned char*)new char[FTrackLength[trk][side]+1024];      // trk img
         FTracksPtr[trk][side][1] = (unsigned char*)new char[FTrackLength[trk][side]+1024];      // clk img
         for(unsigned ij=0; ij < FTrackLength[trk][side]; ij++)   
         {
            FTracksPtr[trk][side][0][ij] = 0x00;
            FTracksPtr[trk][side][1][ij] = 0x00;         
         }

         memcpy(FTracksPtr[trk][side][0], ptr+udiOFF, FTrackLength[trk][side]);
         udiOFF += trklen;

         uint32_t MFMinfoLen = trklen/8 + ((trklen-(trklen/8)*8)? 1:0);

         unsigned char mask;
         for(unsigned i=0; i < MFMinfoLen; i++)
         {
            mask = 0x01;
            for(int j=0; j < 8; j++)
            {
               if(ptr[udiOFF] & mask) FTracksPtr[trk][side][1][i*8+j] = 0xFF;
               else FTracksPtr[trk][side][1][i*8+j] = 0x00;
               mask <<= 1;
            }
            udiOFF++;
         }
      }
   long CRC = -1l;
   for(unsigned int i=0; i < udiOFF; i++) CRC = CalcCRC32(CRC, ptr[i]);


   if(udiOFF < rsize) 
      if( *((uint32_t*)(ptr+udiOFF)) != CRC )
         ShowError(ERR_FILECRC" UDI!");

   delete ptr;
   ReadOnly = ronly;
   FType = DIT_UDI;
   DiskPresent = true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %edx, %ebp
movl %esi, %r15d
movq %rdi, %rbx
movl %esi, %edi
xorl %esi, %esi
movl $0x1, %edx
callq 0x1210
movq %rax, %r14
movl %r15d, %edi
xorl %esi, %esi
movl $0x2, %edx
callq 0x1210
movq %rax, %r12
movl %r15d, %edi
movq %r14, %rsi
xorl %edx, %edx
callq 0x1210
testq %r12, %r12
js 0x54ea
leaq 0x200000(%r12), %rdi
callq 0x1030
movq %rax, %r14
addq $0x400, %r12            # imm = 0x400
movl %r15d, %edi
movq %rax, %rsi
movq %r12, %rdx
callq 0x11b0
cmpq $0x13, %rax
ja 0x54f3
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
leaq 0x2eea(%rip), %rsi      # 0x83d2
jmp 0x553b
leaq 0x2ec3(%rip), %rsi      # 0x83b4
jmp 0x553b
cmpl $0x21494455, (%r14)     # imm = 0x21494455
je 0x5512
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
leaq 0x2ee3(%rip), %rsi      # 0x83f3
jmp 0x553b
cmpb $0x0, 0x8(%r14)
jne 0x5527
cmpb $0x0, 0xb(%r14)
jne 0x5527
cmpl $0x0, 0xc(%r14)
je 0x554e
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
leaq 0x2ed5(%rip), %rsi      # 0x8410
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2410
movq %rax, %r15
movl 0x4(%r14), %eax
addl $0x4, %eax
cmpq %rax, %r15
jne 0x54d4
movzbl 0x9(%r14), %eax
movb %al, 0x145007(%rbx)
movzbl 0xa(%r14), %ecx
movb %cl, 0x145008(%rbx)
incl %ecx
xorl %edx, %edx
movl $0x10, %edi
movl %ecx, %esi
leal 0x5(%rdi), %r8d
cmpq %r8, %r15
jb 0x54d4
movl %edi, %r9d
incl %edi
cmpb $0x0, (%r14,%r9)
movl %edi, %r9d
je 0x55a7
addl (%r14,%r9), %r8d
movl %r8d, %edi
jmp 0x55ea
movzwl (%r14,%r9), %r8d
leal (%rdi,%r8), %r9d
addl $0x6, %r9d
cmpq %r9, %r15
jb 0x54d4
addl %r8d, %edi
movl %r8d, %r9d
shrl $0x3, %r9d
addl %edi, %r9d
andl $0x7, %r8d
cmpl $0x1, %r8d
sbbl $-0x1, %r9d
leal 0x6(%r9), %edi
cmpq %rdi, %r15
jb 0x54d4
addl $0x2, %r9d
movl %r9d, %edi
decl %esi
jne 0x5582
leal 0x1(%rdx), %esi
cmpl %eax, %edx
movl %esi, %edx
jne 0x5580
movl %ebp, 0x2c(%rsp)
leaq 0x40000(%rbx), %rax
movq %rax, 0x40(%rsp)
movl $0x10, %eax
xorl %r12d, %r12d
xorl %esi, %esi
movq %rbx, 0x8(%rsp)
movq %rsi, %rbp
shlq $0xa, %rbp
addq %rbx, %rbp
movq %rsi, %rcx
shlq $0xc, %rcx
addq 0x40(%rsp), %rcx
movq %rcx, 0x30(%rsp)
xorl %r13d, %r13d
movl %eax, %r8d
movq %rsi, 0x18(%rsp)
movq %rbp, 0x10(%rsp)
movl %r8d, %eax
cmpq %rax, %r15
jbe 0x5831
movq %r8, 0x20(%rsp)
leal 0x1(%r8), %ecx
cmpb $0x0, (%r14,%rax)
movq %r13, 0x38(%rsp)
je 0x56de
movl %ecx, (%rsp)
movl $0x186a, (%rbp,%r13,4)  # imm = 0x186A
movl $0x1c6a, %edi           # imm = 0x1C6A
callq 0x1030
movq %r13, %rbp
shlq $0x4, %rbp
movq 0x30(%rsp), %rbx
leaq (%rbx,%rbp), %r13
movq %rax, (%rbp,%rbx)
movl $0x1c6a, %edi           # imm = 0x1C6A
callq 0x1030
movq %rax, 0x8(%rbp,%rbx)
xorl %eax, %eax
movq (%r13), %rcx
movb %r12b, (%rcx,%rax)
movq 0x8(%r13), %rcx
movb %r12b, (%rcx,%rax)
incq %rax
cmpq $0x186a, %rax           # imm = 0x186A
jne 0x569e
movl (%rsp), %eax
movl (%r14,%rax), %eax
movq 0x20(%rsp), %rcx
addl %ecx, %eax
addl $0x5, %eax
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rbp
movq 0x8(%rsp), %rbx
jmp 0x5813
movl %ecx, %eax
movzwl (%r14,%rax), %eax
movq %rax, (%rsp)
movl %eax, (%rbp,%r13,4)
leaq 0x400(%rax), %rdi
movq %rdi, 0x50(%rsp)
callq 0x1030
movq %r13, %rbp
shlq $0x4, %rbp
movq 0x30(%rsp), %rbx
leaq (%rbx,%rbp), %r13
movq %rax, 0x48(%rsp)
movq %rax, (%rbp,%rbx)
movq 0x50(%rsp), %rdi
callq 0x1030
movq %rax, 0x8(%rbp,%rbx)
cmpl $0x0, (%rsp)
je 0x5768
movq 0x10(%rsp), %rax
movq 0x38(%rsp), %rcx
leaq (%rax,%rcx,4), %rax
xorl %ecx, %ecx
movq (%r13), %rdx
movb %r12b, (%rdx,%rcx)
movq 0x8(%r13), %rdx
movb %r12b, (%rdx,%rcx)
incq %rcx
movl (%rax), %edx
cmpq %rdx, %rcx
jb 0x573e
movq (%r13), %rdi
movq 0x8(%rsp), %rbx
movq 0x20(%rsp), %rbp
jmp 0x5779
xorl %edx, %edx
movq 0x8(%rsp), %rbx
movq 0x20(%rsp), %rbp
movq 0x48(%rsp), %rdi
addl $0x3, %ebp
movl %ebp, %esi
addq %r14, %rsi
callq 0x10e0
movq (%rsp), %rcx
leal (%rcx,%rbp), %eax
movl %ecx, %edx
shrl $0x3, %edx
xorl %esi, %esi
testb $0x7, %cl
setne %sil
movl %edx, %ecx
addl %esi, %ecx
je 0x5809
movq %rbp, %r11
movl %ecx, %ecx
addl %edx, %r11d
addl %esi, %r11d
xorl %edx, %edx
xorl %esi, %esi
movq 0x10(%rsp), %rbp
movl %eax, %eax
movl $0x1, %edi
xorl %r8d, %r8d
movzbl (%r14,%rax), %r9d
andl %edi, %r9d
movq 0x8(%r13), %r10
addq %rdx, %r10
negl %r9d
movl $0x0, %r9d
sbbl %r9d, %r9d
movb %r9b, (%r8,%r10)
movzbl %dil, %edi
addl %edi, %edi
incq %r8
cmpq $0x8, %r8
jne 0x57bf
incl %eax
incq %rsi
addq $0x8, %rdx
cmpq %rcx, %rsi
jb 0x57b5
addl (%rsp), %r11d
movl %r11d, %eax
movq 0x18(%rsp), %rsi
jmp 0x5813
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rbp
movq 0x38(%rsp), %rdi
leaq 0x1(%rdi), %r13
movzbl 0x145008(%rbx), %edx
movl %eax, %r8d
cmpq %rdx, %rdi
jb 0x5641
jmp 0x5834
movl %r8d, %eax
leaq 0x1(%rsi), %rcx
movzbl 0x145007(%rbx), %edx
cmpq %rdx, %rsi
movq %rcx, %rsi
jb 0x5616
xorl %ecx, %ecx
testl %eax, %eax
je 0x5885
movl %eax, %eax
xorl %edx, %edx
movzbl (%r14,%rdx), %esi
xorl %esi, %ecx
movl $0xfffffff8, %esi       # imm = 0xFFFFFFF8
movl %ecx, %edi
andl $0x1, %ecx
negl %ecx
sarl %edi
andl $0xedb88320, %ecx       # imm = 0xEDB88320
xorl %edi, %ecx
incl %esi
jne 0x5861
incq %rdx
cmpq %rax, %rdx
jne 0x5855
notl %ecx
movslq %ecx, %rcx
jmp 0x588e
movq $-0x1, %rcx
xorl %eax, %eax
cmpq %rax, %r15
jbe 0x58a8
movl (%r14,%rax), %eax
cmpq %rax, %rcx
je 0x58a8
leaq 0x2b8c(%rip), %rsi      # 0x842f
callq 0x2410
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
movl 0x2c(%rsp), %eax
movq 0x8(%rsp), %rcx
movb %al, 0x145005(%rcx)
movl $0x5, 0x141000(%rcx)
movb $0x1, 0x145006(%rcx)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq