/* FIXOBJ : cleanup routine for Amiga Object files (c) 1986 John Hodgson

   Note : FIXOBJ attempts to remove last record filler by truncating all
   information past the last HUNK_END, providing the HUNK_END sequence
   is within the last 128-byte record. The algorithm used here could be
   thwarted if end-of-file filler happens to contain a bogus HUNK_END, or
   if a particular load file ends with anything besides HUNK_END.

   Format: FIXOBJ <source-file> <dest-file>.
 
   Note : Due to a bug in the RAM: device, do not attempt to FIXOBJ
          the source file if residing in ramdisk. (as of 1.1)

   Rev 1.1 : Corrected for use with Aztec "C" */

#include <stdio.h>

/* constant definitions */

#define REVHUNK_END (0xf203)
#define BYTEBITS (8)
#define ENDOFFSET (2)

main(argc,argv)
int argc;
char *argv[];
{
  FILE *rdptr,*wrtptr,*fopen();
  long pos,ctr,ftell();
  unsigned short media;

  if (argc!=3) {
    printf("Usage : fixobj srcfile destfile\n");
    exit(0);
  }
  if ((rdptr=fopen(argv[1],"r"))==NULL) {
    printf("Error opening file %s for reading.\n",argv[1]);
    exit(0);
  }

/* search last record backwards for HUNK_END combo in reverse order */

  media=0;
  for (ctr=-1;ctr>-128;ctr--) {

    /* simulate a 16-bit shift register for easy hunk check */

    media<<=BYTEBITS;
    fseek(rdptr,ctr,ENDOFFSET);
    media|=getc(rdptr);
    if (media == REVHUNK_END) break;
  }
  if ((media!=REVHUNK_END) || ctr==-2) {
    (ctr==-2) ? printf("No corrections made!\n"):
                printf("Invalid load format!\n");
    fclose(rdptr);
    exit(0);
  }
  if ((wrtptr=fopen(argv[2],"w"))==NULL) {
    printf("Error opening file %s for writing.\n",argv[2]);
    fclose(rdptr);
    exit(0);
  }

/* duplicate file up to HUNK_END, inclusive */

  pos=ftell(rdptr)+1;
  rewind(rdptr);

  for (ctr=0;ctr<pos;ctr++) putc(getc(rdptr),wrtptr);

  fclose(rdptr); fclose(wrtptr);
}

