// HEXPAT.C

// Patch Interrupt-Vectors in HEX-File

#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "e:\l\mylib\source\fil.c"

INT error=0;

VOID exit_fn(VOID)
{
  if (error)
  {
    printf("\nPatch HEX-File \n"
           "usage: HEXPAT name tt ff\n"
           "       name....source <name>.HEX\n"
           "       tt......destination address msb (hex)\n"
           "       ff......source address msb (hex)\n"
           "       creates patched file <name>.HEY\n"
          );
  }
}

CHAR HEXDIGITS[] = "0123456789ABCDEF";

INT ishex(UCHAR hex)
{
  return strchr(HEXDIGITS,toupper(hex))!=0;
}

UCHAR hex2bin(UCHAR hi, UCHAR lo)
{
  return (strchr(HEXDIGITS,toupper(hi)) - HEXDIGITS) * 16 +
         (strchr(HEXDIGITS,toupper(lo)) - HEXDIGITS);
}

UINT bin2hex(UCHAR bin)
{
  return HEXDIGITS[bin >> 4]*256+HEXDIGITS[bin & 0x0f];
}

/* process_HEX
 *************
 * l HEX-line
 * f outpu-file
 * pass  0..analyze and write to textfile, fill buffer
 *       1..write to binary-file
 */

INT process_HEX(CHAR *l,CHAR *to, CHAR *from)
{
  // Interpretierte Zeile
  // HEX-Zeile
  printf("%s\n",l);

  if (l[0]!=':')
  {
    return 1;
  }

  if (!((l[7]=='0') && ((l[8]=='0') || (l[8]=='1'))))
  {
    return 2;
  }

  if (l[8]=='1') /* Ende-Record */
  {
    /* prfen der restlichen Bestandteile des ENDE-Records */
    if (strcmp(&l[1],"00000001FF")!=0)
    {
      return 3;
    }
    else
      return 0;
  }

  if (memcmp(from,&l[3],2)==0)
  {
    memcpy(&l[3],to,2);

    UINT  chk=0;

    for (int i=1; i<(strlen(l)-2); i++,i++)
      chk+=hex2bin(l[i],l[1+i]);
    chk = (0-chk)%256;
    l[i] = bin2hex(chk>>4);
    l[i+1] = bin2hex(chk&0x0f);
  }
  return 0;
}

VOID main(INT argc, CHAR *argv[])
{
  atexit(exit_fn);

  if (argc!=4)
  {
    error=1;
    exit(EXIT_FAILURE);
  }

  if (!(ishex(argv[2][0]) && ishex(argv[2][1]) &&
        ishex(argv[3][0]) && ishex(argv[3][1])
     ))
  {
    printf("<to> and <from>-fields in hex-Notation\n");
    exit(EXIT_FAILURE);
  }

  // Delete destination
  // ***********************************************
  FILE *fdst=NULL; // destination-file
  CHAR dateiHEY[128];
  strcpy(dateiHEY, argv[1]);
  strcat(dateiHEY, ".HEY");
  fdst = fopen(dateiHEY,"wt");
  if (fdst==NULL)
  {
    printf("File %s cannot be created\n",dateiHEY);
    fclose (fdst);
    exit(EXIT_FAILURE);
  }

  // Open file to be converted
  // ***********************************************
  FILE *fsrc=NULL; // source-file
  CHAR dateiHEX[128];
  strcpy(dateiHEX, argv[1]);
  strcat(dateiHEX, ".HEX");
  fsrc = fopen(dateiHEX,"rt");

  if (fsrc==NULL)
  {
    printf("File %s does not exist\n",dateiHEX);
    fclose (fsrc);
    exit(EXIT_FAILURE);
  }

  for (;;)
  {
    CHAR line[80];
    if (fscanf(fsrc,"%s",line)==EOF)
      break;
    else
    {
      if (strlen(line))
      {
        INT error=process_HEX(line,argv[2],argv[3]);
        if (error)
        {
          printf("error:%i\n",error);
          exit(EXIT_FAILURE);
        }
        if (fprintf(fdst,"%s\n",line)!=strlen(line)+1)
        {
          printf("Disk full\n");
          goto end;
        }
      }
    }
  }
end:
  fclose(fsrc);
  fclose(fdst);
  exit(EXIT_SUCCESS);
}

