// File: /workspace/github_cpp_makefile_star2_O2/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, %r14
movl %esi, %edi
callq 0x6db6
testq %rax, %rax
js 0x49f7
movq %rax, %r12
leaq 0x200000(%rax), %rdi
callq 0x1030
movq %rax, %rbx
addq $0x400, %r12            # imm = 0x400
movl %r15d, %edi
movq %rax, %rsi
movq %r12, %rdx
callq 0x11a0
cmpq $0x13, %rax
ja 0x4a00
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x1140
leaq 0x2981(%rip), %rsi      # 0x7376
jmp 0x4a40
leaq 0x295a(%rip), %rsi      # 0x7358
jmp 0x4a40
cmpl $0x21494455, (%rbx)     # imm = 0x21494455
je 0x4a1c
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x1140
leaq 0x297d(%rip), %rsi      # 0x7397
jmp 0x4a40
cmpb $0x0, 0x8(%rbx)
jne 0x4a2e
cmpb $0x0, 0xb(%rbx)
jne 0x4a2e
cmpl $0x0, 0xc(%rbx)
je 0x4a53
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x1140
leaq 0x2974(%rip), %rsi      # 0x73b4
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x201c
movq %rax, %r15
movl 0x4(%rbx), %eax
addl $0x4, %eax
cmpq %rax, %r15
jne 0x49e3
movzbl 0x9(%rbx), %ecx
movb %cl, 0x145007(%r14)
movzbl 0xa(%rbx), %eax
movb %al, 0x145008(%r14)
movl %eax, %edx
incl %edx
movl %ecx, %esi
incl %esi
pushq $0x10
popq %r9
xorl %edi, %edi
movl %edx, %r8d
cmpl %esi, %edi
je 0x4b01
subl $0x1, %r8d
jb 0x4afd
leal 0x5(%r9), %r10d
cmpq %r10, %r15
jb 0x49e3
movl %r9d, %r11d
incl %r9d
cmpb $0x0, (%rbx,%r11)
movl %r9d, %r11d
je 0x4ab8
addl (%rbx,%r11), %r10d
movl %r10d, %r9d
jmp 0x4a8c
movzwl (%rbx,%r11), %r10d
leal (%r9,%r10), %r11d
addl $0x6, %r11d
cmpq %r11, %r15
jb 0x49e3
addl %r10d, %r9d
movl %r10d, %r11d
shrl $0x3, %r11d
addl %r9d, %r11d
andl $0x7, %r10d
cmpl $0x1, %r10d
sbbl $-0x1, %r11d
leal 0x6(%r11), %r9d
cmpq %r9, %r15
jb 0x49e3
addl $0x2, %r11d
movl %r11d, %r9d
jmp 0x4a8c
incl %edi
jmp 0x4a85
movl %ebp, 0x24(%rsp)
leaq 0x40000(%r14), %rdx
movq %rdx, 0x38(%rsp)
pushq $0x10
popq %r13
xorl %ebp, %ebp
xorl %edx, %edx
movq %r14, 0x8(%rsp)
movq %r15, 0x28(%rsp)
movzbl %cl, %ecx
cmpq %rcx, %rdx
ja 0x4d22
movq %rdx, %rcx
shlq $0xa, %rcx
addq %r14, %rcx
movq %rcx, 0x30(%rsp)
movq %rdx, 0x40(%rsp)
shlq $0xc, %rdx
addq 0x38(%rsp), %rdx
movq %rdx, 0x18(%rsp)
xorl %r12d, %r12d
movzbl %al, %ecx
cmpq %rcx, %r12
ja 0x4d0e
movl %r13d, %ecx
cmpq %rcx, %r15
jbe 0x4d0e
leal 0x1(%r13), %eax
cmpb $0x0, (%rbx,%rcx)
movl %eax, %eax
movq %r12, 0x50(%rsp)
je 0x4c0d
movq %rax, 0x10(%rsp)
movq 0x30(%rsp), %rax
movl $0x186a, (%rax,%r12,4)  # imm = 0x186A
movl $0x1c6a, %edi           # imm = 0x1C6A
callq 0x1030
movq %r12, %r14
shlq $0x4, %r14
movq 0x18(%rsp), %r15
leaq (%r15,%r14), %r12
movq %rax, (%r14,%r15)
movl $0x1c6a, %edi           # imm = 0x1C6A
callq 0x1030
movq %rax, 0x8(%r14,%r15)
xorl %eax, %eax
movq 0x8(%rsp), %r14
cmpq $0x186a, %rax           # imm = 0x186A
je 0x4be5
movq (%r12), %rcx
movb %bpl, (%rcx,%rax)
movq 0x8(%r12), %rcx
movb %bpl, (%rcx,%rax)
incq %rax
jmp 0x4bc7
movq 0x10(%rsp), %rax
movl (%rbx,%rax), %eax
addl %eax, %r13d
addl $0x5, %r13d
movq 0x28(%rsp), %r15
movq 0x50(%rsp), %r12
incq %r12
movb 0x145008(%r14), %al
jmp 0x4b54
movzwl (%rbx,%rax), %ecx
movq 0x30(%rsp), %rax
leaq (%rax,%r12,4), %r14
movq %rcx, 0x10(%rsp)
movl %ecx, (%r14)
leaq 0x400(%rcx), %rdi
movq %rdi, 0x48(%rsp)
callq 0x1030
movq %r12, %r15
shlq $0x4, %r15
movq 0x18(%rsp), %rcx
leaq (%rcx,%r15), %r12
movq %rax, (%r15,%rcx)
movq 0x48(%rsp), %rdi
callq 0x1030
movq 0x18(%rsp), %rcx
movq %rax, 0x8(%r15,%rcx)
movq 0x10(%rsp), %r15
movl %r15d, %ecx
xorl %eax, %eax
movl %ecx, %edx
cmpq %rdx, %rax
jae 0x4c85
movq (%r12), %rcx
movb %bpl, (%rcx,%rax)
movq 0x8(%r12), %rcx
movb %bpl, (%rcx,%rax)
incq %rax
movl (%r14), %ecx
jmp 0x4c65
leal 0x3(%r13), %esi
movq (%r12), %rdi
addq %rbx, %rsi
callq 0x10d0
addl %r15d, %r13d
addl $0x3, %r13d
movl %r15d, %eax
shrl $0x3, %eax
andl $0x7, %r15d
cmpl $0x1, %r15d
sbbl $-0x1, %eax
xorl %ecx, %ecx
xorl %edx, %edx
movq 0x8(%rsp), %r14
movq 0x28(%rsp), %r15
pushq $0x1
popq %r11
cmpq %rax, %rdx
je 0x4bf9
movl %r13d, %esi
xorl %edi, %edi
movl %r11d, %r8d
cmpq $0x8, %rdi
je 0x4d02
movzbl (%rbx,%rsi), %r9d
andl %r8d, %r9d
movq 0x8(%r12), %r10
addq %rcx, %r10
negl %r9d
movl $0x0, %r9d
sbbl %r9d, %r9d
movb %r9b, (%rdi,%r10)
movzbl %r8b, %r8d
addl %r8d, %r8d
incq %rdi
jmp 0x4cd0
incl %r13d
incq %rdx
addq $0x8, %rcx
jmp 0x4cbf
movq 0x40(%rsp), %rdx
incq %rdx
movb 0x145007(%r14), %cl
jmp 0x4b23
movl %r13d, %r14d
pushq $-0x1
popq %rdi
xorl %r12d, %r12d
movl 0x24(%rsp), %ebp
cmpq %r12, %r14
je 0x4d46
movzbl (%rbx,%r12), %esi
callq 0x1870
movslq %eax, %rdi
incq %r12
jmp 0x4d2f
cmpq %r14, %r15
jbe 0x4d60
movl (%rbx,%r14), %eax
cmpq %rax, %rdi
je 0x4d60
leaq 0x2678(%rip), %rsi      # 0x73d3
callq 0x201c
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x1140
movq 0x8(%rsp), %rax
movb %bpl, 0x145005(%rax)
movl $0x5, 0x141000(%rax)
movb $0x1, 0x145006(%rax)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop