/*
 *	EMUL-8: a pdp8e emulator.
 *
 *	Author:
 *		Bill Haygood
 *		41832 Ernest Road
 *		Loon Lake, WA 99148-9607
 *		Internet: billh@comtch.iea.com
 *		Voice/AnsMach/FAX \
 *			or	   509-233-2555
 *		  Cellular/Pager  /
 *
 *	Copyright 1992, 1993, 1994 by the author with all rights reserved.
 *
 *	'main' module.
 */
#include "pdp8.h"
#include "pdp8regs.h"
#include "pdp8dis.h"
#include "pdp8itab.h"
#include "pdp8fpp8.h"
#include "pdp8iot.h"
#include "pdp8loc.h"
#include "pdp8misc.h"
#include "pdp8run.h"

#define VERSION "1994.02.23.2148"

#define MAXMEM	FIELDS * 4096L		/* 32K (max array on 80x86)	*/

UBYTE	regs [256] ;			/* Holds pdp8 'hardware' status	*/
BYTE *clktxt [] = { "DK8-EA Line Freq", "DK8-EC Crystal",
		"DK8-EP Programmable", "pdp8/a", "vt78", "vt278",  } ;

/* -------------------------------------------------------------------- */
/*
 *	main entry.
 */
main (INT argc, BYTE *argv [])
{
    UWORD *p ;
    UINT temp, temp2, temp3 ;			/* were ULONG		*/
    UINT i, j, k ;				/* were INT; JvZ	*/
    UWORD addr, dis_pc, dis_ifld ;
    UBYTE exitflag = FALSE ;
    UBYTE option = FALSE ;
    UBYTE rulerflag = TRUE ;
    UBYTE df_set = FALSE ;
    UBYTE dirty = FALSE ;
    UBYTE outregs = FALSE ;
    BYTE *pdp8ram = "pdp8.ram" ;
    BYTE *pdp8con = "pdp8.con" ;
    BYTE *pdp8aux = "pdp8.aux" ;
    UBYTE breaka ;
    UBYTE disassemble = FALSE ;
    INT discount = 16, count ;
    INT newline = TRUE ;
    UBYTE ran = FALSE ;
    UINT tempPC ;
    time_t StartTime, EndTime, DeltaTime ;
    INT hours, minutes, seconds ;
    LONG oldtime, newtime, oldticks, newticks ;
    INT len1 = strlen (pdp8ram) + 1, len2 = len1 + 1 ;
    BYTE emul8 = FALSE ;

    if (argc == 1 || (argc > 1 && argv [1][0] != '-'))
    {
	printf ("Usage: pdp8 [-option [value]] [...]\r\n"
		"                       The '-file' option, if specified,\r\n"
		"                       must come first; others may"
					" come in any logical\r\n"
		"                       order [Comments in brackets show default]\r\n"
		"   -auxout [file]      Save pdp8 aux console to file\r\n"
		"                       e.g. -auxout pdp8vdu.aux [pdp8.aux]\r\n"
		"   -auxvdu [ioadr] [out]  Install/remove auxilliary VDU\r\n"
		"                       e.g. -auxvdu 75 [40]\r\n"
		"   -boot [device]      Boot from disk [RK8E]\r\n"
		"   -break [addr][inst] Set breakpoint (5 digit addr)\r\n"
		"                       e.g. to break at inst 6046:\r\n"
		"                               -break 6046\r\n"
		"                            to break at addr 300:\r\n"
		"                               -break 00300\r\n"
		"   -clear              Press 'CLEAR' switch\r\n"
		"                       [equivalent to IOT CAF (6007)]\r\n"
		"   -clock [[type] [ticks]] [out]  Specify clock\r\n"
		"                 type = dk8ea dk8ec pdp8a vt78 vt278\r\n"
		"                       e.g. -clock dk8ec 100\r\n"
		"                       [ticks = 120 for dk8ea,"
					" 50 for dk8ec,\r\n"
		"                       and 100 for others]\r\n"
		"   -conout [file]      Save pdp8 console to file\r\n"
		"                       e.g. -conout pdp8con.out [pdp8.con]\r\n"
		"   -cont [octal]       5-digit start addr\r\n"
		"                       e.g. -cont 16000 [current IF/PC]\r\n"
		"   -count cpu | eae | fpp  Count instructions [cpu]\r\n"
		"   -dep addr value [... value]\r\n"
		"                       e.g. -dep 200 7300 1177 7402\r\n"
		"   -diag               Run a MAINDEC diag program\r\n"
		"   -dis [dec#]         Disassemble instructions\r\n"
		"                       e.g. -dis 150 [16]\r\n"
		"   -eae [mode] [out]   EAE emulation in/out\r\n"
		"                       e.g. -eae b\r\n"
		"   -emul8 [ioadr]      Octal IOT code for EMUL-8 insts\r\n"
		"                       e.g. -emul8 60 [77]\r\n"
		"   -exam addr [#locs]  Display memory\r\n"
		"                       e.g. -exam 0 100 [8]\r\n"
		"   -exec [dec#]        Execute dec# instructions\r\n"
		"                       e.g. -exec 100 [10e6]\r\n"
		"   -file name          Set pdp8 memory file\r\n"
		"         (This option, if specified, must come first)\r\n"
		"                       e.g. -file pdp8spec.ram [pdp8.ram]\r\n"
		"   -flags octal        Specify FLAGS register value\r\n"
		"                       e.g. -flags 5166\r\n"
		"   -fpp [out]          FPP-8/A emulation in/out\r\n"
		"   -fpp regs [dec#]    Display FPP regs & base regs [0]\r\n"
		"   -hardware           List 'hardware' status\r\n"
		"   -hist [file]        Output PC histogram (to file)\r\n"
		"                       e.g. -hist pdp8.hst [stdout]\r\n"
		"   -init [octal-value [start [#locs]]]\r\n"
		"                       e.g. -init 7402 1000 200\r\n"
		"   -lpt [file]         Lineprinter output file\r\n"
		"                       e.g. -lpt lpt.out [stderr]\r\n"
		"   -mask octal         Set breakpoint mask\r\n"
		"                       e.g. -mask 77000\r\n"
		"   -ptr tape ...       Specify PTReader filenames\r\n"
		"                       [no defaults]\r\n"
		"   -ptp tape ...       Specify PTPunch filenames\r\n"
		"                       [no defaults]\r\n"
		"   -<reg> octal        Specify register value\r\n"
		"                where <reg> = link ac mq sr sc gtf sf\r\n"
		"                       e.g. -sr 7777\r\n"
		"   -regs               Display pdp8 registers\r\n"
		"   -res                List 'hardware' resources\r\n"
		"   -rk8e pack ...      Specify up to 4 RK8E files\r\n"
		"                       e.g. -rk8e pack0 pack1\r\n"
		"                       [first pack MUST have valid filename;\r\n"
		"                       emulator will create all others\r\n"
		"   -rk8e regs          Display RK8E registers\r\n"
		"   -rx50 [ioadr] [out]  RX50 emulation in/out\r\n"
		"                       e.g. -rx50 75\r\n"
		"                       [first floppy MUST have valid filename;\r\n"
		"                       emulator will create the other one\r\n"
		"                       [rx50 not yet implemented]\r\n"
		"   -tab [file]         Output inst usage (to file)\r\n"
		"                       e.g. -tab pdp8.tab [no defaults]\r\n"
		"   -trace cpu | eae | fpp | dec#  Trace instructions\r\n"
		"                       e.g. -trace eae 1000 [cpu]\r\n"
		"   -tracefile name     Output trace to file 'name'\r\n"
		"                       e.g. -tracefile pdp8.trace [stderr]\r\n"
		) ;
	exit (1) ;
    }
/*
 *	Initialization.
 */
    base = mem32k ;
/*
 *	Get pdp8 memory file, if specified.
 */
    if (argc > 1 && strcmp (argv [1], "-file") == 0)
    {
	argv++, argc-- ;
	if (argc > 1 && argv [1][0] != '-')
	{
	    pdp8ram = argv [1] ;
	    argv++, argc-- ;
	}
    }
/*
 *	Read in the pdp8 memory file.
 */
    if (pdp8file = fopen (pdp8ram, "rb"))
    {
	if (fread ((BYTE *) regs, 1, len2, pdp8file) != len2)
	{
	    if (newline == FALSE)
		printf ("\r\n") ;
	    printf ("Error during '%s' read.\r\n", pdp8ram) ;
	    newline = exitflag = TRUE ;
	}
	if (strcmp ((BYTE *) regs, pdp8ram))
	{
	    printf ("File not pdp8 memory file.\r\n") ;
	    exit (99) ;
	}
	if (fread ((BYTE *) &regs [len2], 1, regs [len1], pdp8file)
							!= regs [len1])
	{
	    if (newline == FALSE)
		printf ("\r\n") ;
	    printf ("Error reading pdp8 'hardware' registers.\r\n") ;
	    newline = exitflag = TRUE ;
	}
/*
 *	Indexing is sizeof (BYTE); first 8 bytes are signature.
 */
	i = len2 ;
	os8date          = regs [i++] << 8 , os8date |= regs [i++] ;
	DF               = regs [i++] << 12 ;
	IB               = regs [i++] << 12 ;
	IF               = regs [i++] << 12 ;
	UB               = regs [i++] << 12 ;
	UF               = regs [i++] << 12 ;
	PC               = regs [i++] << 8 , PC |= regs [i++] ;
	AC               = regs [i++] << 8 , AC |= regs [i++] ;
	MQ               = regs [i++] << 8 , MQ |= regs [i++] ;
	SR               = regs [i++] << 8 , SR |= regs [i++] ;
	SF               = regs [i++] ;
	int_ena          = regs [i++] ;
	int_inh          = regs [i++] ;
	delay            = regs [i++] ;
	io_flags         = regs [i++] << 24 ;
				io_flags |= regs [i++] << 16 ;
				io_flags |= regs [i++] << 8 ;
				io_flags |= regs [i++] ;
	int_mask         = regs [i++] << 24 ;
				int_mask |= regs [i++] << 16 ;
				int_mask |= regs [i++] << 8 ;
				int_mask |= regs [i++] ;
	if (EAE          = regs [i++])
	{
	    SC           = regs [i++] ;
	    GTF          = regs [i++] ;
	}
	coninchar        = regs [i++] ;
	conoutchar       = regs [i++] ;
	if (clocktype   = regs [i++])
	    tickspersec = regs [i++] << 8 , tickspersec |= regs [i] ;
	if (aux_vdu      = regs [i++])
	{
	    auxinchar    = regs [i++] ;
	    auxoutchar   = regs [i++] ;
	}
	if (FPP          = regs [i++])
	{
	    fpp_mode     = regs [i++] ;
	    fpp_run      = regs [i++] ;
	    fpp_pause    = regs [i++] ;
	    fpp_aptp     = regs [i++] << 8 , fpp_aptp |= regs [i++] ;
	    fpp_command = regs [i++] << 8 , fpp_command |= regs [i++] ;
	    fpp_stat    = regs [i++] << 8 , fpp_stat |= regs [i++] ;
	    fpp_ac [0]  = regs [i++] << 8 , fpp_ac [0] |= regs [i++] ;
	    fpp_ac [1]  = regs [i++] << 8 , fpp_ac [1] |= regs [i++] ;
	    fpp_ac [2]  = regs [i++] << 8 , fpp_ac [2] |= regs [i++] ;
	    fpp_ac [3]  = regs [i++] << 8 , fpp_ac [3] |= regs [i++] ;
	    fpp_ac [4]  = regs [i++] << 8 , fpp_ac [4] |= regs [i++] ;
	    fpp_ac [5]  = regs [i++] << 8 , fpp_ac [5] |= regs [i++] ;
	    fpp_pc      = regs [i++] << 8 , fpp_pc |= regs [i++] ;
	    fpp_x0      = regs [i++] << 8 , fpp_x0 |= regs [i++] ;
	    fpp_br      = regs [i++] << 8 , fpp_br |= regs [i++] ;
	    fpp_opadd   = regs [i++] << 8 , fpp_opadd |= regs [i++] ;
	}
	rk8command       = regs [i++] << 8 , rk8command |= regs [i++] ;
	rk8curaddr       = regs [i++] << 8 , rk8curaddr |= regs [i++] ;
	rk8block         = regs [i++] << 8 , rk8block |= regs [i++] ;
	rk8status        = regs [i++] << 8 , rk8status |= regs [i++] ;
	rk8unit          = regs [i++] ;
	rk8words         = regs [i++] << 4 ;
	rk8count         = regs [i++] << 4 ;
	rk8lock          = regs [i++] ;
	rk8write         = regs [i++] ;
	if (rx50         = regs [i++])
	{
	    rx5command   = regs [i++] << 8 , rx5command |= regs [i++] ;
	    rx5curaddr   = regs [i++] << 8 , rx5curaddr |= regs [i++] ;
	    rx5block     = regs [i++] << 8 , rx5block |= regs [i++] ;
	    rx5status    = regs [i++] << 8 , rx5status |= regs [i++] ;
	    rx5unit      = regs [i++] ;
	    rx5words     = regs [i++] << 4 ;
	    rx5count     = regs [i++] << 4 ;
	    rx5lock      = regs [i++] ;
	    rx5write     = regs [i++] ;
	}
	emul8            = regs [i++] ;
/*
 *	Unpack and decompress pdp8 memory from 'pdp8.ram' file.  The
 *	compression scheme: 1 bit to indicate whether the following datum
 *	is repeated (0=repeated, 1=not repeated).  If datum is not
 *	repeated, the next 12 bits contain the datum.  Else, the next 4
 *	bits contain the number of bits in the repeat count.  Then that
 *	number of following bits contain the repeat count - 1.  The next
 *	12 bits contain the datum.  Using this scheme, a non-repeated
 *	datum requires 13 bits and a datum followed by one datum of the
 *	same value requires 18 bits.  So even if the best case consists
 *	only of pairs of repeated data, the data can still compress to
 *	75% of its original uncompressed size.  If all of memory
 *	consists of the same 12 bit datum, then 32K of memory will
 *	compress to 4 bytes !  Worst case: every memory adjacent datum
 *	different will compress to 52K bytes (32K * 13 bits).  Note
 *	that this scheme requires only a small amount of code to
 *	implement.
 */
	i = 0 ;
	p = base ;
	while (i < MAXMEM)
	{
	    if (inbits (1))
		p [i++] = inbits (12) ;
	    else
	    {
		count = inbits (inbits (4)) ;	/* Get count		*/
		addr = inbits (12) ;		/* Get datum		*/
		for (j = 0 ; j <= count && i < MAXMEM ; j++)
		    p [i++] = addr ;		/* Copy to pdp8 memory	*/
	    }
	}
	fclose (pdp8file) ;
	pdp8file = NULL ;
    }
    else
	dirty = TRUE ;
/*
 *	Get the options.
 */
    while (argc > 1)
    {
/*
 *	Check for pdp8 memory initialization.
 *
 *	Usage:	pdp8 -init <value> [<start> [<#locs>]]
 *	where:	value = value to be loaded into memory
 *		start = 5 digit octal starting address
 *		#locs = number of locations to init
 *	If <value> is not specified, '7402' = HLT is used.
 */
	if (strcmp (argv [1], "-init") == 0)
	{
	    argv++, argc-- ;
	    temp = 07402 ;
	    temp2 = 0 ;
	    temp3 = MAXMEM ;
	    p = base ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		if (temp > 07777)
		{
		    temp &= 07777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in initializing value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		argv++, argc-- ;
		if (argc > 1 && argv [1][0] != '-')
		{
		    sscanf (argv [1], "%o", &temp2) ;
		    argv++, argc-- ;
		    if (temp2 > (MAXMEM - 1))
		    {
			if (newline == FALSE)
			    printf ("\r\n") ;
			printf ("Error in init starting address.\r\n") ;
			newline = exitflag = TRUE ;
		    }
		    p += temp2 ;
		    if (argc > 1 && argv [1][0] != '-')
		    {
			sscanf (argv [1], "%o", &temp3) ;
			argv++, argc-- ;
			if ((temp2 + temp3) > MAXMEM)
			{
			    if (newline == FALSE)
				printf ("\r\n") ;
			    printf ("Error in init range.\r\n") ;
			    newline = exitflag = TRUE ;
			}
			temp3 += temp2 ;
		    }
		}
	    }
	    for (i = temp2 ; i < temp3 ; i++)
		*p++ = temp ;
	    dirty = outregs = TRUE ;
	    option++ ;
	}
/*
 *	Enable/Disable EAE and/or set the EAE mode.
 */
	if (argc > 1 && strcmp (argv [1], "-eae") == 0)
	{
	    UBYTE truth ;
	    argv++, argc-- ;
	    if (argc == 1 || argv [1][0] == '-')
	    {
		truth = 'A' ;
		if (EAE == FALSE || EAE != truth)
		    dirty = TRUE ;
		EAE = truth ;
	    }
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if (strcmp (argv [1], "out"))
		{
		    sscanf (argv [1], "%c", chrsout) ;
		    argv++, argc-- ;
		    truth = chrsout [0] ;
		    truth = (truth == 'B' || truth == 'b')
					? 'B' : 'A' ;
		    if (EAE != truth)
			dirty = TRUE ;
		    EAE = truth ;
		}
		else
		{
		    argv++, argc-- ;
		    if (EAE)
			dirty = TRUE ;
		    EAE = FALSE ;		/* Remove EAE emulation	*/
		    GTF = FALSE ;		/* Clear EAE GT Flag	*/
		    SC = 0 ;			/* Clear EAE SC		*/
		    option++ ;
		}
	    }
	    if (EAE == 'A')
		GTF = FALSE ;
	    option++ ;
	}
/*
 *	Set the EAE Step Counter.
 */
	if (argc > 1 && strcmp (argv [1], "-sc") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 037)
		{
		    temp &= 037 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in EAE SC value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (EAE)
		{
		    if (SC != temp)
			dirty = outregs = TRUE ;
		    SC = temp ;
		}
	    }
	    option++ ;
	}
/*
 *	Set the EAE Greater Than Flag.
 */
	if (argc > 1 && strcmp (argv [1], "-gtf") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		UBYTE truth ;
		sscanf (argv [1], "%c", &truth) ;
		argv++, argc-- ;
		truth = ((truth == 'T' || truth == 't' || truth == '1')
					&& EAE == 'B') ? TRUE : FALSE ;
		if (EAE)
		{
		    if (GTF != truth)
			dirty = outregs = TRUE ;
		    GTF = truth ;
		}
	    }
	    option++ ;
	}
/*
 *	Enable/Disable FPP-8/A.
 */
	if (argc > 1 && strcmp (argv [1], "-fpp") == 0)
	{
	    argv++, argc-- ;
	    if ((argc > 1 && argv [1][0] == '-') || argc == 1)
	    {
		if (FPP == FALSE)
		    dirty = TRUE ;
		FPP = FP ;
		option++ ;
	    }
	    else if (strcmp (argv [1], "out") == 0)
	    {
/*
 *	Remove FPP emulation.
 */
		argv++, argc-- ;
		if (FPP)
		    dirty = TRUE ;
		FPP = FALSE ;		/* This sets fpp_data = 0	*/
		fpp_mode = fpp_run = fpp_pause = 0 ;
		fpp_aptp = fpp_command = fpp_stat = 0 ;
		fpp_ac [0] = fpp_ac [1] = fpp_ac [2] = 0 ;
		fpp_ac [3] = fpp_ac [4] = fpp_ac [5] = 0 ;
		fpp_pc = fpp_x0 = fpp_br = fpp_opadd = 0 ;
		int_mask &= ~fppFLAG ;
		io_flags &= ~fppFLAG ;
		option++ ;
	    }
	    else if (strcmp (argv [1], "regs") == 0)
	    {
/*
 *	Display FPP registers.
 */
		argv++, argc-- ;
		if (FPP)
		{
		    INT j ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    newline = TRUE ;
/*
 * FPP-8/A: RUN  MODE DATA COMM STAT  APT   FPC  INDEX  BASE OPADR
 *           NO  LEAV  EP  0002 0004 22000 21003 33000 47400 50772
 */
		    printf ("FPP-8/A: RUN  MODE DATA COMM STAT"
				"  APT   FPC  INDEX  BASE OPADR\r\n"
			"        %s %s  %s  %04o %04o"
			" %05o %05o %05o %05o %05o\r\n",
			(fpp_run == TRUE) ? " YES "
			: (fpp_pause) ? "PAUSE" : "  NO ",
			(fpp_mode == LEAV) ? "LEAV" : "LOCK",
			(fpp_data == DP) ? "DP"
			: (fpp_data == FP) ? "FP" : "EP",
			fpp_command & 07777, fpp_stat, fpp_aptp,
			fpp_pc, fpp_x0, fpp_br, fpp_opadd) ;
		    if (argc > 1 && argv [1][0] != '-')
		    {
			option = TRUE ;
			sscanf (argv [1], "%d", &k) ;
			argv++, argc-- ;
		    }
/*
 *	COMM = DP EXIT_UFLOW 4K ENA_INT OPADR NDX BASER FAC LOCK APTFIELD
 *	COMM = FP UFLOW=0 32K DIS_INT ~OPADR ~NDX ~BASER ~FAC LEAV APTFIELD
 */
		    printf ("    COMM =") ;
		    if (fpp_command & BIT0)
			printf (" DP") ;
		    else
			printf (" FP") ;
		    if (fpp_command & BIT1)
			printf (" EXIT_UFLOW") ;
		    else
			printf (" UFLOW=0") ;
		    if (fpp_command & BIT2)
			printf (" 4K") ;
		    else
			printf (" 32K") ;
		    if (fpp_command & BIT3)
			printf (" ENA_INT") ;
		    else
			printf (" DIS_INT") ;
		    if (fpp_command & BIT4)
			printf (" OPADR") ;
		    else
			printf (" ~OPADR") ;
		    if (fpp_command & BIT5)
			printf (" NDX") ;
		    else
			printf (" ~NDX") ;
		    if (fpp_command & BIT6)
			printf (" BASER") ;
		    else
		printf (" ~BASER") ;
		    if (fpp_command & BIT7)
			printf (" FAC") ;
		    else
			printf (" ~FAC") ;
		    if (fpp_command & BIT8)
			printf (" LOCK") ;
		    else
			printf (" LEAV") ;
		    printf (" APTFIELD\r\n") ;
/*
 *         STAT = DP TRAP FPHLT DIV0 FADDM/FMULM LOCK EP PAUSED
 */
		    if (fpp_stat)
		    {
			printf ("    STAT =") ;
			if (fpp_stat & BIT0)
			    printf (" DP") ;
			if (fpp_stat & BIT1)
			    printf (" TRAP") ;
			if (fpp_stat & BIT2)
			    printf (" FPHLT") ;
			if (fpp_stat & BIT3)
			    printf (" DIV0") ;
			if (fpp_stat & BIT7)
			    printf (" FADDM/FMULM") ;
			if (fpp_stat & BIT8)
			    printf (" LOCK") ;
			if (fpp_stat & BIT9)
			    printf (" EP") ;
			if (fpp_stat & BIT10)
			    printf (" PAUSED") ;
			else if (fpp_stat & BIT11)
			    printf (" RUN") ;
			printf ("\r\n") ;
		    }
/*
 *        INDEX = 0123 4567 1234 5670 2345 6701 3456 7012
 */
		    printf ("   INDEX = %05o/", fpp_x0) ;
		    for (i = 0 ; i < 8 ; i++)
			printf (" %04o", *(base + (fpp_x0 + i))) ;
		    printf ("\r\n") ;
/*
 *          FAC = 0002 4667 4022 5356 7513 4700 = -3.14159265358979
 */
		    i = sprintf (chrsout, "     FAC =       ") ;
		    i += sprintf (&chrsout [i], " %04o %04o %04o = ",
				fpp_ac [0], fpp_ac [1], fpp_ac [2]) ;
		    if (fpp_data == EP)
		    {
			i -= 3 ;
			i += sprintf (&chrsout [i], " %04o %04o %04o = ",
				fpp_ac [3], fpp_ac [4], fpp_ac [5]) ;
		    }
		    outfpp (fpp_ac, i) ;
/*
 *	  OPADR = 47400/ 0002 4667 4022 5356 7513 4700 = -3.14159265358979
 */
		    i = sprintf (chrsout, "   OPADR = %05o/", fpp_opadd) ;
		    i += sprintf (&chrsout [i], " %04o %04o %04o = ",
				*(base + fpp_opadd),
				*(base + fpp_opadd + 1),
				*(base + fpp_opadd + 2)) ;
		    if (fpp_data == EP)
		    {
			i -= 3 ;
			i += sprintf (&chrsout [i],
					" %04o %04o %04o = ",
					*(base + fpp_opadd + 3),
					*(base + fpp_opadd + 4),
					*(base + fpp_opadd + 5)) ;
		    }
		outfpp (base + fpp_opadd, i) ;
/*
 *         BASE = 47400/ 0002 4667 4022 5356 7513 4700 = -3.14159265358979
 *                47406/ 0001 2000 0000 0000 0000 0000 =  1.
 *		  ...
 */
		    if (k && k <= 128)
		    {
			INT step = (fpp_data == EP) ? 6 : 3 ;
			if (fpp_data == EP && k > 64)
			    k = 64 ;
			i = sprintf (chrsout, "    BASE = %05o/", fpp_br) ;
			i += sprintf (&chrsout [i], " %04o %04o %04o = ",
						*(base + fpp_br),
						*(base + fpp_br + 1),
						*(base + fpp_br + 2)) ;
			if (fpp_data == EP)
			{
			    i -= 3 ;
			    i += sprintf (&chrsout [i],
						" %04o %04o %04o = ",
						*(base + fpp_br + 3),
						*(base + fpp_br + 4),
						*(base + fpp_br + 5)) ;
			}
			outfpp (base + fpp_br, i) ;
			for (j = 1 ; j < k ; j++)
			{
			    i = sprintf (chrsout, "           %05o/",
						fpp_br + (j * step)) ;
			    i += sprintf (&chrsout [i],
				    " %04o %04o %04o = ",
				    *(base + fpp_br + (j * step)),
				    *(base + fpp_br + (j * step) + 1),
				    *(base + fpp_br + (j * step) + 2)) ;
			    if (fpp_data == EP)
			    {
				i -= 3 ;
				i += sprintf (&chrsout [i],
				    " %04o %04o %04o = ",
				    *(base + fpp_br + (j * step) + 3),
				    *(base + fpp_br + (j * step) + 4),
				    *(base + fpp_br + (j * step) + 5)) ;
			    }
			    outfpp (base + (fpp_br + (j * step)), i) ;
			}
		    }
		}
		else
		{
		    printf ("FPP out\r\n") ;
		    newline = exitflag = TRUE ;
		}
		option++ ;
	    }
	}
/*
 *	Press "CLEAR" switch (equivalent to CAF instruction).
 */
	if (argc > 1 && strcmp (argv [1], "-clear") == 0)
	{
	    argv++, argc-- ;
	    i6007 () ;
	    dirty = outregs = TRUE ;
	    option++ ;
	}
/*
 *	Get address deposit values.
 */
	if (argc > 1 && strcmp (argv [1], "-dep") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > MAXMEM)
		{
		    temp &= MAXMEM - 1 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in 'deposit' address.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		p = base + temp ;
	    }
	    while (argc > 1 && argv [1][0] != '-'
					&& (p - base) < MAXMEM)
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 07777)
		{
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in 'deposit' value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		*p++ = temp ;
	    }
	    dirty = outregs = TRUE ;
	    option++ ;
	}
/*
 *	Examine pdp8 memory.
 */
	if (argc > 1 && strcmp (argv [1], "-exam") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > MAXMEM)
		{
		    temp &= MAXMEM - 1 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in 'exam' starting address.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		addr = temp ;
		if (argc == 1 || argv [1][0] == '-')
		    temp = 1 ;
		else
		{
		    sscanf (argv [1], "%o", &temp) ;
		    argv++, argc-- ;
		}
		if (temp == 0)
		    temp++ ;
		temp += addr + 7 ;
		addr &= ~7 ;
		temp -= addr ;
		temp &= ~7 ;
		if ((addr + temp) > MAXMEM)
		    temp = MAXMEM - addr ;
		if (rulerflag)
		{
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf (" Addr    0     1     2"
				"     3     4     5     6     7\r\n") ;
		    newline = TRUE ;
		    rulerflag = FALSE ;
		}
		p = base + addr ;
		while (temp > 0)
		{
		    i = 0 ;
		    chrsout [i++] = ((addr & 070000) >> 12) + '0' ;
		    chrsout [i++] = ((addr & 07000) >> 9) + '0' ;
		    chrsout [i++] = ((addr & 0700) >> 6) + '0' ;
		    chrsout [i++] = ((addr & 070) >> 3) + '0' ;
		    chrsout [i++] = ((addr & 07)) + '0' ;
		    for (j = 0 ; j < 8 ; j++)
		    {
			chrsout [i++] = ' ' ;
			chrsout [i++] = ' ' ;
			chrsout [i++] = ((*p & 07000) >> 9) + '0' ;
			chrsout [i++] = ((*p & 0700) >> 6) + '0' ;
			chrsout [i++] = ((*p & 070) >> 3) + '0' ;
			chrsout [i++] = ((*p++ & 07)) + '0' ;
		    }
		    chrsout [i++] = ' ' ;
		    chrsout [i++] = ' ' ;
		    p -= 010 ;
		    for (j = 0 ; j < 8 ; j++, p++)
		    {
			if ((*p & 07400) == 0 && ((*p > 037 && *p < 0177)
					|| (*p > 0237 && *p < 0377)))
			    chrsout [i++] = *p & 0177 ;
			else
			    chrsout [i++] = '.' ;
		    }
		    chrsout [i] = 0 ;
		    printf ("%s\r\n", chrsout) ;
		    newline = TRUE ;
		    addr += 010 ;
		    temp -= 010 ;
		}
	    }
	    option++ ;
	}
/*
 *	Examine pdp8 registers.
 */
	if (argc > 1 && strcmp (argv [1], "-regs") == 0)
	{
	    argv++, argc-- ;
	    outregs = option = TRUE ;
	}
/*
 *	Get the starting Data Field register.
 */
	if (argc > 1 && strcmp (argv [1], "-df") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp >= FIELDS)
		{
		    temp = FIELDS - 1 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in DF value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		temp <<= 12 ;
		if (DF != temp)
		    dirty = outregs = TRUE ;
		DF = temp ;
		df_set = TRUE ;
	    }
	    option++ ;
	}
/*
 *	Get the starting Instruction Field register.
 */
	if (argc > 1 && strcmp (argv [1], "-if") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp >= FIELDS)
		{
		    temp = FIELDS - 1 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in IF value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		temp <<= 12 ;
		if (IF != temp)
		    dirty = outregs = TRUE ;
		IB = IF = temp ;
	    }
	    option++ ;
	}
/*
 *	Get the starting Program Counter register.
 */
	if (argc > 1 && strcmp (argv [1], "-pc") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 07777)
		{
		    temp &= 07777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in PC value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (PC != temp)
		    dirty = outregs = TRUE ;
		PC = temp ;
	    }
	    option++ ;
	}
/*
 *	Get the starting LINK register.
 */
	if (argc > 1 && strcmp (argv [1], "-link") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%1o", &temp) ;
		argv++, argc-- ;
		if (temp > 1)
		{
		    temp &= 1 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in LINK value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (((AC & 010000) >> 12) != temp)
		    dirty = outregs = TRUE ;
		AC = (AC & 07777) + (temp << 12) ;
	    }
	    option++ ;
	}
/*
 *	Get the starting AC (and perhaps LINK) register(s).
 */
	if (argc > 1 && strcmp (argv [1], "-ac") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		if (temp > 017777)
		{
		    temp &= 017777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in LINK/AC value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (temp < 010000 && strlen (argv [1]) < 5)
		    temp += AC & 010000 ;
		argv++, argc-- ;
		if ((AC & 017777) != temp)
		    dirty = outregs = TRUE ;
		AC = temp ;
	    }
	    option++ ;
	}
/*
 *	Get the starting MQ register.
 */
	if (argc > 1 && strcmp (argv [1], "-mq") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 07777)
		{
		    temp &= 07777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in MQ value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (MQ != temp)
		    dirty = outregs = TRUE ;
		MQ = temp ;
	    }
	    option++ ;
	}
/*
 *	Get the starting Switch Register.
 */
	if (argc > 1 && strcmp (argv [1], "-sr") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 07777)
		{
		    temp &= 07777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in SR value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (SR != temp)
		    dirty = outregs = TRUE ;
		SR = temp ;
	    }
	    option++ ;
	}
/*
 *	Get the starting SF register.
 */
	if (argc > 1 && strcmp (argv [1], "-sf") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 0177)
		{
		    temp &= 07777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in SF value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
/*
 *	Bit:    0    1-3  4-6
 *	SF:     UF   IF   DF
 */
		temp2 = (UF >> 6) | (IF >> 9) + (DF >> 12) ;
		if (temp2 != temp)
		{
		    dirty = outregs = TRUE ;
		    UB = (temp & 0100) << 6 ;
		    IB = (temp & 070) << 9 ;
		    DF = (temp & 07) << 12 ;
		}
	    }
	    option++ ;
	}
/*
 *	Get the starting FLAGS register.
 */
	if (argc > 1 && strcmp (argv [1], "-flags") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > 07777)
		{
		    temp &= 07777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in FLAGS value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		if (EAE != 'B')
		    temp &= ~02000 ;
		if ((io_flags & int_mask) == 0)
		    temp &= ~01000 ;
/*
 *	Bit:    0    1    2    3    4    5   6-8  9-11
 *	Flags: Link GTF  IReq IInh IEna  UF   IF   DF
 */
		temp2 = ((AC & 010000) >> 1) ;
		temp2 |= (EAE == 'B') ? (GTF << 10) : 0 ;
		temp2 |= (io_flags & int_mask) ? BIT2 : 0 ;
		temp2 |= (int_inh << 8) | (int_ena << 7)
			| (UF >> 6) | (IF >> 9) + (DF >> 12) ;
		if (temp2 != temp)
		{
		    dirty = outregs = TRUE ;
		    AC = ((temp & 04000) << 1) + (AC & 07777)  ;
		    GTF = (temp & 02000) >> 10 ;
		    int_inh = (temp & 0400) >> 8 ;
		    int_ena = (temp & 0200) >> 7 ;
		    UB = (temp & 0100) << 6 ;
		    IB = (temp & 070) << 9 ;
		    DF = (temp & 07) << 12 ;
		}
	    }
	    option++ ;
	}
/*
 *	Get the pdp8 starting execution address.
 */
	if (argc > 1 && strcmp (argv [1], "-cont") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		argv++, argc-- ;
		if (temp > MAXMEM)
		{
		    temp = 0 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in pdp8 'cont' address.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		IB = IF = temp & 070000 ;
		if (df_set == 0)
		    DF = IF ;
		PC = temp & 07777 ;
	    }
	    run = TRUE ;
	    option++ ;
	}
/*
 *	Get the PTR paper tape filenames.
 */
	if (argc > 1 && strcmp (argv [1], "-ptr") == 0)
	{
	    argv++, argc-- ;
	    i = 0 ;
	    while (argc > 1 && argv [1][0] != '-')
	    {
		if (i < MAXTAPES)
		    ptrtape [i++] = argv [1] ;
		argv++, argc-- ;
	    }
	    if (i < MAXTAPES)
		ptrtape [i] = NULL ;
	    else
		printf ("More than %d PTReader tapes specified.\r\n",
								MAXTAPES) ;
	    option = TRUE ;
	}
/*
 *	Get the PTP paper tape filenames.
 */
	if (argc > 1 && strcmp (argv [1], "-ptp") == 0)
	{
	    argv++, argc-- ;
	    i = 0 ;
	    while (argc > 1 && argv [1][0] != '-')
	    {
		if (i < MAXTAPES)
		    ptptape [i++] = argv [1] ;
		argv++, argc-- ;
	    }
	    if (i < MAXTAPES)
		ptptape [i] = NULL ;
	    else
		printf ("More than %d PTPunch tapes specified.\r\n",
							MAXTAPES) ;
	    option = TRUE ;
	}
/*
 *	Get the RK8-E pack name.
 */
	if (argc > 1 && strcmp (argv [1], "-rk8e") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && strcmp (argv [1], "regs") == 0)
	    {
/*
 *	Display RK8-E registers.
 */
		argv++, argc-- ;
		if (newline == FALSE)
		{
		    printf ("\r\n") ;
		    newline = TRUE ;
		}
		printf ("RK8E:    COMM STAT UNIT CURAD BLOCK WDCT LOCK WRIT\r\n"
		    "         %04o %04o   %o  %05o %5o  %3d   %c    %c\r\n",
			rk8command, rk8status, rk8unit,
			((rk8command & 070) << 9) + rk8curaddr,
			rk8block, rk8words, (rk8lock) ? 'T' : 'F',
			(rk8write) ? 'T' : 'F') ;
		option++ ;
	    }
	    else
	    {
/*
 *	Get the RK8E pack names.
 */
		for (i = 0 ; argc > 1 && argv [1][0] != '-' && i < 4 ; i++)
		{
		    if ((rk8 [i].drive = fopen (argv [1], "rb+")) == NULL)
		    {
			rk8file [i] = argv [1] ;
			if (i)
			{
			    rk8 [i].drive = fopen (argv [1], "w") ;
			    fclose (rk8 [i].drive) ;
			    rk8 [i].drive = fopen (argv [1], "rb+") ;
			}
			else
			{
			    if (newline == FALSE)
				printf ("\r\n") ;
			    printf ("Could not find RK8-E pack '%s'.\r\n",
								argv [1]) ;
			    newline = exitflag = TRUE ;
			}
		    }
		    if (exitflag == FALSE)
		    {
			if ((rk8 [i].buff = (UBYTE *)
					calloc (RK8BUFSIZ, 1)) == NULL)
			{
			    printf ("Could not allocate buffer memory for "
					"RK8-E pack '%s'.\r\n", argv [1]) ;
			    newline = exitflag = TRUE ;
			}
			if (setvbuf (rk8 [i].drive, NULL, _IOFBF, 32768))
			{
			    printf ("Could not 'setvbuf' for "
					"RK8-E pack '%s'.\r\n", argv [1]) ;
			    newline = exitflag = TRUE ;
			}
			rk8 [i].cyl = 0 ;
			fseek (rk8 [i].drive, 0L, SEEK_END) ;
			if (rk8 [i].maxcyl =
				ftell (rk8 [i].drive) / RK8BUFSIZ)
			    rk8read (i) ;
			else
			    rk8 [i].maxcyl = 1 ;
			rk8 [i].dirty = FALSE ;
		    }
		    else
			break ;
		    argv++, argc-- ;
		    option = TRUE ;
		}
	    }
	}
/*
 *	Enable/Disable RX50 floppy disk system.
 */
	if (argc > 1 && strcmp (argv [1], "-rx50") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if (strcmp (argv [1], "out") == 0)
		{
		    argv++, argc-- ;
		    if (aux_vdu)
			dirty = TRUE ;
		    aux_vdu = FALSE ;
		}
		else
		{
		    sscanf (argv [1], "%o", &temp) ;
		    argv++, argc-- ;
		    if (temp & ~077)
		    {
			if (newline == FALSE)
			    printf ("\r\n") ;
			printf ("Error in RX50 I/O address.\r\n") ;
			newline = exitflag = TRUE ;
		    }
		    else
		    {
			if (rx50 != temp)
			    dirty = TRUE ;
			rx50 = temp ;
		    }
		}
	    }
	    else
	    {
		if (rx50 == FALSE)
		    dirty = TRUE ;
		rx50 = 075 ;
	    }
	    option = TRUE ;
	}
/*
 *	Select octal 'device' code for special EMUL-8 instructions.
 */
	if (argc > 1 && strcmp (argv [1], "-emul8") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && strcmp (argv [1], "out") == 0)
	    {
		sscanf (argv [1], "%c", chrsout) ;
		argv++, argc-- ;
		if (emul8)
		    dirty = TRUE ;
		emul8 = FALSE ;
	    }
	    else
	    {
		temp = 0 ;
		if (argc > 1 && argv [1][0] != '-')
		{
		    sscanf (argv [1], "%o", &temp) ;
		    argv++, argc-- ;
		}
		if (temp == 0)
		    temp = 077 ;
		if (emul8 != temp)
		{
		    emul8 = temp ;
		    dirty = TRUE ;
		}
	    }
	    option++ ;
	}
/*
 *	Get the LP8-E output device (file) name.
 */
	if (argc > 1 && strcmp (argv [1], "-lpt") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if (lp8printer = fopen (argv [1], "wb"))
		    setbuf (lp8printer, NULL ) ;   /* unbuffered for .EJ */
		else
		{
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Could not open print file '%s'.\r\n", argv [1]) ;
		    newline = exitflag = TRUE ;
		}
		argv++, argc-- ;
	    }
	    else
		lp8printer = stderr ;	/* use stdout if no lpt file	*/
	    option++ ;
	}
/*
 *	Check for auxiliary console.
 */
	if (argc > 1 && strcmp (argv [1], "-auxvdu") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if (strcmp (argv [1], "out") == 0)
		{
		    argv++, argc-- ;
		    if (aux_vdu)
			dirty = TRUE ;
		    aux_vdu = FALSE ;
		}
		else
		{
		    sscanf (argv [1], "%o", &temp) ;
		    argv++, argc-- ;
		    if (temp & ~077)
		    {
			if (newline == FALSE)
			    printf ("\r\n") ;
			printf ("Error in AUXVDU I/O address.\r\n") ;
			newline = exitflag = TRUE ;
		    }
		    else
		    {
			if (aux_vdu != temp)
			    dirty = TRUE ;
			aux_vdu = temp ;
		    }
		}
	    }
	    else
	    {
		if (aux_vdu == FALSE)
		    dirty = TRUE ;
		aux_vdu = 040 ;
	    }
	    option = TRUE ;
	}
/*
 *	Get the trace flag, if specified.
 */
	if (argc > 1 && strcmp (argv [1], "-trace") == 0)
	{
	    argv++, argc-- ;
	    while (argc > 1 && argv [1][0] != '-')
	    {
		if (strcmp (argv [1], "cpu") == 0)
		    cpu_trace = eae_trace = TRUE ;
		else if (strcmp (argv [1], "eae") == 0)
		    eae_trace = TRUE ;
		else if (strcmp (argv [1], "fpp") == 0)
		    fpp_trace = TRUE ;
		else
		    sscanf (argv [1], "%d", &trace) ;
		argv++, argc-- ;
	    }
	    if ((cpu_trace | eae_trace | fpp_trace) == 0)
		cpu_trace = eae_trace = fpp_trace = TRUE ;
	    if (trace == 0)
		trace = 16 ;
	    run = option = TRUE ;
	}
/*
 *	Get trace output file name, if specified.
 */
	if (argc > 1 && strcmp (argv [1], "-tracefile") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if ((tracefile = fopen (argv [1], "w")) == NULL)
		{
		    printf ("Could not open trace output file.\r\n") ;
		    exitflag = TRUE ;
		}
		argv++, argc-- ;
	    }
	    option = TRUE ;
	}
/*
 *	Get the break mask, if specified.
 */
	if (argc > 1 && strcmp (argv [1], "-mask") == 0)
	{
	    argv++, argc-- ;
	    breakflag = TRUE ;
	    breaka = FALSE ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		if (strlen (argv [1]) > 4)
		    breaka = TRUE ;
		argv++, argc-- ;
		if (temp > 077777)
		{
		    temp &= 077777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in mask value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		else
		{
		    if (breaka)
			addrmask = temp ;
		    else
			instmask = temp ;
		}
	    }
	    else
	    {
		if (newline == FALSE)
		    printf ("\r\n") ;
		printf ("Break mask must be specified.\r\n") ;
		newline = exitflag = TRUE ;
	    }
	    option++ ;
	}
/*
 *	Get the break flag, if specified.
 */
	if (argc > 1 && strcmp (argv [1], "-break") == 0)
	{
	    argv++, argc-- ;
	    breakflag = TRUE ;
	    breaka = FALSE ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%o", &temp) ;
		if (strlen (argv [1]) > 4)
		    breaka++ ;
		argv++, argc-- ;
		if (temp > 077777)
		{
		    temp &= 077777 ;
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Error in addr value.\r\n") ;
		    newline = exitflag = TRUE ;
		}
		else
		{
		    if (breaka)
			breakaddr = temp ;
		    else
			breakinst = temp ;
		}
		run = TRUE ;
	    }
	    else
	    {
		if (newline == FALSE)
		    printf ("\r\n") ;
		printf ("Breakpoint must be specified.\r\n") ;
		newline = exitflag = TRUE ;
	    }
	    option++ ;
	}
/*
 *	Check for tabulate option.
 */
	if (argc > 1 && strcmp (argv [1], "-tab") == 0)
	{
	    argv++, argc-- ;
	    tabulate = run = TRUE ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if ((tabfile = fopen (argv [1], "wb")) == NULL)
		{
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Could not open tab file '%s'.\r\n", argv [1]) ;
		    newline = exitflag = TRUE ;
		}
		argv++, argc-- ;
	    }
	    else
		tabfile = stdout ;	/* use stdout if no tab file	*/
	    option++ ;
	}
/*
 *	Check for profile option.
 */
	if (argc > 1 && strcmp (argv [1], "-hist") == 0)
	{
	    argv++, argc-- ;
	    profile = run = TRUE ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if ((histofile = fopen (argv [1], "wb")) == NULL)
		{
		    if (newline == FALSE)
			printf ("\r\n") ;
		    printf ("Could not open histogram file '%s'.\r\n",
								argv [1]) ;
		    newline = exitflag = TRUE ;
		}
		argv++, argc-- ;
	    }
	    else
		histofile = stdout ;	/* use stdout if no file spec	*/
	    option++ ;
	}
/*
 *	Check for number of instructions to execute.
 */
	if (argc > 1 && strcmp (argv [1], "-exec") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%ld", &exec) ;
		argv++, argc-- ;
	    }
	    else
		exec = 10000000 ;  /* 10 million, so 26 secs == 8/e */
	    run = TRUE ;
	    option++ ;
	}
/*
 *	Check for disassemble option.
 */
	if (argc > 1 && strcmp (argv [1], "-dis") == 0)
	{
	    argv++, argc-- ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		sscanf (argv [1], "%d", &discount) ;
		argv++, argc-- ;
	    }
	    else
		discount = 16 ;
	    dis_ifld = IF ;
	    dis_pc = PC ;
	    disassemble = TRUE ;
	    option++ ;
	}
/*
 *	Count instructions executed, if requested.
 */
	if (argc > 1 && strcmp (argv [1], "-count") == 0)
	{
	    argv++, argc-- ;
	    while (argc > 1 && argv [1][0] != '-')
	    {
		if (strcmp (argv [1], "cpu") == 0)
		    cpu_count++ ;
		else if (strcmp (argv [1], "eae") == 0)
		    eae_count++ ;
		else if (strcmp (argv [1], "fpp") == 0)
		    fpp_count++ ;
		else
		{
		    printf ("Unknown count argument\n") ;
		    exitflag = TRUE ;
		}
		argv++, argc-- ;
	    }
	    if ((cpu_count || eae_count || fpp_count) == FALSE)
		cpu_count = eae_count = fpp_count = TRUE ;
	    run = option = TRUE ;
	}
/*
 *	Check for diagnostic option (necessary to run
 *	certain MAINDEC diagnostics).
 */
	if (argc > 1 && strcmp (argv [1], "-diag") == 0)
	{
	    argv++, argc-- ;
	    diag = run = option = TRUE ;
	}
/*
 *	Save pdp8 console output to memory file, if specified.
 */
    if (argc > 1 && strcmp (argv [1], "-conout") == 0)
    {
	argv++, argc-- ;
	option++ ;
	if (argc > 1 && argv [1][0] != '-')
	{
	    pdp8con = argv [1] ;
	    argv++, argc-- ;
	}
	if ((pdp8conout = fopen (pdp8con, "w")) == NULL)
	    newline = exitflag = TRUE ;
    }
/*
 *	Save pdp8 aux console output to memory file, if specified.
 */
    if (argc > 1 && strcmp (argv [1], "-auxout") == 0)
    {
	argv++, argc-- ;
	option++ ;
	if (argc > 1 && argv [1][0] != '-')
	{
	    pdp8aux = argv [1] ;
	    argv++, argc-- ;
	}
	if ((pdp8auxout = fopen (pdp8aux, "w")) == NULL)
	    newline = exitflag = TRUE ;
    }
/*
 *	Check for clock type and ticks per second request.
 */
    if (argc > 1 && strcmp (argv [1], "-clock") == 0)
    {
	argv++, argc-- ;
	if (argc > 1 && argv [1][0] != '-')
	{
	    if (argc > 1 && strcmp (argv [1], "dk8ea") == 0)
	    {
		clocktype = DK8EA ;
		tickspersec = 120 ;
		argv++, argc-- ;
		dirty = TRUE ;
	    }
	    else if (argc > 1 && strcmp (argv [1], "dk8ec") == 0)
	    {
		clocktype = DK8EC ;
		tickspersec = 50 ;
		argv++, argc-- ;
		dirty = TRUE ;
		if (argc > 1 && argv [1][0] != '-')
		{
		    sscanf (argv [1], "%ld", &tickspersec) ;
		    if (tickspersec != 50 && tickspersec != 500)
			tickspersec = 50 ;
		    if (tickspersec == 0)
			tickspersec = 50 ;
		    argv++, argc-- ;
		}
	    }
	    else if (argc > 1 && strcmp (argv [1], "dk8ep") == 0)
	    {
		clocktype = DK8EP ;
		tickspersec = 100 ;
		argv++, argc-- ;
		dirty = TRUE ;
		if (argc > 1 && argv [1][0] != '-')
		{
		    sscanf (argv [1], "%ld", &tickspersec) ;
		    if (tickspersec > 1000)
			tickspersec = 1000 ;
		    if (tickspersec == 0)
			tickspersec = 100 ;
		    argv++, argc-- ;
		}
	    }
	    else if (argc > 1 && strcmp (argv [1], "pdp8a") == 0)
	    {
		clocktype = PDP8A ;
		tickspersec = 100 ;
		argv++, argc-- ;
		dirty = TRUE ;
	    }
	    else if (argc > 1 && strcmp (argv [1], "vt78") == 0)
	    {
		clocktype = VT78 ;
		tickspersec = 100 ;
		argv++, argc-- ;
		dirty = TRUE ;
	    }
	    else if (argc > 1 && strcmp (argv [1], "vt278") == 0)
	    {
		clocktype = VT278 ;
		tickspersec = 100 ;
		argv++, argc-- ;
		dirty = TRUE ;
	    }
	    else if (argc > 1 && strcmp (argv [1], "out") == 0)
	    {
		clocktype = 0 ;
		int_mask &= ~clockFLAG ;
		io_flags &= ~clockFLAG ;
		argv++, argc-- ;
		dirty = TRUE ;
	    }
	    else if (argc > 1 && clocktype >= 6)
	    {
		LONG ticks = tickspersec ;
		sscanf (argv [1], "%ld", &ticks) ;
		tickspersec = ticks ;
		if (tickspersec > 1000)
		    tickspersec = 1000 ;
		if (tickspersec == 0)
		    tickspersec = 100 ;
		argv++, argc-- ;
		dirty = TRUE ;
	    }
	}
	newline = option = TRUE ;
    }
/*
 *	Check for boot request.
 */
	if (argc > 1 && strcmp (argv [1], "-boot") == 0)
	{
	    argv++, argc-- ;
	    int_ena = int_inh = delay = 0 ;
	    if (argc > 1 && argv [1][0] != '-')
	    {
		if (argc > 1 && strcmp (argv [1], "rk8e") == 0)
		{
		    argv++, argc-- ;
		    IB = IF = DF = UF = 0 ;
		    if (rk8 [0].drive)		/* Disallow if no drive	*/
		    {
			PC = 027 ;
			p = base + PC ;
			*p++ = 06007 ;
			*p++ = 06743 ;
			*p++ = 06741 ;
			*p = 05031 ;
			run = newline = TRUE ;
		    }
		}
/*
 *	Put other bootstraps here.
 */
	    }
	    else
	    {
		IB = IF = DF = UF = 0 ;
/*
 *	If none specified, test for presence of "hardware".
 */
		if (rk8 [0].drive)	/* Try RK8E first		*/
		{
		    PC = 027 ;
		    p = base + PC ;
		    *p++ = 06007 ;
		    *p++ = 06743 ;
		    *p++ = 06741 ;
		    *p = 05031 ;
		    run = newline = TRUE ;
		}
/*
 *	Put other "hardware" tests here.
 */
	    }
	    option++ ;
	}
/*
 *	List 'hardware' status.
 *	          1         2         3         4         5
 *	012345678901234567890123456789012345678901234567890
 *	EMUL-8 'hardware' status:
 *	DF/0 IF/0 PC/7600 L/1 AC/1234 MQ/2345 SR/7777
 */
	if (argc > 1 && strcmp (argv [1], "-hardware") == 0)
	{
	    argv++, argc-- ;
	    printf ("\r\nEMUL-8 'hardware' status:\r\n") ;
	    printf ("PDP8:  DF/%o IF/%o PC/%04o"
			" L/%o AC/%04o MQ/%04o SR/%04o\r\n",
			DF >> 12, IF >> 12, PC,
			AC >> 12, AC & 07777, MQ, SR) ;
	    printf ("       IB/%o UB/%c UF/%c SF/%03o"
			" INTENA/%s INTINH/%s DELAY/%s\r\n",
			IB >> 12,
			(UB) ? 'T' : 'F',
			(UF) ? 'T' : 'F',
			SF,
			(int_ena) ? "ON" : "OFF",
			(int_inh) ? "ON" : "OFF",
			(delay) ? "ON" : "OFF") ;
	    printf ("       IOFLAGS/") ;
	    if (io_flags & userFLAG)
		printf ("UF ") ;
	    if (io_flags & fppFLAG)
		printf ("FPP ") ;
	    if (io_flags & clockFLAG)
		printf ("CLOCK ") ;
	    if (io_flags & coninFLAG)
		printf ("CONIN ") ;
	    if (io_flags & conoutFLAG)
		printf ("CONOUT ") ;
	    if (io_flags & auxinFLAG)
		printf ("AUXIN ") ;
	    if (io_flags & auxoutFLAG)
		printf ("AUXOUT ") ;
	    if (io_flags & pt8rdrFLAG)
		printf ("READER ") ;
	    if (io_flags & pt8punFLAG)
		printf ("PUNCH ") ;
	    if (io_flags & lp8doneFLAG)
		printf ("PRINTER ") ;
	    if (io_flags & rk8FLAG)
		printf ("RK8E ") ;
	    printf ("\r\n       INTENAB/") ;
	    if (int_mask & userFLAG)
		printf ("UF ") ;
	    if (int_mask & fppFLAG)
		printf ("FPP ") ;
	    if (int_mask & clockFLAG)
		printf ("CLOCK ") ;
	    if (int_mask & coninFLAG)
		printf ("CONIN ") ;
	    if (int_mask & conoutFLAG)
		printf ("CONOUT ") ;
	    if (aux_vdu)
	    {
		if (int_mask & auxinFLAG)
		    printf ("AUXIN ") ;
		if (int_mask & auxoutFLAG)
		    printf ("AUXOUT ") ;
	    }
	    if (rx50 && (int_mask & rx50FLAG))
		    printf ("RX50 ") ;
	    if (int_mask & pt8rdrFLAG)
		printf ("READER ") ;
	    if (int_mask & pt8punFLAG)
		printf ("PUNCH ") ;
	    if (int_mask & lp8doneFLAG)
		printf ("PRINTER ") ;
	    if (int_mask & rk8FLAG)
		printf ("RK8E ") ;
	    printf ("\r\n") ;
	    if (coninchar || conoutchar || auxinchar || auxoutchar)
	    {
		printf ("      ") ;
		if (temp = coninchar & 0177)
		{
		    printf (" CONINCHAR/%03o", temp) ;
		    if (temp >= ' ')
			printf (" (%c)", temp) ;
		}
		if (temp = conoutchar & 0177)
		{
		    printf (" CONOUTCHAR/%03o", temp) ;
		    if (temp >= ' ')
			printf (" (%c)", temp) ;
		}
		if (aux_vdu)
		{
		    if (temp = auxinchar & 0177)
		    {
			printf (" AUXINCHAR/%03o", temp) ;
			if (temp >= ' ')
			    printf (" (%c)", temp) ;
		    }
		    if (temp = auxoutchar & 0177)
		    {
			printf (" AUXOUTCHAR/%03o", temp) ;
			if (temp >= ' ')
			    printf (" (%c)", temp) ;
		    }
		}
		printf ("\r\n") ;
	    }
	    if (EAE)
		printf ("EAE:   MODE/%c SC/%02o GTF/%c\r\n",
			EAE, SC, (GTF) ? 'T' : 'F') ;
	    printf ("RK8E:  COMM/%04o STAT/%04o CURAD/%05o BLOCK/%o\r\n",
			rk8command, rk8status,
			((rk8command & 070) << 9) + rk8curaddr, rk8block) ;
	    printf ("       UNIT/%o WDCT/%d LOCK/%c WRITE/%c\r\n",
			rk8unit, rk8words,
			(rk8lock) ? 'T' : 'F', (rk8write) ? 'T' : 'F') ;
	    if (FPP)
	    {
		printf ("FPP8:  RUN/%s PAUSE/%s MODE/%s DATA/%cP"
			" COMM/%04o STAT/%04o\r\n",
			(fpp_run) ? "YES" : "NO",
			(fpp_pause) ? "YES" : "NO",
			(fpp_mode) ? "LOCK" : "LEAV",
			(fpp_data == DP) ? 'D' :
			(fpp_data == FP) ? 'F' : 'E',
			fpp_command & 07777, fpp_stat) ;
		printf ("       APT/%05o FPC/%05o NDX/%05o"
			" BASER/%05o OPADR/%05o\r\n",
			fpp_aptp, fpp_pc, fpp_x0, fpp_br, fpp_opadd) ;
		printf ("       FAC/%04o %04o %04o %04o %04o %04o\r\n",
			fpp_ac [0], fpp_ac [1], fpp_ac [2],
			fpp_ac [3], fpp_ac [4], fpp_ac [5]) ;
	    }
	    if (rx50)
	    {
		printf ("RX50:  qqqqqqqqqqqqqqqqqqqqq\r\n") ;
	    }
	    if (clocktype)
		printf ("CLOCK: %s Clock running at %d ticks/sec\r\n",
			clktxt [clocktype - 1], tickspersec) ;
	    option = TRUE ;
	}
/*
 *	List 'hardware' resources.
 *	          1         2         3         4         5
 *	012345678901234567890123456789012345678901234567890
 *	EMUL-8 Resources:                   (IOADR)
 *	PDP-8/E with 32K memory
 *	KE8-E Extended Arithmetic Element
 *	PT8-E Paper Tape Reader/Punch        (01/02)
 *	Console Video Display Unit           (03/04)
 *	DK8-EA Line Freq Clock (120 ticks/sec) (13)
 *	Auxilliary Video Display Unit        (40/41)
 *	FPP-8/A Floating Point Processor     (55/56)
 *	LP8-E Line Printer                     (66)
 *	RK8-E Hard Disk with 4 drives          (74)
 *	RX50 Floppy Disk with 2 drives         (75)
 *	EMUL-8 IOTs                            (77)
 */
	if (argc > 1 && strcmp (argv [1], "-res") == 0)
	{
	    argv++, argc-- ;
	    printf ("\r\nEMUL-8 Resources:                    (IOADR)\r\n") ;
	    printf ("PDP-8/E with 32K memory\r\n") ;
	    if (EAE)
		printf ("KE8-E Extended Arithmetic Element\r\n") ;
	    printf ("PT8-E Paper Tape Reader/Punch        (01/02)\r\n") ;
	    printf ("Console Video Display Unit           (03/04)\r\n") ;
/*
 *	Output clock type.
 *	DK8-EA Line Freq Clock (120 ticks/sec) (13)
 *	pdp8/a Clock (100 ticks/sec)           (13)
 *	VT78 Clock (100 ticks/sec)             (13)
 *	VT278 Clock (100 ticks/sec)            (13)
 *	DK8-EC Crystal Clock (50 ticks/sec)    (13)
 */
	    if (clocktype)
	    {
		strcpy (chrsout, clktxt [clocktype - 1]) ;
		sprintf (&chrsout [strlen (chrsout)],
				" Clock (%d ticks/sec)", tickspersec) ;
		sprintf (&chrsout [strlen (chrsout)], "              ") ;
		sprintf (&chrsout [39], "(13)") ;
		printf ("%s\r\n", chrsout) ;
	    }
	    if (aux_vdu)
		printf ("Auxilliary Video Display Unit"
			"        (%02o/%02o)\r\n", aux_vdu, aux_vdu + 1) ;
	    if (FPP)
		printf ("FPP-8/A Floating Point Processor     (55/56)\r\n") ;
	    printf ("LP8-E Line Printer                     (66)\r\n") ;
	    printf ("RK8-E Hard Disk with 4 drives          (74)\r\n") ;
	    if (rx50)
		printf ("RX50 Floppy Disk with 2 drives"
					"         (%02o)\r\n", rx50) ;
	    if (emul8)
		printf ("EMUL-8 IOTs                            "
						"(%02o)\r\n", emul8) ;
	    option = TRUE ;
	}
/*
 *	Handle unknown option request.
 */
	if (option)
	    option = FALSE ;
	else
	{
	    if (newline == FALSE)
		printf ("\r\n") ;
	    printf ("Unknown option '%s' -- aborting.\r\n", argv [1]) ;
	    newline = exitflag = TRUE ;
	    argv++, argc-- ;
	}
    }
/*
 *	If an error occurred above, do not run the emulator.
 */
    if (exitflag)
	run = dirty = FALSE ;
/*
 *	Load instruction and text vectors.
 */
    if (run || disassemble)
    {
	if (EAE)
	    loadEAE () ;
	if (clocktype && loadCLOCK () == 0)
	{
	    printf ("Clock IOT conflict.\r\n") ;
	    run = disassemble = FALSE ;
	}
	if (aux_vdu && loadAUXVDU (aux_vdu) == 0)
	{
	    printf ("AUXVDU IOT conflict.\r\n") ;
	    run = disassemble = FALSE ;
	}
	if (FPP)
	{
	    if (loadFPP ())
		fppexec = (fpp_count || fpp_trace) ? fppexec1 : fppexec2 ;
	    else
	    {
		printf ("FPP IOT conflict.\r\n") ;
		run = disassemble = FALSE ;
	    }
	}
	if (rx50 && loadRX50 (rx50) == 0)
	{
	    printf ("RX50 IOT conflict.\r\n") ;
	    run = disassemble = FALSE ;
	}
	if (emul8)
	{
	    emul8 = loadEMUL8 (emul8) ;
	    if (emul8 == FALSE)
	    {
		printf ("EMUL-8 IOT conflict.\r\n") ;
		run = disassemble = FALSE ;
	    }
	}
    }
/*
 *	Output banner.
 */
    if (run || disassemble)
	printf ("EMUL-8 version %s (c) Bill Haygood,"
				" billh@comtch.iea.com\r\n", VERSION) ;
/*
 *	Disassemble pdp8 code, if requested.
 */
    if (disassemble)
    {
	temp = IF ;
	IF = dis_ifld ;
	dis_ifld = temp ;
	temp = PC ;
	PC = dis_pc ;
	dis_pc = temp ;
	run = FALSE ;
	if (newline == FALSE)
	    printf ("\r\n") ;
	printf (" Addr Inst Program\r\n") ;
	newline = TRUE ;
	while (discount && discount--)
	{
/*
	            1  1 1                  3
	0      7    2  5 7                  6
	  Addr Code Instruction
	 00400 6211 CDF 10
	 00401 1776 TAD I 576
	 00402 7776 SPA SNA SZL CLA OSR HLT
	 00403 7777 CLA MQL MQA SCA LSR 7000
*/
	    sprintf (chrsout, "%05o ", IF + PC) ;
	    INST = *(base + (IF + PC)) ;
	    sprintf (pdp8exec, "%04o ", INST) ;
	    strcat (chrsout, pdp8exec) ;
	    disassem () ;
	    strcat (chrsout, pdp8exec) ;
	    if (incrPC)
		++PC ;
	    if (++PC & 010000)
		PC &= 07777 ;
	    printf ("%s\r\n", chrsout) ;
	    newline = TRUE ;
	}
	IF = dis_ifld ;
	PC = dis_pc ;
    }
/*
 *	Output register contents at conclusion of emulation ?
 */
    if (run)
    {
	dirty = outregs = TRUE ;
	if (clocktype)
	{
/*
 *	Set up the clock tick count.
 */
	    oldticks = time (NULL) ;
	    while (oldticks == time (&newticks))
		;
	    oldtime = clock () ;
	    while (newticks == time (NULL))
		;
	    newtime = ticktime = clock () ;
	    ticks = newtime - oldtime ;
	    if (tickspersec == 0)
		tickspersec = 100 ;
            ticks /= tickspersec ;
	}
	else
	    tickspersec = 100 ;
	local_init () ;			/* Do local initialization	*/
/*
 *	Restore the OS/8 date, if present.
 */
	if (os8date)
	{
	    *(base + 07777) |= (os8date >> 5) & 0200 ;
	    *(base + 017666) = os8date & 07777 ;
	    os8date = 0 ;
	}
    }
/*
 *	Set up table to count instruction usage, if requested.
 */
    if (tabulate && (tab = (ULONG *) calloc (8192, 4)) == NULL)
    {
	if (newline == FALSE)
	    printf ("\r\n") ;
	printf ("Could not allocate memory for inst counts.\r\n") ;
	newline = TRUE ;
    }
/*
 *	Set up table to monitor PC usage, if requested.
 */
    if (profile && (histo = (ULONG *) calloc (8192, 4)) == NULL)
    {
	if (newline == FALSE)
	    printf ("\r\n") ;
	printf ("Could not allocate memory for histogram.\r\n") ;
	newline = TRUE ;
    }
/*
 *	Print header if tracing code.
 */
    if (cpu_trace || eae_trace || fpp_trace)
	newline = header (newline, cpu_trace | eae_trace, fpp_trace) ;
/*
 *	Get the time we started.
 */
    time(&StartTime) ;			/* Remember when we started */
/*
 *	Execute pdp8 instructions.
 */
    if (run)
    {
	exec8 () ;
	ran = TRUE ;
    }
/*
 *	Display pdp8/e registers, if requested.
 */
    run = ran ;
    time (&EndTime) ;
    if (outregs && ran && (cpu_trace | eae_trace | fpp_trace) == 0)
    {
	if (lastPC == 0)
	    lastPC = (PC - 1) & 07777 ;
	if (newline == 0 || (conoutchar & 0160))  /* NL if last char not CR,LF */
	    newline = printf ("\r\n") ;
	newline = header (newline, TRUE, FALSE) ;
	sprintf (chrsout, "%06o ", (DF << 3) + IF + lastPC) ;
	INST = *(base + (IF + lastPC)) ;
	sprintf (pdp8exec, "%04o ", INST) ;
	strcat (chrsout, pdp8exec) ;
	tempPC = PC ;
	PC = lastPC ;
	disassem () ;
	strcat (chrsout, pdp8exec) ;
	PC = tempPC ;
	if (incrPC && lastPC == ((PC - 1) & 07777))
	    PC = ++PC & 07777 ;
	outline () ;
    }
    run = FALSE ;
    if (outregs)
    {
	if (newline == FALSE)
	    printf ("\r\n") ;
	if (ran == 0)
	    newline = header (newline, TRUE, FALSE) ;
	sprintf (chrsout, "%06o ", (DF << 3) + IF + PC) ;
	INST = *(base + (IF + PC)) ;
	sprintf (pdp8exec, "%04o ", INST) ;
	strcat (chrsout, pdp8exec) ;
	disassem () ;
	strcat (chrsout, pdp8exec) ;
/*
 *	Display execution time (in seconds) when we exit.
 */
	if (ran)
	{
	    DeltaTime = EndTime - StartTime ;
	    hours = DeltaTime / 3600 ;
	    DeltaTime -= hours * 3600 ;
	    minutes = DeltaTime / 60 ;
	    seconds = DeltaTime - (minutes * 60) ;
	    for (i = strlen (chrsout) ; i < 45 ; chrsout [i++] = ' ')
		;
	    sprintf (&chrsout [45], "Runtime = %d:%02d:%02d",
						hours, minutes, seconds) ;
	    printf ("%s\r\n", chrsout) ;
	}
	else
	    outline () ;
    }
/*
 *	Output instruction counts, if requested.
 */
    if (tabulate && tabfile)
    {
	printf ("\r\n") ;
	newline = TRUE ;
	for (i = 0 ; i < 010000 ; i += 010)
	{
	    /* FIX: should check for EOF after every 'fprint' */
	    fprintf (tabfile, "%04o", i) ;
	    for (j = 0 ; j < 010 ; j++)
		fprintf (tabfile, " %8u", *(tab + (i + j))) ;
	    fprintf (tabfile, "\r\n") ;
	}
	fprintf (tabfile, "User mode instruction tabulation.\r\n") ;
	for ( ; i < 020000 ; i += 010)
	{
	    /* FIX: should check for EOF after every 'fprint' */
	    fprintf (tabfile, "%04o", i & 07777) ;
	    for (j = 0 ; j < 010 ; j++)
		fprintf (tabfile, " %8u", *(tab + (i + j))) ;
	    fprintf (tabfile, "\r\n") ;
	}
	free (tab) ;
	if (tabfile != stdout)
	    fclose (tabfile) ;
    }
/*
 *	Output PC histogram, if requested.
 */
    if (profile && histofile)
    {
	printf ("\r\n") ;
	newline = TRUE ;
	for (i = 0 ; i < 020000 ; i += 010)
	{
	    ULONG nonzero = 0, counts ;
	    chrsout[0] = '\0' ;
	    for (j = 0 ; j < 010 ; j++)
	    {
		counts = *(histo + (i + j)) ;
		nonzero += counts ;
		sprintf (pdp8exec, "%8u", counts) ;
		strcat (chrsout, pdp8exec) ;
	    }
	    if (nonzero)    /* only print if there are non-zero counts */
		fprintf (histofile, "%05o%s\r\n", i<<2, chrsout) ;
	}
	free (histo) ;
	if (histofile != stdout)
	    fclose (histofile) ;
    }
/*
 *	Output number of instructions executed, if requested.
 */
    if (cpu_count || eae_count || fpp_count)
    {
	printf ("Instructions executed:\r\n") ;
	if (cpu_count)
	    printf ("     PDP8: %11.0f\r\n", cpu_count - 1) ;
	if (eae_count)
	    printf ("     KE8E: %11.0f\r\n", eae_count - 1) ;
	if (fpp_count)
	    printf ("     FPP8: %11.0f\r\n", fpp_count - 1) ;
    }
/*
 *	Check validity of OS/8 date word.
 */
    if (os8date == 0)
	os8date = validate () ;
/*
 *	Output the pdp8 memory file, if necessary.
 */
    if (dirty)
    {
	if (pdp8file)
	    fclose (pdp8file) ;
	if (pdp8file = fopen (pdp8ram, "wb"))
	{
	    strcpy ((BYTE *) regs, pdp8ram) ;
	    i = len2 ;
	    regs [i++]     = os8date >> 8 , regs [i++] = os8date ;
	    regs [i++]     = DF >> 12 ;
	    regs [i++]     = IB >> 12 ;
	    regs [i++]     = IF >> 12 ;
	    regs [i++]     = UB >> 12 ;
	    regs [i++]     = UF >> 12 ;
	    regs [i++]     = PC >> 8 , regs [i++] = PC ;
	    regs [i++]     = AC >> 8 , regs [i++] = AC ;
	    regs [i++]     = MQ >> 8 , regs [i++] = MQ ;
	    regs [i++]     = SR >> 8 , regs [i++] = SR ;
	    regs [i++]     = SF ;
	    regs [i++]     = int_ena ;
	    regs [i++]     = int_inh ;
	    regs [i++]     = delay ;
	    regs [i++]     = io_flags >> 24 ;
				regs [i++] = io_flags >> 16 ;
				regs [i++] = io_flags >> 8 ;
				regs [i++] = io_flags ;
	    regs [i++]     = int_mask >> 24 ;
				regs [i++] = int_mask >> 16 ;
				regs [i++] = int_mask >> 8 ;
				regs [i++] = int_mask ;
	    if (regs [i++] = EAE)
	    {
		regs [i++] = SC ;
		regs [i++] = GTF ;
	    }
	    regs [i++]     = coninchar ;
	    regs [i++]     = conoutchar ;
	    if (regs [i++] = clocktype)
		regs [i++] = tickspersec >> 8 , regs [i++] = tickspersec ;
	    if (regs [i++] = aux_vdu)
	    {
		regs [i++] = auxinchar ;
		regs [i++] = auxoutchar ;
	    }
	    if (regs [i++] = FPP)
	    {
		regs [i++] = fpp_mode ;
		regs [i++] = fpp_run ;
		regs [i++] = fpp_pause ;
		regs [i++] = fpp_aptp >> 8 , regs [i++] = fpp_aptp ;
		regs [i++] = fpp_command >> 8 , regs [i++] = fpp_command ;
		regs [i++] = fpp_stat >> 8 , regs [i++] = fpp_stat ;
		regs [i++] = fpp_ac [0] >> 8 , regs [i++] = fpp_ac [0] ;
		regs [i++] = fpp_ac [1] >> 8 , regs [i++] = fpp_ac [1] ;
		regs [i++] = fpp_ac [2] >> 8 , regs [i++] = fpp_ac [2] ;
		regs [i++] = fpp_ac [3] >> 8 , regs [i++] = fpp_ac [3] ;
		regs [i++] = fpp_ac [4] >> 8 , regs [i++] = fpp_ac [4] ;
		regs [i++] = fpp_ac [5] >> 8 , regs [i++] = fpp_ac [5] ;
		regs [i++] = fpp_pc >> 8 , regs [i++] = fpp_pc ;
		regs [i++] = fpp_x0 >> 8 , regs [i++] = fpp_x0 ;
		regs [i++] = fpp_br >> 8 , regs [i++] = fpp_br ;
		regs [i++] = fpp_opadd >> 8 , regs [i++] = fpp_opadd ;
	    }
	    regs [i++]     = rk8command >> 8 , regs [i++] = rk8command ;
	    regs [i++]     = rk8curaddr >> 8 , regs [i++] = rk8curaddr ;
	    regs [i++]     = rk8block >> 8 , regs [i++] = rk8block ;
	    regs [i++]     = rk8status >> 8 , regs [i++] = rk8status ;
	    regs [i++]     = rk8unit ;
	    regs [i++]     = rk8words >> 4 ;
	    regs [i++]     = rk8count >> 4 ;
	    regs [i++]     = rk8lock ;
	    regs [i++]     = rk8write ;
	    if (regs [i++] = rx50)
	    {
		regs [i++]     = rx5command >> 8 , regs [i++] = rx5command ;
		regs [i++]     = rx5curaddr >> 8 , regs [i++] = rx5curaddr ;
		regs [i++]     = rx5block >> 8 , regs [i++] = rx5block ;
		regs [i++]     = rx5status >> 8 , regs [i++] = rx5status ;
		regs [i++]     = rx5unit ;
		regs [i++]     = rx5words >> 4 ;
		regs [i++]     = rx5count >> 4 ;
		regs [i++]     = rx5lock ;
		regs [i++]     = rx5write ;
	    }
	    regs [i++]     = emul8 ;
	    regs [len1]    = i - len2 ;
/*
 *	Write pdp8 'hardware' registers to 'pdp8.ram' file.
 */
	    if (fwrite ((BYTE *) regs, 1, i, pdp8file) != i)
	    {
		if (newline == FALSE)
		    printf ("\r\n") ;
		printf ("'EMUL-8' memory dump file write failed.\r\n") ;
	    }
/*
 *	Check the pdp8 memory for any locations containing data
 *	in bits to the left of bit 0 (1 << 11).
 */
	p = base ;
	for (i = 0 ; i < MAXMEM && (p [i] & 0xf000) == 0 ; i++)
	    ;
	if (i < MAXMEM)
	{
	    printf ("pdp8 memory loc\r\n") ;
	    for ( ; i < MAXMEM ; i++)
		if (p [i] & 0xf000)
		    printf ("          %05o / %06o\r\n", i, *p) ;
	}
/*
 *	Compress and pack pdp8 memory to 'pdp8.ram' file.  The compression
 *	scheme: Output 1 bit to indicate whether the following datum is
 *	repeated (1=not repeated, 0=repeated).  If datum is not repeated,
 *	the next 12 bits contain the datum.  Else, the next 4 bits contain
 *	the number of bits in the repeat count.  Then that number of
 *	following bits contain the repeat count - 1.  The next 12 bits
 *	contain the datum.  In this manner, if all of memory consists of
 *	the same 12 bit datum, then 32K of memory will compress to
 *	4 bytes !  Worst case: every memory adjacent datum different
 *	will compress to 52K bytes.
 */
	    i = 0 ;
	    p = base ;
	    while (i < MAXMEM)
	    {
		addr = p [i++] & 07777 ;
		count = 0 ;
		while ((p [i] & 07777) == addr && i < MAXMEM)
		    i++, count++ ;
		if (count == 0)
		    outbits (1, 1) ;
		else
		{
		    j = 1 << 14 , k = 0 ;
		    while ((count & j) == 0)
			j >>= 1 , k++ ;
		    j = 15 - k ;
		    outbits (0, 1) ;		/* Repeated value	*/
		    outbits (j, 4) ;		/* Set count size	*/
		    outbits (count, j) ;	/* Count		*/
		}
		outbits (addr, 12) ;		/* 12-bit pdp8 datum	*/
	    }
	    outbits (0, 0) ;			/* Flush any bytes	*/
	    fclose (pdp8file) ;
	}
	else
	{
	    if (newline == FALSE)
		printf ("\r\n") ;
	    printf ("Error during write '%s' open.\r\n", pdp8ram) ;
	}
    }
/*
 *	Close paper tapes and the line printer.
 */
    if (pt8reader)
	fclose (pt8reader) ;
    if (pt8punch)
	fclose (pt8punch) ;
    if (lp8printer)
	fclose (lp8printer) ;
/*
 *	Close console and aux console output files, if open.
 */
    if (pdp8conout)
	fclose (pdp8conout) ;
    if (pdp8auxout)
	fclose (pdp8auxout) ;
/*
 *	Close the trace output file.
 */
    if (tracefile)
	fclose (tracefile) ;
/*
 *	Write RK8-E pack(s).
 */
    for (i = 0, j = 0 ; i < 4 && rk8 [i].drive ; i++)
    {
	if (rk8 [i].dirty)
	    rk8writ (i) ;
	if (i)
	{
	    fseek (rk8 [i].drive, 0L, SEEK_END) ;
	    j = ftell (rk8 [i].drive) ;
	}
	fclose (rk8 [i].drive) ;
	if (i && j == 0)
	    remove (rk8file [i]) ;
	if (rk8 [i].buff)
	    free (rk8 [i].buff) ;
    }
/*
 *	Write RX50 pack(s).
 */
    for (i = 0, j = 0 ; i < 2 && rx5 [i].drive ; i++)
    {
	if (rx5 [i].dirty)
	    rx5writ (i) ;
	if (i)
	{
	    fseek (rx5 [i].drive, 0L, SEEK_END) ;
	    j = ftell (rx5 [i].drive) ;
	}
	fclose (rx5 [i].drive) ;
	if (i && j == 0)
	    remove (rx5file [i]) ;
	if (rx5 [i].buff)
	    free (rx5 [i].buff) ;
    }
/*
 *	Do any necessary local uninitialization.
 */
    if (ran)
	local_uninit () ;
/*
 *	Exit.
 */
    return 0 ;
}
/* -------------------------------------------------------------------- */
