//---------------------------------------------------------------------------
// Проект 29. Разбор строки Intel HEX
// Проверка контрольной суммы записи прошивки.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
//---------------------------------------------------------------------------

// Строка Intel HEX: ':' LL AAAA TT [данные] CC. Контрольная сумма — до нуля
// по модулю 256 суммы всех байтов записи. Ядро проверяется на реальной строке.
int hexNibble(char c)
{
    if (c>='0'&&c<='9') return c-'0';
    if (c>='A'&&c<='F') return c-'A'+10;
    if (c>='a'&&c<='f') return c-'a'+10;
    return -1;
}
int hexByteAt(const AnsiString &s, int pos)   // pos 1-based
{
    int hi=hexNibble(s[pos]), lo=hexNibble(s[pos+1]);
    return (hi<0||lo<0)?-1:(hi<<4|lo);
}
bool intelHexOk(const AnsiString &line)
{
    if (line.IsEmpty() || line[1] != ':') return false;
    int len = (line.Length()-1)/2;
    int sum=0;
    for (int i=0;i<len;i++){
        int b=hexByteAt(line, 2+i*2);
        if (b<0) return false;
        sum += b;
    }
    return (sum & 0xFF) == 0;                    // включая байт контрольной суммы
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonCheckClick(TObject *Sender)
{
    AnsiString line = EditHex->Text.Trim();
    LabelOk->Caption = intelHexOk(line) ? "Контрольная сумма верна" : "Ошибка записи";
}
//---------------------------------------------------------------------------
