/* profile.c - profiles execution of a program
   usage profiler progname progargs1 .. progargsn
   uses the time of day interrupt to sample the instruction pointer
   18 times a second.
*/
#define AZTEC		/* uses aztec c 8086 compiler */
#ifdef AZTEC
#define forkv fexecv	/* use the lattice library name */
/* note that the aztec lib function
 * wants the extension on the file name,
 * but lattice only wants the 'run name'
 */

#endif
#include <stdio.h>
#include <fcntl.h>
/* the ip_array is 16K long, which means that the resolution of
   the profiler is to 4 bytes
 */
#define IP_ARRAY_SIZE 16384
unsigned int ip_array[IP_ARRAY_SIZE];

extern unsigned instruction_pointer;
extern unsigned program_segment;

unsigned registers[4];

main(argc,argv)
int argc;
char *argv[];
{
	int r;	/* register file */
	char *name;
	char *extension;
	if (argc == 1)
	{
		usage();
		exit();
	}
	/* predict what segments are going to be */
	extension = index(*(++argv),'.') + 1;
	if (!strncmp(extension,"com",3))
		forkv("regs.com",NULL);
	else if (!strncmp(extension,"exe",3))
		forkv("regs.exe",NULL);
	else
		exit();
	if (-1 == (r = open("register",O_RDONLY)))
	{
		fprintf(stderr,"cant find register file\n");
		exit();
	}
	read(r,registers,8);	/* read the registers in */
	close(r);				/* close the file		*/
	unlink("register");
	/* otherwise we're going to try . . . */
	int_setup();	/* start sampling	*/
	name = *argv; /* name to execute */
	forkv(name,argv);
	int_restore();	/* stop sampling	*/
	display_results();
	exit();
}

display_results()
{
	register unsigned int i;
	for (i = 0; i < IP_ARRAY_SIZE; i++)
		if (ip_array[i])
			printf("%04x : %u\n",(i << 2),ip_array[i]);
}
/*
	logs the instruction pointer to the ip array
*/

ip_log()
{
	if (program_segment == registers[0])
		ip_array[(instruction_pointer >> 2)]++;
}
char *usage_txt[] =
{
	"profile.com - profiles execution of a program\r\n",
    "usage profile progname progargs1 .. progargsn\r\n",
	NULL
};
usage()
{
#define STDERR 2
	register char **up;
	up = usage_txt;
	while (*up)
	{
		write(STDERR,*up,strlen(*up));
		++up;
	}
}

