// File: /workspace/github_cpp_makefile_star2_O1/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, %ebx
movl %esi, %r15d
movq %rdi, %rbp
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 0x54d2
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 0x54db
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
leaq 0x2ea6(%rip), %rsi      # 0x8376
jmp 0x5523
leaq 0x2e7f(%rip), %rsi      # 0x8358
jmp 0x5523
cmpl $0x21494455, (%r14)     # imm = 0x21494455
je 0x54fa
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
leaq 0x2e9f(%rip), %rsi      # 0x8397
jmp 0x5523
cmpb $0x0, 0x8(%r14)
jne 0x550f
cmpb $0x0, 0xb(%r14)
jne 0x550f
cmpl $0x0, 0xc(%r14)
je 0x5536
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
leaq 0x2e91(%rip), %rsi      # 0x83b4
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x23fa
movq %rax, %r15
movl 0x4(%r14), %eax
addl $0x4, %eax
cmpq %rax, %r15
jne 0x54bc
movl %ebx, 0x1c(%rsp)
movb 0x9(%r14), %al
movb %al, 0x145007(%rbp)
movb 0xa(%r14), %al
movb %al, 0x145008(%rbp)
movq $0x0, 0x8(%rsp)
movl $0x10, %ebx
leaq 0x2e00(%rip), %r12      # 0x8376
movq %rbp, 0x10(%rsp)
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
leal 0x1(%rbx), %r13d
leal 0x5(%rbx), %eax
cmpq %rax, %r15
jae 0x55ab
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
movq %r12, %rsi
callq 0x23fa
movl $0x1, %eax
movl %r13d, %ebx
jmp 0x5613
movl %ebx, %eax
cmpb $0x0, (%r14,%rax)
movl %r13d, %eax
je 0x55c7
movl (%r14,%rax), %eax
addl %eax, %ebx
addl $0x5, %ebx
movl $0x7, %eax
jmp 0x5613
movzwl (%r14,%rax), %eax
leal (%rax,%r13), %ebx
addl $0x2, %ebx
leal (%rax,%r13), %ecx
addl $0x6, %ecx
cmpq %rcx, %r15
jb 0x55f9
movl %eax, %ecx
shrl $0x3, %ecx
andl $0x7, %eax
addl %ecx, %ebx
cmpl $0x1, %eax
sbbl $-0x1, %ebx
leal 0x4(%rbx), %ecx
xorl %eax, %eax
cmpq %rcx, %r15
jae 0x5613
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
movq %r12, %rsi
callq 0x23fa
movl $0x1, %eax
cmpl $0x7, %eax
je 0x5620
testl %eax, %eax
jne 0x5919
movq 0x10(%rsp), %rax
movzbl 0x145008(%rax), %eax
incl %ebp
cmpl %eax, %ebp
jb 0x5580
movq 0x8(%rsp), %rdx
leal 0x1(%rdx), %eax
movq 0x10(%rsp), %rbp
movzbl 0x145007(%rbp), %ecx
cmpl %ecx, %edx
movq %rax, 0x8(%rsp)
jb 0x557b
leaq 0x40000(%rbp), %rax
movq %rax, 0x40(%rsp)
movl $0x10, %r12d
xorl %r13d, %r13d
xorl %eax, %eax
movq %r15, 0x28(%rsp)
movq %rax, %rcx
shlq $0xa, %rcx
addq %rbp, %rcx
movq %rcx, 0x20(%rsp)
movq %rax, 0x48(%rsp)
shlq $0xc, %rax
addq 0x40(%rsp), %rax
movq %rax, 0x38(%rsp)
movq $0x0, 0x8(%rsp)
movl %r12d, %ebx
movl %ebx, %eax
cmpq %rax, %r15
jbe 0x5878
leal 0x1(%rbx), %ecx
cmpb $0x0, (%r14,%rax)
je 0x5733
movl %ecx, 0x30(%rsp)
movq 0x20(%rsp), %rax
movq 0x8(%rsp), %rbp
movl $0x186a, (%rax,%rbp,4)  # imm = 0x186A
movl $0x1c6a, %edi           # imm = 0x1C6A
callq 0x1030
shlq $0x4, %rbp
movq 0x38(%rsp), %r15
leaq (%r15,%rbp), %r12
movq %rax, (%rbp,%r15)
movl $0x1c6a, %edi           # imm = 0x1C6A
callq 0x1030
movq %rax, 0x8(%rbp,%r15)
xorl %eax, %eax
movq (%r12), %rcx
movb %r13b, (%rcx,%rax)
movq 0x8(%r12), %rcx
movb %r13b, (%rcx,%rax)
incq %rax
cmpq $0x186a, %rax           # imm = 0x186A
jne 0x56f8
movl 0x30(%rsp), %eax
movl (%r14,%rax), %eax
leal (%rbx,%rax), %r12d
addl $0x5, %r12d
movq 0x10(%rsp), %rbp
movq 0x28(%rsp), %r15
jmp 0x5855
movl %ecx, %eax
movzwl (%r14,%rax), %eax
movq 0x8(%rsp), %r12
movq 0x20(%rsp), %rcx
movl %eax, (%rcx,%r12,4)
movq %rax, 0x30(%rsp)
leaq 0x400(%rax), %rdi
movq %rdi, 0x50(%rsp)
callq 0x1030
shlq $0x4, %r12
movq 0x38(%rsp), %r15
leaq (%r15,%r12), %rbp
movq %rax, (%r12,%r15)
movq 0x50(%rsp), %rdi
callq 0x1030
movq %rax, 0x8(%r12,%r15)
movq 0x20(%rsp), %rax
movq 0x8(%rsp), %rcx
movl (%rax,%rcx,4), %eax
testl %eax, %eax
je 0x57b9
movq 0x20(%rsp), %rax
movq 0x8(%rsp), %rcx
leaq (%rax,%rcx,4), %rcx
xorl %edx, %edx
movq (%rbp), %rax
movb %r13b, (%rax,%rdx)
movq 0x8(%rbp), %rax
movb %r13b, (%rax,%rdx)
incq %rdx
movl (%rcx), %eax
cmpq %rax, %rdx
jb 0x579f
leal 0x3(%rbx), %r12d
movq (%rbp), %rdi
movl %r12d, %esi
addq %r14, %rsi
movl %eax, %edx
callq 0x10e0
movq 0x30(%rsp), %r11
addl %r11d, %r12d
movl %r11d, %ecx
shrl $0x3, %ecx
xorl %edx, %edx
testb $0x7, %r11b
setne %dl
movl %ecx, %eax
addl %edx, %eax
je 0x5724
movl %eax, %eax
addl %ecx, %ebx
leal (%rdx,%rbx), %ecx
addl $0x3, %ecx
xorl %edx, %edx
xorl %esi, %esi
movq 0x28(%rsp), %r15
movl %r12d, %r12d
movl $0x1, %edi
xorl %r8d, %r8d
movzbl (%r14,%r12), %r9d
andl %edi, %r9d
negl %r9d
movl $0x0, %r9d
sbbl %r9d, %r9d
movq 0x8(%rbp), %r10
addq %rdx, %r10
movb %r9b, (%r8,%r10)
movzbl %dil, %edi
addl %edi, %edi
incq %r8
cmpq $0x8, %r8
jne 0x580d
incl %r12d
incq %rsi
addq $0x8, %rdx
cmpq %rax, %rsi
jb 0x5802
addl %r11d, %ecx
movl %ecx, %r12d
movq 0x10(%rsp), %rbp
movq 0x8(%rsp), %rdx
leaq 0x1(%rdx), %rax
movzbl 0x145008(%rbp), %ecx
movl %r12d, %ebx
cmpq %rcx, %rdx
movq %rax, 0x8(%rsp)
jb 0x56a1
jmp 0x587b
movl %ebx, %r12d
movq 0x48(%rsp), %rdx
leaq 0x1(%rdx), %rax
movzbl 0x145007(%rbp), %ecx
cmpq %rcx, %rdx
jb 0x5673
movl %r12d, %eax
testl %r12d, %r12d
je 0x58d0
xorl %ecx, %ecx
xorl %edx, %edx
movzbl (%r14,%rcx), %esi
xorl %esi, %edx
movl $0xfffffff8, %esi       # imm = 0xFFFFFFF8
movl %edx, %edi
andl $0x1, %edx
negl %edx
sarl %edi
andl $0xedb88320, %edx       # imm = 0xEDB88320
xorl %edi, %edx
incl %esi
jne 0x58ac
incq %rcx
cmpq %rax, %rcx
jne 0x58a0
notl %edx
movslq %edx, %rcx
jmp 0x58d7
movq $-0x1, %rcx
movl 0x1c(%rsp), %ebx
cmpq %rax, %r15
jbe 0x58f5
movl (%r14,%rax), %eax
cmpq %rax, %rcx
je 0x58f5
leaq 0x2ae3(%rip), %rsi      # 0x83d3
callq 0x23fa
movl $0x1, %esi
movq %r14, %rdi
callq 0x1150
movb %bl, 0x145005(%rbp)
movl $0x5, 0x141000(%rbp)
movb $0x1, 0x145006(%rbp)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq