[comp.sys.m68k.pc] S-record generator

Mike.Blackwell@ROVER.RI.CMU.EDU (09/11/90)

Here's a program I whipped up a while ago which let me compile and link
68030 programs on a Sun-3, then download them to a stand alone 68030
system in S-record format. These days, you should be using something
like VxWorks instead, it will make your life much simpler... Should be
enough to get you started, though.

		Mike Blackwell, Robotics Institute, Carnegie Mellon

---------- cut here ----------

/************************************************************************/
/*									*/
/* srec.c  --  Convert a.out files to Motorola S-record format.		*/
/*									*/
/* Link code modules with something like:				*/
/* test.run: $(OBJS)							*/
/*           ld -N -e _Start -s -T 8000 $(OBJS) -o test.i		*/
/*           srec test.i > test.run					*/
/*									*/
/* HISTORY								*/
/*									*/
/* 10-Jun-88  Mike Blackwell (mkb) at Carnegie Mellon University	*/
/*	Created.							*/
/*									*/
/************************************************************************/

#include <stdio.h>
#include <a.out.h>

#define TEXTPOS(x)	sizeof(x)
#define DATAPOS(x)	TEXTPOS(x) + x.a_text

main(argc, argv)
int argc;
char *argv[];
{
    long Taddr, Daddr;			/* Starting addrs of text and data */
    long Tsize, Dsize;			/* Size of text and data segs */
    struct exec filhdr;
    FILE *afp;				/* File descriptor of a.out file */

    if (argc == 2) {
	if ((afp = fopen (argv[1], "r")) == NULL) {
	    fprintf(stderr, "Can't open input file %s\n", argv[1]);
	    exit(1);
	}
    } else {
	fprintf(stderr, "Usage: %s file\n", argv[0]);
	exit(1);
    }

    /* Get the header information. */
    if (fread (&filhdr, sizeof(struct exec), 1, afp) != 1) {
	fprintf(stderr, "Bad format in input file %s\n", argv[1]);
	exit(1);
    }

    /* Check  the magic number. */
    fprintf(stderr, "Machine type = %d\n", filhdr.a_machtype);
    fprintf(stderr, "Magic number = 0%o\n", filhdr.a_magic);
    if (filhdr.a_magic != OMAGIC) {
	fprintf(stderr, "Bad magic number (0%o) in input file %s\n", filhdr.a_magic, argv[1]);
	exit(1);
    }

    /* Record the base loading address. */
    Taddr = filhdr.a_entry;
    Tsize = filhdr.a_text;
    Daddr = Taddr + Tsize;
    Dsize = filhdr.a_data;

    /* Output the records. */
    write_srec("S0", 0, 0, 0);
    outbin(afp, Taddr, Tsize);			/* Text segment */
    fseek(afp, DATAPOS(filhdr), 0);		/* Seek to data */
    outbin(afp, Daddr, Dsize);			/* Data segment */
    write_srec("S9", Taddr, 0, 0);

    fprintf(stderr, "Text segment = %06x, Size = %x\n", Taddr, Tsize);
    fprintf(stderr, "Data segment = %06x, Size = %x\n", Daddr, Dsize);
    fprintf(stderr, "Start address = %06x\n", Taddr);
}


/* Procedure that puts out records for a particular segment. */
outbin(afp, addr, size)
FILE *afp;
long addr;
int size;
{
    int i, n;
    char data[16];

    for (i = 0; i < size; i += 16) {
	n = ((i + 16) <= size) ? 16 : size - i;
	fread(data, 1, n, afp);
	write_srec("S2", addr + i, n, data);
    }
}


write_srec(stype, addr, len, data)
char *stype, *data;
int addr, len;
{
    int chk, i;

    printf("%2s%02X%06X", stype, len + 4, addr);
    chk = (len + 4);
    chk += ((addr >> 16) & 0xFF) + ((addr >> 8) & 0xFF) + (addr & 0xFF);
    for (i = 0; i < len; i++) {
	printf("%02X", data[i] & 0xFF);
	chk += data[i] & 0xFF;
    }
    printf("%02X\n", ~chk & 0xFF);
}