Skip to content

Pseudocodes obtained by reverse engineering

Paulo Matias edited this page Aug 17, 2014 · 1 revision

Pseudocodes

These are some C-like pseudocodes obtained by reverse engineering mikrobootloader.exe. Together with the bootloader source codes (which are included inside the MikroC PRO package for each microcontroller), they are an invaluable resource to better understand the device programming protocol.

addAppResetCode

int __cdecl addAppResetCode(int a)
{
  MCUTYPE mcutype; // eax@1
  int v2; // eax@2
  char v3; // cf@2
  int result; // eax@2
  int v5; // eax@5
  int v6; // eax@5
  int v7; // eax@6
  int v8; // eax@7
  int v9; // ebx@9
  int v10; // eax@10
  int v11; // edx@11
  int v12; // eax@11
  int v13; // ebx@14
  int v14; // eax@15
  int v15; // edx@16
  int v16; // eax@16
  int v17; // ebx@19
  int v18; // edx@20
  int v19; // eax@20
  unsigned int bootrom_displacement; // ebx@26
  int v21; // eax@27
  int v22; // edx@28
  int v23; // eax@28
  int v24; // ebx@31
  unsigned int v25; // edx@32
  unsigned int v26; // ecx@32
  unsigned int v27; // eax@32

  mcutype = *(_BYTE *)(*(_DWORD *)(a - LoadedHexObjVar) + McuType);
  if ( mcutype >= DSPIC )
  {
    v5 = mcutype - DSPIC;
    v3 = (unsigned int)v5 < 2;
    v6 = v5 - 2;
    if ( v3 )                                   // DSPIC
    {
LABEL_14:
      System::__linkproc___DynArraySetLength(6);
      v13 = getDynArrayLength(*(_DWORD *)(a - FlashBinDataVar));
      result = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
      if ( v13 >= result )
      {
        v14 = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
        if ( v14 - 1 >= 0 )
        {
          v15 = v14;
          v16 = 0;
          do
          {
            *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + v16) = *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + v16);
            ++v16;
            --v15;
          }
          while ( v15 );
        }
        **(_BYTE **)(a - FlashBinDataVar) = 2 * *(_DWORD *)(a - BootStartVar) / 3u;
        *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 1) = 2 * *(_DWORD *)(a - BootStartVar) / 3u >> 8;
        *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 2) = 4;
        *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 3) = 2 * *(_DWORD *)(a - BootStartVar) / 3u >> 16;
        *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 4) = 0;
        result = *(_DWORD *)(a - FlashBinDataVar);
        *(_BYTE *)(result + 5) = 0;
      }
      return result;
    }
    v7 = v6 - 8;
    if ( v7 )
    {
      v8 = v7 - 10;
      v3 = (unsigned int)v8 < 8;
      result = v8 - 8;
      if ( v3 )                                 // > ARM
      {
        System::__linkproc___DynArraySetLength(20);
        v24 = getDynArrayLength(*(_DWORD *)(a - FlashBinDataVar));
        result = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
        if ( v24 >= result )
        {
          v25 = (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 3) << 24)
              + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 2) << 16)
              + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 1) << 8)
              + **(_BYTE **)(a - FlashBinDataVar);
          v26 = (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 7) << 24)
              + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 6) << 16)
              + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 5) << 8)
              + *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 4);
          v27 = (((((*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 3) << 24)
                  + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 2) << 16)
                  + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 1) << 8)
                  + (unsigned int)**(_BYTE **)(a - FlashBinDataVar)) >> 11) & 1) << 26)
              + ((unsigned __int8)((unsigned __int16)((*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 1) << 8)
                                                    + **(_BYTE **)(a - FlashBinDataVar)) >> 8) >> 4 << 16)
              + (((((*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 3) << 24)
                  + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 2) << 16)
                  + (*(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 1) << 8)
                  + (unsigned int)**(_BYTE **)(a - FlashBinDataVar)) >> 8) & 7) << 12)
              + **(_BYTE **)(a - FlashBinDataVar)
              - 0xDC00000;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 2) = **(_BYTE **)(a - FlashBinDataVar);
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 3) = BYTE1(v27);
          **(_BYTE **)(a - CodeToJumpVar) = v27 >> 16;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 1) = BYTE3(v27);
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 6) = v25 >> 16;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 7) = ((((v25 >> 27) & 1) << 26)
                                                          + ((unsigned __int16)(HIWORD(v25) >> 12) << 16)
                                                          + (((v25 >> 24) & 7) << 12)
                                                          + (unsigned __int8)(v25 >> 16)
                                                          - 0xD400000) >> 8;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 4) = ((((v25 >> 27) & 1) << 26)
                                                          + ((unsigned __int16)(HIWORD(v25) >> 12) << 16)
                                                          + (((v25 >> 24) & 7) << 12)
                                                          + (unsigned __int8)(v25 >> 16)
                                                          - 0xD400000) >> 16;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 5) = ((((v25 >> 27) & 1) << 26)
                                                          + ((unsigned __int16)(HIWORD(v25) >> 12) << 16)
                                                          + (((v25 >> 24) & 7) << 12)
                                                          + (unsigned __int8)(v25 >> 16)
                                                          - 0xD400000) >> 24;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 8) = 0x85u;// mov sp, r0
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 9) = 0x46u;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 12) = v26;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 13) = ((((v26 >> 11) & 1) << 26)
                                                           + ((unsigned __int16)v26 >> 12 << 16)
                                                           + (((v26 >> 8) & 7) << 12)
                                                           + (unsigned __int8)v26
                                                           - 0xDC00000) >> 8;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 10) = ((((v26 >> 11) & 1) << 26)
                                                           + ((unsigned __int16)v26 >> 12 << 16)
                                                           + (((v26 >> 8) & 7) << 12)
                                                           + (unsigned __int8)v26
                                                           - 0xDC00000) >> 16;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 11) = ((((v26 >> 11) & 1) << 26)
                                                           + ((unsigned __int16)v26 >> 12 << 16)
                                                           + (((v26 >> 8) & 7) << 12)
                                                           + (unsigned __int8)v26
                                                           - 0xDC00000) >> 24;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 16) = v26 >> 16;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 17) = ((((v26 >> 27) & 1) << 26)
                                                           + ((unsigned __int16)(HIWORD(v26) >> 12) << 16)
                                                           + (((v26 >> 24) & 7) << 12)
                                                           + (unsigned __int8)(v26 >> 16)
                                                           - 0xD400000) >> 8;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 14) = ((((v26 >> 27) & 1) << 26)
                                                           + ((unsigned __int16)(HIWORD(v26) >> 12) << 16)
                                                           + (((v26 >> 24) & 7) << 12)
                                                           + (unsigned __int8)(v26 >> 16)
                                                           - 0xD400000) >> 16;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 15) = ((((v26 >> 27) & 1) << 26)
                                                           + ((unsigned __int16)(HIWORD(v26) >> 12) << 16)
                                                           + (((v26 >> 24) & 7) << 12)
                                                           + (unsigned __int8)(v26 >> 16)
                                                           - 0xD400000) >> 24;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 18) = 0;// bx r0
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 19) = 0x47u;
          *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 4) = *(_DWORD *)(a - BootStartVar) + 1;
          *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 5) = *(_WORD *)(a - BootStartVar) >> 8;
          *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 6) = *(_DWORD *)(a - BootStartVar) >> 16;
          result = *(_DWORD *)(a - BootStartVar) >> 24;
          *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 7) = result;
        }
      }
    }
    else                                        // PIC32
    {
      System::__linkproc___DynArraySetLength(16);
      v17 = getDynArrayLength(*(_DWORD *)(a - MipsBootRomDataVar));
      result = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
      if ( v17 >= result )
      {
        *(_BYTE *)(a - OneByteFlagVar) = 1;
        v18 = 0;
        v19 = 0;
        do
        {
          v18 += *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + v19) << 8 * v19;
          ++v19;
        }
        while ( v19 != 4 );
        if ( v18 != 0x27BDFFFC && v18 != 0x70000000 )
          *(_BYTE *)(a - OneByteFlagVar) = 0;
        if ( *(_BYTE *)(a - OneByteFlagVar) )
        {
          bootrom_displacement = 0x40u;
          **(_BYTE **)(a - CodeToJumpVar) = 0xC0u;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 1) = 0xBFu;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 2) = 0x1Eu;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 3) = 0x3Cu;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 4) = 0x50u;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 5) = 0;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 6) = 0xDEu;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 7) = 0x37u;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 8) = 8;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 9) = 0;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 10) = 0xC0u;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 11) = 3;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 12) = 0;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 13) = 0;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 14) = 0;
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + 15) = 0x70u;
        }
        else
        {
          bootrom_displacement = 0;
          v21 = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
          if ( v21 - 1 >= 0 )
          {
            v22 = v21;
            v23 = 0;
            do
            {
              *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + v23) = *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + v23);
              ++v23;
              --v22;
            }
            while ( v22 );
          }
        }
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement) = *(_DWORD *)(*(_DWORD *)(a - 4)
                                                                                           + BootStart) >> 16;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 1) = *(_DWORD *)(*(_DWORD *)(a - 4)
                                                                                               + BootStart) >> 24;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 2) = 0x1Eu;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 3) = 0x3Cu;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 4) = *(_DWORD *)(*(_DWORD *)(a - 4)
                                                                                               + BootStart);
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 5) = *(_WORD *)(*(_DWORD *)(a - 4)
                                                                                              + BootStart) >> 8;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 6) = 0xDEu;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 7) = 0x37u;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 8) = 8;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 9) = 0;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 10) = 0xC0u;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 11) = 3;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 12) = 0;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 13) = 0;
        *(_BYTE *)(*(_DWORD *)(a - MipsBootRomDataVar) + bootrom_displacement + 14) = 0;
        result = *(_DWORD *)(a - MipsBootRomDataVar);
        *(_BYTE *)(result + bootrom_displacement + 15) = 0x70u;
      }
    }
  }
  else                                          // < DSPIC
  {
    v2 = mcutype - 2;
    v3 = (unsigned int)v2 < 2;
    result = v2 - 2;
    if ( !v3 )
    {
      if ( result )
        return result;
      goto LABEL_14;
    }
    System::__linkproc___DynArraySetLength(4);
    v9 = getDynArrayLength(*(_DWORD *)(a - FlashBinDataVar));
    result = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
    if ( v9 >= result )
    {
      v10 = getDynArrayLength(*(_DWORD *)(a - CodeToJumpVar));
      if ( v10 - 1 >= 0 )
      {
        v11 = v10;
        v12 = 0;
        do
        {
          *(_BYTE *)(*(_DWORD *)(a - CodeToJumpVar) + v12) = *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + v12);
          ++v12;
          --v11;
        }
        while ( v11 );
      }
      **(_BYTE **)(a - FlashBinDataVar) = *(_DWORD *)(a - BootStartVar) >> 1;
      *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 1) = 0xEFu;
      *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 2) = *(_DWORD *)(a - BootStartVar) >> 9;
      result = *(_DWORD *)(a - BootStartVar) >> 17;
      LOBYTE(result) = result & 0xF | 0xF0;
      *(_BYTE *)(*(_DWORD *)(a - FlashBinDataVar) + 3) = result;
    }
  }
  return result;
}

readHexFile

int __fastcall readHexFile(int argSelf, int argFileName)
{
  int v2; // edx@3
  int v3; // eax@4
  int v4; // esi@5
  signed int v5; // eax@6
  int v6; // edi@8
  signed int v7; // ebx@9
  int lineByte; // eax@10
  int v9; // ecx@12
  unsigned __int16 addrField; // ax@20
  int v11; // ecx@22
  MCUTYPE mcuType; // eax@24
  int v13; // eax@25
  int v14; // eax@26
  char v15; // cf@26
  int v16; // eax@26
  int v17; // eax@29
  int v18; // eax@29
  int v19; // eax@30
  int v20; // esi@66
  int v21; // ebx@66
  int v22; // esi@80
  int v23; // ebx@80
  int v24; // ebx@86
  int v25; // eax@86
  int v26; // esi@87
  int v27; // eax@91
  int v28; // eax@91
  int v29; // esi@92
  unsigned int v31; // [sp+8h] [bp-8Ch]@3
  int (*v32)(); // [sp+Ch] [bp-88h]@3
  int (*v33)(); // [sp+10h] [bp-84h]@3
  unsigned int v34; // [sp+14h] [bp-80h]@1
  int (*v35)(); // [sp+18h] [bp-7Ch]@1
  int (*v36)(); // [sp+1Ch] [bp-78h]@1
  int v37; // [sp+2Ch] [bp-68h]@81
  int v38; // [sp+30h] [bp-64h]@67
  int v39; // [sp+34h] [bp-60h]@22
  int v40; // [sp+38h] [bp-5Ch]@22
  int tmpHexStr__; // [sp+3Ch] [bp-58h]@20
  int tmpHexStr; // [sp+40h] [bp-54h]@20
  int v43; // [sp+44h] [bp-50h]@19
  int tmpHexStr_; // [sp+48h] [bp-4Ch]@18
  int v45; // [sp+4Ch] [bp-48h]@12
  int v46; // [sp+50h] [bp-44h]@12
  int v47; // [sp+54h] [bp-40h]@12
  int v48; // [sp+58h] [bp-3Ch]@10
  int last_addr; // [sp+5Ch] [bp-38h]@34
  char addrValid; // [sp+63h] [bp-31h]@3
  int baseAddr; // [sp+64h] [bp-30h]@3
  int recordType; // [sp+68h] [bp-2Ch]@18
  int checkSum; // [sp+6Ch] [bp-28h]@6
  int numberDataBytes; // [sp+70h] [bp-24h]@8
  int completeAddr; // [sp+74h] [bp-20h]@20
  int v56; // [sp+78h] [bp-1Ch]@5
  int v57; // [sp+7Ch] [bp-18h]@3
  int self; // [sp+80h] [bp-14h]@1
  int v59; // [sp+84h] [bp-10h]@89
  int lineStr; // [sp+88h] [bp-Ch]@6
  int tmpStr; // [sp+8Ch] [bp-8h]@10
  int fileName; // [sp+90h] [bp-4h]@1
  int v63; // [sp+94h] [bp+0h]@1

  fileName = argFileName;
  self = argSelf;
  System::__linkproc___LStrAddRef(argFileName);
  v36 = (int (*)())&v63;
  v35 = loc_58DB80;
  v34 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v34);
  if ( !Sysutils::FileExists() || !*(_BYTE *)(self + McuType) )
  {
LABEL_95:
    __writefsdword(0, v34);
    v36 = loc_58DB87;
    System::__linkproc___LStrArrayClr(&v37, 12);
    System::__linkproc___DynArrayClear(&v59, off_58D3AC);
    return System::__linkproc___LStrArrayClr(&lineStr, 3);
  }
  baseAddr = 0;
  addrValid = 1;
  System::__linkproc___DynArraySetLength(0);
  System::__linkproc___DynArraySetLength(0);
  LOBYTE(v2) = 1;
  v57 = unknown_libname_38(off_41B964, v2);
  (*(void (__fastcall **)(int, int))(*(_DWORD *)v57 + 104))(v57, fileName);
  v33 = (int (*)())&v63;
  v32 = loc_58DB43;
  v31 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v31);
  if ( (*(int (**)(void))(*(_DWORD *)v57 + 20))() > 0 )
  {
    v3 = (*(int (**)(void))(*(_DWORD *)v57 + 20))();
    if ( v3 - 1 >= 0 )
    {
      v4 = v3;
      v56 = 0;
      while ( 1 )
      {
        checkSum = 0;
        (*(void (__fastcall **)(int, int, int *))(*(_DWORD *)v57 + 12))(v57, v56, &lineStr);
        v5 = lineStr;
        if ( lineStr )
          v5 = *(_DWORD *)(lineStr - 4);
        numberDataBytes = v5 / 2;
        v6 = v5 / 2;
        if ( v5 / 2 > 0 )
        {
          v7 = 1;
          do
          {
            System::__linkproc___LStrCopy(lineStr, 2 * v7, 2, (int)&tmpStr);
            System::__linkproc___LStrCat3(&v48, &str___3[1], tmpStr);
            lineByte = Sysutils::StrToInt(v48);
            checkSum += lineByte;
            ++v7;
            --v6;
          }
          while ( v6 );
        }
        if ( (_BYTE)checkSum )
          break;
        ++v56;
        --v4;
        if ( !v4 )
          goto LABEL_14;
      }
      Sysutils::IntToStr(v56, &v46);
      Sysutils::ExtractFileName(fileName, &v45);
      System::__linkproc___LStrCatN(&v47, 8, v9, &stru_58DBF8[1], &str_No_data_will_be[1]);
      Dialogs::MessageDlg(0);
      System::__linkproc___TryFinallyExit(v31, v32, v33);
      goto LABEL_95;
    }
  }
LABEL_14:
  if ( (*(int (**)(void))(*(_DWORD *)v57 + 20))() > 0 )
  {
    v56 = 0;
    while ( (*(int (**)(void))(*(_DWORD *)v57 + 20))() - 1 >= v56 )
    {
      (*(void (__fastcall **)(int, int, int *))(*(_DWORD *)v57 + 12))(v57, v56, &lineStr);
      if ( lineStr )
      {
        System::__linkproc___LStrCopy(lineStr, 8, 2, (int)&tmpStr);
        System::__linkproc___LStrCat3(&tmpHexStr_, &str___3[1], tmpStr);
        recordType = Sysutils::StrToInt(tmpHexStr_);
        if ( recordType == 4 )
        {
          System::__linkproc___LStrCopy(lineStr, 10, 4, (int)&tmpStr);
          System::__linkproc___LStrCat3(&v43, &str___3[1], tmpStr);
          baseAddr = Sysutils::StrToInt(v43);
        }
        System::__linkproc___LStrCopy(lineStr, 2, 2, (int)&tmpStr);
        System::__linkproc___LStrCat3(&tmpHexStr, &str___3[1], tmpStr);
        numberDataBytes = Sysutils::StrToInt(tmpHexStr);
        System::__linkproc___LStrCopy(lineStr, 4, 4, (int)&tmpStr);
        System::__linkproc___LStrCat3(&tmpHexStr__, &str___3[1], tmpStr);
        addrField = Sysutils::StrToInt(tmpHexStr__);
        completeAddr = addrField + ((unsigned __int16)baseAddr << 16);
        if ( (unsigned __int8)(*(_BYTE *)(self + McuType) - STM32L1XX) < 4u )// STM32xxxx
        {
          if ( (unsigned int)completeAddr < 0x8000000 )
          {
            Sysutils::IntToStr(v56, &v39);
            System::__linkproc___LStrCatN(&v40, 3, v11, v39, &str___violates_inte[1]);
            Dialogs::MessageDlg(0);
            System::__linkproc___TryFinallyExit(v31, v32, v33);
            goto LABEL_95;
          }
          completeAddr -= 0x8000000u;
        }
        mcuType = *(_BYTE *)(self + McuType);
        if ( mcuType >= DSPIC )
        {
          v17 = mcuType - DSPIC;
          v15 = (unsigned int)v17 < 2;
          v18 = v17 - 2;
          if ( v15 )                            // DSPIC
          {
            if ( *(_WORD *)(self + 1072) >= 0x1200u )
              last_addr = 4 * *(_DWORD *)(self + McuSize) / 3u;
            else
              last_addr = 2 * *(_DWORD *)(self + BootStart);
            addrValid = completeAddr < (unsigned int)last_addr;
          }
          else
          {
            v19 = v18 - 8;
            if ( v19 )                          // >= ARM
            {
              if ( (unsigned int)(v19 - 10) < 8 )
              {
                if ( *(_WORD *)(self + BootRev) >= 0x1200u )
                  last_addr = *(_DWORD *)(self + McuSize);
                else
                  last_addr = *(_DWORD *)(self + BootStart);
                addrValid = completeAddr < (unsigned int)last_addr;
              }
            }
            else                                // PIC32
            {
              if ( *(_WORD *)(self + BootRev) >= 0x1200u )
                last_addr = *(_DWORD *)(self + McuSize) + 0x1D000000;
              else
                last_addr = 0x1F800000u;
              if ( (unsigned int)completeAddr >= 0x1D000000 && completeAddr < (unsigned int)last_addr )
              {
                addrValid = 1;
                completeAddr -= 0x1D000000u;
              }
              else
              {
                addrValid = 0;
                if ( !recordType )
                {
                  if ( (unsigned int)completeAddr >= 0x1FC00000 )
                  {
                    if ( (unsigned int)completeAddr < 0x1FC02FF0 )
                    {
                      completeAddr -= 0x1FC00000u;
                      resizeMipsBootRomData(self, numberDataBytes + completeAddr);
                      if ( numberDataBytes - 1 >= 0 )
                      {
                        v20 = numberDataBytes;
                        v21 = 0;
                        do
                        {
                          System::__linkproc___LStrCopy(lineStr, 2 * v21 + 10, 2, (int)&tmpStr);
                          System::__linkproc___LStrCat3(&v38, &str___3[1], tmpStr);
                          *(_BYTE *)(*(_DWORD *)(self + mipsBootRomData) + completeAddr + v21++) = Sysutils::StrToInt(v38);
                          --v20;
                        }
                        while ( v20 );
                      }
                    }
                  }
                }
              }
            }
          }
        }
        else                                    // < DSPIC
        {
          v13 = mcuType - 1;
          if ( v13 )
          {
            v14 = v13 - 1;
            v15 = (unsigned int)v14 < 2;
            v16 = v14 - 2;
            if ( v15 )                          // PIC18 or PIC18FJ
            {
              if ( *(_WORD *)(self + BootRev) >= 0x1200u )
                last_addr = *(_DWORD *)(self + McuSize);
              else
                last_addr = *(_DWORD *)(self + BootStart);
              addrValid = completeAddr < (unsigned int)last_addr;
            }
            else
            {
              if ( !v16 )                       // PIC24
              {
                if ( *(_WORD *)(self + BootRev) >= 0x1200u )
                  last_addr = 4 * *(_DWORD *)(self + McuSize) / 3u;
                else
                  last_addr = 2 * *(_DWORD *)(self + BootStart);
                addrValid = completeAddr < (unsigned int)last_addr;
              }
            }
          }
          else                                  // PIC16
          {
            if ( *(_WORD *)(self + BootRev) >= 0x1200u )
              last_addr = *(_DWORD *)(self + McuSize);
            else
              last_addr = *(_DWORD *)(self + BootStart);
            addrValid = completeAddr < (unsigned int)last_addr;
          }
        }
        if ( !recordType && addrValid )
        {
          sub_58D2E4(self, numberDataBytes + completeAddr);
          if ( numberDataBytes - 1 >= 0 )
          {
            v22 = numberDataBytes;
            v23 = 0;
            do
            {
              System::__linkproc___LStrCopy(lineStr, 2 * v23 + 10, 2, (int)&tmpStr);
              System::__linkproc___LStrCat3(&v37, &str___3[1], tmpStr);
              *(_BYTE *)(*(_DWORD *)(self + flashBinData) + completeAddr + v23++) = Sysutils::StrToInt(v37);
              --v22;
            }
            while ( v22 );
          }
          ++v56;
        }
        else
        {
          ++v56;
        }
      }
      else
      {
        ++v56;
      }
    }
  }
  if ( *(_BYTE *)(self + McuType) == PIC24 || (unsigned __int8)(*(_BYTE *)(self + McuType) - DSPIC) < 2u )
  {                                             // PIC24 or DSPIC
    v24 = 0;
    v25 = getDynArrayLength(*(_DWORD *)(self + flashBinData));
    if ( v25 - 1 >= 0 )
    {
      v26 = v25;
      v56 = 0;
      do
      {
        if ( (v56 + 1) % 4 )
        {
          System::__linkproc___DynArraySetLength(v24 + 1);
          *(_BYTE *)(v59 + v24++) = *(_BYTE *)(*(_DWORD *)(self + flashBinData) + v56);
        }
        ++v56;
        --v26;
      }
      while ( v26 );
    }
    v27 = getDynArrayLength(v59);
    System::__linkproc___DynArraySetLength(v27);
    v28 = getDynArrayLength(v59);
    if ( v28 - 1 >= 0 )
    {
      v29 = v28;
      v56 = 0;
      do
      {
        *(_BYTE *)(*(_DWORD *)(self + flashBinData) + v56) = *(_BYTE *)(v59 + v56);
        ++v56;
        --v29;
      }
      while ( v29 );
    }
  }
  *(_BYTE *)(self + 1097) = 1;
  *(_BYTE *)(self + 1098) = *(_BYTE *)(self + McuType);
  __writefsdword(0, v31);
  v33 = loc_58DB4A;
  return System::TObject::Free(v57);
}

ButtonStartBootloaderClick

int __fastcall TmBoot_ButtonStartBootloaderClick(int a1)
{
  int v1; // eax@7
  int v2; // eax@8
  int v3; // eax@8
  int v4; // eax@8
  char mcutype; // al@12
  char isnt_pic24; // al@14
  int flashbindata_len; // eax@18
  int mipsbootromdata_len; // eax@20
  int flashbindata_len_; // eax@23
  unsigned int v10; // ST08_4@24
  int v11; // eax@24
  int mipsbootromdata_len_; // eax@26
  int v13; // eax@29
  int v14; // eax@29
  signed int v15; // eax@32
  signed int v16; // eax@32
  int v17; // eax@34
  int v18; // edx@39
  int v19; // esi@45
  int v20; // edi@45
  int v21; // eax@46
  int const21; // edx@51
  int v23; // eax@60
  unsigned __int64 v24; // ST08_8@60
  __int64 v25; // ST00_8@60
  int v26; // eax@60
  int v27; // eax@61
  int v28; // eax@61
  int v29; // eax@65
  int v30; // eax@70
  int v31; // eax@70
  unsigned int last_dirty_pos___; // ST08_4@72
  int addr; // ST04_4@72
  int flashbindata_len_m1; // eax@72
  int v35; // eax@75
  int v36; // eax@75
  int v37; // eax@75
  int const21_; // edx@80
  unsigned int last_dirty_pos_; // ST08_4@87
  int posresetvec_; // ST04_4@87
  int flashbindata_len_m1_; // eax@87
  int v42; // ecx@93
  int v43; // ST0C_4@93
  unsigned int v45; // [sp+10h] [bp-70h]@1
  int (*v46)(); // [sp+14h] [bp-6Ch]@1
  char v47[4]; // [sp+18h] [bp-68h]@1
  unsigned int v48; // [sp+1Ch] [bp-64h]@1
  int (*v49)(); // [sp+20h] [bp-60h]@1
  int (*v50)(); // [sp+24h] [bp-5Ch]@1
  int v51; // [sp+34h] [bp-4Ch]@1
  int v52; // [sp+38h] [bp-48h]@1
  unsigned int start_addr; // [sp+3Ch] [bp-44h]@10
  int last_dirty_pos__; // [sp+4Ch] [bp-34h]@74
  unsigned int last_dirty_pos; // [sp+50h] [bp-30h]@59
  unsigned int addr_; // [sp+54h] [bp-2Ch]@44
  int some_ack_status; // [sp+58h] [bp-28h]@52
  unsigned int bootrom_addr; // [sp+5Ch] [bp-24h]@10
  unsigned int numFlashBlks; // [sp+60h] [bp-20h]@41
  int numFlashBlks_; // [sp+64h] [bp-1Ch]@29
  int mipsbootromdata; // [sp+6Ch] [bp-14h]@1
  unsigned int bootstart; // [sp+70h] [bp-10h]@12
  int flashbindata; // [sp+74h] [bp-Ch]@1
  int codetojump; // [sp+78h] [bp-8h]@1
  int loadedHexObj; // [sp+7Ch] [bp-4h]@1
  char closure[4]; // [sp+80h] [bp+0h]@1

  v52 = 0;
  v51 = 0;
  codetojump = 0;
  flashbindata = 0;
  mipsbootromdata = 0;
  loadedHexObj = a1;
  v50 = (int (*)())closure;
  v49 = loc_58FA50;
  v48 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v48);
  *(_DWORD *)v47 = closure;
  v46 = loc_58FA07;
  v45 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v45);
  if ( !byte_5A25ED )
  {
    unknown_libname_410(*(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624), &str_Error__Connect_[1]);
    __writefsdword(0, v45);
    goto LABEL_96;
  }
  if ( !*(_BYTE *)(loadedHexObj + 1097) )
  {
    unknown_libname_410(*(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624), &str_Error__Load_HEX[1]);
    __writefsdword(0, v45);
    goto LABEL_96;
  }
  if ( *(_BYTE *)(loadedHexObj + McuType) != *(_BYTE *)(loadedHexObj + 1098) )
  {
    unknown_libname_410(*(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624), &str_Error__Reload_H[1]);
    __writefsdword(0, v45);
    goto LABEL_96;
  }
  v1 = *(_DWORD *)(loadedHexObj + 984);
  if ( *(_DWORD *)(v1 + 12) )
  {
    *(_DWORD *)(v1 + 12) = 0;
    __writefsdword(0, v45);
    goto LABEL_96;
  }
  (*(void (__fastcall **)(_DWORD, _DWORD))(**(_DWORD **)(loadedHexObj + 976) + 104))(*(_DWORD *)(loadedHexObj + 976), 0);
  (*(void (__fastcall **)(_DWORD, _DWORD))(**(_DWORD **)(loadedHexObj + 980) + 104))(*(_DWORD *)(loadedHexObj + 980), 0);
  v2 = *(_DWORD *)(loadedHexObj + 984);
  *(_DWORD *)(v2 + 12) = 1;
  Controls::TControl::SetText(v2, &str_Stop_uploading[1]);
  unknown_libname_410(*(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624), &str_Uploading_[1]);
  v3 = getDynArrayLength(*(_DWORD *)(loadedHexObj + flashBinData));
  System::__linkproc___DynArrayCopyRange(&flashbindata, v3);
  v4 = getDynArrayLength(*(_DWORD *)(loadedHexObj + mipsBootRomData));
  System::__linkproc___DynArrayCopyRange(&mipsbootromdata, v4);
  start_addr = 0;
  bootrom_addr = 0;
  if ( *(_BYTE *)(loadedHexObj + McuType) == PIC32 )
  {
    start_addr = 0x1D000000u;
    bootrom_addr = 0x1FC00000u;
  }
  bootstart = *(_DWORD *)(loadedHexObj + BootStart);
  mcutype = *(_BYTE *)(loadedHexObj + McuType);
  if ( mcutype == PIC32 )
  {
    bootstart &= 0x1FFFFFFFu;
  }
  else
  {
    isnt_pic24 = mcutype - PIC24;
    if ( !isnt_pic24 || (unsigned __int8)(isnt_pic24 - 6) < 2u )// PIC24 || DSPIC
      bootstart = 3 * (bootstart >> 1);
  }
  addAppResetCode((int)closure);
  if ( getDynArrayLength(flashbindata) <= 0 )
    goto LABEL_89;
  flashbindata_len = getDynArrayLength(flashbindata);
  if ( bootstart - (signed __int64)getDynArrayLength(codetojump) < (signed __int64)(flashbindata_len
                                                                                  + (unsigned __int64)start_addr)
    || *(_BYTE *)(loadedHexObj + McuType) == PIC32
    && (mipsbootromdata_len = getDynArrayLength(mipsbootromdata),
        0x1FC03000 - *(_WORD *)(loadedHexObj + EraseBlock) < (signed __int64)(mipsbootromdata_len
                                                                            + (unsigned __int64)bootrom_addr)) )
  {
    if ( Dialogs::MessageDlg(0) == 7 )
    {
      sub_58DD94((int)&loadedHexObj, (int)closure);
      __writefsdword(0, v45);
      goto LABEL_96;
    }
    flashbindata_len_ = getDynArrayLength(flashbindata);
    if ( bootstart - (signed __int64)getDynArrayLength(codetojump) < (signed __int64)(flashbindata_len_
                                                                                    + (unsigned __int64)start_addr) )
    {
      v10 = bootstart;
      v11 = getDynArrayLength(codetojump);
      System::__linkproc___DynArraySetLength(v10 - v11 - start_addr);
    }
    if ( *(_BYTE *)(loadedHexObj + McuType) == PIC32 )
    {
      mipsbootromdata_len_ = getDynArrayLength(mipsbootromdata);
      if ( 0x1FC03000 - *(_WORD *)(loadedHexObj + EraseBlock) < (signed __int64)(mipsbootromdata_len_
                                                                               + (unsigned __int64)bootrom_addr) )
        System::__linkproc___DynArraySetLength(0x1FC03000 - *(_WORD *)(loadedHexObj + EraseBlock) - bootrom_addr);
    }
  }
  if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - STM32F2XX) >= 2u )// != STM32
  {
    v15 = getDynArrayLength(flashbindata);
    numFlashBlks_ = v15 / *(_WORD *)(loadedHexObj + EraseBlock);
    v16 = getDynArrayLength(flashbindata);
    if ( v16 % *(_WORD *)(loadedHexObj + EraseBlock) )
      ++numFlashBlks_;
    v17 = getDynArrayLength(flashbindata);
    if ( bootstart - *(_WORD *)(loadedHexObj + EraseBlock) < (signed __int64)(v17 + (unsigned __int64)start_addr)
      && numFlashBlks_ > 0 )
      --numFlashBlks_;
  }
  else                                          // == STM32
  {
    v13 = getDynArrayLength(flashbindata);
    numFlashBlks_ = sub_58EBF4(v13) + 1;
    v14 = getDynArrayLength(flashbindata);
    if ( bootstart - (signed __int64)sub_58ECE8(bootstart - 1) < (signed __int64)(v14 + (unsigned __int64)start_addr)
      && numFlashBlks_ > 0 )
      --numFlashBlks_;
  }
  sub_499F24(*(_DWORD *)(loadedHexObj + 996), numFlashBlks_);
  sub_499FE0(*(_DWORD *)(loadedHexObj + 996), 0);
  (*(void (__fastcall **)(_DWORD, _strings *))(**(_DWORD **)(*(_DWORD *)(loadedHexObj + 908) + 624) + 56))(
    *(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624),
    &str_Flash_Erase___[1]);
  if ( *(_BYTE *)(loadedHexObj + McuType) != 20 )
    (*(void (__fastcall **)(_DWORD, _DWORD))(**(_DWORD **)(loadedHexObj + 984) + 104))(
      *(_DWORD *)(loadedHexObj + 984),
      0);
  unknown_libname_735(*(_DWORD *)(loadedHexObj + 1028), 1000);
  LOBYTE(v18) = 1;
  unknown_libname_734(*(_DWORD *)(loadedHexObj + 1028), v18);
  if ( numFlashBlks_ <= 0 )
  {
LABEL_59:
    unknown_libname_734(*(_DWORD *)(loadedHexObj + 1028), 0);
    sub_499FE0(*(_DWORD *)(loadedHexObj + 996), *(_DWORD *)(*(_DWORD *)(loadedHexObj + 996) + 424));
    (*(void (**)(void))(**(_DWORD **)(loadedHexObj + 996) + 132))();
    addr_ = start_addr;
    last_dirty_pos = getDynArrayLength(flashbindata);
    if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - STM32F2XX) >= 2u )// != STM32
    {
      v29 = getDynArrayLength(flashbindata);
      if ( bootstart - *(_WORD *)(loadedHexObj + EraseBlock) >= (signed __int64)(v29 + (unsigned __int64)start_addr) )
      {
        while ( (signed int)last_dirty_pos % *(_WORD *)(loadedHexObj + WriteBlock) )
          ++last_dirty_pos;
      }
      else
      {
        last_dirty_pos = bootstart - *(_WORD *)(loadedHexObj + EraseBlock) - start_addr;
      }
    }
    else                                        // == STM32
    {
      v23 = getDynArrayLength(flashbindata);
      v24 = v23 + (unsigned __int64)start_addr;
      v25 = bootstart;
      v26 = sub_58EBF4(bootstart - 1);
      if ( v25 - sub_58ECE8(v26) >= (signed __int64)v24 )
      {
        while ( (signed int)last_dirty_pos % *(_WORD *)(loadedHexObj + WriteBlock) )
          ++last_dirty_pos;
      }
      else
      {
        v27 = sub_58EBF4(bootstart - 1);
        v28 = sub_58ECE8(v27);
        last_dirty_pos = bootstart - v28 - start_addr;
      }
    }
    if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - STM32F2XX) >= 2u )
    {
      sub_499F24(*(_DWORD *)(loadedHexObj + 996), 7 * (last_dirty_pos + *(_WORD *)(loadedHexObj + EraseBlock)));
    }
    else
    {
      v30 = sub_58EBF4(bootstart - 1);
      v31 = sub_58ECE8(v30);
      sub_499F24(*(_DWORD *)(loadedHexObj + 996), 7 * (last_dirty_pos + v31));
    }
    sub_499FE0(*(_DWORD *)(loadedHexObj + 996), 0);
    (*(void (__fastcall **)(_DWORD, _strings *))(**(_DWORD **)(*(_DWORD *)(loadedHexObj + 908) + 624) + 56))(
      *(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624),
      &str_Flash_Write___[1]);
    last_dirty_pos___ = last_dirty_pos;
    addr = addr_;
    flashbindata_len_m1 = getDynArrayLengthMinusOne(flashbindata);
    if ( send_writes(flashbindata, flashbindata_len_m1, 0, (unsigned int)closure, last_dirty_pos___, addr) > 0 )
    {
      __writefsdword(0, v45);
      goto LABEL_96;
    }
    last_dirty_pos__ = last_dirty_pos;
    if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - STM32F2XX) >= 2u )// != STM32
    {
      addr_ = bootstart - *(_WORD *)(loadedHexObj + EraseBlock);
      if ( *(_BYTE *)(loadedHexObj + McuType) == PIC24
        || (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - DSPIC) < 2u )
        addr_ = 2 * addr_ / 3;
      last_dirty_pos = *(_WORD *)(loadedHexObj + EraseBlock);
    }
    else                                        // == STM32
    {
      v35 = sub_58EBF4(bootstart - 1);
      v36 = sub_58ECE8(v35);
      addr_ = bootstart - v36;
      v37 = sub_58EBF4(bootstart - 1);
      last_dirty_pos = sub_58ECE8(v37);
    }
    send_erase_packet(loadedHexObj, addr_, 1);
    if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - 36) >= 2u )
    {
      LOBYTE(const21_) = 21;
      some_ack_status = check_ack_packet(loadedHexObj, const21_, 1000);
    }
    else
    {
      LOBYTE(const21_) = 21;
      some_ack_status = check_ack_packet(loadedHexObj, const21_, 4000);
    }
    if ( some_ack_status )
    {
      sub_58CFB0(loadedHexObj, some_ack_status);
      sub_58DF8C(closure);
      __writefsdword(0, v45);
      goto LABEL_96;
    }
    if ( !*(_DWORD *)(*(_DWORD *)(loadedHexObj + 984) + 12) )
    {
      sub_58DD94((int)&loadedHexObj, (int)closure);
      __writefsdword(0, v45);
      goto LABEL_96;
    }
    last_dirty_pos_ = last_dirty_pos;
    posresetvec_ = addr_;
    flashbindata_len_m1_ = getDynArrayLengthMinusOne(flashbindata);
    if ( send_writes(
           flashbindata,
           flashbindata_len_m1_,
           last_dirty_pos__,
           (unsigned int)closure,
           last_dirty_pos_,
           posresetvec_) > 0 )
    {
      __writefsdword(0, v45);
      goto LABEL_96;
    }
LABEL_89:
    if ( *(_BYTE *)(loadedHexObj + McuType) == PIC32 )
      send_pic32_stuff((int)closure);
    if ( *(_DWORD *)(*(_DWORD *)(loadedHexObj + 984) + 12) )
    {
      System::__linkproc___LStrAsg(*(_DWORD *)(loadedHexObj + 916) + 48, &str_Success[1]);
      sub_5481CC(*(_DWORD *)(loadedHexObj + 916), &str_Restarting_MCU_[1]);
      sub_548024(*(_DWORD *)(loadedHexObj + 916), &str_Uploading_progr_1[1]);
      Dialogs::TOpenDialog::GetFileName(*(_DWORD *)(loadedHexObj + 880), &v51);
      System::__linkproc___LStrCatN(&v52, 3, v42, v51, &str___finished_with[1]);
      sub_5480C4(*(_DWORD *)(loadedHexObj + 916), v52);
      unknown_libname_410(*(_DWORD *)(*(_DWORD *)(loadedHexObj + 908) + 624), &str_Completed_succe[1]);
      sub_58DF8C(closure);
      (*(void (__fastcall **)(_DWORD, _DWORD, int))(**(_DWORD **)(loadedHexObj + 916) + 88))(
        *(_DWORD *)(loadedHexObj + 916),
        **(_DWORD **)(loadedHexObj + 916),
        v43);
      if ( (unsigned __int8)sub_4AE0F8(*(_DWORD *)(loadedHexObj + 892)) )
        Forms::TCustomForm::Close(dword_5A25E8);
      __writefsdword(0, v45);
    }
    else
    {
      sub_58DD94((int)&loadedHexObj, (int)closure);
      __writefsdword(0, v45);
    }
    goto LABEL_96;
  }
  while ( 1 )
  {
    if ( numFlashBlks_ <= (signed int)0x7FFFu )
      numFlashBlks = numFlashBlks_;
    else
      numFlashBlks = 0x7FFFu;
    numFlashBlks_ -= numFlashBlks;
    if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - STM32F2XX) >= 2u )// != STM32
    {
      addr_ = start_addr + *(_WORD *)(loadedHexObj + EraseBlock) * (numFlashBlks - 1);
      if ( *(_BYTE *)(loadedHexObj + McuType) == PIC24
        || (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - DSPIC) < 2u )
        addr_ = 2 * addr_ / 3;
    }
    else                                        // == STM32
    {
      addr_ = start_addr;
      if ( ((numFlashBlks - 2) & 0x80000000u) == 0 )
      {
        v19 = numFlashBlks - 2 + 1;
        v20 = 0;
        do
        {
          v21 = sub_58ECE8(v20);
          addr_ += v21;
          ++v20;
          --v19;
        }
        while ( v19 );
      }
    }
    send_erase_packet(loadedHexObj, addr_, numFlashBlks);
    if ( (unsigned __int8)(*(_BYTE *)(loadedHexObj + McuType) - STM32F2XX) >= 2u )
    {
      LOBYTE(const21) = 21;
      some_ack_status = check_ack_packet(loadedHexObj, const21, 100 * numFlashBlks);
    }
    else
    {
      LOBYTE(const21) = 21;
      some_ack_status = check_ack_packet(loadedHexObj, const21, 4000 * numFlashBlks);
    }
    if ( some_ack_status )
    {
      sub_58CFB0(loadedHexObj, some_ack_status);
      sub_58DF8C(closure);
      __writefsdword(0, v45);
      goto LABEL_96;
    }
    if ( !*(_DWORD *)(*(_DWORD *)(loadedHexObj + 984) + 12) )
      break;
    if ( numFlashBlks_ <= 0 )
      goto LABEL_59;
  }
  sub_58DD94((int)&loadedHexObj, (int)closure);
  __writefsdword(0, v45);
LABEL_96:
  __writefsdword(0, v48);
  v50 = loc_58FA57;
  System::__linkproc___LStrClr(&v51);
  System::__linkproc___LStrClr(&v52);
  System::__linkproc___DynArrayClear(&mipsbootromdata, off_58BA74);
  return System::__linkproc___FinalizeArray(&flashbindata, off_58BA74, 2);
}

parseBootInfo

int __usercall parseBootInfo<eax>(int argSelf<eax>, int a2<ebx>, int a3<edi>, int a4<esi>)
{
  int self; // esi@1
  int packetLen; // edi@2
  int i; // ebx@2
  int v7; // ebx@15
  int v8; // ebx@23
  int v9; // ebx@31
  int v10; // ebx@39
  int v11; // ebx@50
  unsigned int v13; // [sp-18h] [bp-1Ch]@1
  int (*v14)(); // [sp-14h] [bp-18h]@1
  int (*v15)(); // [sp-10h] [bp-14h]@1
  int v16; // [sp-Ch] [bp-10h]@1
  int v17; // [sp-8h] [bp-Ch]@1
  int v18; // [sp-4h] [bp-8h]@1
  int v19; // [sp+0h] [bp-4h]@1
  int v20; // [sp+4h] [bp+0h]@1

  v19 = 0;
  v18 = a2;
  v17 = a4;
  v16 = a3;
  self = argSelf;
  v15 = (int (*)())&v20;
  v14 = loc_58C892;
  v13 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v13);
  if ( byte_5A25FC )
  {
    byte_5A25FC = 0;
    packetLen = *(_BYTE *)packet;
    for ( i = 1; i < packetLen; ++i )
    {
      switch ( *(_BYTE *)(packet + i) )
      {
        case FieldMcuType:
          ++i;
          *(_BYTE *)(self + McuType) = *(_BYTE *)(packet + i);
          break;
        case FieldMcuSize:
          if ( *(_BYTE *)(self + McuType) == PIC24 || (unsigned __int8)(*(_BYTE *)(self + McuType) - 10) < 2u )// <= DSPIC
          {
            while ( (i + 1) % 2 )
              ++i;
          }
          if ( *(_BYTE *)(self + McuType) == PIC32 || (unsigned __int8)(*(_BYTE *)(self + McuType) - 30) < 8u )
          {
            while ( (i + 1) % 4 )
              ++i;
          }
          v7 = i + 1;
          *(_DWORD *)(self + McuSize) = *(_BYTE *)(packet + v7++);
          *(_DWORD *)(self + McuSize) += *(_BYTE *)(packet + v7++) << 8;
          *(_DWORD *)(self + McuSize) += *(_BYTE *)(packet + v7) << 16;
          i = v7 + 1;
          *(_DWORD *)(self + McuSize) += *(_BYTE *)(packet + i) << 24;
          break;
        case FieldEraseBlock:
          if ( *(_BYTE *)(self + McuType) == PIC24
            || (unsigned __int8)(*(_BYTE *)(self + McuType) - 10) < 2u
            || *(_BYTE *)(self + McuType) == PIC32
            || (unsigned __int8)(*(_BYTE *)(self + McuType) - 30) < 8u )
          {
            while ( (i + 1) % 2 )
              ++i;
          }
          v8 = i + 1;
          *(_WORD *)(self + EraseBlock) = *(_BYTE *)(packet + v8);
          i = v8 + 1;
          *(_WORD *)(self + EraseBlock) += *(_BYTE *)(packet + i) << 8;
          break;
        case FieldWriteBlock:
          if ( *(_BYTE *)(self + McuType) == PIC24
            || (unsigned __int8)(*(_BYTE *)(self + McuType) - 10) < 2u
            || *(_BYTE *)(self + McuType) == PIC32
            || (unsigned __int8)(*(_BYTE *)(self + McuType) - 30) < 8u )
          {
            while ( (i + 1) % 2 )
              ++i;
          }
          v9 = i + 1;
          *(_WORD *)(self + WriteBlock) = *(_BYTE *)(packet + v9);
          i = v9 + 1;
          *(_WORD *)(self + WriteBlock) += *(_BYTE *)(packet + i) << 8;
          break;
        case FieldBootRev:
          if ( *(_BYTE *)(self + McuType) == PIC24
            || (unsigned __int8)(*(_BYTE *)(self + McuType) - 10) < 2u
            || *(_BYTE *)(self + McuType) == PIC32
            || (unsigned __int8)(*(_BYTE *)(self + McuType) - 30) < 8u )
          {
            while ( (i + 1) % 2 )
              ++i;
          }
          v10 = i + 1;
          *(_WORD *)(self + BootRev) = *(_BYTE *)(packet + v10);
          i = v10 + 1;
          *(_WORD *)(self + BootRev) += *(_BYTE *)(packet + i) << 8;
          break;
        case FieldBootStart:
          if ( *(_BYTE *)(self + McuType) == PIC24 || (unsigned __int8)(*(_BYTE *)(self + McuType) - 10) < 2u )
          {
            while ( (i + 1) % 2 )
              ++i;
          }
          if ( *(_BYTE *)(self + McuType) == PIC32 || (unsigned __int8)(*(_BYTE *)(self + McuType) - 30) < 8u )
          {
            while ( (i + 1) % 4 )
              ++i;
          }
          v11 = i + 1;
          *(_DWORD *)(self + BootStart) = *(_BYTE *)(packet + v11++);
          *(_DWORD *)(self + BootStart) += *(_BYTE *)(packet + v11++) << 8;
          *(_DWORD *)(self + BootStart) += *(_BYTE *)(packet + v11) << 16;
          i = v11 + 1;
          *(_DWORD *)(self + BootStart) += *(_BYTE *)(packet + i) << 24;
          break;
        case FieldDevDsc:
          System::__linkproc___LStrSetLength(self + DevDsc, 0);
          while ( *(_BYTE *)(packet + i) )
          {
            ++i;
            unknown_libname_63(&v19, *(_BYTE *)(packet + i));
            System::__linkproc___LStrCat(self + DevDsc, v19);
          }
          break;
        default:
          continue;
      }
    }
  }
  __writefsdword(0, v13);
  v15 = loc_58C899;
  return System::__linkproc___LStrClr(&v19);
}

Enums

; enum MCUTYPE
PIC16            = 1
PIC18            = 2
PIC18FJ          = 3
PIC24            = 4
DSPIC            = 10
PIC32            = 20
ARM              = 30
STELLARIS_M3     = 31
STELLARIS_M4     = 32
STELLARIS        = 33
STM32L1XX        = 34
STM32F1XX        = 35
STM32F2XX        = 36
STM32F4XX        = 37

; ---------------------------------------------------------------------------

; enum ClassAttr
flashBinData     = 1064
mipsBootRomData  = 1068
BootRev          = 1072
BootStart        = 1076
McuType          = 1080
McuSize          = 1084
EraseBlock       = 1088
WriteBlock       = 1090
DevDsc           = 1092

; ---------------------------------------------------------------------------

; enum FieldType
FieldMcuType     = 1
FieldMcuId       = 2
FieldEraseBlock  = 3
FieldWriteBlock  = 4
FieldBootRev     = 5
FieldBootStart   = 6
FieldDevDsc      = 7
FieldMcuSize     = 8

; ---------------------------------------------------------------------------

; enum addResetArg
LoadedHexObjVar     = 4
CodeToJumpVar       = 8
FlashBinDataVar     = 12
BootStartVar        = 16
MipsBootRomDataVar  = 20
OneByteFlagVar      = 21
NumFlashBlks_Var    = 28
NumFlashBlksVar     = 32
BootromAddrVar      = 36
SomeAckStatusVar    = 40
Addr_Var            = 44
LastDirtyPosVar     = 48