AUSAM/source/mac/mac/mac00.c

Compare this file to the similar file:
Show the results in this format:

#include	"mac.h"
#include	"mac.x"

char	tmp[16]		"/tmp/mac";		/* Space for tmp file name */
char	*arg[8];				/* Exec arg list */

main(argc, argv)
char	*argv[ ];
{
	register int nfile;
	register int pid;
	register int fd;
	register int i;
	register char *r;

	nfile = 0;					/* No args seen */
	OPTION('h') = TRUE;				/* default */
	for (i=1; i<argc; i++)  {
		p = argv[i];
		if (*p == '-')  {
			/* Option flag */
			p++;
			if (*p == 'h' || *p == 'o' || *p == 'b')  {
				OPTION('h') = FALSE;
				OPTION('o') = FALSE;
				OPTION('b') = FALSE;
				}

			OPTION(*p) = TRUE;
			}
		else
			/* File-name */
			arg[nfile++] = p;
		}

	if (nfile > 2)  {
		/* object file needed */
		OPTION('a') = TRUE;
		OPTION('d') = FALSE;
		OPTION('l') = FALSE;
		}

	if (OPTION('l'))
		/* listing - no code dump */
		OPTION('d') = FALSE;
	else
		if (OPTION('h') || OPTION('o') || OPTION('b'))
			OPTION('d') = TRUE;

	if (OPTION('n'))  {
		OPTION('d') = FALSE;
		OPTION('l') = FALSE;
		}


	if (nfile < 1)  {
		printf("Usage: %s opcode-file [source] [object]\n", argv[0]);
		exit(1);
		}

	/*
	 *   Try to open r-file.
	 *   try 'file' first, and if that fails,
	 *   try '/usr/lib/mac/file'.
	 */
	for (i=0; i<13; i++)
		buf[i] = "/usr/lib/mac/"[i];
	r = arg[0];
	for (i=13; *r != '\0'; i++)
		buf[i] = *r++;
	fd = open(&buf[13], 0);
	if (fd < 0)
		/* try lib */
		fd = open(&buf[0], 0);

	if (fd < 0)  {
		synerr("Can't open r-file");
		exit(1);
		}

	if (nfile > 1 && fopen(arg[1], &ibuf) < 0)  {
		printf("Can't find source file\n");
		exit(1);
		}


	/*
	 *   Make temp file.
	 */
	pid = getpid();
	num(pid, tmp+8);
	unit = creat(tmp, 0600);
	if (unit < 0)  {
		printf("Can't create temp\n");
		exit(1);
		}

	close(unit);
	unit = open(tmp, 2);

	if (!OPTION('u'))
		/* unlink temp file if OPTION('u') is not on */
		unlink(tmp);

	tbl(fd);		/* initialise tables */
	pass1();		/* parse source, build symtab, temp code */

	close(ibuf.b_fdesc);
	if (errcount)  {
		synerr("Errors in pass 1.");
		exit(1);
		}

	seek(unit, 0, 0);

	if (OPTION('l'))
		if (nfile < 2)  {
			warning("Listing from std. input impossible!!");
			OPTION('l') = FALSE;
			}
		else	{
			i = fopen(arg[1], &ibuf);
			if (i < 0)  {
				synerr("Can't re-open source");
				exit(1);
				}
			}

	if (nfile > 2 && (afd = creat(arg[2], 0666)) < 0)  {
		synerr("Can't create object file");
		OPTION('a') = FALSE;
		}

	if (nfile < 3  &&  OPTION('a'))
		if ((afd = creat("m.out", 0666)) < 0)  {
			synerr("Can't create m.out");
			OPTION('a') = FALSE;
			}


	adjust();		/* adjust location counters for assembly */
	pass2();		/* initiate pass2 */
	cdump();		/* code dump to std output */
	sdump();		/* symbol table dump to std output */

	return;
}

tbl(fd)
register int fd;
{
	register struct st *s;
	register int i;


	/*
	 *	read header record:
	 *
	 *	contains number of format descriptors,
	 *	and number of opcode descriptors,
	 *	pre-defined labels, literals,
	 *	and the size of the parser table.
	 *	It also contains interesting information
	 *	about the target machine.
	 *
	 *	the file contains:-
	 *		literals;
	 *		format descriptors;
	 *		opcode table;
	 *		parser table;
	 *		pre-defined labels;
	 *
	 *	calculate core requirements and sbrk() 
	 *	for the core.
	 */

	read(fd, &head, HT);
	i = head.h_literals;
	if (i)  {
		i =* 8;			/* sizeof literal */
		literals = sbrk(i);
		read(fd, literals, i);
		}
	i = FD * head.h_formats;
	memory = sbrk(i);
	read(fd, &memory[0], i);
	i = head.h_o_len * head.h_ops;
	opcode = sbrk(i);
	read(fd, &opcode[0], i);
	i = head.h_p_len * TBL;
	parse = sbrk(i);
	read(fd, &parse[0], i);
	symtab = coreptr = cpget();

	i = head.h_labels;
	while (i-- > 0)  {
		read(fd, buf, ST);
		/* enter label in symbol table */
		s = buf;
		lscan(s->s_name, DEF, any(buf[0],alptab), s->s_value, s->s_mode);
		}

	return;
}

adjust()
{
	register struct	lt *q;
	register int rs;
	register int i;
	register int nwrd;

	/*
	 *   adjust all locn. counters and
	 *   set up code pointers. brk core.
	 *
	 *	l_rel_f	:	pointer to start of core segment
	 *	l_start :	start addr of code seg. (logical)
	 */
	rs = 0;
	q = &locn[0];
	for (i=0; i<LCOUNT; i++)  {
		if (q->l_value > q->l_limit)		/* backwards org ??? */
			q->l_limit = q->l_value;
		rs =+ (q->l_limit - q->l_start);
		q->l_value = 0;
		q++;
		}

	/*
	 *   rs:  Number of basic units in all segments.
	 *	  Allow 1 word / byte.
	 *	  If r option is on - allow space for reloc info.
	 */
	if (OPTION('r'))
		rs =* 2;

	code = sbrk(rs * INT);
	if (code < 0)  {
		synerr("no core for assembly");
		exit(1);
		}
	endcore = sbrk(0);

	/*
	 *   Fix pointers to core for pass 2 assembly
	 */
	rs = 0;
	q = &locn[0];
	for (i=0; i<LCOUNT; i++)  {
		q->l_rel_f = q->l_next = code + rs;
		nwrd = q->l_limit - q->l_start;
		if (OPTION('r'))  {
			q->l_rel_n = q->l_reloc = code + rs + nwrd;
			rs =+ (nwrd * 2);
			}
		else
			rs =+  nwrd;

		q++;
		}

	nline = lcntr = 0;		/* Reset line and segment counters */
	return;
}