{System requniments:
 - MS-DOS (or compatible for 80%) v2.0 or later;
 - CGA - compatible text mode display with text 80x25 16 colors;
 - BIOS system compatible with IBM BIOS v1.0.
Source code of BinHex.Exe (for Borland (R) Turbo Pascal v7.0,
 FreePASCAL Compiler v1.4, etc...):
============================================================================}
{$A-,B+,D-,E-,F-,G-,I-,L-,N-,O-,P+,Q-,R-,S-,T-,V-,X+,Y-}
{$M 1024,0,0}
Program HexData;
Uses Crt,Dos;
Const
    HexTable : Array[0..15] Of Char = '0123456789ABCDEF';
Var
  Crc32HexTable  : Array[0..255] Of LongInt;
  SourceFileName : String;
  TargetFileName : String;
  StartTime      : DateTime;
  Time           : DateTime;
  CrcValue       : LongInt;
{===========================================================================}
Function NormalLine(Line : String) : String;
Var
  LineIndex : Byte;
Begin
 While Line<>'' Do If Ord(Line[1])<33 Then Delete(Line,1,1) Else Break;
 While Line<>'' Do If Ord(Line[Length(Line)])<33 Then
 Delete(Line,Length(Line),1) Else Break;
 For LineIndex:=1 To Length(Line) Do
 Line[LineIndex]:=UpCase(Line[LineIndex]);
 NormalLine:=Line;
end;
{===========================================================================}
Procedure MakeCRC32Tables;
Var
  Crc   : LongInt;
  Index : Byte;
  Value : Byte;
Begin
 For Index:=0 To 255 Do
 Begin
  Crc:=Index;
  For Value:=1 To 8 Do If Odd(Crc) Then Crc:=(Crc Div 2) XOr LongInt($EDB88320)
  Else Crc:=Crc Div 2;
  Crc32HexTable[Index]:=Crc;
 end;
end;
{===========================================================================}
Function Hex(Value : LongInt) : String;
Var
  Line : String;
Begin
 Line:='';
 While Value>0 Do
 Begin
  Case Value Mod $10 Of
   0: Line:='0'+Line;
   1: Line:='1'+Line;
   2: Line:='2'+Line;
   3: Line:='3'+Line;
   4: Line:='4'+Line;
   5: Line:='5'+Line;
   6: Line:='6'+Line;
   7: Line:='7'+Line;
   8: Line:='8'+Line;
   9: Line:='9'+Line;
  10: Line:='A'+Line;
  11: Line:='B'+Line;
  12: Line:='C'+Line;
  13: Line:='D'+Line;
  14: Line:='E'+Line;
  15: Line:='F'+Line;
  end;
  Value:=Value Div $10;
 end;
 Hex:=Line;
end;
{===========================================================================}
Function ByteToHex(Value : Byte) : String;
Begin
 ByteToHex:=HexTable[Value Shr 4]+HexTable[Value And 15];
end;
{===========================================================================}
Function DayOfWeek(Year : Word; Month,Day : Byte) : Byte;
 {--------------------------------------------------------------------------}
 Function DaysCount(Year : Word; Month,Day : Byte) : LongInt;
  {-------------------------------------------------------------------------}
  Function MonthDays(Year : Word; Month : Byte) : Word;
   {------------------------------------------------------------------------}
   Function IsLeapYear(Year : Word) : Boolean;
   Begin
    IsLeapYear:=((Year Div 4)*4)=Year;
   end;
  Begin
   Case Month Of
    1:  MonthDays:=0;
    2:  MonthDays:=31;
    3:  MonthDays:=59+Ord(IsLeapYear(Year));
    4:  MonthDays:=90+Ord(IsLeapYear(Year));
    5:  MonthDays:=120+Ord(IsLeapYear(Year));
    6:  MonthDays:=151+Ord(IsLeapYear(Year));
    7:  MonthDays:=181+Ord(IsLeapYear(Year));
    8:  MonthDays:=212+Ord(IsLeapYear(Year));
    9:  MonthDays:=243+Ord(IsLeapYear(Year));
    10: MonthDays:=273+Ord(IsLeapYear(Year));
    11: MonthDays:=304+Ord(IsLeapYear(Year));
    12: MonthDays:=334+Ord(IsLeapYear(Year));
   end;
  end;
 Begin
  DaysCount:=(LongInt(Year)*365)+(Year Div 4)+(Year Div 100)+
  MonthDays(Year,Month)+Day;
 end;
Begin
 Case DaysCount(Year,Month,Day)-((DaysCount(Year,Month,Day) Div 7)*7) Of
  0: DayOfWeek:=6;
  1: DayOfWeek:=7;
  2: DayOfWeek:=1;
  3: DayOfWeek:=2;
  4: DayOfWeek:=3;
  5: DayOfWeek:=4;
  6: DayOfWeek:=5;
 end;
end;
{===========================================================================}
Function TimeToLine(Hour,Minute,Second : Byte) : String;
Var
  Line : String;
  Wrk  : String;
Begin
 Str(Hour,Line);
 Str(Minute,Wrk);
 If Length(Line)<2 Then Line:='0'+Line;
 If Length(Wrk)<2 Then Wrk:='0'+Wrk;
 Line:=Line+':'+Wrk;
 Str(Second,Wrk);
 If Length(Wrk)<2 Then Wrk:='0'+Wrk;
 TimeToLine:=Line+':'+Wrk;
end;
{===========================================================================}
Function WorkTime : String;
Var
  OldTime : LongInt;
  CurTime : LongInt;
Begin
 OldTime:=(LongInt(StartTime.Hour)*3600)+(StartTime.Min*60)+StartTime.Sec;
 CurTime:=(LongInt(Time.Hour)*3600)+(Time.Min*60)+Time.Sec;
 CurTime:=CurTime-OldTime;
 Time.Hour:=CurTime Div 3600;
 CurTime:=CurTime-(LongInt(Time.Hour)*3600);
 Time.Min:=CurTime Div 60;
 Time.Sec:=CurTime-(Time.Min*60);
 WorkTime:=TimeToLine(Time.Hour,Time.Min,Time.Sec);
end;
{===========================================================================}
Procedure BinToHex;
Var
  InFile           : File;
  OutFile          : Text;
  OldInAttribute   : Word;
  OldOutAttribute  : Word;
  Answer           : Char;
  OldPosition      : LongInt;
  OldSecond        : Byte;
  WorkLine         : String;
  TempLine         : String;
  FileDateTime     : DateTime;
  FilePackDateTime : LongInt;
  ReadCount        : Word;
  HexLine          : String;
  Buffer           : Byte;
 {--------------------------------------------------------------------------}
 Procedure OutError(Message : String);
 Begin
  If IOResult=0 Then Exit;
  Close(InFile);
  Close(OutFile);
  SetFAttr(InFile,OldInAttribute);
  SetFAttr(OutFile,0);
  Erase(OutFile);
  WriteLn('ERROR: '+Message+'.');
  Halt;
 end;
 {--------------------------------------------------------------------------}
 Procedure WriteTarget(Line : String);
 Begin
  WriteLn(OutFile,Line);
  OutError('Cannot write to target file');
 end;
Begin
 If (Pos('\',SourceFileName)>0) Or (Pos(':',SourceFileName)>0) Or
 (Pos('\',TargetFileName)>0) Or (Pos(':',TargetFileName)>0) Then
 Begin
  WriteLn('File name cannot include path.');
  Exit;
 end;
 Assign(InFile,SourceFileName);
 Assign(OutFile,TargetFileName);
 GetFAttr(InFile,OldInAttribute);
 GetFAttr(OutFile,OldOutAttribute);
 SetFAttr(InFile,0);
 SetFAttr(OutFile,0);
 ReSet(InFile,1);
 If IOResult<>0 Then
 Begin
  SetFAttr(InFile,OldInAttribute);
  SetFAttr(OutFile,OldOutAttribute);
  WriteLn('File: '+SourceFileName+' does not exist');
  Exit;
 end;
 Answer:='Y';
 ReSet(OutFile);
 If IOResult=0 Then
 Begin
  Close(OutFile);
  TextColor(DarkGray);
  Repeat
   Write('File: '+TargetFileName+' is already exist. Over-write? (Y/N)');
   Answer:=UpCase(ReadKey);
   If Answer='N' Then
   Begin
    Close(InFile);
    SetFAttr(InFile,OldInAttribute);
    SetFAttr(OutFile,OldOutAttribute);
    Exit;
   end;
   GoToXY(1,WhereY);
   ClrEol;
   If Answer='Y' Then Break;
  Until False;
 end;
 ReWrite(OutFile);
 If IOResult<>0 Then
 Begin
  Close(InFile);
  SetFAttr(InFile,OldInAttribute);
  SetFAttr(OutFile,OldOutAttribute);
  WriteLn('Cannot open file: '+TargetFileName+' for write');
  Exit;
 end;
 WriteTarget('BINARY HEXADECIMAL FILE.');
 WriteTarget('====================================================');
 WriteTarget('File name: '+SourceFileName+'.');
 Str(FileSize(InFile),WorkLine);
 WriteTarget('File size: '+WorkLine+'.');
 GetFTime(InFile,FilePackDateTime);
 UnPackTime(FilePackDateTime,FileDateTime);
 Case DayOfWeek(FileDateTime.Year,FileDateTime.Month,FileDateTime.Day) Of
 1: WorkLine:='Mon';
 2: WorkLine:='Tues';
 3: WorkLine:='Wednes';
 4: WorkLine:='Thurs';
 5: WorkLine:='Fri';
 6: WorkLine:='Satur';
 7: WorkLine:='Sun';
 end;
 Str(FileDateTime.Day,TempLine);
 WorkLine:=WorkLine+'day, '+TempLine+' ';
 Case FileDateTime.Month Of
  1: TempLine:='January';
  2: TempLine:='February';
  3: TempLine:='March';
  4: TempLine:='April';
  5: TempLine:='May';
  6: TempLine:='June';
  7: TempLine:='July';
  8: TempLine:='August';
  9: TempLine:='September';
 10: TempLine:='October';
 11: TempLine:='November';
 12: TempLine:='December';
 end;
 WorkLine:=WorkLine+TempLine+' ';
 Str(FileDateTime.Year,TempLine);
 WorkLine:=WorkLine+TempLine;
 WriteTarget('File date is: '+WorkLine+' year.');
 Str(FileDateTime.Hour,WorkLine);
 If Length(WorkLine)<2 Then WorkLine:='0'+WorkLine;
 Str(FileDateTime.Min,TempLine);
 If Length(TempLine)<2 Then TempLine:='0'+TempLine;
 WorkLine:=WorkLine+':'+TempLine+':';
 HexLine:='';
 OldSecond:=0;
 OldPosition:=0;
 Str(FileDateTime.Sec,TempLine);
 If Length(TempLine)<2 Then TempLine:='0'+TempLine;
 WriteTarget('File time is: '+WorkLine+TempLine+'.');
 WorkLine:='';
 If (OldInAttribute And ReadOnly)<>0 Then WorkLine:=WorkLine+'R' Else
 WorkLine:=WorkLine+' ';
 If (OldInAttribute And Hidden)<>0 Then WorkLine:=WorkLine+'H' Else
 WorkLine:=WorkLine+' ';
 If (OldInAttribute And SysFile)<>0 Then WorkLine:=WorkLine+'S' Else
 WorkLine:=WorkLine+' ';
 If (OldInAttribute And VolumeID)<>0 Then WorkLine:=WorkLine+'V' Else
 WorkLine:=WorkLine+' ';
 If (OldInAttribute And Directory)<>0 Then WorkLine:=WorkLine+'D' Else
 WorkLine:=WorkLine+' ';
 If (OldInAttribute And Archive)<>0 Then WorkLine:=WorkLine+'A' Else
 WorkLine:=WorkLine+' ';
 WriteTarget('File attributes is: '+WorkLine+'.');
 GetTime(StartTime.Hour,StartTime.Min,StartTime.Sec,Time.Year);
 CRCValue:=LongInt($FFFFFFFF);
 TextColor(Green);
 WriteLn('Calculating CRC-32 Code.');
 Write('Source file size is:       ');
 TextColor(Blue);
 Write(FileSize(InFile));
 TextColor(Green);
 WriteLn(' bytes.');
 Write('Current file position: ');
 TextColor(Red);
 Write('0000000000');
 TextColor(Green);
 WriteLn('.');
 Write('Current speed: ');
 TextColor(Blue);
 Write('0000000000');
 TextColor(Green);
 WriteLn(' bytes per second.');
 TextColor(Yellow);
 Write('000%');
 TextColor(Green);
 WriteLn(' Complete.');
 Write('Start time:   ');
 TextColor(Magenta);
 Write(TimeToLine(StartTime.Hour,StartTime.Min,StartTime.Sec));
 TextColor(Green);
 WriteLn('.');
 WriteLn('Current time: 00:00:00.');
 WriteLn('Work time:    00:00:00.');
 WriteLn('CRC code: 0000000000.');
 TextColor(Yellow);
 WriteLn('Esc=Break.');
 TextColor(LightBlue);
 WriteLn('Please waith...');
 WriteLn;
 TextColor(LightGray);
 Repeat
  TextColor(Red);
  Str(FilePos(InFile),WorkLine);
  While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
  GoToXY(24,WhereY-10);
  Write(WorkLine);
  GoToXY(16,WhereY+1);
  GetTime(Time.Hour,Time.Min,Time.Sec,Time.Year);
  If OldSecond<>Time.Sec Then
  Begin
   OldSecond:=Time.Sec;
   Str(FilePos(InFile)-OldPosition,WorkLine);
   OldPosition:=FilePos(InFile);
   While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
   Write(WorkLine);
  end;
  TextColor(Magenta);
  Str((FilePos(InFile)*100) Div FileSize(InFile),WorkLine);
  While Length(WorkLine)<3 Do WorkLine:=' '+WorkLine;
  GoToXY(1,WhereY+1);
  Write(Copy(WorkLine,1,3));
  GoToXY(15,WhereY+2);
  Write(TimeToLine(Time.Hour,Time.Min,Time.Sec));
  GoToXY(15,WhereY+1);
  Write(WorkTime);
  Str(CRCValue,WorkLine);
  While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
  TextColor(Red);
  GoToXY(11,WhereY+1);
  Write(WorkLine);
  TextColor(LightGray);
  GoToXY(1,WhereY+4);
  If KeyPressed Then If ReadKey=Chr(27) Then
  Begin
   Close(InFile);
   Close(OutFile);
   SetFAttr(InFile,OldInAttribute);
   SetFAttr(OutFile,0);
   Erase(OutFile);
   Exit;
  end;
  Repeat
   BlockRead(InFile,Buffer,1,ReadCount);
   If IOResult<>0 Then
   Begin
    Repeat
     Write('Cannot read from the source file. Retry? (Y/N)');
     Answer:=UpCase(ReadKey);
     If (Answer='Y') Or (Answer='N') Then Break;
     GoToXY(1,WhereY);
     ClrEol;
    Until False;
    If Answer='N' Then
    Begin
     Close(InFile);
     Close(OutFile);
     SetFAttr(InFile,OldInAttribute);
     SetFAttr(OutFile,0);
     Erase(OutFile);
     Exit;
    end;
   end Else Break;
  Until False;
  If ReadCount=0 Then Break;
  CRCValue:=Crc32HexTable[Byte(CRCValue) XOr Buffer] XOr (CRCValue Div $100);
 Until False;
 TextColor(Green);
 Write('Resultative CRC code is: ');
 TextColor(Blue);
 Str(CRCValue,WorkLine);
 Write(WorkLine);
 TextColor(Green);
 WriteLn('.');
 TextColor(LightGray);
 Seek(InFile,0);
 OutError('Cannot seek in the source file.');
 Str(CRCValue,WorkLine);
 WriteTarget('CRC-32 Code: '+WorkLine+'.');
 WriteTarget('====================================================');
 WriteLn;
 GetTime(StartTime.Hour,StartTime.Min,StartTime.Sec,Time.Year);
 TextColor(Brown);
 WriteLn('Conversion process.');
 TextColor(Green);
 Write('From: ');
 TextColor(Blue);
 Write(Copy(SourceFileName,1,72));
 TextColor(Green);
 WriteLn('.');
 Write('  To: ');
 TextColor(Blue);
 Write(Copy(TargetFileName,1,72));
 TextColor(Green);
 WriteLn('.');
 Str(FileSize(InFile),WorkLine);
 While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
 Write('Source file size is:   ');
 TextColor(Blue);
 Write(WorkLine);
 TextColor(Green);
 WriteLn(' bytes.');
 Write('Current file position: ');
 TextColor(Red);
 Write('0000000000');
 TextColor(Green);
 WriteLn('.');
 Write('Current speed: ');
 TextColor(Blue);
 Write('0000000000');
 TextColor(Green);
 WriteLn(' bytes per second.');
 TextColor(Yellow);
 Write('000%');
 TextColor(Green);
 WriteLn(' Complete.');
 Write('Start time:   ');
 TextColor(Magenta);
 Write(TimeToLine(StartTime.Hour,StartTime.Min,StartTime.Sec));
 TextColor(Green);
 WriteLn('.');
 WriteLn('Current time: 00:00:00.');
 WriteLn('Work time:    00:00:00.');
 TextColor(Yellow);
 WriteLn('Esc=Break.');
 TextColor(LightBlue);
 WriteLn('Please waith...');
 WriteLn;
 TextColor(LightGray);
 Repeat
  TextColor(Red);
  Str(FilePos(InFile),WorkLine);
  While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
  GoToXY(24,WhereY-9);
  Write(WorkLine);
  GoToXY(16,WhereY+1);
  GetTime(Time.Hour,Time.Min,Time.Sec,Time.Year);
  If OldSecond<>Time.Sec Then
  Begin
   OldSecond:=Time.Sec;
   Str(FilePos(InFile)-OldPosition,WorkLine);
   OldPosition:=FilePos(InFile);
   While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
   Write(WorkLine);
  end;
  TextColor(Magenta);
  Str((FilePos(InFile)*100) Div FileSize(InFile),WorkLine);
  While Length(WorkLine)<3 Do WorkLine:=' '+WorkLine;
  GoToXY(1,WhereY+1);
  Write(Copy(WorkLine,1,3));
  GoToXY(15,WhereY+2);
  Write(TimeToLine(Time.Hour,Time.Min,Time.Sec));
  GoToXY(15,WhereY+1);
  Write(WorkTime);
  TextColor(LightGray);
  GoToXY(1,WhereY+4);
  If KeyPressed Then If ReadKey=Chr(27) Then
  Begin
   Close(InFile);
   Close(OutFile);
   SetFAttr(InFile,OldInAttribute);
   SetFAttr(OutFile,0);
   Erase(OutFile);
   Exit;
  end;
  Repeat
   BlockRead(InFile,Buffer,1,ReadCount);
   If IOResult<>0 Then
   Begin
    Repeat
     Write('Cannot read from the source file. Retry? (Y/N)');
     Answer:=UpCase(ReadKey);
     If (Answer='Y') Or (Answer='N') Then Break;
     GoToXY(1,WhereY);
     ClrEol;
    Until False;
    If Answer='N' Then
    Begin
     Close(InFile);
     Close(OutFile);
     SetFAttr(InFile,OldInAttribute);
     SetFAttr(OutFile,0);
     Erase(OutFile);
     Exit;
    end;
   end Else Break;
  Until False;
  If ReadCount=0 Then Break;
  HexLine:=HexLine+ByteToHex(Buffer);
  If Length(HexLine)=50 Then
  Begin
   WriteTarget('['+HexLine+']');
   HexLine:='';
  end;
 Until False;
 If HexLine<>'' Then WriteTarget('['+HexLine+']');
 WriteTarget('====================================================');
 Write(OutFile,Chr(26));
 OutError('Cannot write to target file');
 Close(InFile);
 Close(OutFile);
 SetFAttr(InFile,OldInAttribute);
 SetFAttr(OutFile,0);
 TextColor(Yellow);
 WriteLn('File: '+SourceFileName+' is succefully converted to: '+
 TargetFileName+'.');
 While KeyPressed Do;
 Repeat
  Randomize;
  TextColor(Random(15));
  GoToXY(1,25);
  Write('Please press any character or numeric key to continue...');
  GoToXY(1,25);
 Until KeyPressed;
 Answer:=ReadKey;
end;
{===========================================================================}
Procedure HexToBin;
Var
  InFile          : Text;
  OutFile         : File;
  OldInAttribute  : Word;
  OldOutAttribute : Word;
  Answer          : Char;
  HexLine         : String;
  WorkLine        : String;
  NormalSize      : LongInt;
  ErrorInteger    : Integer;
  TargetFileDT    : DateTime;
  OldSecond       : Byte;
  OldPosition     : LongInt;
  Buffer          : Byte;
  TargetTime      : LongInt;
  OutAttribute    : Byte;
  SourceCRC32     : LongInt;
 Procedure ErrorOut(Message : String);
 Begin
  Close(InFile);
  Close(OutFile);
  SetFAttr(InFile,OldInAttribute);
  SetFAttr(OutFile,0);
  Erase(OutFile);
  TextColor(Yellow);
  WriteLn('ERROR: '+Message+'.');
  Halt;
 end;
 Procedure CheckError(Message : String);
 Begin
  If IOResult=0 Then Exit;
  ErrorOut(Message);
 end;
 Function ReadSource : String;
 Var
   Line : String;
 Begin
  If EoF(InFile) Then ErrorOut('Cannot read from the source file');
  ReadLn(InFile,Line);
  CheckError('Cannot read from the source file');
  ReadSource:=Line;
 end;
Begin
 If (Pos('\',SourceFileName)>0) Or (Pos(':',SourceFileName)>0) Then
 Begin
  WriteLn('File name cannot include path.');
  Exit;
 end;
 Assign(InFile,SourceFileName);
 GetFAttr(InFile,OldInAttribute);
 SetFAttr(InFile,0);
 ReSet(InFile);
 If IOResult<>0 Then
 Begin
  SetFAttr(InFile,OldInAttribute);
  SetFAttr(OutFile,OldOutAttribute);
  WriteLn('Source file: '+SourceFileName+' does not exist');
  Exit;
 end;
 If ReadSource<>'BINARY HEXADECIMAL FILE.' Then
 ErrorOut('Invalid source file');
 If ReadSource<>'====================================================' Then
 ErrorOut('Invalid source file');
 WorkLine:=ReadSource;
 If Copy(WorkLine,1,11)<>'File name: ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,Length(WorkLine),1)<>'.' Then
 ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,Pos(':',WorkLine)+2,255);
 WorkLine:=Copy(WorkLine,1,Length(WorkLine)-1);
 If ParamCount=2 Then TargetFileName:=WorkLine;
 If (Pos('\',TargetFileName)>0) Or (Pos(':',TargetFileName)>0) Then
 Begin
  WriteLn('File name cannot include path.');
  Exit;
 end;
 Assign(OutFile,TargetFileName);
 GetFAttr(OutFile,OldOutAttribute);
 SetFAttr(OutFile,0);
 Answer:='Y';
 ReSet(OutFile);
 If IOResult=0 Then
 Begin
  Close(OutFile);
  TextColor(DarkGray);
  Repeat
   Write('File: '+TargetFileName+' is already exist. Over-write? (Y/N)');
   Answer:=UpCase(ReadKey);
   If Answer='N' Then
   Begin
    Close(InFile);
    SetFAttr(InFile,OldInAttribute);
    SetFAttr(OutFile,OldOutAttribute);
    Exit;
   end;
   GoToXY(1,WhereY);
   ClrEol;
   If Answer='Y' Then Break;
  Until False;
 end;
 ReWrite(OutFile,1);
 If IOResult<>0 Then
 Begin
  Close(InFile);
  SetFAttr(InFile,OldInAttribute);
  SetFAttr(OutFile,OldOutAttribute);
  WriteLn('Cannot open file: '+TargetFileName+' for write.');
  Exit;
 end;
 WorkLine:=ReadSource;
 If Copy(WorkLine,1,11)<>'File size: ' Then ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,12,255);
 If Copy(WorkLine,Length(WorkLine),1)<>'.' Then
 ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,1,Length(WorkLine)-1);
 Val(WorkLine,NormalSize,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 WorkLine:=ReadSource;
 If Copy(WorkLine,1,14)<>'File date is: ' Then
 ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,Pos(',',WorkLine)+2,255);
 Val(Copy(WorkLine,1,Pos(' ',WorkLine)-1),TargetFileDT.Day,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,Pos(' ',WorkLine)+1,255);
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='January' Then
 TargetFileDT.Month:=1 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='February' Then
 TargetFileDT.Month:=2 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='March' Then
 TargetFileDT.Month:=3 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='April' Then
 TargetFileDT.Month:=4 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='May' Then
 TargetFileDT.Month:=5 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='June' Then
 TargetFileDT.Month:=6 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='July' Then
 TargetFileDT.Month:=7 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='August' Then
 TargetFileDT.Month:=8 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='September' Then
 TargetFileDT.Month:=9 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='October' Then
 TargetFileDT.Month:=10 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='November' Then
 TargetFileDT.Month:=11 Else
 If Copy(WorkLine,1,Pos(' ',WorkLine)-1)='December' Then
 TargetFileDT.Month:=12 Else ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,Pos(' ',WorkLine)+1,255);
 If Copy(WorkLine,Length(WorkLine)-4,5)<>'year.' Then
 ErrorOut('Invalid source file');
 Val(Copy(WorkLine,1,4),TargetFileDT.Year,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 WorkLine:=ReadSource;
 If Copy(WorkLine,1,14)<>'File time is: ' Then
 ErrorOut('Invalid source file');
 If Copy(WorkLine,Length(WorkLine),1)<>'.' Then
 ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,15,8);
 Val(Copy(WorkLine,1,2),TargetFileDT.Hour,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 Val(Copy(WorkLine,4,2),TargetFileDT.Min,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 Val(Copy(WorkLine,7,2),TargetFileDT.Sec,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 WorkLine:=ReadSource;
 If Copy(WorkLine,1,20)<>'File attributes is: ' Then
 ErrorOut('Invalid source file');
 If Copy(WorkLine,Length(WorkLine),1)<>'.' Then
 ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,21,6);
 If Length(WorkLine)<>6 Then ErrorOut('Invalid source file');
 OutAttribute:=0;
 If Copy(WorkLine,1,1)='R' Then OutAttribute:=OutAttribute+ReadOnly Else
 If Copy(WorkLine,1,1)<>' ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,2,1)='H' Then OutAttribute:=OutAttribute+Hidden Else
 If Copy(WorkLine,2,1)<>' ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,3,1)='S' Then OutAttribute:=OutAttribute+SysFile Else
 If Copy(WorkLine,3,1)<>' ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,4,1)='V' Then OutAttribute:=OutAttribute+VolumeID Else
 If Copy(WorkLine,4,1)<>' ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,5,1)='D' Then OutAttribute:=OutAttribute+Directory Else
 If Copy(WorkLine,5,1)<>' ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,6,1)='A' Then OutAttribute:=OutAttribute+Archive Else
 If Copy(WorkLine,6,1)<>' ' Then ErrorOut('Invalid source file');
 WorkLine:=ReadSource;
 If Copy(WorkLine,1,13)<>'CRC-32 Code: ' Then ErrorOut('Invalid source file');
 If Copy(WorkLine,Length(WorkLine),1)<>'.' Then ErrorOut('Invalid source file');
 WorkLine:=Copy(WorkLine,14,255);
 WorkLine:=Copy(WorkLine,1,Length(WorkLine)-1);
 Val(WorkLine,SourceCRC32,ErrorInteger);
 If ErrorInteger<>0 Then ErrorOut('Invalid source file');
 If ReadSource<>'====================================================' Then
 ErrorOut('Invalid source file');
 CRCValue:=LongInt($FFFFFFFF);
 OldPosition:=0;
 OldSecond:=0;
 GetTime(StartTime.Hour,StartTime.Min,StartTime.Sec,Time.Year);
 TextColor(Brown);
 WriteLn('Conversion process.');
 TextColor(Green);
 Write('From: ');
 TextColor(Blue);
 Write(Copy(SourceFileName,1,72));
 TextColor(Green);
 WriteLn('.');
 Write('  To: ');
 TextColor(Blue);
 Write(Copy(TargetFileName,1,72));
 TextColor(Green);
 WriteLn('.');
 Str(NormalSize,WorkLine);
 While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
 Write('Expected file size is: ');
 TextColor(Blue);
 Write(WorkLine);
 TextColor(Green);
 WriteLn(' bytes.');
 Write('Current file position: ');
 TextColor(Red);
 Write('0000000000');
 TextColor(Green);
 WriteLn('.');
 Write('Current speed: ');
 TextColor(Blue);
 Write('0000000000');
 TextColor(Green);
 WriteLn(' bytes per second.');
 TextColor(Yellow);
 Write('000%');
 TextColor(Green);
 WriteLn(' Complete.');
 Write('Start time:   ');
 TextColor(Magenta);
 Write(TimeToLine(StartTime.Hour,StartTime.Min,StartTime.Sec));
 TextColor(Green);
 WriteLn('.');
 WriteLn('Current time: 00:00:00.');
 WriteLn('Work time:    00:00:00.');
 WriteLn('CRC code: 0000000000.');
 TextColor(Yellow);
 WriteLn('Esc=Break.');
 TextColor(LightBlue);
 WriteLn('Please waith...');
 WriteLn;
 TextColor(LightGray);
 Repeat
  TextColor(Red);
  Str(FilePos(OutFile),WorkLine);
  While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
  GoToXY(24,WhereY-10);
  Write(WorkLine);
  GoToXY(16,WhereY+1);
  GetTime(Time.Hour,Time.Min,Time.Sec,Time.Year);
  If OldSecond<>Time.Sec Then
  Begin
   OldSecond:=Time.Sec;
   Str(FilePos(OutFile)-OldPosition,WorkLine);
   OldPosition:=FilePos(OutFile);
   While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
   Write(WorkLine);
  end;
  TextColor(Magenta);
  Str((FilePos(OutFile)*100) Div NormalSize,WorkLine);
  While Length(WorkLine)<3 Do WorkLine:=' '+WorkLine;
  GoToXY(1,WhereY+1);
  Write(Copy(WorkLine,1,3));
  GoToXY(15,WhereY+2);
  Write(TimeToLine(Time.Hour,Time.Min,Time.Sec));
  GoToXY(15,WhereY+1);
  Write(WorkTime);
  Str(CRCValue,WorkLine);
  While Length(WorkLine)<10 Do WorkLine:=' '+WorkLine;
  TextColor(Red);
  GoToXY(11,WhereY+1);
  Write(WorkLine);
  TextColor(LightGray);
  GoToXY(1,WhereY+4);
  If KeyPressed Then If ReadKey=Chr(27) Then
  Begin
   Close(InFile);
   Close(OutFile);
   SetFAttr(InFile,OldInAttribute);
   SetFAttr(OutFile,0);
   Erase(OutFile);
   Exit;
  end;
  HexLine:=ReadSource;
  If HexLine='====================================================' Then
  Break;
  If Length(HexLine)>52 Then ErrorOut('Invalid source file');
  If (Copy(HexLine,1,1)<>'[') Or (Copy(HexLine,Length(HexLine),1)<>']') Then
  ErrorOut('Invalid source file');
  HexLine:=Copy(HexLine,2,Length(HexLine)-2);
  If ((Length(HexLine) Div 2)*2)<>Length(HexLine) Then
  ErrorOut('Invalid source file');
  While HexLine<>'' Do
  Begin
   Val('$'+Copy(HexLine,1,2),Buffer,ErrorInteger);
   If ErrorInteger<>0 Then ErrorOut('Invalid source file');
   CRCValue:=Crc32HexTable[Byte(CRCValue) XOr Buffer] XOr (CRCValue Div $100);
   BlockWrite(OutFile,Buffer,1);
   CheckError('Fail in writing to the target file');
   Delete(HexLine,1,2);
  end;
 Until False;
 If NormalSize<>FileSize(OutFile) Then ErrorOut('Invalid source file');
 If CRCValue<>SourceCRC32 Then ErrorOut('Bad source file CRC-code.');
 PackTime(TargetFileDT,TargetTime);
 SetFTime(OutFile,TargetTime);
 Close(InFile);
 Close(OutFile);
 SetFAttr(InFile,OldInAttribute);
 SetFAttr(OutFile,OutAttribute);
 TextColor(Yellow);
 WriteLn('File: '+SourceFileName+' is succefully converted to: '+
 TargetFileName+'.');
 While KeyPressed Do;
 Repeat
  Randomize;
  TextColor(Random(15));
  GoToXY(1,25);
  Write('Please press any character or numeric key to continue...');
  GoToXY(1,25);
 Until KeyPressed;
 Answer:=ReadKey;
end;
{===========================================================================}
Procedure Help;
Begin
  WriteLn('Usage: BinHex SourceFile.Ext TargetFile.Ext BIN|HEX');
  WriteLn('BIN - Convert binary to hexadecimal.');
  WriteLn('HEX - Convert hexadecimal to binary.');
  Halt;
end;
{===========================================================================}
Begin
 WriteLn;
 CheckBreak:=False;
 CheckEOF:=False;
 DirectVideo:=False;
 CheckSnow:=True;
 Window(1,1,80,25);
 TextBackGround(Black);
 TextColor(LightGray);
 ClrScr;
 WriteLn;
 TextColor(DarkGray);
 WriteLn('Text binary hexadecimal convertor.');
 TextColor(Yellow);
 WriteLn('****************************************');
 TextColor(Green);
 WriteLn('(C) Copyright Sandul Yura Valentinovich.');
 WriteLn('(R) Monday, 8 July 2002 year.');
 WriteLn('All rights reserved.');
 TextColor(Red);
 WriteLn('*** The FreeWare ***');
 TextColor(Yellow);
 WriteLn('****************************************');
 WriteLn;
 TextColor(LightGray);
 If (Lo(DOSVersion)<3) And (Hi(DOSVersion)<30) Then
 Begin
  WriteLn('This program required the DOS version 3.30 or later.');
  Exit;
 end;
 If Crc32HexTable[1]=0 Then MakeCrc32Tables;
 If (NormalLine(ParamStr(ParamCount))<>'BIN') And
 (NormalLine(ParamStr(ParamCount))<>'HEX') Then Help;
 If (ParamCount=2) And (NormalLine(ParamStr(ParamCount))='BIN') Then Help;
 SourceFileName:=NormalLine(ParamStr(1));
 TargetFileName:=NormalLine(ParamStr(2));
 If NormalLine(ParamStr(ParamCount))='BIN' Then BinToHex Else
 If NormalLine(ParamStr(ParamCount))='HEX' Then HexToBin Else
 WriteLn('Incorrect parameter.');
 TextColor(LightGray);
 WriteLn;
end.
{===========================================================================}