1988-06-22 16:57:09 +00:00
|
|
|
/*
|
|
|
|
Main loop
|
|
|
|
*/
|
|
|
|
|
1994-06-24 11:31:16 +00:00
|
|
|
/* $Id$ */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2019-02-10 12:20:04 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
1988-06-22 16:57:09 +00:00
|
|
|
#include <setjmp.h>
|
|
|
|
|
|
|
|
#include <em_abs.h>
|
|
|
|
#include "e.out.h"
|
|
|
|
#include "logging.h"
|
|
|
|
#include "nofloat.h"
|
|
|
|
#include "global.h"
|
|
|
|
#include "log.h"
|
2019-03-17 14:42:00 +00:00
|
|
|
#include "io.h"
|
1988-06-22 16:57:09 +00:00
|
|
|
#include "trap.h"
|
|
|
|
#include "warn.h"
|
|
|
|
#include "text.h"
|
|
|
|
#include "read.h"
|
|
|
|
#include "opcode.h"
|
2019-03-17 14:42:00 +00:00
|
|
|
#include "m_sigtrp.h"
|
1988-06-22 16:57:09 +00:00
|
|
|
#include "rsb.h"
|
|
|
|
|
|
|
|
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 */
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
PRIVATE char *dflt_av[] = {"e.out", 0}; /* default arguments */
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
/* External definitions - too lazy to create a header file for each. */
|
|
|
|
extern void init(int , char **);
|
|
|
|
extern void disassemble(void);
|
|
|
|
extern void tally(void);
|
|
|
|
extern void out_tally(void);
|
|
|
|
|
2019-06-15 16:42:48 +00:00
|
|
|
/** Check dynamically that the interpreter can run on the target machine. */
|
|
|
|
static void check_requirements(char *name)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Verify that shift right supported signed shifts. According to ISO C90,
|
|
|
|
* this is not mandatory, we should not support it here!
|
|
|
|
*/
|
|
|
|
int shrv = -4;
|
|
|
|
if ((shrv >> 1) != -2)
|
|
|
|
{
|
|
|
|
fprintf(stderr,
|
|
|
|
"%s compiled with compiler that does not support signed right shifts. Aborted.",
|
|
|
|
name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
int main(int argc, char *argv[])
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
register int i;
|
|
|
|
register int nosetjmp = 1;
|
|
|
|
int must_disassemble = 0;
|
|
|
|
int must_tally = 0;
|
2019-06-15 16:42:48 +00:00
|
|
|
|
|
|
|
|
1988-06-22 16:57:09 +00:00
|
|
|
prog_name = argv[0];
|
|
|
|
|
2019-06-15 16:42:48 +00:00
|
|
|
check_requirements(prog_name);
|
|
|
|
|
|
|
|
|
1988-06-22 16:57:09 +00:00
|
|
|
/* 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 */
|
|
|
|
}
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
else break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef LOGGING
|
|
|
|
/* Initialize the logging machine */
|
|
|
|
init_log();
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
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);
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* NOFLOAT */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
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();
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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*/
|
|
|
|
}
|
|
|
|
|