/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */

#ifndef lint
static char    *rcsid = "$Header:loadboot.c 12.0$";
#endif



#include <dos.h>
#include <stdio.h>
#include <io.h>
#include <malloc.h>
#include <sys/types.h>
#include "pcparam.h"
#include "rb.h"
#include "aout.h"
#include "abios_st.h"
#include "dio.h"


extern char far *buff_dio;
extern u_short *dbugptr;


static int compare(char far *, char far *, int);

/* following must be less than 32k */
#define XFERBUF (1024 * 16)		/* use 16K chunks */

u_long
loadboot(fd)
	u_short         fd;
{
	long            block, addr = 0;
	u_short         xblock;
	int             r;
	char far       *cp;
	char far       *cp2;
	struct AOUT     adot;
	u_short		bytes;

	dos_lseek(fd, 0L, 0);	/* to start of the file */

	block = filelength(fd) - sizeof(struct AOUT);

	cp = (char *) &adot;
	if (dos_read(fd, cp, sizeof(struct AOUT), &r) != 0 || r != sizeof(struct AOUT))
		pcpanic("Error reading exec header");


	adot.a_entry = exchl((long) adot.a_entry) & 0x00ffffff;
	adot.a_text = exchl((long) adot.a_text);
	adot.a_data = exchl((long) adot.a_data);
	adot.a_bss = exchl((long) adot.a_bss);
	adot.a_magic = exchl((long) adot.a_magic);
	adot.a_syms = exchl((long) adot.a_syms);
	adot.a_trsize = exchl((long) adot.a_trsize);
	adot.a_drsize = exchl((long) adot.a_drsize);

	if (adot.a_magic != 0407 && adot.a_magic != 0410 && adot.a_magic != 0413)
	{
		printf("\nBad Magic number 0%o \n", adot.a_magic);
		exit(-1);
	}
	addr = adot.a_entry;

	cp = buff_dio;
	cp2 = cp + XFERBUF;	/* verify buffer */

	while (block > 0L)
	{
		if (block > XFERBUF)
			xblock = XFERBUF;
		else
			xblock = (u_short) block;

		if (dos_read(fd, cp, xblock, &r) != 0 || r != xblock)
		{
			printf("\nError reading Unix Binary, DOS error = %d, xblock = %d", r, xblock);
			exit(-1);
		}
		if (moveout(addr, (char far *) cp, xblock) < 0)
			pcpanic("Error writing bootfile to Unix");
		
		if (movein(addr, (char far *) cp2, xblock) < 0)
			pcpanic("Error verifying bootfile from Unix");

		if ((r=compare(cp,cp2,xblock)) > 0)
			printf("loadboot: verify failed at %lx - expected %x, got %x\n", addr+r-1, cp[r-1], cp2[r-1]);

		block -= xblock;
		addr += xblock;
		printf(".");
	}
	printf("\n");

	return ((u_long) adot.a_entry);
}


static int
compare(cp, cp2, length)
char far *cp, far *cp2;
int length;
{
	register char far *rcp = cp, far *rcp2 = cp2;
	while (--length >= 0)
		if (*rcp++ != *rcp2++)
			return(rcp-cp);
	return(0);
}
