/* dload.c -- loader program for monitor 
 * copyright (c) 1984  American Information Systems Corporation
 *  Dock Williams
 *  March, 1984
 *
 */

#include "3200config.h"

extern char loadmsg[];
extern char badmemchk[];

dload()

/* dload()
 * 
 *  read in data over the auxilliary port and load into memory
 *  as follows:
 *  wait for sync characters AISL
 *  read in four bytes for load address (MSB first)
 *  read in four bytes for size (MSB first)
 *  read in four bytes for checksum value (MSB first)
 *  load size bytes of data starting at load address and
 *      calculate a checksum as the data is read in
 *  compare calculated checksum with received checksum
 *  print a message if checksums are unequal
 *  recalculate checksum now looking at data as it is in memory
 *  compare recalculated checksum with received checksum and 
 *  print a message if they are unequal
 *  finally print the load address and the size of the loaded image
 */

{
	register char c, *wrtaddr;
	register int i, chksum;
	int loadaddr, chksumval, numbytes;

	extern char loaddmsg[];
	extern char badtxchk[];
	extern char badmemechk[];
	extern char loadaddrmsg[];
	extern char sizemsg[];

	printf("%s", loadmsg);

	*((char*) (U_SETOUT+UART_MAPENABLE)) = DTR1;	/* turn on DTR */

resync:
	if (quitchk()) goto out;
	if (inc_aux() != 'A') goto resync;
	if (inc_aux() != 'I') goto resync;
	if (inc_aux() != 'S') goto resync;
	if (inc_aux() != 'L') goto resync;

	loadaddr = getint();
	if (quitchk()) goto out;
	outquick('.');
	numbytes = getint();
	if (quitchk()) goto out;
	outquick('.');
	chksumval = getint();
	if (quitchk()) goto out;
	outquick('.');

	chksum = 0;
	wrtaddr = (char *)loadaddr;
	for (i = 0; i < numbytes; i++) {
	    c = inc_aux();
	    if (quitchk()) goto out;
	    chksum += (c & 0x000000ff);
	    *wrtaddr++ = c;
	}

	*((char*) (U_CLROUT+UART_MAPENABLE)) = DTR1;	/* turn off DTR */

	if (chksum != chksumval)
	    {
	    printf("%s", badtxchk);
	    return;
	    }

	chksum = 0;
	wrtaddr = (char *)loadaddr;
	for (i = 0; i < numbytes; i++) {
	    chksum += (*wrtaddr++ & 0x00ff);
	}
	if (chksum != chksumval)
	    printf("%s", badmemchk);

	printf("%s%x%s%x\n", loadaddrmsg, loadaddr, sizemsg, numbytes);
	return;
out:
	*((char*) (U_CLROUT+UART_MAPENABLE)) = DTR1;	/* turn off DTR */
	printf("\nLoader Aborted\n");
}

getint()

/* getint()
 *
 * get an integer value (32 bits) by succesively reading 
 * the auxilliary port; most significant byte received first
 */
{
    register char c;
    register int i,x;

    x = 0;
    for(i = 0; i < 4; i++) {
	c = inc_aux();
	x = (x<<8) | (c & 0x000000ff);
    }
    return(x);
}
