PROGRAM comhex;

{ konvertiert COM-Files in Intel-HEX-Files }

CONST hexziffer : ARRAY [0..15] OF char = '0123456789ABCDEF';
      maxpuffer = 64;

TYPE  hexzahl   = STRING [4];

VAR   filename  : STRING [14];
      comfile   : FILE;
      hexfile   : text;
      size      : integer;
      checksum  : integer;
      puffer    : ARRAY [0..8191] OF byte;
      textpuf   : ARRAY [1..maxpuffer, 0..3] OF STRING [75];
      seite     : integer;
      max, low  : integer;

{====================================================================}

FUNCTION hexbyte (x : integer) : hexzahl;

BEGIN { hexbyte }
  hexbyte := hexziffer [(lo (x) SHR 4)]+hexziffer [(lo (x) AND 15)]
END;  { hexbyte }

{====================================================================}

FUNCTION hexword (x : integer) : hexzahl;

BEGIN { hexword }
  hexword := hexbyte (hi (x))+hexbyte (lo (x))
END;  { hexword }

{====================================================================}

PROCEDURE schreibseite (nummer : integer);

VAR i, j, b : integer;
    line    : STRING [75];

BEGIN { schreibseite }
  FOR i := 0 TO 3 DO
    BEGIN
      line := '20'+hexword ($80+((nummer SHL 7)+(i SHL 5)))+'00';
      checksum := 32+((nummer+1) SHR 1) +
                  (i SHL 5)+((nummer+1) AND 1) SHL 7;
      FOR j := 0 TO 31 DO
        BEGIN
          b := puffer [((seite-low-1) SHL 7)+(i SHL 5)+j];
          line := line+hexbyte (b);
          checksum := checksum+b
        END;
      textpuf [seite-low, i] := ':'+line+hexbyte (256-lo (checksum))
    END
END;  { schreibseite }

{====================================================================}

PROCEDURE schreibpuffer (x : integer);

VAR i, j : integer;

BEGIN { schreibpuffer }
  FOR i := 1 TO x DO
    FOR j := 0 TO 3 DO
      writeln (hexfile, textpuf [i, j])
END;  { schreibpuffer }

{====================================================================}

BEGIN { comhex }
  write ('Name des Programms : ');
  readln (filename);
  IF pos ('.', filename) <> 0
    THEN
      filename := copy (filename, 1, pos ('.', filename)-1);
  assign (comfile, filename+'.COM');
  {$I-}
  reset (comfile);
  {$I+}
  IF ioresult = 0
    THEN
      BEGIN
        assign (hexfile, filename+'HEX');
        rewrite (hexfile);
        size := filesize (comfile);
        max := maxpuffer;
        low := 0;
        WHILE low < size DO
          BEGIN
            IF size-low < max
              THEN
                max := size-low;
            writeln (low:5, size:5, max:5);
            blockread (comfile, puffer, max);
            FOR seite := 1+low TO low+max DO
              schreibseite (seite);
            schreibpuffer (max);
            low := low+max;
          END;
        close (comfile);
        writeln (hexfile, ':0000000000');
        close (hexfile)
      END
END.  { comhex }

