// File: /workspace/github_cpp_makefile_star2_O2/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 $0xb08, %rsp            # imm = 0xB08
movl %edx, %r14d
movl %esi, %ebp
movq %rdi, 0x68(%rsp)
movl %esi, %edi
callq 0x6db6
testq %rax, %rax
js 0x3a10
movq %rax, %r12
movq %rax, %rdi
addq $0x200000, %rdi         # imm = 0x200000
callq 0x1030
movq %rax, %r15
movl %ebp, %edi
movq %rax, %rsi
movq %r12, %rdx
callq 0x11a0
testq %rax, %rax
je 0x39fc
cmpq $0xc, %rax
ja 0x3a19
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x1140
leaq 0x3968(%rip), %rsi      # 0x7376
jmp 0x3a3a
leaq 0x3941(%rip), %rsi      # 0x7358
jmp 0x3a3a
movabsq $0x5249414c434e4953, %rcx # imm = 0x5249414C434E4953
cmpq %rcx, (%r15)
je 0x3a50
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x1140
leaq 0x3af4(%rip), %rsi      # 0x752e
addq $0xb08, %rsp            # imm = 0xB08
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x201c
movb 0x8(%r15), %r13b
movzbl %r13b, %r12d
imulq $0xe, %r12, %rbx
leaq 0xd(%rbx), %rcx
cmpq %rcx, %rax
jb 0x39fc
xorl %edx, %edx
xorl %ecx, %ecx
cmpq $0x9, %rdx
je 0x3a7b
movzbl (%r15,%rdx), %esi
incq %rdx
addl %esi, %ecx
jmp 0x3a69
leaq 0x9(%r15), %rsi
pushq $0x9
popq %rdx
xorl %edi, %edi
cmpq %r12, %rdi
je 0x3ab8
leaq (%r15,%rdx), %r8
movq %r8, 0x300(%rsp,%rdi,8)
xorl %r8d, %r8d
cmpl $0xe, %r8d
je 0x3aab
movzbl (%rsi,%r8), %r9d
addl %r9d, %ecx
incq %r8
jmp 0x3a98
addq $0xe, %rdx
incq %rdi
addq $0xe, %rsi
jmp 0x3a84
xorl %esi, %esi
xorl %ebp, %ebp
cmpq %r12, %rsi
je 0x3b0b
movq 0x300(%rsp,%rsi,8), %rdi
movzbl 0xd(%rdi), %r8d
movl %r8d, %edi
shll $0x8, %edi
leal (%rdx,%rdi), %r9d
addl $0x4, %r9d
cmpq %r9, %rax
jb 0x39fc
addl %r8d, %ebp
movl %edi, %r8d
movl %edx, %r9d
subl $0x1, %r8d
jb 0x3b04
movl %r9d, %r10d
incl %r9d
movzbl (%r15,%r10), %r10d
addl %r10d, %ecx
jmp 0x3aee
addl %edi, %edx
incq %rsi
jmp 0x3abc
movl %edx, %eax
cmpl %ecx, (%r15,%rax)
je 0x3b1f
leaq 0x3a31(%rip), %rsi      # 0x754b
callq 0x201c
cmpw $0x9f0, %bp             # imm = 0x9F0
movl %r14d, 0x9c(%rsp)
movq %r12, 0x90(%rsp)
movb %r13b, 0x66(%rsp)
jae 0x3b40
pushq $0x50
popq %rsi
jmp 0x3b69
movzwl %bp, %eax
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
pushq $0x2
popq %rdx
movq 0x68(%rsp), %rdi
callq 0x6062
movq 0x68(%rsp), %rdi
movw $0x101, 0x145005(%rdi)  # imm = 0x101
movl $0x2, 0x141000(%rdi)
addl $0x9, %ebx
movw $0x9f0, %r12w           # imm = 0x9F0
movb $0x1, 0x65(%rsp)
xorl %esi, %esi
xorl %ebp, %ebp
movb $0x1, %r13b
movq $0x0, 0x78(%rsp)
movq $0x0, 0x88(%rsp)
cmpq 0x90(%rsp), %rsi
je 0x3dca
movzbl %r13b, %eax
movzbl 0x145007(%rdi), %ecx
incl %ecx
movzbl 0x145008(%rdi), %edx
incl %edx
imull %ecx, %edx
cmpl %eax, %edx
jbe 0x3dd2
movq %rsi, 0x80(%rsp)
movq 0x300(%rsp,%rsi,8), %r14
movq (%r14), %rax
movq %rax, 0x100(%rsp)
movb 0x8(%r14), %cl
movb %cl, 0x108(%rsp)
cmpb $0x1, %al
sete 0x74(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x1855
leaq 0x100(%rsp), %rdi
leaq 0x3935(%rip), %rsi      # 0x7564
pushq $0x9
popq %rdx
callq 0x1150
testl %eax, %eax
setne 0x67(%rsp)
movq %r14, 0xa0(%rsp)
movb 0xd(%r14), %r14b
movq 0x80(%rsp), %rax
shrl $0x4, %eax
incb %al
movzbl %al, %ecx
movq 0x68(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
leaq 0xa8(%rsp), %r8
xorl %r9d, %r9d
callq 0x1d64
testb %al, %al
je 0x3cd1
movq 0xe0(%rsp), %rax
movq 0x80(%rsp), %rcx
shll $0x4, %ecx
movzbl %cl, %ecx
movq 0xa0(%rsp), %rdi
movq (%rdi), %rdx
movl 0x8(%rdi), %esi
movb 0xc(%rdi), %dil
movb %dil, 0xc(%rax,%rcx)
movl %esi, 0x8(%rax,%rcx)
movq %rdx, (%rax,%rcx)
movb %r14b, 0xd(%rax,%rcx)
movb %bpl, 0xe(%rax,%rcx)
movb %r13b, 0xf(%rax,%rcx)
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq 0xa8(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1adc
movq 0x88(%rsp), %rax
addb 0x74(%rsp), %al
movq %rax, 0x88(%rsp)
movq 0x78(%rsp), %rax
incb %al
movq %rax, 0x78(%rsp)
movb 0x67(%rsp), %al
andb %al, 0x65(%rsp)
movzbl %r14b, %r14d
movzwl %r14w, %eax
movl %r12d, %ecx
subl %eax, %ecx
movl %ecx, 0x74(%rsp)
movq 0x68(%rsp), %rdi
subl $0x1, %r14d
jb 0x3db5
movl %r13d, %eax
shrb %al
movl %r13d, %ecx
andb $0x1, %cl
incb %bpl
movzbl %al, %esi
movzbl %cl, %edx
movzbl %bpl, %ebp
movl %ebp, %ecx
leaq 0xa8(%rsp), %r8
xorl %r9d, %r9d
callq 0x1d64
testb %al, %al
je 0x3d74
movq 0xe0(%rsp), %rdi
movl %ebx, %esi
addq %r15, %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x10d0
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq 0xa8(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1adc
addl $0x100, %ebx            # imm = 0x100
decl %r12d
cmpb $0x10, %bpl
movl $0x0, %eax
cmovael %eax, %ebp
sbbb $-0x1, %r13b
movzbl %r13b, %eax
movq 0x68(%rsp), %rdi
movzbl 0x145007(%rdi), %ecx
incl %ecx
movzbl 0x145008(%rdi), %edx
incl %edx
imull %ecx, %edx
cmpl %eax, %edx
ja 0x3d0f
jmp 0x3dba
movl 0x74(%rsp), %r12d
movq 0x80(%rsp), %rsi
incq %rsi
jmp 0x3bb7
movb 0x66(%rsp), %al
movl %eax, %ebx
jmp 0x3de1
movl %esi, %eax
movq %rax, 0x90(%rsp)
movq 0x78(%rsp), %rbx
movb 0x65(%rsp), %al
andb 0x145009(%rdi), %al
cmpb $0x1, %al
jne 0x3ef9
movzbl %bl, %eax
movzbl 0x88(%rsp), %ecx
addl %eax, %ecx
cmpl $0x7e, %ecx
ja 0x3ef9
movl %ebx, %eax
shrb $0x4, %al
incb %al
movzbl %al, %ecx
leaq 0xa8(%rsp), %r8
xorl %esi, %esi
xorl %edx, %edx
xorl %r9d, %r9d
callq 0x1d64
testb %al, %al
je 0x3e5e
leaq 0xa8(%rsp), %rsi
movq 0x38(%rsi), %rax
movq 0x90(%rsp), %rcx
shll $0x4, %ecx
movzbl %cl, %ecx
movaps 0x6374(%rip), %xmm0     # 0xa1c0
movups %xmm0, (%rax,%rcx)
pushq $0xb
popq %rcx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1adc
incb %bl
movq %rbx, 0x78(%rsp)
movzbl 0x6361(%rip), %eax      # 0xa1cd
movb 0x635c(%rip), %bl       # 0xa1ce
incb %bl
shll $0x8, %eax
movq %rax, 0x80(%rsp)
xorl %r14d, %r14d
movq 0x68(%rsp), %rdi
cmpl %r14d, 0x80(%rsp)
je 0x3ef4
movzbl %bl, %ecx
xorl %esi, %esi
xorl %edx, %edx
leaq 0xa8(%rsp), %r8
xorl %r9d, %r9d
callq 0x1d64
testb %al, %al
je 0x3edf
movq 0xe0(%rsp), %rdi
leaq 0x6726(%rip), %rax      # 0xa5e1
leaq (%rax,%r14), %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x10d0
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq 0xa8(%rsp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1adc
incb %bl
cmpb $0x10, %bl
ja 0x3eef
addq $0x100, %r14            # imm = 0x100
jmp 0x3e82
movq 0x68(%rsp), %rdi
movq 0x78(%rsp), %rbx
pushq $0x9
popq %rcx
leaq 0xa8(%rsp), %r8
xorl %esi, %esi
xorl %edx, %edx
xorl %r9d, %r9d
callq 0x1d64
testb %al, %al
je 0x3f58
leaq 0xa8(%rsp), %rsi
movq 0x38(%rsi), %rax
movb %bpl, 0xe1(%rax)
movb %r13b, 0xe2(%rax)
movb %bl, 0xe4(%rax)
movq 0x88(%rsp), %rcx
movb %cl, 0xf4(%rax)
movw %r12w, 0xe5(%rax)
pushq $0xb
popq %rcx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
callq 0x1adc
pushq $0x1
popq %rsi
movq %r15, %rdi
callq 0x1140
movl 0x9c(%rsp), %eax
movq 0x68(%rsp), %rcx
movb %al, 0x145005(%rcx)
addq $0xb08, %rsp            # imm = 0xB08
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop