home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assemblers / cas.lha / reloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-15  |  2.9 KB  |  104 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. typedef unsigned char byte;
  7. typedef unsigned int word;
  8.  
  9. byte Nib(int X) {
  10.    if (X >= '0' && X <= '9') return ((byte)(X - '0'));
  11.    if (X >= 'a' && X <= 'f') return ((byte)(X - 'a' + 10));
  12.    if (X >= 'A' && X <= 'F') return ((byte)(X - 'A' + 10));
  13.    fprintf(stderr, "Bad hexadecimal digit in input\n");
  14.    exit(1);
  15. }
  16.  
  17. byte CheckSum;
  18. byte GetHex(FILE *InF) {
  19.    int A, B; byte Bt;
  20.    A = fgetc(InF); B = fgetc(InF);
  21.    if (A == EOF || B == EOF) {
  22.       fprintf(stderr, "Unexpected EOF.\n"); exit(1);
  23.    }
  24.    Bt = Nib(A) << 4 | Nib(B);
  25.    CheckSum = (CheckSum + Bt)&0xff; return Bt;
  26. }
  27.  
  28. word GetWord(FILE *InF) {
  29.    word A, B;
  30.    A = GetHex(InF); B = GetHex(InF);
  31.    return (A << 8) | B;
  32. }
  33.  
  34. void PutHex(FILE *OutF, byte Ch) {
  35.    fprintf(OutF, "%02x", Ch); CheckSum = (CheckSum + Ch)&0xff;
  36. }
  37.  
  38. void PutWord(FILE *OutF, word W) {
  39.    PutHex(OutF, (byte)(W >> 8)); PutHex(OutF, (byte)(W&0xff));
  40. }
  41.  
  42. void Relocate(word Offset, FILE *InF, FILE *OutF) {
  43.    int Ch, I;
  44.    byte Size, Mark; word Addr;
  45.    byte Buffer[0x10];
  46.    while (1) {
  47.       do {
  48.          Ch = fgetc(InF);
  49.          if (Ch == EOF) { fprintf(stderr, "Unexpected EOF.\n"); exit(1); }
  50.       } while (Ch != ':');
  51.       CheckSum = 0;
  52.       Size = GetHex(InF); Addr = GetWord(InF) + Offset; Mark = GetHex(InF);
  53.       for (I = 0; I < Size; I++) Buffer[I] = GetHex(InF);
  54.       (void)GetHex(InF); (void)fgetc(InF);
  55.       if (CheckSum != 0) {
  56.          fprintf(stderr, "Bad checksum.\n"); exit(1);
  57.       }
  58.       fputc(':', OutF);
  59.       CheckSum = 0;
  60.       PutHex(OutF, Size); PutWord(OutF, Addr); PutHex(OutF, Mark);
  61.       for (I = 0; I < Size; I++) PutHex(OutF, Buffer[I]);
  62.       PutHex(OutF, (byte)-CheckSum);
  63.       fputc('\n', OutF);
  64.       if (Mark) break;
  65.    }
  66. }
  67.  
  68. word atoh(char *S) {
  69.    word Val;
  70.    for (Val = 0; *S != '\0'; S++) {
  71.       if (isdigit(*S)) Val = (Val << 4) | (*S - '0');
  72.       else if (isxdigit(*S)) Val = (Val << 4) | (tolower(*S) - 'a' + 10);
  73.       else return 0;
  74.    }
  75.    return Val;
  76. }
  77.  
  78. char *Convert(char *Path) {
  79.    static char *S; char *T;
  80.    S = (char *)malloc(strlen(Path) + 1);
  81.    if (S == 0) return 0;
  82.    strcpy(S, Path);
  83.    for (T = S + strlen(S); T > S; T--)
  84.       if (T[-1] == '.') break;
  85.    if (T == S) { free(S); return 0; }
  86.    *T++ = 'h', *T++ = 'x', *T = '\0';
  87.    return S;
  88. }
  89.  
  90. main(int ArgC, char **ArgV) {
  91.    word Offset; FILE *InF, *OutF; char *OutName;
  92.    if (ArgC != 3) { printf("Usage: relocate Offset Input.\n"); exit(0); }
  93.    Offset = atoh(ArgV[1]);
  94.    if (Offset == 0) printf("Zero offset/bad offset specified.\n");
  95.    OutName = Convert(ArgV[2]);
  96.    if (OutName == 0) { printf("%s not of form *.hex.\n", ArgV[2]); exit(0); }
  97.    InF = fopen(ArgV[2], "r");
  98.    if (InF == 0) { printf("Cannot open %s.\n", ArgV[2]); exit(0); }
  99.    OutF = fopen(OutName, "w");
  100.    if (OutF == 0) { printf("Cannot open %s.\n", OutName); exit(0); }
  101.    Relocate(Offset, InF, OutF);
  102.    fclose(InF), fclose(OutF);
  103. }
  104.