194 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| 	Main loop
 | |
| */
 | |
| 
 | |
| /* $Id$ */
 | |
| 
 | |
| #include	<stdio.h>
 | |
| #include	<setjmp.h>
 | |
| 
 | |
| #include	<em_abs.h>
 | |
| #include	"e.out.h"
 | |
| #include	"logging.h"
 | |
| #include	"nofloat.h"
 | |
| #include	"global.h"
 | |
| #include	"log.h"
 | |
| #include	"trap.h"
 | |
| #include	"warn.h"
 | |
| #include	"text.h"
 | |
| #include	"read.h"
 | |
| #include	"opcode.h"
 | |
| #include	"rsb.h"
 | |
| 
 | |
| extern int atoi();
 | |
| extern long atol();
 | |
| extern char *strcpy();
 | |
| 
 | |
| char mess_file[64] = "int.mess";	/* name of message file */
 | |
| 
 | |
| jmp_buf trapbuf;
 | |
| char *prog_name;
 | |
| int running;				/* set if EM machine is running */
 | |
| 
 | |
| size maxstack;				/* if set, max stack size */
 | |
| size maxheap;				/* if set, max heap size */
 | |
| 
 | |
| #ifdef	LOGGING
 | |
| extern long inr;			/* from log.c */
 | |
| #endif	/* LOGGING */
 | |
| 
 | |
| PRIVATE char *dflt_av[] = {"e.out", 0};	/* default arguments */
 | |
| 
 | |
| main(argc, argv)
 | |
| 	int argc;
 | |
| 	char *argv[];
 | |
| {
 | |
| 	register int i;
 | |
| 	register int nosetjmp = 1;
 | |
| 	int must_disassemble = 0;
 | |
| 	int must_tally = 0;
 | |
| 	
 | |
| 	prog_name = argv[0];
 | |
| 
 | |
| 	/* Initialize the EM machine */
 | |
| 	PreIgnMask = 0;
 | |
| 	FRALimit = FRALIMIT;
 | |
| 	
 | |
| 	for (i = 1; i < argc; i++) {
 | |
| 		if (*(argv[i]) == '-') {
 | |
| 			switch (*(argv[i] + 1)) {
 | |
| 			case 'd':	/* disassembly */
 | |
| 				must_disassemble = 1;
 | |
| 				break;
 | |
| 			case 'h':	/* limit heap size */
 | |
| 				maxheap = atol(argv[i] + 2);
 | |
| 				break;
 | |
| 			case 'I':	/* IgnMask pre-setting */
 | |
| 				if (atoi(argv[i] + 2) < 16)
 | |
| 					PreIgnMask = BIT(atoi(argv[i] + 2));
 | |
| 				break;
 | |
| 			case 'm':	/* messagefile name override */
 | |
| 				strcpy(mess_file, argv[i] + 2);
 | |
| 				break;
 | |
| 			case 'r':	/* FRALimit override */
 | |
| 				FRALimit = atoi(argv[i] + 2);
 | |
| 				break;
 | |
| 			case 's':	/* limit stack size */
 | |
| 				maxstack = atol(argv[i] + 2);
 | |
| 				break;
 | |
| 			case 't':	/* switch on tallying */
 | |
| 				must_tally= 1;
 | |
| 				break;
 | |
| 			case 'W':	/* disable warning */
 | |
| 				set_wmask(atoi(argv[i] + 2));
 | |
| 				break;
 | |
| 			default:
 | |
| 				fprintf(stderr,
 | |
| 					"%s: bad option: %s\n",
 | |
| 					prog_name,
 | |
| 					argv[i]
 | |
| 				);
 | |
| 				exit(1);
 | |
| 			}
 | |
| 		}
 | |
| #ifdef	LOGGING
 | |
| 		else if (logarg(argv[i])) {
 | |
| 			/* interesting for the logging machine */
 | |
| 		}
 | |
| #endif	/* LOGGING */
 | |
| 		else break;
 | |
| 	}
 | |
| 
 | |
| #ifdef	LOGGING
 | |
| 	/* Initialize the logging machine */
 | |
| 	init_log();
 | |
| #endif	/* LOGGING */
 | |
| 
 | |
| 	if (argc > i)
 | |
| 		init(argc - i, argv + i);
 | |
| 	else
 | |
| 		init(1, dflt_av);
 | |
| 
 | |
| 	/* Text dump only? */
 | |
| 	if (must_disassemble) {
 | |
| 		message(
 | |
| 		    "text segment disassembly produced; program was not run");
 | |
| 		disassemble();
 | |
| 		close_down(0);
 | |
| 	}
 | |
| 
 | |
| 	/* Analyse FLAGS word */
 | |
| 	if (FLAGS&FB_TEST)
 | |
| 		must_test = 1;
 | |
| 
 | |
| 	if ((FLAGS&FB_PROFILE) || (FLAGS&FB_FLOW) || (FLAGS&FB_COUNT))
 | |
| 		must_tally = 1;
 | |
| 
 | |
| #ifdef	NOFLOAT
 | |
| 	if (FLAGS&FB_REALS)
 | |
| 		warning(WFLUSED);
 | |
| #endif	/* NOFLOAT */
 | |
| 
 | |
| 	if (FLAGS&FB_EXTRA)
 | |
| 		warning(WEXTRIGN);
 | |
| 
 | |
| 	/* Call first procedure */
 | |
| 	running = 1;			/* start the machine */
 | |
| 	OnTrap = TR_HALT;		/* default trap handling */
 | |
| 	call(ENTRY, RSB_STP);
 | |
| 
 | |
| 	/* Run the machine */
 | |
| 	while (running) {
 | |
| #ifdef	LOGGING
 | |
| 		inr++;
 | |
| 		if (must_log && inr >= log_start) {
 | |
| 			/* log this instruction */
 | |
| 			logging = 1;
 | |
| 		}
 | |
| #endif	/* LOGGING */
 | |
| 
 | |
| 		LOG(("@x9 PC = %lu OPCODE = %lu", PC,
 | |
| 			btol(text_loc(PC)) < SECONDARY ?
 | |
| 				btol(text_loc(PC)) :
 | |
| 				btol(text_loc(PC)) + btol(text_loc(PC+1))
 | |
| 		));
 | |
| 
 | |
| 		newPC(PC);		/* just check for validity */
 | |
| 		do_instr(nextPCbyte());	/* here it happens */
 | |
| 
 | |
| 		if (must_tally) {
 | |
| 			tally();
 | |
| 		}
 | |
| 
 | |
| 		if (signalled) {
 | |
| 			/* a signal has come in during this instruction */
 | |
| 			LOG(("@t1 signal %d caught by EM machine", signalled));
 | |
| 			trap_signal();
 | |
| 		}
 | |
| 
 | |
| 		if (nosetjmp) {
 | |
| 			/* entry point after a trap occurred */
 | |
| 			setjmp(trapbuf);
 | |
| 			nosetjmp = 0;
 | |
| 		}
 | |
| 
 | |
| #ifdef	LOGGING
 | |
| 		log_eoi();
 | |
| #endif	/* LOGGING */
 | |
| 	}
 | |
| 	
 | |
| 	if (must_tally) {
 | |
| 		out_tally();
 | |
| 	}
 | |
| 	
 | |
| 	if (ES_def == DEFINED) {
 | |
| 		message("program exits with status %ld", ES);
 | |
| 		close_down((int) ES);
 | |
| 	}
 | |
| 	else {
 | |
| 		message("program exits with undefined status");
 | |
| 		close_down(0);
 | |
| 	}
 | |
| 	/*NOTREACHED*/
 | |
| }
 | |
| 
 |