// File: /workspace/github_cpp_makefile_star2_O3/atsidaev[P]trx2x/DiskImage.cpp
// Function: TDiskImage::readSCL(int, bool)
void TDiskImage::readSCL(int hfile, bool readonly)
{
   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);

   if(!rsize)
   {
      delete ptr;
      ShowError(ERR_CORRUPT);
      return;
   }
   if(rsize < 9+4)      // header
   {
      delete ptr;
      ShowError(ERR_CORRUPT);
      return;
   }
   if(memcmp(ptr, "SINCLAIR", 8) != 0) 
   {
      delete ptr;
      ShowError(ERR_FORMAT" SCL!");
      return;
   }

   unsigned int FileCount = ptr[8];
   if(rsize < 9+4+FileCount*14)
   {
      delete ptr;
      ShowError(ERR_CORRUPT);
      return;
   }

   TRDOS_DIR_ELEMENT *fileinfo[256];

   unsigned short FilesTotalSecs = 0;

// checking for corrupt + SCL-CRC + FileDIRS parse
   uint32_t SCLCRC = 0;
   uint32_t sclOFF = 0;
   unsigned int i, j;
   for(i=0; i < 9; i++) SCLCRC += unsigned(ptr[sclOFF++]);

   for(i=0; i < FileCount; i++)
   {
      fileinfo[i] = (TRDOS_DIR_ELEMENT*)(ptr+sclOFF);
      for(j=0; j < 14; j++) SCLCRC += unsigned(ptr[sclOFF++]);
   }
   for(i=0; i < FileCount; i++)
   {
      unsigned SL = unsigned(fileinfo[i]->SecLen)*256;
      FilesTotalSecs += fileinfo[i]->SecLen;
      if(rsize < sclOFF+4+SL)
      {
         delete ptr;
         ShowError(ERR_CORRUPT);
         return;
      }
      for(j=0; j < SL; j++) SCLCRC += unsigned(ptr[sclOFF++]);
   }

   if( *((uint32_t*)(ptr+sclOFF)) != SCLCRC )
      ShowError(ERR_FILECRC" SCL!");


   if(FilesTotalSecs < 2544) FilesTotalSecs = 2544;
   else
   {
      int cyls = ((16+FilesTotalSecs) / (16*2)) + ( ((16+FilesTotalSecs) % (16*2))?  1:0);
      FilesTotalSecs = (cyls * 16*2)-16;
   }

   formatTRDOS((FilesTotalSecs+16)/(16*2), 2);
   ReadOnly = true;
   FType = DIT_SCL;
   DiskPresent = true;

   sclOFF = 9+14*FileCount;

   bool BOOTADD=true;

   unsigned char SEC=0, TRK=1;
   unsigned short FreeSEC = 2544;
   unsigned char _FileCount = 0;
   unsigned char _DelFileCount = 0;

   TRDOS_DIR_ELEMENT trdosde;
   VGFIND_SECTOR vgfs;
   char sbuf[512];

   for(i=0; i < FileCount; i++)
   {
      if(TRK >= (MaxTrack+1)*(MaxSide+1)) break;      // disk full ?

      memcpy(sbuf, fileinfo[i]->FileName, 9);
      if(sbuf[0] == 0x01) _DelFileCount++;
      _FileCount++; 
      make_uppercase(sbuf);
      if(!memcmp(sbuf, "BOOT    B", 9)) BOOTADD = false;

      memcpy(&trdosde, fileinfo[i], 14);

      trdosde.FirstSec = SEC;
      trdosde.FirstTrk = TRK;

      unsigned int dirsec = ((i*16)/256)+1;
      if(FindSector(0, 0, dirsec, &vgfs))         // DIR ELEMENT write
      {
         memcpy(vgfs.SectorPointer + ((i*16)%256), &trdosde, 16);
         ApplySectorCRC(vgfs);
      }

      for(j=0; j < unsigned(trdosde.SecLen); j++)
      {
         if(FindSector(TRK/2, TRK%2, SEC+1, &vgfs))       // SECTOR write
         {
            memcpy(vgfs.SectorPointer, ptr+sclOFF, 256);
            ApplySectorCRC(vgfs);
         }
         sclOFF+=256;
         SEC++;
         FreeSEC--;
         if(SEC > 15) { SEC=0; TRK++; }

         if(TRK >= (MaxTrack+1)*(MaxSide+1)) break;      // disk full ?
      }
   }
   if(!AddBOOT) BOOTADD = false;

   if(BOOTADD&&(unsigned(_FileCount)+unsigned(_DelFileCount) < 127))
   {
      unsigned int dirsec = ((_FileCount*16)/256)+1;
      if(FindSector(0, 0, dirsec, &vgfs))         // DIR ELEMENT write
      {
         memcpy(vgfs.SectorPointer + ((i*16)%256), sbootdir, 16);
         ApplySectorCRC(vgfs);
      }
      _FileCount++;

      memcpy(&trdosde, sbootdir, 16);

      unsigned char _bSEC=trdosde.FirstSec+1;
      unsigned int _bOFF=0;

      for(j=0; j < unsigned(trdosde.SecLen); j++)
      {
         if(FindSector(0, 0, _bSEC++, &vgfs))       // SECTOR write
         {
            memcpy(vgfs.SectorPointer, sbootimage+_bOFF, 256);
            ApplySectorCRC(vgfs);
         }
         _bOFF+=256;
         if(_bSEC > 16) break;
      }
   }

   if(FindSector(0, 0, 9, &vgfs))         // update disk info
   {
      vgfs.SectorPointer[0xE1] = SEC;
      vgfs.SectorPointer[0xE2] = TRK;
      vgfs.SectorPointer[0xE4] = _FileCount;
      vgfs.SectorPointer[0xF4] = _DelFileCount;
      *((unsigned short*)(vgfs.SectorPointer+0xE5)) = FreeSEC;
      ApplySectorCRC(vgfs);
   }

   delete ptr;
   ReadOnly = readonly;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xaf8, %rsp            # imm = 0xAF8
movl %edx, %ebx
movl %esi, %ebp
movq %rdi, %r14
movl %esi, %edi
xorl %esi, %esi
movl $0x1, %edx
callq 0x1210
movq %rax, %r15
movl %ebp, %edi
xorl %esi, %esi
movl $0x2, %edx
callq 0x1210
movq %rax, %r12
movl %ebp, %edi
movq %r15, %rsi
xorl %edx, %edx
callq 0x1210
testq %r12, %r12
js 0x43ad
movq %r12, %rdi
addq $0x200000, %rdi         # imm = 0x200000
callq 0x1030
movq %rax, %r15
movl %ebp, %edi
movq %rax, %rsi
movq %r12, %rdx
callq 0x11b0
testq %rax, %rax
je 0x4397
cmpq $0xc, %rax
ja 0x43b6
movl $0x1, %esi
movq %r15, %rdi
callq 0x1150
leaq 0x4027(%rip), %rsi      # 0x83d2
jmp 0x43d9
leaq 0x4000(%rip), %rsi      # 0x83b4
jmp 0x43d9
movabsq $0x5249414c434e4953, %rcx # imm = 0x5249414C434E4953
cmpq %rcx, (%r15)
je 0x43ef
movl $0x1, %esi
movq %r15, %rdi
callq 0x1150
leaq 0x41b1(%rip), %rsi      # 0x858a
addq $0xaf8, %rsp            # imm = 0xAF8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2410
movb 0x8(%r15), %bpl
movzbl %bpl, %r12d
movl %r12d, %r13d
shll $0x4, %r13d
subq %r12, %r13
subq %r12, %r13
leaq 0xd(%r13), %rcx
cmpq %rcx, %rax
jb 0x4397
xorl %edx, %edx
xorl %ecx, %ecx
movzbl (%r15,%rdx), %esi
incq %rdx
addl %esi, %ecx
cmpq $0x9, %rdx
jne 0x4411
testb %bpl, %bpl
movl %ebx, 0x7c(%rsp)
je 0x44c3
leaq 0x9(%r15), %rsi
movl $0x9, %edx
xorl %edi, %edi
leaq (%r15,%rdx), %r8
movq %r8, 0x2f0(%rsp,%rdi,8)
xorl %r8d, %r8d
movzbl (%rsi,%r8), %r9d
addl %r9d, %ecx
incq %r8
cmpl $0xe, %r8d
jne 0x4448
addq $0xe, %rdx
incq %rdi
addq $0xe, %rsi
cmpq %r12, %rdi
jne 0x4439
testb %bpl, %bpl
je 0x44c8
xorl %esi, %esi
xorl %ebx, %ebx
movq 0x2f0(%rsp,%rsi,8), %rdi
movzbl 0xd(%rdi), %edi
movl %edi, %r8d
shll $0x8, %r8d
leal (%rdx,%r8), %r9d
addl $0x4, %r9d
cmpq %r9, %rax
jb 0x4397
movl %r8d, %r9d
movl %edx, %r10d
testb %dil, %dil
je 0x44b7
movl %r10d, %r11d
incl %r10d
movzbl (%r15,%r11), %r11d
addl %r11d, %ecx
decl %r9d
jne 0x44a1
addl %r8d, %edx
addl %edi, %ebx
incq %rsi
cmpq %r12, %rsi
jne 0x4472
jmp 0x44ca
movl $0x9, %edx
xorl %ebx, %ebx
movl %edx, %eax
cmpl %ecx, (%r15,%rax)
je 0x44de
leaq 0x40ce(%rip), %rsi      # 0x85a7
callq 0x2410
movzwl %bx, %eax
movl $0x50, %esi
cmpl $0x9f0, %eax            # imm = 0x9F0
jb 0x4513
leal 0x10(%rax), %ecx
xorl %edx, %edx
testb $0x1f, %cl
setne %dl
shll $0x5, %edx
addl %edx, %eax
addl $0x10, %eax
andl $0xffe0, %eax           # imm = 0xFFE0
addl $0xfff0, %eax           # imm = 0xFFF0
movzwl %ax, %esi
addl $0x10, %esi
shrl $0x5, %esi
movq %r14, %rdi
movl $0x2, %edx
callq 0x6ddc
movq $0x0, 0x80(%rsp)
movw $0x101, 0x145005(%r14)  # imm = 0x101
movl $0x2, 0x141000(%r14)
testb %bpl, %bpl
movq %r15, 0x68(%rsp)
je 0x479f
movb %bpl, 0x58(%rsp)
addl $0x9, %r13d
movb $0x1, %bl
movw $0x9f0, %ax             # imm = 0x9F0
movl %eax, 0x5c(%rsp)
xorl %r8d, %r8d
xorl %esi, %esi
movq $0x0, 0x60(%rsp)
xorl %ebp, %ebp
movb $0x1, %dil
movq %r12, 0x90(%rsp)
movzbl %bl, %eax
movzbl 0x145007(%r14), %ecx
incl %ecx
movzbl 0x145008(%r14), %edx
incl %edx
imull %ecx, %edx
cmpl %eax, %edx
jbe 0x47b5
movq 0x2f0(%rsp,%r8,8), %r15
movq (%r15), %rax
movq %rax, 0xf0(%rsp)
movb 0x8(%r15), %cl
movb %cl, 0xf8(%rsp)
cmpb $0x1, %al
sete 0x5a(%rsp)
testb %al, %al
je 0x45e6
leaq 0xf1(%rsp), %rcx
leal -0x61(%rax), %edx
cmpb $0x19, %dl
ja 0x45dd
addb $-0x20, %al
movb %al, -0x1(%rcx)
movb (%rcx), %al
incq %rcx
testb %al, %al
jne 0x45d0
movb %dil, 0x5b(%rsp)
movq %rsi, 0x70(%rsp)
movq 0xf0(%rsp), %rax
movabsq $0x20202020544f4f42, %rcx # imm = 0x20202020544F4F42
xorq %rcx, %rax
movzbl 0xf8(%rsp), %ecx
xorq $0x42, %rcx
orq %rax, %rcx
setne 0x59(%rsp)
movb 0xd(%r15), %r12b
movq %r8, 0x88(%rsp)
movl %r8d, %eax
shrl $0x4, %eax
incb %al
movzbl %al, %ecx
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
leaq 0x98(%rsp), %r8
xorl %r9d, %r9d
callq 0x20f6
testb %al, %al
je 0x469f
movq 0xd0(%rsp), %rax
movq 0x88(%rsp), %rcx
shll $0x4, %ecx
movzbl %cl, %ecx
movq (%r15), %rdx
movl 0x8(%r15), %esi
movb 0xc(%r15), %dil
movb %dil, 0xc(%rax,%rcx)
movl %esi, 0x8(%rax,%rcx)
movq %rdx, (%rax,%rcx)
movb %r12b, 0xd(%rax,%rcx)
movb %bpl, 0xe(%rax,%rcx)
movb %bl, 0xf(%rax,%rcx)
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x98(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1e3c
testb %r12b, %r12b
je 0x4755
movzbl %r12b, %r12d
xorl %r15d, %r15d
movl %ebx, %eax
shrb %al
movl %ebx, %ecx
andb $0x1, %cl
incb %bpl
movzbl %al, %esi
movzbl %cl, %edx
movzbl %bpl, %ebp
movq %r14, %rdi
movl %ebp, %ecx
leaq 0x98(%rsp), %r8
xorl %r9d, %r9d
callq 0x20f6
testb %al, %al
je 0x4710
movq 0xd0(%rsp), %rdi
movl %r13d, %esi
addq 0x68(%rsp), %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x10e0
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x98(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1e3c
addl $0x100, %r13d           # imm = 0x100
cmpb $0x10, %bpl
movl $0x0, %eax
cmovael %eax, %ebp
sbbb $-0x1, %bl
movzbl %bl, %eax
movzbl 0x145007(%r14), %ecx
incl %ecx
movzbl 0x145008(%r14), %edx
incl %edx
imull %ecx, %edx
incl %r15d
cmpl %eax, %edx
jbe 0x4750
cmpl %r12d, %r15d
jb 0x46af
subl %r15d, 0x5c(%rsp)
movq 0x70(%rsp), %rsi
addb 0x5a(%rsp), %sil
movq 0x60(%rsp), %rax
incb %al
movq %rax, 0x60(%rsp)
movb 0x5b(%rsp), %dil
andb 0x59(%rsp), %dil
movq 0x88(%rsp), %r8
incq %r8
movq 0x90(%rsp), %r12
cmpq %r12, %r8
movq 0x68(%rsp), %r15
jne 0x457d
movb 0x58(%rsp), %al
movl %eax, %r13d
jmp 0x47bd
movw $0x9f0, %ax             # imm = 0x9F0
movl %eax, 0x5c(%rsp)
movb $0x1, %dil
xorl %ebp, %ebp
movb $0x1, %bl
xorl %r13d, %r13d
xorl %esi, %esi
jmp 0x47cd
movl %r8d, %r12d
movq 0x60(%rsp), %r13
shll $0x4, %r12d
movzbl %r12b, %eax
movq %rax, 0x80(%rsp)
cmpb $0x1, 0x145009(%r14)
movq %rsi, 0x70(%rsp)
jne 0x48fa
testb $0x1, %dil
je 0x48fa
movzbl %r13b, %eax
movzbl %sil, %ecx
addl %eax, %ecx
cmpl $0x7e, %ecx
ja 0x48fa
movl %r13d, %eax
shrb $0x4, %al
incb %al
movzbl %al, %ecx
leaq 0x98(%rsp), %r8
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %r9d, %r9d
callq 0x20f6
testb %al, %al
je 0x4852
leaq 0x98(%rsp), %rsi
movq 0x38(%rsi), %rax
movaps 0x699a(%rip), %xmm0     # 0xb1d0
movq 0x80(%rsp), %rcx
movups %xmm0, (%rax,%rcx)
movl $0xb, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1e3c
incb %r13b
movzbl 0x6980(%rip), %r15d     # 0xb1dd
testq %r15, %r15
je 0x48f5
movq %r13, 0x60(%rsp)
movb 0x696c(%rip), %r13b     # 0xb1de
addb $0x2, %r13b
shll $0x8, %r15d
xorl %r12d, %r12d
leal -0x1(%r13), %eax
movzbl %al, %ecx
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
leaq 0x98(%rsp), %r8
xorl %r9d, %r9d
callq 0x20f6
testb %al, %al
je 0x48d4
movq 0xd0(%rsp), %rdi
leaq 0x6d43(%rip), %rax      # 0xb5f1
leaq (%rax,%r12), %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x10e0
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x98(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1e3c
cmpb $0x10, %r13b
ja 0x48e9
addq $0x100, %r12            # imm = 0x100
incb %r13b
cmpl %r12d, %r15d
jne 0x487d
movq 0x68(%rsp), %r15
movq 0x60(%rsp), %r13
jmp 0x48fa
movq 0x68(%rsp), %r15
leaq 0x98(%rsp), %r8
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
movl $0x9, %ecx
xorl %r9d, %r9d
callq 0x20f6
testb %al, %al
je 0x4960
leaq 0x98(%rsp), %rsi
movq 0x38(%rsi), %rax
movb %bpl, 0xe1(%rax)
movb %bl, 0xe2(%rax)
movb %r13b, 0xe4(%rax)
movq 0x70(%rsp), %rcx
movb %cl, 0xf4(%rax)
movl 0x5c(%rsp), %ecx
movw %cx, 0xe5(%rax)
movl $0xb, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1e3c
movl $0x1, %esi
movq %r15, %rdi
callq 0x1150
movl 0x7c(%rsp), %eax
movb %al, 0x145005(%r14)
addq $0xaf8, %rsp            # imm = 0xAF8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq