/* i7090_cpu.c: IBM 7090 CPU simulator

   Copyright (c) 2005, Richard Cornwell

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

   cpu          7094 central processor
   rtc		real time clock

   The IBM 7090 was first introduced as the IBM 704. This led to the 709,
   7090, 7094, 7040 and 7044. All where 36 bit signed magnitude machines.
   They were single address machines and had 3 or more index registers. 
   These were the first machines to include indexing. Also first machines
   to impliment indirect addressing, built in floating point, first Fortran
   compiler, first TimeShareing Sytem CTSS. 

     IBM 704:	Announced May 7, 1954 withdrawn April 7, 1960.
                First floating point.
		First index addressing.
		Memory to 32k words.
                
     IBM 709:   Announced January 2, 1957 withdrawn April 7, 1960.
		First indirect addressing.
		First I/O channel.
		Added indicator register.

     IBM 7090:	Announced Decemeber 30, 1958 withdrawn July 14, 1969.
		Transister version of 709.

     IBM 7094 & IBM 7094/II: Announced January 15, 1962 withdrawn July 14, 1969.
		Added double precision floating point.
		Added up to 7 index registers.

     IBM 7040	Announced April 1961. 
		Transisterize 704, with channel.
		Character operate instructions.
		Currently not implmented in simulator.

     IBM 7044	Announced 1961
		Enhanced verion of 7040.
		Currently not implmented in simulator.

   The system state for the IBM 7090 is:

   AC<S,P,Q,1:35>	AC register
   MQ<S,1:35>		MQ register
   XR<0:15>[8]		XR index registers register
   IC<0:15>		program counter
   SSW<0:5>             sense switches
   SLT<0:3>             sense lights
   ID<S:36>		indicators lights
   ACOVF                AC overflow
   MQOVF                MQ overflow
   DVC                  divide check
   IOC                  I/O check
   TM                   transfer trap mode
   CTM                  copy trap mode (for 709 compatibility)
   FTM                  floating trap mode (off is 704 compatibility)
   STM                  select trap mode
   NMODE                storage nullifcation mode
   MTM                  multi-tag mode (7090 compatibility)

   CTSS required a set of special features: memory extension (to 65K),
   protection, and relocation.  Additional state:

   INST_BASE            instruction memory select (A vs B core)
   DATA_BASE            data memory select (A vs B core)
   BASE<0:6>            start address block
   LIMIT<0:6>           limit address block

   The 7094 had five instruction formats: memory reference,
   memory reference with count, convert, decrement, and immediate.

      00000000011 11 1111 112 222222222333333
     S12345678901 23 4567 890 123456789012345
    +------------+--+----+---+---------------+
    |   opcode   |ND|0000|tag|     address   | memory reference
    +------------+--+----+---+---------------+

      00000000011 111111 112 222222222333333
     S12345678901 234567 890 123456789012345
    +------------+------+---+---------------+
    |   opcode   | count|tag|     address   | memory reference
    +------------+------+---+---------------+ with count

      000000000 11111111 11 2 222222222333333
     S123456789 01234567 89 0 123456789012345
    +----------+--------+--+-+---------------+
    |  opcode  | count  |00|X|    address    | convert
    +----------+--------+--+-+---------------+

      00 000000011111111 112 222222222333333
     S12 345678901234567 890 123456789012345
    +---+---------------+---+---------------+
    |opc|   decrement   |tag|     address   | decrement
    +---+---------------+---+---------------+

      00000000011 111111 112222222222333333
     S12345678901 234567 890123456789012345
    +------------+------+------------------+
    |   opcode   |000000|   immediate      | immediate
    +------------+------+------------------+

   This routine is the instruction decode routine for the 7094.
   It is called from the simulator control program to execute
   instructions in simulated memory, starting at the simulated PC.
   It runs until a stop condition occurs.

   General notes:

   1. Reasons to stop.  The simulator can be stopped by:

        HALT instruction
        illegal instruction
        illegal I/O operation for device
        illegal I/O operation for channel
        breakpoint encountered
        nested XEC's exceeding limit
        divide check
        I/O error in I/O simulator

   2. Data channel traps.  The 7094 is a channel-based system.
      Channels can generate traps for errors and status conditions.
      Channel trap state:

        iotraps[0..7]   flags for channels A..H
        ioflags         channel trap enables
        itrap           channel trap inhibit due to trap (cleared by RCT)
        ihold           channel trap inhibit due to XEC, ENAB, RCT, RDS,
                        or WDS (cleared after one instruction)

   3. Arithmetic.  The 7094 uses signed magnitude arithmetic for
      integer and floating point calculations, and 2's complement
      arithmetic for indexing calculations.

   4. Adding I/O devices.  These modules must be modified:

        i7094_defs.h    add device definitions
        i7094_chan.c    add channel subsystem
        i7094_sys.c     add sim_devices table entry
*/

#include "i7090_defs.h"
#include "sim_timer.h"
#include <math.h>

#define UNIT_V_MSIZE	(UNIT_V_UF + 0)
#define UNIT_MSIZE	(7 << UNIT_V_MSIZE)
#define UNIT_V_CPUMODEL	(UNIT_V_UF + 4)
#define UNIT_MODEL	(0xff << UNIT_V_CPUMODEL)
#define CPU_MODEL	((cpu_unit.flags >> UNIT_V_CPUMODEL) & 0xff)
#define MODEL(x)	(x << UNIT_V_CPUMODEL)
#define MEMAMOUNT(x)	(x << UNIT_V_MSIZE)
#define UNIT_DUALCORE	(1 << (UNIT_V_UF+3))
#define UNIT_FASTIO	(1 << (UNIT_V_UF + 12))
#define OPTION_EFP	(1 << (UNIT_V_UF + 13))
#define OPTION_FPSM	(1 << (UNIT_V_UF_31))
#define OPTION_TIMER	(1 << (UNIT_V_UF + 14))

#define TMR_RTC		1

#define HIST_XCT	1	/* instruction */
#define HIST_INT	2	/* interrupt cycle */
#define HIST_TRP	3	/* trap cycle */
#define HIST_MIN	64
#define HIST_MAX	65536
#define HIST_NOEA	0x40000000
#define HIST_PC		0x10000

struct InstHistory
{
    t_int64             ac;
    t_int64             mq;
    t_int64             op;
    t_int64             sr;
    uint32              ic;
    uint16              ea;
    uint16              xr1;
    uint16              xr2;
    uint16              xr4;
};

t_stat              cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr,
			   int32 sw);
t_stat              cpu_dep(t_value val, t_addr addr, UNIT * uptr,
			    int32 sw);
t_stat              cpu_reset(DEVICE * dptr);
t_stat              cpu_set_size(UNIT * uptr, int32 val, char *cptr,
				 void *desc);
t_stat              cpu_show_hist(FILE * st, UNIT * uptr, int32 val,
				  void *desc);
t_stat              cpu_set_hist(UNIT * uptr, int32 val, char *cptr,
				 void *desc);
uint32		    cpu_cmd(UNIT * uptr, uint16 cmd, uint16 dev);

/* Interval timer option */
t_stat              rtc_srv(UNIT * uptr);
t_stat              rtc_reset(DEVICE * dptr);

t_uint64            M[MAXMEMSIZE] = { 0 };	/* memory */
t_uint64            AC, MQ;			/* registers */
uint16              XR[8];			/* Index registers */
uint16              IC;				/* program counter */
t_uint64            ID;				/* Indicator registers */
t_uint64            SR;				/* Internal temp register */
t_uint64            KEYS;			/* Console Keys */
uint8               SL;				/* Sense lights */
uint16              SW = 0;			/* Sense switch */
uint8               MTM;			/* Multi Index mode */
uint8               TM;				/* Trap mode */
uint8               STM;			/* Special trap mode */
uint8               CTM;			/* Copy trap mode */
uint8               FTM;			/* Floating trap mode */
uint8               nmode;			/* Storage null mode */
uint8               smode;			/* Signifigance mode */
uint8               itrap;			/* Can take io traps */
uint8               dcheck;			/* Divide check */
uint8               acoflag;			/* AC Overflow */
uint8               mqoflag;			/* MQ Overflow */
uint8               ihold = 0;			/* Hold interrupts */
uint8               interval_irq = 0;		/* Interval timer IRQ */
uint16              iotraps;			/* IO trap flags */
t_uint64            ioflags;			/* Trap enable flags */
uint8               iocheck;
uint8               iowait;			/* Waiting on io */
uint16              baseaddr = 0;		/* Base relocation. */
uint16              limitaddr = 077777;		/* Max address */
uint16              memmask = 077777;		/* Mask for memory access */
uint8               bcore;			/* Access to B core memory */
						/* 00 - A Core */
						/* 01 - Execute A core, Eff B */
						/* 10 - Execute B core, Eff A */
						/* 11 - Execute B core, Eff B */
uint8               dualcore;			/* Set to true if dual core in
							 use */

uint16		    dev_pulse[NUM_CHAN];	/* SPRA device pulses */
int                 cycle_time = 12;            /* Cycle time in 100ns */

/* History information */
int32               hst_p = 0;			/* History pointer */
int32               hst_lnt = 0;		/* History length */
struct InstHistory *hst = NULL;			/* History stack */
extern uint32       sim_brk_summ;
extern uint32       sim_brk_types;
extern uint32       sim_brk_dflt;
extern uint32       drum_addr;

#define DP_FLOAT	1
#define CHANNEL		2
#define MULTIIX		4
#define TIMER		7
#define INDICATORS	16
#define PROTECT		32
#define DUALCORE	64

/* CPU data structures

   cpu_dev	CPU device descriptor
   cpu_unit	CPU unit descriptor
   cpu_reg	CPU register list
   cpu_mod	CPU modifiers list
*/

UNIT                cpu_unit =
    { UDATA(rtc_srv, UNIT_BINK | MODEL(0x90) | MEMAMOUNT(4),
	    MAXMEMSIZE / 2), 60 };

REG                 cpu_reg[] = {
    {ORDATA(IC, IC, 15), REG_FIT},
    {"AC", &AC, 8, 38, 0, 1, REG_FIT, 0},
    {"MQ", &MQ, 8, 36, 0, 1, REG_FIT, 0},
    {BRDATA(XR, XR, 8, 15, 8), REG_FIT},
    {ORDATA(ID, ID, 36)},
#ifdef EXTRA_SL
    {ORDATA(SL, SL, 8), REG_FIT},
#else
    {ORDATA(SL, SL, 4), REG_FIT},
#endif
#ifdef EXTRA_SW
    {ORDATA(SW, SW, 12), REG_FIT},
#else
    {ORDATA(SW, SW, 6), REG_FIT},
#endif
    {FLDATA(SW1, SW, 0), REG_FIT},
    {FLDATA(SW2, SW, 1), REG_FIT},
    {FLDATA(SW3, SW, 2), REG_FIT},
    {FLDATA(SW4, SW, 3), REG_FIT},
    {FLDATA(SW5, SW, 4), REG_FIT},
    {FLDATA(SW6, SW, 5), REG_FIT},
#ifdef EXTRA_SW
    {FLDATA(SW7, SW, 6), REG_FIT},
    {FLDATA(SW8, SW, 7), REG_FIT},
    {FLDATA(SW9, SW, 8), REG_FIT},
    {FLDATA(SW10, SW, 9), REG_FIT},
    {FLDATA(SW11, SW, 10), REG_FIT},
    {FLDATA(SW12, SW, 11), REG_FIT},
#endif
    {ORDATA(KEYS, KEYS, 36), REG_FIT},
    {ORDATA(MTM, MTM, 1), REG_FIT},
    {ORDATA(TM, TM, 1), REG_FIT},
    {ORDATA(STM, STM, 1), REG_FIT},
    {ORDATA(CTM, CTM, 1), REG_FIT},
    {ORDATA(FTM, FTM, 1), REG_FIT},
    {ORDATA(NMODE, nmode, 1), REG_FIT},
    {ORDATA(ACOVF, acoflag, 1), REG_FIT},
    {ORDATA(MQOVF, mqoflag, 1), REG_FIT},
    {ORDATA(IOC, iocheck, 1), REG_FIT},
    {ORDATA(DVC, dcheck, 1), REG_FIT},
    {ORDATA(BASE, baseaddr, 14), REG_FIT},
    {ORDATA(LIMIT, limitaddr, 14), REG_FIT},
    {ORDATA(ENB, ioflags, 36), REG_FIT},
    {FLDATA(INST_BASE, bcore, 0), REG_FIT},
    {FLDATA(DATA_BASE, bcore, 1), REG_FIT},
    {NULL}
};

MTAB                cpu_mod[] = {
    {UNIT_MODEL, MODEL(0x4), "704", "704", NULL, NULL, NULL},
#ifdef I7090
    {UNIT_MODEL, MODEL(0x9), "709", "709", NULL, NULL, NULL},
    {UNIT_MODEL, MODEL(0x90), "7090", "7090", NULL, NULL, NULL},
    {UNIT_MODEL, MODEL(0x94), "7094", "7094", NULL, NULL, NULL},
#endif
    {UNIT_MSIZE, MEMAMOUNT(0), "4K", "4K", &cpu_set_size},
    {UNIT_MSIZE, MEMAMOUNT(1), "8K", "8K", &cpu_set_size},
    {UNIT_MSIZE, MEMAMOUNT(2), "16K", "16K", &cpu_set_size},
    {UNIT_MSIZE, MEMAMOUNT(4), "32K", "32K", &cpu_set_size},
    {UNIT_FASTIO, 0, NULL, "TRUEIO", NULL, NULL, NULL},
    {UNIT_FASTIO, UNIT_FASTIO, "FASTIO", "FASTIO", NULL, NULL, NULL},
#ifdef I7090
    {OPTION_EFP, 0, NULL, "NOEFP", NULL, NULL, NULL},
    {OPTION_EFP, OPTION_EFP, "EFP", "EFP", NULL, NULL, NULL},
    {OPTION_FPSM, 0, NULL, "NOFPSM", NULL, NULL, NULL},
    {OPTION_FPSM, OPTION_FPSM, "FPSM", "FPSM", NULL, NULL, NULL},
    {OPTION_TIMER, 0, NULL, "NOCLOCK", NULL, NULL, NULL},
    {OPTION_TIMER, OPTION_TIMER, "CLOCK", "CLOCK", NULL, NULL, NULL},
    {UNIT_DUALCORE, 0, NULL, "STANDARD", NULL, NULL, NULL},
    {UNIT_DUALCORE, UNIT_DUALCORE, "CTSS", "CTSS", NULL, NULL, NULL},
#endif
    {MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_SHP, 0, "HISTORY", "HISTORY",
     &cpu_set_hist, &cpu_show_hist},
    {0}
};

DEVICE              cpu_dev = {
    "CPU", &cpu_unit, cpu_reg, cpu_mod,
    1, 8, 15, 1, 8, 36,
    &cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL,
    NULL, DEV_DEBUG, 0, dev_debug
};


extern int32        sim_interval;

#define	T_B	0x0001		/* Do load with indirection */
#define	T_D	0x0002		/* Do ea, but no indirection */
#define	T_F	0x0004		/* Ea = Y, no indirection */
#define	T_T	0x0008		/* Do ea with indirection, no load */
#define	S_B	0x0010		/* Do ea, but store at end */
#define	S_F	0x0020		/* Ea = Y, no indirection, store */
#define S_X	0x0040		/* Store index registers with SR */
#define T_N	0x0100		/* Nop op addressing, but instruct */
#define	I_9	0x0200		/* 709 and up */
#define	I_94	0x0400		/* 7094 only */
#define	I_D	0x0800		/* Need dual core */
#define	X_T	0x1000		/* Trap if in io trap mode or B core */
#define	X_B	0x2000		/* Trap if in B core */
#define X_C	0x4000		/* Trap if in copy trap mode or B core */
#define	N	0x0000		/* No instruction */

/*
  Opcode flags, and execution.

  T_B	T_D	T_T	T_F	S_B	S_X	S_F
  *	*	*		*			SR <- MA <- Y - xr
  *		*		*			SR <- MA <- [MA] if ind
  *			*			*	SR <- [MA]
				*		*	[MA] <- SR
					*		xr <- SR
*/

/* Positive opcodes */
uint16	pos_opcode_flags[01000] = {
	/* 0	1	2	3	4	5	6	7 */
	/*HTR*/
/* 0000 */ T_T,	N, 	N, 	N, 	N,	N,	N,	N,
/* 0010 */ N, 	N, 	N, 	N, 	N,	N,	N,	N,
	/*TRA	TTR	TRCA		TRCC		TRCE	TRCG */
/* 0020 */ T_T, T_T, 	X_T|T_T,N, 	X_T|T_T,N,	X_T|T_T,X_T|T_T,
	/* TEFA	TEFC	TEFE	TEFG */
/* 0030 */ X_T|T_T, X_T|T_T,X_T|T_T,X_T|T_T, N,	N,	N,	N,
	/* TLQ   IIA     TIO     OAI      PAI    	TIF  */
/* 0040 */ T_T,  I_9,	 I_9|T_T,I_9,  	  I_9,	 N,	I_9|T_T, N,
	/*	  IIR			RFT	SIR	RNT	RIR */
/* 0050 */ N, 	  I_9,  N,	N, 	I_9,	I_9,	I_9,	I_9,
	/* TCOA	TCOB	TCOC	TCOD	TCOE	TCOF	TCOG	TCOH */
/* 0060 */ X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,
	/*				TSX */
/* 0070 */ N,	N, 	N, 	N,  	S_X,	N,	N,	N,
	/* TZE     TIA */
/* 0100 */ T_T, I_D|X_B|T_T,N, 	N, 	N, 	N,	N,	N,
	/*				CVR     CVR+100*/
/* 0110 */ N,	N,	N,	N,      I_9,	I_9, 	I_9,	I_9,
	/* TPL */
/* 0120 */ T_T,	N,	N,	N,	N,	N,	N,	N,
	/*	XCA	*/
/* 0130 */ N, I_9|T_N,	N, 	N,	N, 	N,	N,	N,
	/* TOV */
/* 0140 */ T_T,	N,	N,	N,	N,	N,	N,	N,
/* 0150 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*     TQO	TQP */
/* 0160 */ N, 	T_T,  T_T,	N, 	N, 	N, 	N,	N,
/* 0170 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* MPY				VLM       VLM + 100 */
/* 0200 */ T_B,	N,	N,	N,      I_9|T_B, I_9|T_B,N,	N,
/* 0210 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* DVH    DVP 			VDH	VDP     VDH+200 VDP+200  */
/* 0220 */ T_B,  T_B,	N,  	N,	I_9|T_B,I_9|T_B,I_9|T_B,I_9|T_B,
/* 0230 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* FDH  FDP*/
/* 0240 */ T_B,	T_B,	N,	N,	N,	N,	N,	N,
/* 0250 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* FMP    DFMP */
/* 0260 */ T_B,  I_94|T_B,N,	N, 	N,	N,	N,	N,
/* 0270 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* FAD	DFAD	FSB	DFSB	FAM	DFAM	FSM	DFSM */
/* 0300 */ T_B, I_94|T_B,  T_B,  I_94|T_B, I_9|T_B,I_94|T_B,I_9|T_B,I_94|T_B,
/* 0310 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* ANS      	ERA */
/* 0320 */ T_B|S_B,N,  I_9|T_B,	N,	N,	N,	N,	N,
/* 0330 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* CAS */
/* 0340 */ T_B,	N,	N,	N,	N,	N,	N,	N,
/* 0350 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*	ACL */
/* 0360 */ N,   T_B,	N,	N,	N,	N,	N,	N,
/* 0370 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* ADD	ADM	SUB */
/* 0400 */ T_B, T_B,  T_B,      N,	N,	N,	N,	N,
/* 0410 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* HPR */
/* 0420 */ T_N,	N,	N,	N,	N,	N,	N,	N,
/* 0430 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* IIS	LDI	OSI	DLD	OFT	RIS	ONT	*/
/* 0440 */I_9|T_B,I_9|T_B,I_9|T_B,I_94|T_B,I_9|T_B,I_9|T_B,I_9|T_B,	N,
/* 0450 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* LDA */
/* 0460 */X_C|T_B,N,	N,	N,	N,	N,	N,	N,
/* 0470 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* CLA		CLS */
/* 0500 */ T_B, N, 	T_B,	N,	N,	N,	N,	N,
/* 0510 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* ZET		XEC */
/* 0520 */ T_B,	N,  I_9|T_B, 	N,	N,	N,	N,	N,
	/*				LXA	LAC */
/* 0530 */ N,	N,	N,	N, 	S_X|T_F,T_F|S_X,N,	N,
	/* RSCA	RSCC	RSCE	RSCG	STCA	STCC	STCE	STCG */
/* 0540 */ X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,
/* 0550 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* LDQ	ECA	LRI		ENB */
/* 0560 */ T_B,	T_B|S_B,I_D|X_B|T_B,N, 	I_9|T_B,N,	N,	N,
/* 0570 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* STZ	STO	SLW 		STI*/
/* 0600 */ S_B, S_B,	S_B, 	N,      I_9|S_B,N,	N, 	N,
/* 0610 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*	STA	STD			STT */
/* 0620 */ N, 	T_B|S_B, T_B|S_B,N, 	N,	T_B|S_B,N,	N,
	/*  STP				SXA		SCA */
/* 0630 */ T_B|S_B,N, 	N, 	N,  	I_9|S_F, N,  	I_9|S_F,N,
	/*  SCHA   SCHC	SCHE	SCHG	SCDA	SCDC	SCDE	SCDG */
/* 0640 */ X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,
/* 0650 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 0660 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* ELD  EAD      EDP     EMP */
/* 0670 */ T_B,	T_B,	T_B,	T_B,	N,	N,	N,	N,
	/*  CPY */
/* 0700 */ X_C|T_B,N,	N,	N,	N,	N,	N,	N,
/* 0710 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 0720 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*		        	PAX			PAC */
/* 0730 */ N,	N,	N, 	N, 	S_X,	N,	N,    S_X|I_9,
/* 0740 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*				PXA		PCA */
/* 0750 */ N,	N,	N,	N,	T_N,	N, 	T_N, 	N,
	/* PSE	NOP	RDS	LLS	BSR	LRS	WRS	ALS */
/* 0760 */ T_D,	T_N, X_T|T_D,	T_D, X_T|T_D,	T_D,	X_T|T_D, T_D,
	/*  WEF	ARS	REW		AXT	DRS	SDN	 */
/* 0770 */ X_T|T_D,T_D, X_T|T_D, N,	S_X,	X_T|T_D,X_T|T_D, N
};
 
/* Negative opcodes */
uint16	neg_opcode_flags[01000] = {
/* 4000 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4010 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*	ESNT	TRCB		TRCD		TRCF	TRCH */
/* 4020 */ N,	I_9|T_T,X_T|T_T,N,	X_T|T_T,N,	X_T|T_T,X_T|T_T,
	/* TEFB TEFD	TEFF	TEFH */
/* 4030 */ X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,N,	N,	N,	N,
	/*		RIA				PIA */
/* 4040 */ N,	N, 	I_9,     N,	N,	N, 	I_9,     N,
	/* 	IIL			LFT	SIL	LNT	RIL */
/* 4050 */ N,	I_9,    N,	N,   	I_9,	I_9,	I_9,	I_9,
	/* TCNA	TCNB	TCNC	TNCD	TNCE	TNCF	TNCG	TNCH */
/* 4060 */X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,
/* 4070 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* TNZ	TIB */
/* 4100 */ T_T,I_D|X_B|T_T, N,	N,	N,	N,	N,	N,
	/*				CAQ    CAQ +100 */
/* 4110 */ N,	N,	N,	N,	I_9,	I_9,	I_9,	I_9,
	/* TMI */
/* 4120 */ T_T, N,	N,	N,	N,	N,	N,	N,
	/* XCL */
/* 4130 */I_9|T_N, N,	N,	N,	N,	N,	N,	N,
	/* TNO */
/* 4140 */ T_T, N,	N,	N,	N,	N,	N,	N,
	/*				CRQ     CRQ+100 */
/* 4150 */ N,	N,	N,	N,      I_9,	I_9,	I_9,	I_9,
/* 4160 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4170 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* MPR */
/* 4200 */ T_B,	N,	N,	N,	N,	N,	N,	N,
/* 4210 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4220 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4230 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* DFDH DFDP */
/* 4240 */ I_94|T_B, I_94|T_B,N,N,	N,	N,	N,	N,
/* 4250 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* UFM  DUFM */
/* 4260 */ T_B, I_94|T_B, N,	N,	N,	N,	N,	N,
/* 4270 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* UFA	DUFA	UFS	DUFS	UAM	DUAM	USM	DUSM */
/* 4300 */ T_B, I_94|T_B, T_B, I_94|T_B, I_9|T_B, I_94|T_B, I_9|T_B, I_94|T_B,
/* 4310 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* ANA */
/* 4320 */ T_B,	N,	N,	N,	N,	N,	N,	N,
/* 4330 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* LAS */
/* 4340 */ I_9|T_B,N,	N,	N,	N,	N,	N,	N,
/* 4350 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4360 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4370 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* SBM */
/* 4400 */ T_B,	N,	N,	N,	N,	N,	N,	N,
/* 4410 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4420 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4430 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4440 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4450 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4460 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4470 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* CAL  ORA */
/* 4500 */ T_B,	T_B,	N,	N,	N,	N,	N,	N,
/* 4510 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* NZT */
/* 4520 */ I_9|T_B, N,	N,	N,	N,	N,	N,	N,
	/*				LXD	LDC */
/* 4530 */ N,	N,	N,	N,	T_F|S_X,I_9|T_F|S_X, N,	N,
	/* RSCB	RSCD	RSCF	RSCH	STCB	STCD	STCF	STCH */
/* 4540 */ X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,
/* 4550 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*	ECQ			LPI */
/* 4560 */ N,	S_B|T_B,N,	N,I_D|X_B|T_B,  N,	N,	N,
/* 4570 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* STQ	SRI	     ORS	DST    SPI*/
/* 4600 */ S_B, I_D|X_B|S_B,T_B|S_B,I_94|S_B,I_D|X_B|S_B,N,N,	N,
/* 4610 */ N,	N,	N,	N,	N,	N,	N,	N,
	/* SLQ					STL */
/* 4620 */ S_B|T_B,N,	N,	N,	N,	T_B|I_9|S_B,N,	N,
	/*				SXD		SCD */
/* 4630 */ N,	N,	N,	N,      S_F, 	N,	S_F,	N,
	/* SCHB	SCHD	SCHF	SCHH	SCDB	SCDD	SCDF	SCDH */
/* 4640 */ X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,X_T|T_T,
/* 4650 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4660 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*      ESB     EUA     EST */
/* 4670 */ N,	T_B,	T_B,	T_B|S_B,N,	N,	N,	N, 
	/* CAD */
/* 4700 */ X_C|T_B,N,	N,	N,	N,	N,	N,	N,
/* 4710 */ N,	N,	N,	N,	N,	N,	N,	N,
/* 4720 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*				PDX			PDC */
/* 4730 */ N,	N,	N,	N,	S_X,	N,	N,	S_X,
/* 4740 */ N,	N,	N,	N,	N,	N,	N,	N,
	/*				PXD		PCD */
/* 4750 */ N,	N,	N,	N,	S_X,	N,	S_X,	N,
	/* MSE	 SPOPS		LGL	BSF	LGR */
/* 4760 */ T_D,  T_D,	N,	T_D, X_T|T_D,   T_D,	N,	N,
	/*		RUN	RQL	AXC     TRS */
/* 4770 */ N,	N,	X_T|T_D,T_D,	S_X,	X_T|T_D,N,	N
};

#define do_trapmode  \
     if (TM) { \
	  sim_interval = sim_interval - 1;	/* count down */ \
          M[tbase] &= ~AMASK; \
          M[tbase] |= (IC - 1) & memmask; \
	  ihold = 1; \
     }

#define do_transfer(new_pc) IC = (TM)? 1 :(new_pc)

#define update_xr(t, v) \
         if ((t)) { \
	     if (MTM) { \
	         if ((t)&04) XR[4] = (uint16)(v); \
	         if ((t)&02) XR[2] = (uint16)(v); \
	         if ((t)&01) XR[1] = (uint16)(v); \
             } else { \
                 XR[(t)] = (uint16)(v); \
 	     } \
         }

#define get_xr(t) \
    (((t)) ? ((MTM) ? (XR[(t)&04] | XR[(t)&02] | XR[(t)&01]) : XR[(t)]) : 0)

#define ReadMem() \
         /* In address nulify mode, half address */ \
         MA &= memmask; \
	 if (bcore & 2) { 	/* Excuting in B core? check address */ \
           MA = AMASK & (MA + baseaddr); \
           if ((MA & 077400) >limitaddr) { \
	       /* Trap to A core */ \
	       /* bcore to D3,4, IC=ADDR */ \
	       /* Not sure correct, but MA is going to DECR */ \
	       M[32] = (((t_uint64)bcore) << 32) | (((t_uint64)MA) << 18) | IC;\
		/* store 32, IC = 33 */ \
		IC = 33; \
	       bcore = 0; \
	       goto next_exe; \
           } \
	 } \
	 if (bcore & 1)  	/* Addressing in B core? fix address */ \
    	   MA |= 0100000; \
         sim_interval = sim_interval - 1;		/* count down */ \
	 SR = ReadP(MA);

t_stat
sim_instr(void)
{
    t_stat              reason;
    t_uint64            temp = 0LL;
    t_uint64            ibr;
    uint16              opcode;
    uint16              MA;
    uint8               tag;
    uint16              decr;
    uint16              xr;
    uint16              opinfo;
    int                 fptemp, fptemp2;
    uint8               f;
    uint16              tbase;
    int                 xeccnt = 15;
    int                 shiftcnt;
    int                 stopnext = 0;
    int			first_rdwr = 0;

    /* Set cycle time for delays */
    switch(CPU_MODEL) {
    case 0x4:
    case 0x9: cycle_time = 120; break;
    default:
    case 0x90:  cycle_time = 22; break;
    case 0x94:  cycle_time = 18; break;
    }

    reason = 0;

    /* Enable timer if option set */
    if (cpu_unit.flags & OPTION_TIMER) {
	sim_rtcn_init(cpu_unit.wait, TMR_RTC);
	sim_activate(&cpu_unit, cpu_unit.wait);
    }
    interval_irq = 0;

/* Main instruction fetch/decode loop */
    tbase = 0;
    if (bcore & 2)
	tbase = 0100000 | baseaddr;

    iowait = 0;
    while (reason == 0) {	/* loop until halted */

/* If doing fast I/O don't sit in idle loop */
	if (iowait && (cpu_unit.flags & UNIT_FASTIO))
	    sim_interval = 0;
	if (iowait == 0 && stopnext)
	    return SCPE_STEP;

	if (sim_interval <= 0) {	/* event queue? */
	    reason = sim_process_event();
	    if (reason != SCPE_OK) {
		if (reason == SCPE_STEP && iowait)
		    stopnext = 1;
		else
		    break;	/* process */
	    }
	}

	if (iowait == 0 && sim_brk_summ && sim_brk_test(IC, SWMASK('E'))) {
	    reason = STOP_IBKPT;
	    break;
	}

/* Check if we need to take any traps */
#ifdef I7090	/* I704 did not have interrupts */
	if (itrap && ihold == 0 && iowait == 0 && ioflags != 0) {
	    t_uint64            mask = 00000001000001LL;

	    MA = 012;
	    f = 0;

	    for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
		/* CRC *//* Trap *//* EOF */
		/* Wait until channel stops to trigger interupts */
		if (ioflags & mask /*&& chan_active(shiftcnt) == 0*/) {
		    f = 0;
		    if (mask & AMASK & ioflags) {
			if (chan_stat(shiftcnt, CHS_EOF))
			    f |= 4;	/* We have a EOF */
			if (iotraps & (1 << shiftcnt)) {
			    f |= 1;	/* We have a IOCT/IORT/IOST */
			    iotraps &= ~(1 << shiftcnt);
			}
		    }
		    if (mask & DMASK & ioflags
			&& chan_stat(shiftcnt, CHS_ERR))
				 f |= 2;	/* We have device error */
		    /* check if we need to perform a trap */
		    if (f) {
			SR =
			    (((t_uint64) bcore) << 32) | (((t_uint64) f) <<
							  18) | (IC &
								 memmask);
			sim_interval = sim_interval - 1;	/* count down */
			WriteP(MA, SR);
			if (nmode) {
			    memmask <<= 1;
			    memmask |= 1;
			    nmode = 0;
			}
			MA++;
			itrap = bcore = iowait = 0;
			ihold = 1;
			sim_interval = sim_interval - 1;	/* count down */
			temp = ReadP(MA);
			sim_debug(DEBUG_TRAP, &cpu_dev,
			  "Doing trap chan %c %o >%012Lo loc %o %012Lo\n",
				  shiftcnt + 'A' - 1, f, SR, MA, temp);
			if (hst_lnt) {	/* history enabled? */
			    hst_p = (hst_p + 1);	/* next entry */
			    if (hst_p >= hst_lnt)
				hst_p = 0;
			    hst[hst_p].ic = MA | HIST_PC;
			    hst[hst_p].ea = 0;
			    hst[hst_p].op = temp;
			    hst[hst_p].ac = AC;
			    hst[hst_p].mq = MQ;
			    hst[hst_p].xr1 = XR[1];
			    hst[hst_p].xr2 = XR[2];
			    hst[hst_p].xr4 = XR[4];
			    hst[hst_p].sr = 0;
			}
			goto next_xec;
		    }
		}
		MA += 2;
		mask <<= 1;
	    }

	    /* Interval timer has lower priority then I/O traps */
	    if (interval_irq) {
		SR = (((t_uint64) bcore) << 32) | (((t_uint64) f) << 18) |
		    (IC & memmask);
		sim_interval = sim_interval - 1;	/* count down */
		MA = 6;
		WriteP(MA, SR);
		if (nmode) {
		    memmask <<= 1;
		    memmask |= 1;
		    nmode = 0;
		}
		MA++;
		interval_irq = itrap = bcore = iowait = 0;
		ihold = 1;
		sim_interval = sim_interval - 1;	/* count down */
		temp = ReadP(MA);
		sim_debug(DEBUG_TRAP, &cpu_dev,
			  "Doing timer trap >%012Lo loc %o %012Lo\n", SR,
			  MA, temp);
		if (hst_lnt) {	/* history enabled? */
		    hst_p = (hst_p + 1);	/* next entry */
		    if (hst_p >= hst_lnt)
			hst_p = 0;
		    hst[hst_p].ic = MA | HIST_PC;
		    hst[hst_p].ea = 0;
		    hst[hst_p].op = temp;
		    hst[hst_p].ac = AC;
		    hst[hst_p].mq = MQ;
		    hst[hst_p].xr1 = XR[1];
		    hst[hst_p].xr2 = XR[2];
		    hst[hst_p].xr4 = XR[4];
		    hst[hst_p].sr = 0;
		}
		goto next_xec;
	    }
	}
#endif

/* Split out current instruction */
      next_exe:
	if (iowait) {
	    /* If we are awaiting I/O complete, don't fetch. */
	    sim_interval--;
	    iowait = 0;
	} else {
	    xeccnt = 15;
	    MA = IC & memmask;
	    if (bcore & 2) {	/* Excuting in B core? check address */
		MA = AMASK & (MA + baseaddr);
		if ((MA & 077400) > limitaddr) {
		    /* Trap to A core */
		    /* bcore to D3,4, IC=ADDR */
		    /* Not sure correct, but MA is going to DECR */
		    M[32] =
			(((t_uint64) bcore) << 32) | (((t_uint64) MA) <<
						      18) | IC;
		    /* store 32, IC = 33 */
		    IC = 33;
		    bcore = 0;
		    goto next_exe;
		}
	    }
	    sim_interval--;	/* count down */
	    SR = ReadP(MA);
	    temp = SR;
	    if (hst_lnt) {	/* history enabled? */
		hst_p = (hst_p + 1);	/* next entry */
		if (hst_p >= hst_lnt)
		    hst_p = 0;
		hst[hst_p].ic = MA | HIST_PC;
		hst[hst_p].ea = 0;
		hst[hst_p].op = temp;
		hst[hst_p].ac = AC;
		hst[hst_p].mq = MQ;
		hst[hst_p].xr1 = XR[1];
		hst[hst_p].xr2 = XR[2];
		hst[hst_p].xr4 = XR[4];
		hst[hst_p].sr = 0;
	    }
	    IC = memmask & (IC + 1);
	}
	if (ihold != 0)
	    ihold--;
      next_xec:
	opcode = (uint16)(temp >> 24); 
	MA = (uint16)(temp & AMASK);
	tag = (uint8)(temp >> 15) & 07;
	decr = (uint16)((temp >> 18) & AMASK);
					/* Set flags to D to start with */
	xr = get_xr(tag);
	iowait = 0;			/* Kill iowait */
	sim_interval--;			/* one cycle for execute */

	switch (opcode & 07000) {
	case (OP_TXI << 9):	/* Transfer and inc  XR[T] += D, IC <- Y */
	    do_trapmode;

	    decr &= memmask;
	    xr += decr;
	    xr &= memmask;
	    if (hst_lnt) {	/* history enabled? */
		hst[hst_p].ea = decr;
		hst[hst_p].sr = xr;
	    }

	    /* Save register */
	    update_xr(tag, xr);
	    do_transfer(MA);
	    break;

	case (OP_TXH << 9):	/* Transfer on High Index XR[T] > D, IC <- Y */
	    do_trapmode;
	    if (hst_lnt) {	/* history enabled? */
		hst[hst_p].ea = decr;
		hst[hst_p].sr = xr;
	    }
	    xr &= memmask;
	    decr &= memmask;
	    if (tag && xr > decr)
		do_transfer(MA);
	    break;
	case (OP_TNX << 9):	/* Transfer No index XR[T]  */
	    do_trapmode;
	    if (hst_lnt) {	/* history enabled? */
		hst[hst_p].ea = decr;
		hst[hst_p].sr = xr;
	    }
	    xr &= memmask;
	    decr &= memmask;
	    if (tag && xr > decr) {
		xr = AMASK & (xr - decr);
		update_xr(tag, xr);
	    } else {
		do_transfer(MA);
	    }
	    break;
	case (OP_TXL << 9):	/* Transfer on Low Index XR[T] <= D, IC <- Y */
	    do_trapmode;
	    if (hst_lnt) {	/* history enabled? */
		hst[hst_p].ea = decr;
		hst[hst_p].sr = xr;
	    }
	    xr &= memmask;
	    decr &= memmask;
	    if (tag == 0 || xr <= decr)
		do_transfer(MA);
	    break;
	case (OP_TIX << 9):	/* Transfer and Index XR */
	    do_trapmode;
	    if (hst_lnt) {	/* history enabled? */
		hst[hst_p].ea = decr;
		hst[hst_p].sr = xr;
	    }
	    xr &= memmask;
	    decr &= memmask;
	    if (tag && xr > decr) {
		xr = AMASK & (xr - decr);
		update_xr(tag, xr);
		do_transfer(MA);
	    }
	    break;
	case (OP_STR << 9):
	    M[tbase] &= ~AMASK;
	    M[tbase] |= IC & memmask;
	    if (hst_lnt)	/* history enabled? */
		hst[hst_p].ea = tbase;
	    IC = 2;
	    break;
	case (4 << 9):		/* Neg opcodes */
	    opinfo = neg_opcode_flags[opcode & 0777];
	    goto proc_op;
	case 0:		/* Pos opcodes */
	    opinfo = pos_opcode_flags[opcode];
	  proc_op:
	    /* If proc does not support this opcode, just skip it */
	    if (opinfo & I_9 && CPU_MODEL == 0x4)
		break;
	    if (opinfo & I_94 && CPU_MODEL != 0x94)
		break;
	    if (opinfo & X_B && (bcore & 2)) {
		/* Trap to 0 and drop out of B core */
		MA = 0;
		if (nmode) {
		    memmask <<= 1;
		    memmask |= 1;
		}
		temp = ((t_uint64) (bcore) << 32) | IC;
		nmode = bcore = STM = CTM = 0;
		WriteP(MA, temp);
		IC = MA + 1;
		break;
	    }
	    /* Check for traping conditions */
	    if (opinfo & X_T && STM) {
		/* Trap to 40001 */
		MA = MEMSIZE >> 1;
		if (nmode) {
		    memmask <<= 1;
		    memmask |= 1;
		}
		temp = ((t_uint64) (bcore) << 32) | IC;
		nmode = bcore = STM = CTM = 0;
		WriteP(MA, temp);
		IC = MA + 1;
		break;
	    }
	    if (opinfo & X_C && CTM) {
		/* Trap to 40002 */
		MA = MEMSIZE >> 1;
		if (nmode) {
		    memmask <<= 1;
		    memmask |= 1;
		}
		temp = ((t_uint64) (bcore) << 32) | IC;
		nmode = bcore = STM = CTM = 0;
		WriteP(MA, temp);
		IC = MA + 2;
		break;
	    }
	    /* Merge in index register if needed */
	    if (opinfo & (T_B | T_D | T_T | S_B))
		MA = memmask & (MA - xr);
	    decr &= 077;	/* Set flags to D to start with */
	    /* If indirect flag and indirect instruction do memory access */
	    if ((CPU_MODEL != 0x4) && ((decr & 060) == 060) &&
		(opinfo & (T_B | T_T | S_B))) {
		ReadMem();
		tag = (uint8)((SR >> 15) & 07); 
		xr = get_xr(tag);
		MA = (uint16)(memmask & (SR - xr));
	    }
	    SR = MA;
	    MA &= memmask;
	    if (opinfo & (T_B | T_F | S_F)) {
		ReadMem();
	    }
	    if (hst_lnt) {	/* history enabled? */
		hst[hst_p].ea = MA;
		hst[hst_p].sr = SR;
	    }
	    switch (opcode) {
	    case 0760:		/* PSE */
/* Positive 0760 opcodes */
		switch (MA) {
#ifdef I7090	/* Not on 704 */
		case OP_RDCA:	/* Reset data channel */
		case OP_RDCB:
		case OP_RDCC:
		case OP_RDCD:
		case OP_RDCE:
		case OP_RDCF:
		case OP_RDCG:
		case OP_RDCH:
		    if ((bcore & 2) || STM)
			goto seltrap;
		    if (CPU_MODEL != 0x4)
			chan_rst((MA >> 9) & 017, 0);
		    break;
		case OP_RICA:	/* Reset data channel */
		case OP_RICB:
		case OP_RICC:
		case OP_RICD:
		case OP_RICE:
		case OP_RICF:
		case OP_RICG:
		case OP_RICH:
		    if ((bcore & 2) || STM)
			goto seltrap;
		    if (CPU_MODEL != 0x4)
			chan_rst((MA >> 9) & 017, 1);
		    break;
		    /* Not great coding, but keeps multiple copys out of code */
#endif
		  seltrap:
		    /* Trap to 40000 or 0 depending on mode */
		    if (bcore & 2)
			MA = 0;
		    else
			MA = MEMSIZE >> 1;
		    if (nmode) {
			memmask <<= 1;
			memmask |= 1;
		    }
		    temp = ((t_uint64) (bcore) << 32) | IC;
		    nmode = bcore = STM = CTM = 0;
		    WriteP(MA, temp);
		    IC = MA + 1;
		    break;

		case OP_BTTA:	/* Skip BOT */
		case OP_BTTB:	/* Skip BOT */
		case OP_BTTC:	/* Skip BOT */
		case OP_BTTD:	/* Skip BOT */
		case OP_BTTE:	/* Skip BOT */
		case OP_BTTF:	/* Skip BOT */
		case OP_BTTG:	/* Skip BOT */
		case OP_BTTH:	/* Skip BOT */
		    if ((bcore & 2) || STM)
			goto seltrap;
		    if (CPU_MODEL != 0x4
			&& chan_stat((MA >> 9) & 017, CHS_BOT) == 0)
			IC++;
		    break;
		case OP_SLF:
		    SL = 0;
		    break;
		case OP_SLN1:
		case OP_SLN2:
		case OP_SLN3:
		case OP_SLN4:
#ifdef EXTRA_SL
		case OP_SLN5:
		case OP_SLN6:
		case OP_SLN7:
		case OP_SLN8:
#endif	
		    SL |= 1 << (MA - OP_SLN1);
		    break;
		case OP_SWT1:
		case OP_SWT2:
		case OP_SWT3:
		case OP_SWT4:
		case OP_SWT5:
		case OP_SWT6:
		    if (SW & (1 << (MA - OP_SWT1)))
			IC++;
		    break;
		case OP_LBT:
		    if (AC & 1)
			IC++;
		    break;
		case OP_CLM:
		    AC &= AMSIGN;
		    break;
		case OP_CHS:
		    AC ^= AMSIGN;
		    break;
		case OP_SSP:
		    AC &= AMMASK;
		    break;
		case OP_COM:
		    AC ^= AMMASK;
		    break;
		case OP_ENK:
		    MQ = KEYS;
		    break;
		case OP_IOT:	/* Skip & clear ioready */
		    if (iocheck == 0)
			IC++;
		    iocheck = 0;
		    break;
		case OP_ETM:
		    TM = 1;
		    break;
		case OP_RND:
		    if (MQ & ONEBIT) {
			SR = 1;
			goto iadd;
		    }
		    break;
		case OP_FRN:
		    /* Extract AC char */
		    temp = 0;
		    if (MQ & FPNBIT) {
			/* Save everything but characterist, +1 to fraction */
			SR =
			    (AC & (FPMMASK | AMSIGN | AQSIGN | APSIGN)) +
			    1;
			/* If overflow, normalize */
			if (SR & FPOBIT) {
			    SR >>= 1;	/* Move right one bit */
			    if ((AC & (AQSIGN | APSIGN | FPCMASK)) ==
				FPCMASK) {
				temp = FPOVERR | FPACERR;
			    }
			    AC += FPOBIT;	/* Fix characteristic */
			    /* Fix the sign */
			    AC &= AMMASK;
			    AC |= (SR & AQSIGN) << 1;	/* Fix sign */
			}
			/* Restore fixed ac */
			AC &= ~FPMMASK;
			AC |= SR & FPMMASK;
			if (temp != 0)
			    goto dofptrap;
		    }
		    break;
		case OP_DCT:
		    if (dcheck == 0)
			IC++;
		    dcheck = 0;
		    break;
#ifdef I7090	/* Not on 704 */
		case OP_RCT:
		    if (CPU_MODEL != 0x4) {
		sim_debug(DEBUG_TRAP, &cpu_dev, "RCT %012llo\n", ioflags);
			itrap = 1;
			if (CPU_MODEL == 0x9) 
			    ihold = 1;
			else
			    ihold = 2;
		    }
		    break;
		case OP_LMTM:
		    if (CPU_MODEL != 0x4)
			MTM = 0;
		    break;
#endif
		default:
		    if ((bcore & 2) || STM)
			goto seltrap;
		    f = MA >> 9;
		    if (f < 11) {
			MA &= 0777;
			if (MA >= 0341 && MA <= 0372) {
			    MA -= 0341;
			    if (MA < PUNCH_M) {
				dev_pulse[f] |= 1 << MA;
			    } else {
				MA -= 13;
				if (MA == 2) {
				    if (dev_pulse[f] & PRINT_I)
					IC++;
				    dev_pulse[f] &= ~PRINT_I;
				} else {
				    dev_pulse[f] |= 1 << MA;
				}
			    }
			}
		    }
		    break;
		}
		break;
	    case 04760:	/* MSE */
/* Negative 04760 opcodes */
		switch (MA) {
		case OP_ETTA:	/* Transfer on EOT */
		case OP_ETTB:	/* Transfer on EOT */
		case OP_ETTC:	/* Transfer on EOT */
		case OP_ETTD:	/* Transfer on EOT */
		case OP_ETTE:	/* Transfer on EOT */
		case OP_ETTF:	/* Transfer on EOT */
		case OP_ETTG:	/* Transfer on EOT */
		case OP_ETTH:	/* Transfer on EOT */
		    if ((bcore & 2) || STM)
			goto seltrap;
		    if (chan_stat((MA >> 9) & 017, CHS_EOT) == 0)
			IC++;
		    break;
		case OP_PBT:
		    if (AC & APSIGN)
			IC++;
		    break;
		case OP_EFTM:
		    if (CPU_MODEL != 0x4)
			FTM = 1;
		    break;
		case OP_SSM:
		    AC |= AMSIGN;
		    break;
#ifdef I7090	/* Not on 704 */
		case OP_LFTM:
		    if (CPU_MODEL != 0x4)
			acoflag = mqoflag = FTM = 0;
		    break;
		case OP_ESTM:
		    if (CPU_MODEL != 0x4)
			STM = 1;
		    break;
		case OP_ECTM:
		    if (CPU_MODEL != 0x4)
			CTM = 1;
		    break;
		case OP_EMTM:
		    if (CPU_MODEL != 0x4)
			MTM = 1;
		    break;
#endif
		case OP_LTM:
		    TM = 0;
		    break;
		case OP_LSNM:
		    if (nmode) {
			memmask <<= 1;
			memmask |= 1;
		    }
		    nmode = 0;
		    break;
		case OP_ETT:
		    if ((bcore & 2) || STM)
			goto seltrap;
		    if (chan_stat(0, CHS_EOT) == 0)
			IC++;
		    break;
		case OP_RTT:
		    if ((bcore & 2) || STM)
			goto seltrap;
		    /* Check ERR on channel 0 */
		    if (chan_stat(0, CHS_ERR) == 0)
			IC++;
		    break;
		case OP_SLT1:
		case OP_SLT2:
		case OP_SLT3:
		case OP_SLT4:
#ifdef EXTRA_SL
		case OP_SLT5:
		case OP_SLT6:
		case OP_SLT7:
		case OP_SLT8:
#endif	
		    f = 1 << (MA - OP_SLN1);
		    if (SL & f)
			IC++;
		    SL &= ~f;
		    break;
#ifdef EXTRA_SW
		case OP_SWT7:
		case OP_SWT8:
		case OP_SWT9:
		case OP_SWT10:
		case OP_SWT11:
		case OP_SWT12:
#endif
		    if (SW & (1 << (6 + MA - OP_SWT7)))
			IC++;
		    break;
		default:
		    break;
		}
		break;
/* Transfer opcodes */
	    case OP_HTR:
		/* Stop at HTR instruction if trapped */
		IC--;	
	    case OP_HPR:
	      halt:
		reason = STOP_HALT;
		/* Clear off any pending events before we halt */
		do {
		    int                 trp = 0;
		    t_uint64            mask = 00000001000001LL;

		    f = chan_active(0);
		    chan_proc();
		    for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
			f |= chan_active(shiftcnt);
			/* Check if we need to take any traps */
			if (itrap && ioflags & mask) {
			    if (mask & AMASK & ioflags && 
				(chan_test(shiftcnt, CHS_EOF) ||
				 (iotraps & (1 << shiftcnt))))
				    trp = 1;	/* We have a EOF */
			    if (mask & DMASK & ioflags
				&& chan_test(shiftcnt, CHS_ERR))
				trp = 1;	/* We have a EOF */
			}
			mask <<= 1;
		    }
		    if (trp) {
			reason = 0;
			break;
		    }
		    sim_interval = 0;
		    sim_process_event();
		} while (f);
	        if (opcode == OP_HTR && reason != 0)
		     IC = MA;
		break;
	    case OP_XEC:
		temp = SR;
		opcode = (uint16)(temp >> 24); 
		if (opcode != OP_XEC) {
		    xeccnt = 15;
		    goto next_xec;
		}
		if (xeccnt-- != 0) {
		    iowait = 1;
		    goto next_xec;
		}
		reason = STOP_XECLIM;
		break;
	    case OP_NOP:
		break;
	    case OP_TTR:
		IC = MA;
		break;
	    case OP_TLQ:
		do_trapmode;
		/* Is AC - and MQ + */
		if ((MQ & MSIGN) == 0 && (AC & AMSIGN) != 0)
		    break;
		/* Same sign, compare magintudes */
		if (((MQ & MSIGN) == 0 && (AC & AMSIGN) == 0)) {
		    SR = (MQ & PMASK) - (AC & AQMASK);
		    if ((SR & AMSIGN) == 0)
			break;
		} else if (((MQ & MSIGN) != 0 && (AC & AMSIGN) != 0)) {
		    SR = (AC & AQMASK) - (MQ & PMASK);
		    if ((SR & AMSIGN) == 0)
			break;
		}
		/* Nope, MQ bigger, so take branch */
		do_transfer(MA);
		break;
	    case OP_TRA:
		do_trapmode;
		do_transfer(MA);
		break;
	    case OP_TSX:
		do_trapmode;
		/* Exchange SR and IC */
		SR = AMASK & (-(IC - 1));
		do_transfer(MA);
		break;
	    case OP_TZE:
		f = (AC & AMMASK) == 0;
	      branch:
		do_trapmode;
		if (f) {
		    do_transfer(MA);
		}
		break;
	    case OP_TOV:
		f = acoflag;
		acoflag = 0;
		goto branch;
	    case OP_TQP:
		f = ((MQ & MSIGN) == 0);
		goto branch;
	    case OP_TQO:
		if ((CPU_MODEL == 0x4) || FTM == 0) {
		    f = mqoflag;
		    mqoflag = 0;
		    goto branch;
		}
		break;
	    case OP_TPL:
		f = ((AC & AMSIGN) == 0);
		goto branch;
	    case OP_TNZ:
		f = ((AC & AMMASK) != 0);
		goto branch;
	    case OP_TMI:
		f = ((AC & AMSIGN) != 0);
		goto branch;
	    case OP_TNO:
		f = !acoflag;
		acoflag = 0;
		goto branch;
	    case OP_NZT:
		if ((SR & PMASK) != 0)
		    IC++;
		break;
	    case OP_ZET:
		if ((SR & PMASK) == 0)
		    IC++;
		break;
	    case OP_ESNT:
		IC = MA;
		if (!nmode)
		    memmask >>= 1;
		nmode = 1;
		break;
#ifdef I7090	/* Not on 704 */
/* Indicator opcodes */
	    case OP_IIA:
		ID ^= AC & AQMASK;
		break;
	    case OP_IIS:
		ID ^= SR;
		break;
	    case OP_IIR:
		ID ^= temp & RMASK;
		break;
	    case OP_IIL:
		ID ^= (temp & RMASK) << 18;
		break;
	    case OP_OAI:
		ID |= AC & AQMASK;
		break;
	    case OP_OSI:
		ID |= SR;
		break;
	    case OP_SIR:
		ID |= (temp & RMASK);
		break;
	    case OP_SIL:
		ID |= (temp & RMASK) << 18;
		break;
	    case OP_RIA:
		ID &= ~AC;
		break;
	    case OP_RIS:
		ID &= ~SR;
		break;
	    case OP_RIR:
		ID &= ~(temp & RMASK);
		break;
	    case OP_RIL:
		ID &= ~((temp & RMASK) << 18);
		break;
	    case OP_PIA:
		AC = ID & AQMASK;
		break;
	    case OP_PAI:
		ID = AC & AQMASK;
		break;
	    case OP_LDI:
		ID = SR;
		break;
	    case OP_STI:
		SR = ID;
		break;
	    case OP_ONT:
		if ((ID & SR) == SR)
		    IC++;
		break;
	    case OP_OFT:
		if ((ID & SR) == 0)
		    IC++;
		break;
	    case OP_RFT:
		if (0 == (temp & ID & RMASK))
		    IC++;
		break;
	    case OP_LFT:
		if (0 == (((temp & RMASK) << 18) & ID))
		    IC++;
		break;
	    case OP_RNT:
		if ((temp & RMASK) == (temp & ID & RMASK))
		    IC++;
		break;
	    case OP_LNT:
		if ((temp & RMASK) == (temp & (ID >> 18) & RMASK))
		    IC++;
		break;
	    case OP_TIO:
		do_trapmode;
		if ((ID & AC) == (AC & AQMASK))
		    do_transfer(MA);
		break;
	    case OP_TIF:
		do_trapmode;
		if ((ID & AC) == 0)
		    do_transfer(MA);
		break;
#endif
/* General index and load store opcodes */
	    case OP_XCA:
		SR = (AC & (PMASK));
		if (AC & AMSIGN)
		    SR |= MSIGN;
		AC = MQ;
		if (AC & APSIGN)
		    AC ^= AMSIGN | APSIGN;
		MQ = SR;
		break;
	    case OP_XCL:
		SR = AC & AQMASK;
		AC = MQ & AQMASK;
		MQ = SR;
		break;
	    case OP_AXC:
		SR = (t_uint64)(-(t_int64)SR);
		break;
	    case OP_AXT:
		break;
	    case OP_LXA:
		SR &= memmask;
		break;
	    case OP_LAC:
		SR = (t_uint64)(-(t_int64)SR);
		SR &= memmask;
		break;
	    case OP_LDQ:
		MQ = SR;
		break;
	    case OP_LXD:
		SR >>= 18;
		SR &= memmask;
		break;
	    case OP_LDC:
		SR >>= 18;
		SR = (t_uint64)(-(t_int64)SR);
		SR &= memmask;
		break;
	    case OP_CLA:
		AC = ((SR & MSIGN) << 2) | (SR & PMASK);
		break;
	    case OP_CLS:
		AC = (((SR & MSIGN) ^ MSIGN) << 2) | (SR & PMASK);
		break;
	    case OP_CAL:
		AC = SR;
		break;
	    case OP_STQ:
		SR = MQ;
		break;
	    case OP_ECA:
		temp = AC;
		AC = SR;
		SR = temp;
		break;
	    case OP_ECQ:
		temp = MQ;
		MQ = SR;
		SR = temp;
		break;
	    case OP_SLQ:
		SR = (SR & RMASK) | (MQ & LMASK);
		break;
	    case OP_STL:
		SR &= ~AMASK;
		SR |= IC & memmask;
		break;
	    case OP_STZ:
		SR = 0;
		break;
	    case OP_STO:
		SR = AC & PMASK;
		if (AC & AMSIGN)
		    SR |= MSIGN;
		break;
	    case OP_SLW:
		SR = AC & AQMASK;
		break;
	    case OP_STA:
		SR &= ~AMASK;
		SR |= AC & AMASK;
		break;
	    case OP_STD:
		SR &= ~DMASK;
		SR |= AC & DMASK;
		break;
	    case OP_STT:
		SR &= ~TMASK;
		SR |= AC & TMASK;
		break;
	    case OP_STP:
		SR &= ~PREMASK;
		SR |= AC & PREMASK;
		break;
	    case OP_SXA:
		SR &= ~AMASK;
		SR |= memmask & xr;
		update_xr(tag, xr);
		break;
	    case OP_SCA:
		SR &= ~AMASK;
		SR |= memmask & (-xr);
		update_xr(tag, xr);
		break;
	    case OP_SCD:
		SR &= ~DMASK;
		temp = (-xr) & memmask;
		temp &= AMASK;
		temp <<= 18;
		SR |= temp;
		update_xr(tag, xr);
		break;
	    case OP_SXD:
		SR &= ~DMASK;
		temp = xr & memmask;
		temp &= AMASK;
		temp <<= 18;
		SR |= temp;
		update_xr(tag, xr);
		break;
	    case OP_PDX:
		SR = memmask & (AC >> 18);
		break;
	    case OP_PDC:
		SR = (t_uint64)(memmask & (-(t_int64)(AC >> 18)));
		break;
	    case OP_PXD:
		SR = AC = xr & memmask;
		AC <<= 18;
		break;
	    case OP_PCD:
		AC = (-xr) & memmask;
		AC <<= 18;
		SR = xr & memmask;
		break;
	    case OP_PAX:
		SR = memmask & AC;
		break;
	    case OP_PAC:
		SR = (t_uint64)(memmask & (-(t_int64)AC));
		break;
	    case OP_PXA:
		AC = memmask & xr;
		SR = xr & memmask;
		break;
	    case OP_PCA:
		AC = AMASK & (-xr);
		SR = xr & AMASK;
		break;
/* Integer math */
	    case OP_CAS:
		if (AC & AMSIGN) {
		    if (SR & MSIGN) {
			if ((AC & AMMASK) == (SR & PMASK))
			    IC++;
			else if (((SR & PMASK) - (AC & AMMASK)) & AMSIGN)
			    IC += 2;
		    } else
			IC += 2;
		} else {
		    if ((SR & MSIGN) == 0) {
			if ((AC & AMMASK) == (SR & PMASK))
			    IC++;
			else if (((AC & AMMASK) - (SR & PMASK)) & AMSIGN)
			    IC += 2;
		    }
		}
		break;
	    case OP_LAS:
		SR = (AC & AMMASK) - SR;
		if (SR == 0)
		    IC++;
		if ((SR & AMSIGN))
		    IC += 2;
		break;
	    case OP_ACL:
	      ladd:
		SR += (AC & AQMASK);
		if (SR & AQSIGN)
		    SR++;
		AC = (AC & (AMSIGN | AQSIGN)) | (SR & AQMASK);
		break;
	    case OP_SBM:
		SR |= MSIGN;
		goto iadd;
	    case OP_ADM:
		SR &= PMASK;
		goto iadd;
	    case OP_SUB:
		SR ^= MSIGN;
	    case OP_ADD:
	      iadd:
		f = 0;
		/* Make AC Positive */
		if (AC & AMSIGN) {
		    f = 2;
		    AC &= AMMASK;
		}
		if (AC & APSIGN)
		    f |= 8;
		/* Check signes of SR & AC */
		if (((SR & MSIGN) && ((f & 2) == 0)) ||
		    (((SR & MSIGN) == 0) && ((f & 2) != 0))) {
		    AC ^= AMMASK;	/* One's compliment */
		    f |= 1;
		}
		AC = AC + (SR & PMASK);
		/* Check carry from Q */
		if (f & 1) {	/* Check if signs were not same */
		    if (AC & AMSIGN) {
			f ^= 2;
			AC++;
			if (((AC & APSIGN) != 0) != ((f & 8) != 0))
			    acoflag = 1;
		    } else {
			AC ^= AMMASK;	/* One's compliment */
		    }
		} else {
		    if (((AC & APSIGN) != 0) != ((f & 8) != 0))
			acoflag = 1;
		}
		/* Restore sign to AC */
		AC &= AMMASK;
		if (f & 2)
		    AC |= AMSIGN;
		break;
	    case OP_MPY:
	    case OP_MPR:
		decr = 043;
	    case OP_VLM + 1:
	    case OP_VLM:
		shiftcnt = decr;
		if (shiftcnt == 0)
		    break;
		f = 0;
		/* Save sign */
		if (MQ & MSIGN)
		    f |= 1;
		if (SR & MSIGN)
		    f |= 2;
		SR &= PMASK;
		MQ &= PMASK;
		AC = 0;		/* Clear AC */
		if (SR == 0) {
		    MQ = 0;
		} else {
		    while (shiftcnt-- > 0) {
			if (MQ & 1)
			    AC += SR;
			MQ >>= 1;
			if (AC & 1)
			    MQ |= ONEBIT;
			AC >>= 1;
		    }
		}
		if (opcode == OP_MPR && MQ & ONEBIT)
		    AC++;
		if (f & 2)
		    f ^= 1;
		if (f & 1) {
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}
		break;
	    case OP_DVH:
	    case OP_DVP:
		decr = 043;
	    case OP_VDH + 2:
	    case OP_VDH:
	    case OP_VDP + 2:
	    case OP_VDP:
		shiftcnt = decr;
		if (shiftcnt == 0)
		    break;
		/* Save sign */
		if (SR & MSIGN) {
		    SR &= PMASK;
		    f = 1;
		} else
		    f = 0;

		if (AC & AMSIGN)
		    f |= 2;

		/* Check if SR less then AC */
		if (((SR - (AC & AMMASK)) & AMSIGN) ||
		    (SR == (AC & AMMASK))) {
		    dcheck = 1;
		    if (CPU_MODEL < 0x90) {
			MQ &= PMASK;
			if (f == 2 || f == 1)
			    MQ |= MSIGN;
		    }
		    if (opcode == OP_DVH || opcode == OP_VDH
			|| opcode == (OP_VDH + 2)) {
			goto halt;
		    }
		    break;
		}
		/* Clear signs */
		MQ &= PMASK;
		AC &= AMMASK;
		sim_interval = sim_interval - shiftcnt;
		/* Do divide operation */
		do {
		    AC <<= 1;
		    AC &= AMMASK;
		    MQ <<= 1;
		    if (MQ & MSIGN) {
			MQ ^= MSIGN;
			AC |= 1;
		    }
		    if (SR <= AC) {
			AC -= SR;
			MQ |= 1;
		    }
		} while (--shiftcnt != 0);
		switch (f) {
		case 0:
		    break;
		case 3:
		    AC |= AMSIGN;
		    break;
		case 2:
		    AC |= AMSIGN;
		    /* FALL THRU */
		case 1:
		    MQ |= MSIGN;
		    break;
		}
		break;
/* Floating point */
	    case OP_USM:
	    case OP_FSM:
		SR |= MSIGN;
		goto fpadd;
	    case OP_FSB:
	    case OP_UFS:
		SR ^= MSIGN;	/* Reverse sign */
		goto fpadd;
	    case OP_FAM:
	    case OP_UAM:
		SR &= PMASK;	/* Clear SR sign */
	    case OP_FAD:
	    case OP_UFA:
	      fpadd:
		temp = 0;	/* Steal temp for errors */
		MQ = 0;
		f = 0;
		/* Extract AC char */
		shiftcnt = (int)(AC >> 27) & 01777;	/* Include P&Q */
		/* Diff SR char */
		shiftcnt -= (int)((SR >> 27) & 0377);
		if (shiftcnt > 0) {	/* AC Bigger */
		    /* Exchange AC & SR */
		    AC ^= SR;
		    SR ^= AC;
		    AC ^= SR;
		    /* Fix up signs */
		    if (SR & AMSIGN)
			SR |= MSIGN;
		    AC &= AMMASK;
		    if (AC & APSIGN)
			AC ^= (AMSIGN | APSIGN);
		} else		/* SR Bigger then AC, AC Smaller */
		    shiftcnt = -shiftcnt;	/* Change sign */
		fptemp = (int)((SR >> 27) & 0377);	/* Get exponent */
		/* Save AC & SR signs */
		if (AC & AMSIGN)
		    f |= 1;
		if (SR & MSIGN)
		    f |= 2;
		/* Clear sign */
		SR &= PMASK;
		AC &= FPMMASK;	/* Clear char and sign */
		shiftcnt &= 0377;
		if (shiftcnt >= 0 && shiftcnt < 077) {
		    sim_interval--;
		    while (shiftcnt > 0) {
			MQ >>= 1;
			if (AC & 1)
			    MQ |= FPNBIT;
			AC >>= 1;
			shiftcnt--;
		    }
		} else
		    AC = 0;
		sim_interval--;

		/* Do add */
		if (f == 2 || f == 1) {
		    AC -= (SR & FPMMASK);
		    /* If AC < 0 then SR was larger */
		    if (AC & AMSIGN) {
			AC = ~AC;
			if ((MQ & FPMMASK) != 0) {
			    MQ ^= FPMMASK;
			    MQ++;
			} else
			    AC++;
		    } else
			f ^= 2;	/* Change sign of AC */
		} else
		    AC += SR & FPMMASK;

		/* Check for overflow */
		if (AC & FPOBIT) {
		    if (AC & 1)
			MQ |= FPOBIT;
		    AC >>= 1;
		    MQ >>= 1;
		    /* OV check */
		    if (fptemp == 0377)
			temp |= FPACERR | FPOVERR;
		    fptemp++;
		}
		/* Are we normalizing */
		if (smode == 0 &&
		    (opcode == OP_FAD || opcode == OP_FSB ||
		     opcode == OP_FAM || opcode == OP_FSM)) {
		    sim_interval--;
		    while ((AC & FPNBIT) == 0 &&
			   ((AC & FPMMASK) != 0 || (MQ & FPMMASK) != 0)) {
			/* 704 does not check MQ when normalizing */
			if (CPU_MODEL == 0x4 && (AC & FPMMASK) == 0)
			    break;
			MQ <<= 1;
			AC <<= 1;
			if (MQ & FPOBIT) {
			    AC |= 1;
			    MQ &= ~FPOBIT;
			}
			if (fptemp == 0 && (temp & FPOVERR) == 0)
			    temp |= FPACERR;
			fptemp--;	/* UF Check */
		    }
		    if (AC == 0 && MQ == 0) {
			fptemp = 0;
			f |= f << 1;
		    }
		}

		/* Handle signifigance mode */
		if (smode && MQ & FPNBIT &&
		    (opcode == OP_FAD || opcode == OP_FSB ||
		     opcode == OP_FAM || opcode == OP_FSM)) {
		    sim_interval--;	/* Extra cycle */
		    /* If overflow, normalize */
		    AC++;
		    if (AC & FPOBIT) {
			AC >>= 1;	/* Move right one bit */
			/* OV check */
			if (fptemp == 0377)
			    temp |= FPACERR | FPOVERR;
			fptemp++;
		    }
		}

		/* Put pieces back together */
		AC &= FPMMASK;
		MQ &= FPMMASK;
		AC |= ((t_uint64) (fptemp & 01777)) << 27;
		if (AC != 0) {
		    if (fptemp < 27 && (temp & FPOVERR) == 0)
			temp |= FPMQERR;
		    fptemp -= 27;
		    MQ |= ((t_uint64) (fptemp & 0377)) << 27;
		}
		if (f & 2) {
		    AC |= AMSIGN;
		    MQ |= MSIGN;
		}
		if (temp == 0)
		    break;
	      dofptrap:
		if (CPU_MODEL != 0x4 && FTM) {
		    sim_interval = sim_interval - 1;	/* count down */
		    M[tbase] &= ~(AMASK | DMASK);
		    M[tbase] |= temp | (IC & memmask);
//		    if (FTM) 
		        IC = 010;
		} else {
		    if (temp & FPMQERR)
			mqoflag = 1;
		    if (temp & FPACERR)
			acoflag = 1;
		}
		break;
	    case OP_UFM:
	    case OP_FMP:
		AC = 0;
		temp = 0;
		/* Quick out for times 0 */
		if (SR == 0) {
		    MQ &= MSIGN;
		    if (MQ & MSIGN)
			AC |= AMSIGN;
		    break;
		}
		/* Result sign */
		if ((MQ & MSIGN) != (SR & MSIGN))
		    f = 1;
		else
		    f = 0;
		/* 7090 checks MQ for zero before multipling */
		if (CPU_MODEL == 0x90 && (MQ & PMASK) == 0) {
		    if (f)
			AC |= AMSIGN;
		    break;
		}

		/* Handle signifigance mode */
		if (smode) {
		    /* Find larger operand and move to MQ */
		    if ((MQ & FPMMASK) < (SR & FPMMASK)) {
			MQ ^= SR;
			SR ^= MQ;
			MQ ^= SR;
		    }
		    /* Now normalize number in MQ */
		    fptemp = (int)(MQ >> 27) & 0377;
		    MQ &= FPMMASK;
		    while ((MQ & FPNBIT) == 0 && MQ != 0) {
			fptemp--;
			MQ <<= 1;
		    }
		    /* If zero time zero, fix exponent */
		    if (MQ == 0 && (SR & FPMMASK) == 0) {
			fptemp -= 27;
			MQ = FPNBIT;
		    }
		} else
		    /* Extract characteristic */
		    fptemp = (int)(MQ >> 27) & 0377;
		fptemp += (int)(SR >> 27) & 0377;
		fptemp -= 128;
		MQ &= FPMMASK;
		SR &= FPMMASK;
		/* Do multiply */
		shiftcnt = 27;
		while (shiftcnt-- > 0) {
		    if (MQ & 1)
			AC += SR;
		    MQ >>= 1;
		    if (AC & 1)
			MQ |= FPNBIT;
		    AC >>= 1;
		    AC &= FPMMASK;
		}

		/* Normalize the result */
		if (opcode == OP_FMP) {
		    if ((AC & FPNBIT) == 0) {
			MQ <<= 1;
			AC <<= 1;
			if (MQ & FPOBIT)
			    AC |= 1;
			MQ &= FPMMASK;
			fptemp--;
			if (smode && (AC & FPNBIT) == 0 &&
			    (AC & (FPNBIT >> 1)) == 0) {
			    MQ <<= 1;
			    AC <<= 1;
			    if (MQ & FPOBIT)
				AC |= 1;
			    MQ &= FPMMASK;
			    fptemp--;
			}
		    }
		    if (smode && MQ & FPNBIT) {
			sim_interval--;	/* Extra cycle */
			/* If overflow, normalize */
			AC++;
			if (AC & FPOBIT) {
			    AC >>= 1;	/* Move right one bit */
			    fptemp++;
			}
		    }
		    if (AC == 0)
			fptemp = 0;
		}

		if (AC != 0 || opcode == OP_UFM || smode) {
		    if (fptemp < 0)
			temp |= FPACERR;
		    else if (fptemp > 0377)
			temp |= FPOVERR | FPACERR;
		    AC |= ((t_uint64) (fptemp & 01777)) << 27;
		    fptemp -= 27;
		    if (fptemp < 0)
			temp |= FPMQERR;
		    else if (fptemp > 0377)
			temp |= FPOVERR | FPMQERR;
		    MQ |= ((t_uint64) (fptemp & 0377)) << 27;	/* UF Check */
		}
		if (f & 1) {
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}
		if (temp != 0)
		    goto dofptrap;
		break;
	    case OP_FDH:
	    case OP_FDP:
		/* Sign of SR => MQ */
		if ((SR & MSIGN) != ((AC >> 2) & MSIGN))
		    f = 1;
		else
		    f = 0;
		if (AC & AMSIGN)
		    f |= 2;
		if (CPU_MODEL != 0x4)
		    MQ = 0;
		shiftcnt = 27;

		/* Handle signifigance mode */
		if (smode) {
		    /* Divide check if 0 divisor */
		    if ((SR & FPMMASK) == 0) {
			dcheck = 1;
			if (f & 1)
			    MQ |= MSIGN;
			if (opcode == OP_FDH)
			    goto halt;
		    }
		    fptemp2 = (int)(AC >> 27) & 0377;
		    AC &= FPMMASK;
		    /* If dividend 0, adjust exponent */
		    if (AC == 0) {
			while ((SR & FPNBIT) == 0) {
			    SR <<= 1;
			    fptemp2--;
			}
			if (fptemp2 < 0)
			    temp |= FPSPERR | FPMQERR;
			AC = ((t_uint64) (fptemp2 & 01777)) << 27;
			if (FTM && CPU_MODEL != 0x4 && fptemp2 < 27)
			    temp |= FPSPERR | FPACERR;
			fptemp2 -= 27;
			MQ = ((t_uint64) (fptemp2 & 0377)) << 27;
			/* Fix signs */
			if (f & 1)
			    MQ |= MSIGN;
			if (f & 2)	/* Sign does not change */
			    AC |= AMSIGN;
			break;
		    }
		    fptemp = (int)(SR >> 27) & 0377;
		    SR &= FPMMASK;
		    /* Normalize dividend if larger fraction */
		    if (AC > (SR & FPMMASK)) {
			while ((AC & FPOBIT) == 0) {
			    fptemp2--;
			    AC <<= 1;
			}
			/* Normalize SR, denomalize AC */
			/* We checked before for SR==0 */
			while ((SR & FPOBIT) == 0) {
			    SR <<= 1;
			    fptemp2--;
			    AC >>= 1;
			    fptemp++;
			}
		    } else if (AC < (SR & FPMMASK)) {
			/* Normalize SR, denomalize AC */
			/* We checked before for SR==0 */
			while ((SR & FPOBIT) == 0) {
			    SR <<= 1;
			    fptemp--;
			    AC >>= 1;
			    fptemp2++;
			}
		    }
		    if ((SR & (FPOBIT >> 1)) == 0)
			shiftcnt--;
		    goto fpdivide;
		}

		/* Begin common FDP/FDH code */
		temp = (AC & FPMMASK) - ((SR & FPMMASK) << 1);
		if ((temp & AMSIGN) == 0 || (SR & FPMMASK) == 0) {
		    dcheck = 1;
		    if (f & 1)
			MQ |= MSIGN;
		    if (opcode == OP_FDH)
			goto halt;
		    break;
		}
		temp = 0;
		/* Check for divide by 0 */
		if ((AC & FPMMASK) == 0) {
		    AC = 0;
		    if (CPU_MODEL != 0x4)
			f &= 1;
		} else {
		    /* Split appart fraction and charateristics */
		    fptemp2 = (int)(AC >> 27) & 0377;
		    fptemp = (int)(SR >> 27) & 0377;
		    AC &= FPMMASK;
		    SR &= FPMMASK;
		  fpdivide:
		    /* Precheck SR less then AC */
		    if (((AC - SR) & AMSIGN) == 0) {
			if (AC & 1)
			    MQ |= FPNBIT;
			AC >>= 1;
			fptemp2++;
		    }
		    /* Do actual divide */
		    do {
			AC <<= 1;
			MQ <<= 1;
			if (MQ & FPOBIT) {
			    MQ &= ~FPOBIT;
			    AC |= 1;
			}
			if (SR <= AC) {
			    AC -= SR;
			    MQ |= 1;
			}
		    } while (--shiftcnt != 0);

		    /* Compute new characteristic */
		    AC &= FPMMASK;
		    fptemp = (fptemp2 - fptemp) + 128;	/* UF check */
		    if (fptemp > 0377)
			temp |= FPSPERR | FPOVERR | FPMQERR;
		    else if (fptemp < 0)
			temp |= FPSPERR | FPMQERR;
		    MQ |= ((t_uint64) (fptemp & 0377)) << 27;
		    if (FTM && CPU_MODEL != 0x4 && fptemp2 < 27)
			temp |= FPSPERR | FPACERR;
		    fptemp2 -= 27;
		    AC |= ((t_uint64) (fptemp2 & 01777)) << 27;	/* UF check */
		}
		/* Fix signs on results */
		if (f & 1)
		    MQ |= MSIGN;
		if (f & 2)	/* Sign does not change */
		    AC |= AMSIGN;
		if (temp != 0)
		    goto dofptrap;
		if (smode) {
		    sim_interval = sim_interval - 1;	/* count down */
		    M[tbase] &= ~(AMASK | DMASK);
		    M[tbase] |= (IC & memmask);
		    IC = 011;
		}
		break;
#ifdef I7090	/* Not on 704 */
/* Double precision floating point */
	    case OP_DFSM:
	    case OP_DUSM:
		SR |= MSIGN;
		goto dfpadd;
	    case OP_DFSB:
	    case OP_DUFS:
		SR ^= MSIGN;	/* Reverse sign */
		goto dfpadd;
	    case OP_DFAM:
	    case OP_DUAM:
		SR &= PMASK;	/* Clear SR sign */
	    case OP_DFAD:
	    case OP_DUFA:
	      dfpadd:
		temp = 0;	/* Steal temp for errors */
		if (MA & 1 && FTM) {
		    temp = FPDPERR;
		    goto dofptrap;
		}

		shiftcnt = (int)(AC >> 27) & 01777;	/* Include P&Q */
		shiftcnt -= (int)(SR >> 27) & 0377;

		f = 0;
		/* Save AC & ID signs */
		if (AC & AMSIGN)
		    f |= 1;
		if (SR & MSIGN)
		    f |= 2;
		if (shiftcnt > 0) {	/* AC Bigger */
		    fptemp = (int)(AC >> 27) & 0377;
		    if (shiftcnt <= 0100) {
			ID = AC;
			if (f & 1)	/* Copy sign */
			    ID |= MSIGN;
		    }
		    f = (f >> 1) | ((1 & f) << 1);	/* Exchange signs */
		    if (shiftcnt > 077) {
			if ((AC & FPNBIT) == 0)
			    ID = AC;
			goto dpfnorm;
		    } else {
			AC &= ~FPMMASK;
			AC |= SR & FPMMASK;
			SR &= ~FPMMASK;
			SR |= MQ & FPMMASK;
			MQ &= ~FPMMASK;
			MQ |= M[MA | 1] & FPMMASK;
		    }
		    /* AC=c, MQ=d SR=b, ID=a */
		} else {	/* ID Bigger then AC, AC Smaller */
		    shiftcnt = -shiftcnt;	/* Change sign */
		    fptemp = (int)(SR >> 27) & 0377;
		    if (shiftcnt > 077) {
			if (SR & FPNBIT) {
			    /* Early exit */
			    AC = SR;
			    fptemp = (int)(AC >> 27) & 0377;
			    ID = (SR & (~FPMMASK)) | (MQ & FPMMASK);
			    MQ = M[MA | 1];
			    goto dpdone;
			}
			MQ &= ~FPMMASK;
			AC &= ~FPMMASK;
		    }
		    ID = SR;
		    SR &= ~FPMMASK;
		    SR |= M[MA | 1] & FPMMASK;
		}
		/* Clear sign */
		AC &= FPMMASK;	/* Clear char and sign */
		MQ &= FPMMASK;
		shiftcnt &= 0377;
		if (shiftcnt >= 0 && shiftcnt < 0177) {
		    sim_interval--;
		    while (shiftcnt > 0) {
			MQ >>= 1;
			if (AC & 1)
			    MQ |= FPNBIT;
			AC >>= 1;
			shiftcnt--;
		    }
		} else {
		    AC = 0;
		    MQ = 0;
		}
		sim_interval--;

		/* Do add */
		if (f == 2 || f == 1) {
		    /* Ones compliment AC/MQ */
		    MQ ^= FPMMASK;
		    AC ^= FPMMASK;
		    /* Form 2's compliment */
		    MQ++;
		    if (MQ & FPOBIT) {
			AC++;
			MQ ^= FPOBIT;
		    }
		    /* Subract ID/SR */
		    MQ += (SR & FPMMASK);
		    if (MQ & FPOBIT) {
			AC++;
			MQ ^= FPOBIT;
		    }
		    AC += (ID & FPMMASK);
		    /* If AC,MQ < 0 then ID,SR was larger */
		    if (AC & FPOBIT)
			AC ^= FPOBIT;
		    else {
			f ^= 2;	/* Change sign of AC */
			MQ ^= FPMMASK;
			AC ^= FPMMASK;
			MQ++;
			if (MQ & FPOBIT) {
			    AC++;
			    MQ ^= FPOBIT;
			}
		    }
		} else {
		    MQ += SR & FPMMASK;
		    /* Propegate carry */
		    if (MQ & FPOBIT) {
			AC++;
			MQ ^= FPOBIT;
		    }
		    AC += ID & FPMMASK;
		}

		/* Check for overflow */
		if (AC & FPOBIT) {
		    if (AC & 1)
			MQ |= FPOBIT;
		    AC >>= 1;
		    MQ >>= 1;
		    /* OV check */
		    if (fptemp == 0377)
			temp |= FPACERR | FPOVERR;
		    fptemp++;
		}

	      dpfnorm:
		/* Are we normalizing */
		if (opcode == OP_DFAD || opcode == OP_DFSB ||
		    opcode == OP_DFAM || opcode == OP_DFSM) {
		    sim_interval--;
		    /* Preshift before we normalize */
		    if ((AC & FPMMASK) == 0 && (MQ & FPMMASK) != 0) {
			AC |= MQ & FPMMASK;
			MQ &= ~FPMMASK;
			if (fptemp < 27)
			    temp |= FPACERR;
			fptemp -= 27;
		    }
		    while ((AC & FPNBIT) == 0 && (AC & FPMMASK) != 0) {
			MQ <<= 1;
			AC <<= 1;
			if (MQ & FPOBIT) {
			    AC |= 1;
			    MQ &= ~FPOBIT;
			}
			if (fptemp == 0 && (temp & FPOVERR) == 0)
			    temp |= FPACERR;
			fptemp--;	/* UF Check */
		    }
		    if (AC == 0 && MQ == 0) {
			fptemp = 0;
			f |= f << 1;
		    }
		}
	      dpdone:
		/* Put pieces back together */
		AC &= FPMMASK;
		MQ &= FPMMASK;
		AC |= ((t_uint64) (fptemp & 01777)) << 27;
		if (AC != 0) {
		    if (fptemp < 27 && (temp & FPOVERR) == 0)
			temp |= FPMQERR;
		    fptemp -= 27;
		    MQ |= ((t_uint64) (fptemp & 0377)) << 27;
		}
		if (f & 2)
		    AC |= AMSIGN;
		if (f & 2)
		    MQ |= MSIGN;
		if (temp != 0)
		    goto dofptrap;
		break;
	    case OP_DFMP:
	    case OP_DUFM:
		temp = 0;
		if (MA & 1) {
		    temp |= FPDPERR;
		    if (FTM)
			goto dofptrap;
		}
		/* Quick out for zero result. */
		fptemp = (int)(SR >> 27) & 0377;
		if ((SR & PMASK) == 0) {
		    AC = MQ = 0;
		    break;
		}

		/* Compute exponent */
		fptemp += (int)(AC >> 27) & 0377;
		fptemp -= 128;

		/* Figure out sign */
		if (((AC & AMSIGN) != 0) != (0 != (SR & MSIGN)))
		    f = 1;
		else
		    f = 0;

		/* Prepare for first multiply */
		MQ &= FPMMASK;	/* B */
		ID = AC & FPMMASK;	/* A */
		if (AC == 0 && MQ == 0) {
		    ID = SR & (MSIGN | FPCMASK);
		    AC = (f) ? AMSIGN : 0;
		    MQ = (f) ? MSIGN : 0;
		    if (temp != 0)
			goto dofptrap;
		    break;
		}

		AC = 0;
		/* First multiply B * C */
		if ((SR & FPMMASK) != 0 && MQ != 0) {
		    SR &= FPMMASK;
		    shiftcnt = 27;
		    while (shiftcnt-- > 0) {
			if (MQ & 1)
			    AC += SR;
			MQ >>= 1;
			if (AC & 1)
			    MQ |= FPNBIT;
			AC >>= 1;
			AC &= FPMMASK;
		    }
		}

		/* Adjust registers for second multiply */
		/* ID:A=xxx-0, MQ:b =0 SR:c = xx:xx d=xx:xxx */
		ID ^= SR;	/* A, C */
		SR ^= ID;
		ID ^= SR;	/* C, A */
		MQ = M[MA | 1];	/* D */
		if (MQ == 0 || (SR & FPMMASK) == 0) {
		    /* Early out two. */
		    if ((SR & FPMMASK) == 0 && opcode == OP_DFMP) {
			AC = (f) ? AMSIGN : 0;
			MQ = (f) ? MSIGN : 0;
			if (temp != 0)
			    goto dofptrap;
			break;
		    }
		    MQ = SR;	/* A */
		    SR = ID;	/* C */
		    /* Early out three. */
		    if ((SR & FPMMASK) == 0 && opcode == OP_DFMP) {
			AC = (f) ? AMSIGN : 0;
			MQ = (f) ? MSIGN : 0;
			ID &= FPMMASK;
			if (temp != 0)
			    goto dofptrap;
			break;
		    }
		    ID &= ~FPMMASK;
		    ID |= FPMMASK & AC;	/* BC */
		} else {
		    ibr = AC & FPMMASK;	/* BC */
		    MQ &= FPMMASK;
		    AC = 0;
		    /* Second multiply A * D */
		    shiftcnt = 27;
		    while (shiftcnt-- > 0) {
			if (MQ & 1)
			    AC += SR;
			MQ >>= 1;
			if (AC & 1)
			    MQ |= FPNBIT;
			AC >>= 1;
			AC &= FPMMASK;
		    }
		    MQ = SR;	/* A */
		    SR = ID;	/* C */
		    ID = FPMMASK & ibr;	/* BC */
		    AC += ibr;	/* AD + BC */
		}
		SR &= FPMMASK;

		/* AC:A=220-77, MQ:b =0 SR:c = 220-77 d=0 mq = 7601 */
		/* third multiply high * high */
		if (MQ == 0 || SR == 0) {
		    /* MQ == A, AC = AD + BC, ID = BC, SR = C */
		    MQ = AC;
		    AC = 0;
		    if (opcode == OP_DFMP && SR == 0)
			ID &= FPMMASK;
		} else {
		    MQ &= FPMMASK;	/* Just to be sure */
		    ID &= FPMMASK;	/* Clear char */
		    shiftcnt = 27;
		    while (shiftcnt-- > 0) {
			if (MQ & 1)
			    AC += SR;
			MQ >>= 1;
			if (AC & 1)
			    MQ |= FPNBIT;
			AC >>= 1;
			AC &= FPMMASK;
		    }
		}

		/* Normalize if DFMP */
		if (opcode == OP_DFMP) {
		    /* Check for true zero result */
		    if (MQ == 0 && AC == 0) {
			fptemp = 0;
		    } else if ((AC & FPNBIT) == 0 && (AC & FPMMASK) != 0) {
			MQ <<= 1;
			AC <<= 1;
			if (MQ & FPOBIT)
			    AC |= 1;
			MQ &= FPMMASK;
			fptemp--;	/* UF check */
		    }
		}

		/* Fix exponents and check for over/underflow */
		if (fptemp != 0) {
		    if (fptemp < 0)
			temp |= FPACERR | FPMQERR;
		    else if (fptemp < 27)
			temp |= FPMQERR;
		    else if (fptemp > 0377)
			temp |= FPOVERR | FPACERR;
		    AC |= ((t_uint64) (fptemp & 01777)) << 27;
		    fptemp -= 27;
		    if (fptemp > 0377)
			temp |= FPOVERR | FPMQERR;
		    MQ |= ((t_uint64) (fptemp & 0377)) << 27;	/* UF Check */
		}

		/* Restore signs */
		if (f) {
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}

		/* Handle trapping */
		if (temp != 0)
		    goto dofptrap;
		break;

	    case OP_DFDH:
	    case OP_DFDP:
		if (MA & 1) {
		    temp = FPDPERR;
		    if (FTM)
			goto dofptrap;
		}
		/* Sign of SR => MQ */
		temp = (AC & FPMMASK) - ((SR & FPMMASK) << 1);
		if ((temp & AMSIGN) == 0 || (SR & FPMMASK) == 0) {
		    dcheck = 1;
		    if (opcode == OP_DFDH)
			goto halt;
		    break;
		}

		/* Result sign */
		if (((AC & AMSIGN) != 0) != (0 != (SR & MSIGN)))
		    f = 1;
		else
		    f = 0;
		if (AC & AMSIGN)	/* Sign A+B */
		    f |= 2;
		if (SR & MSIGN)	/* Sign C+D */
		    f |= 4;

		/* Check for divide by 0 */
		if ((MQ & FPMMASK) == 0 && (AC & FPMMASK) == 0) {
		    /* Divide check by 0 */
		    ID = MQ = (f & 1) ? MSIGN : 0;
		    AC = (f & 1) ? AMSIGN : 0;
		    break;
		}
		/* Split appart fraction and charateristics */
		fptemp2 = (int)(AC >> 27) & 01777;
		fptemp = (int)(SR >> 27) & 0377;
		fptemp = fptemp2 - fptemp;
		fptemp += 0200;

		ID = SR & FPMMASK;	/* ID = C */
		AC &= FPMMASK;	/* A */
		MQ &= FPMMASK;	/* B */
		SR &= FPMMASK;	/* C */
		ibr = M[MA | 1] & FPMMASK;	/* D */

		/* Precheck SR less then AC */
		if (((AC - SR) & AMSIGN) == 0) {
		    if (AC & 1)
			MQ |= FPOBIT;
		    MQ >>= 1;
		    AC >>= 1;
		    f |= 16;	/* Q>1 trigger */
		}

		/* Divide AB / C => AC=R, MQ=Q1 */
		shiftcnt = 27;
		do {
		    AC <<= 1;
		    MQ <<= 1;
		    if (MQ & FPOBIT) {
			MQ &= ~FPOBIT;
			AC |= 1;
		    }
		    if (SR <= AC) {
			AC -= SR;
			MQ |= 1;
		    }
		} while (--shiftcnt != 0);
		/* ID=xxx.0, SR=C, ibr=D, AC=R1, MQ=Q1 */
		/* Set up for multiply */
		SR = MQ;	/* SR <- Q1' */
		MQ = ibr;	/* MQ <- D */
		ibr = AC;	/* ibr <- R1 */
		AC = 0;
		/* ID=xxx.C, SR=Q1, ibr=R1, AC=0, MQ=D */
		/* Multiply Q1*D => AC,MQ */
		shiftcnt = 27;
		while (shiftcnt-- > 0) {
		    if (MQ & 1)
			AC += SR;
		    MQ >>= 1;
		    if (AC & 1)
			MQ |= FPNBIT;
		    AC >>= 1;
		    AC &= FPMMASK;
		}
		/* ID=C.C, SR=Q1, ibr=R1, AC=Q1Dh, MQ=Q1Dl */
		/* AC <- R1 - Q1D */
		if (ibr < AC) {
		    AC = AC - ibr;
		    f |= 8;	/* Sign R1 - Q1D */
		} else
		    AC = ibr - AC;
		MQ = 0;		/* MQ <- 0 */
		ID ^= SR;	/* SR<>ID Q1<>C */
		SR ^= ID;
		ID ^= SR;

		/* Divide R1 - Q1D / C => AC=R, MQ=Q */
		if (f & 16)
		    fptemp++;
		/* Adjust ID register to correct exponent */
		ID |= ((t_uint64) (fptemp & 0377)) << 27;
		if (f & 1)
		    ID |= MSIGN;
		/* Check before final divide */
		temp = AC - (SR << 1);
		if ((temp & AMSIGN) == 0 || SR == 0) {
		    if ((f & 0xa) == 2 || (f & 0xa) == 8) {
			MQ |= MSIGN;
			AC |= AMSIGN;
		    }
		    dcheck = 1;
		    if (opcode == OP_DFDH)
			goto halt;
		    break;
		}

		/* Check Quotient > 1 */
		if (((AC - SR) & AMSIGN) == 0) {
		    if (AC & 1)
			MQ |= FPNBIT;
		    MQ >>= 1;
		    AC >>= 1;
		    f |= 32;	/* Q2>1 trigger */
		}

		/* Actual divide (R1-Q1D/C) => AC=R2, MQ=Q2 */
		shiftcnt = 27;
		do {
		    AC <<= 1;
		    MQ <<= 1;
		    if (MQ & FPOBIT) {
			MQ &= ~FPOBIT;
			AC |= 1;
		    }
		    if (SR <= AC) {
			AC -= SR;
			MQ |= 1;
		    }
		} while (--shiftcnt != 0);
		/* ID=Q1, SR=C, ibr=R1, AC=R1-Q1D/C, MQ=Q2 */
		AC = 0;
		if (f & 32) {
		    MQ <<= 1;
		    if (MQ & FPOBIT) {
			AC |= 1;
			MQ ^= FPOBIT;
		    }
		}

		/* MQ = Q2, ID=Q1, SR=C, ibr=R1, AC=xxx */
		/* Sign Q2 = sign C+D, sign Q1 = sign R1-Q1D */
		temp = (MA & 1) ? FPDPERR : 0;	/* Restore errors */

		SR = ID & FPMMASK;	/* SR <- Q1 */
		if ((f & 8)) {
		    AC = SR - AC;
		    MQ ^= FPMMASK;
		    MQ++;
		    if (MQ & FPOBIT) {
			MQ &= FPMMASK;
		    } else {
			AC--;
		    }
		} else {
		    AC += SR;
		}
		/* Check for overflow */
		if (AC & FPOBIT) {
		    if (AC & 1)
			MQ |= FPOBIT;
		    AC >>= 1;
		    MQ >>= 1;
		    /* OV check */
		    if (fptemp == 0377)
			temp |= FPACERR | FPOVERR;
		    fptemp++;
		}

		/* Normalize results */
		while ((AC & FPNBIT) == 0 &&
		       ((AC & FPMMASK) != 0 || (MQ & FPMMASK) != 0)) {
		    MQ <<= 1;
		    AC <<= 1;
		    if (MQ & FPOBIT) {
			AC |= 1;
			MQ ^= FPOBIT;
		    }
		    if (fptemp == 0 && (temp & FPOVERR) == 0)
			temp |= FPACERR;
		    fptemp--;	/* UF Check */
		}
		MQ &= FPMMASK;
		if (AC == 0 && MQ == 0)
		    fptemp = 0;
		/* Compute new characteristic */
		if (fptemp > 0377)
		    temp |= FPOVERR | FPACERR;
		else if (fptemp < 0)
		    temp |= FPACERR | FPMQERR;
		else if (fptemp < 27)
		    temp |= FPMQERR;
		AC |= ((t_uint64) (fptemp & 01777)) << 27;
		fptemp -= 27;
		if (fptemp > 0377)
		    temp |= FPOVERR | FPMQERR;
		MQ |= ((t_uint64) (fptemp & 0377)) << 27;
		/* Fix signs on results */
		if (f & 1) {	/* Sign does not change */
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}
		if (temp != 0)
		    goto dofptrap;
		break;
	    case OP_DLD:
		AC = ((SR & MSIGN) << 2) | (SR & PMASK);
		f = MA & 1;
		MA = memmask & (MA | 1);
		if (bcore)
		    MA |= 0100000;
		MQ = ReadP(MA);
		if (f) {
		    temp = FPDPERR;
		    if (FTM) {
			goto dofptrap;
		    }
		}
		break;
	    case OP_DST:
		SR = (AC & (APSIGN - 1));
		if (AC & AMSIGN)
		    SR |= MSIGN;
		WriteP(MA, SR);
		MA = memmask & (MA + 1);
		if (bcore)	/* Excuting in B core? check address */
		    MA |= 0100000;
		SR = MQ;
		break;
#endif

/* Logic operations */
	    case OP_ORA:
		AC |= SR & AQMASK;
		break;
	    case OP_ORS:
		SR |= AC;
		SR &= AQMASK;
		break;
	    case OP_ANA:
		AC &= SR;
		AC &= AQMASK;
		break;
	    case OP_ANS:
		SR &= AC;
		SR &= AQMASK;
		break;
	    case OP_ERA:
		AC ^= SR;
		AC &= AQMASK;	/* Clear S & Q  */
		break;

#ifdef I7090	/* Not on 704 */
/* Conversion */
	    case OP_CVR + 3:
	    case OP_CVR + 2:
	    case OP_CVR + 1:
	    case OP_CVR:
		shiftcnt = (int)(temp >> 18L) & 0377;
		if (AC & AMSIGN) {
		    f = 1;
		    AC &= AMMASK;
		} else
		    f = 0;
		while (shiftcnt != 0) {
		    MA += (uint16)(AC & 077);
		    ReadMem();
		    MA = (uint16)(AMASK & SR);
		    AC >>= 6;
		    AC |= SR & (077 << 30);
		    shiftcnt--;
		}
		/* Save XR if tag set */
		if (tag & 1)
		    XR[1] = (uint16)(MA & AMASK);
		/* restore sign */
		if (f)
		    AC |= AMSIGN;
		break;

	    case OP_CAQ + 3:
	    case OP_CAQ + 2:
	    case OP_CAQ + 1:
	    case OP_CAQ:
		shiftcnt = (int)(temp >> 18L) & 0377;
		while (shiftcnt != 0) {
		    MA += (uint16)(MQ >> 30) & 077;
		    ReadMem();
		    MA = (uint16)(AMASK & SR);
		    MQ <<= 6;
		    MQ |= (MQ >> 36) & 077;
		    MQ &= WMASK;
		    AC += SR;
		    AC &= AMMASK;
		    shiftcnt--;
		}
		if (tag & 1)
		    XR[1] = (uint16)(MA & AMASK);
		break;

	    case OP_CRQ + 3:
	    case OP_CRQ + 2:
	    case OP_CRQ + 1:
	    case OP_CRQ:
		shiftcnt = (int)(temp >> 18L) & 0377;
		while (shiftcnt != 0) {
		    MA += (uint16)(MQ >> 30) & 077;
		    ReadMem();
		    MA = (uint16)(AMASK & SR);
		    MQ <<= 6;
		    MQ &= (WMASK ^ 077);
		    MQ |= (SR >> 30) & 077;
		    shiftcnt--;
		}
		if (tag & 1)
		    XR[1] = (uint16)(MA & AMASK);
		break;
#endif

/* Shift */
	    case OP_LLS:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		/* Save sign */
		if (MQ & MSIGN)
		    f = 1;
		else
		    f = 0;
		/* Clear it for now */
		AC &= AQMASK;
		while (shiftcnt-- > 0) {
		    MQ <<= 1;
		    AC <<= 1;
		    if (MQ & MSIGN)
			AC |= 1;
		    if (AC & APSIGN)
			acoflag = 1;
		}
		/* Restore sign when done */
		AC &= AMMASK;
		MQ &= PMASK;
		if (f) {
		    AC |= AMSIGN;
		    MQ |= MSIGN;
		}
		break;
	    case OP_LRS:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		/* Save sign */
		if (AC & AMSIGN)
		    f = 1;
		else
		    f = 0;
		/* Clear it for now */
		AC &= AMMASK;
		MQ &= PMASK;
		while (shiftcnt-- > 0) {
		    if (AC & 1)
			MQ |= MSIGN;;
		    MQ >>= 1;
		    AC >>= 1;
		}
		/* Restore sign when done */
		AC &= AMMASK;
		if (f) {
		    AC |= AMSIGN;
		    MQ |= MSIGN;
		}
		break;
	    case OP_ALS:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		/* Save sign */
		if (AC & AMSIGN)
		    f = 1;
		else
		    f = 0;
		/* Clear it for now */
		AC &= AQMASK;
		while (shiftcnt-- > 0) {
		    AC <<= 1;
		    if (AC & APSIGN)
			acoflag = 1;
		}
		/* Restore sign and overflow when done */
		AC &= AMMASK;
		if (f)
		    AC |= AMSIGN;
		break;
	    case OP_ARS:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		/* Save sign */
		if (AC & AMSIGN)
		    f = 1;
		else
		    f = 0;
		/* Clear it for now */
		AC &= AMMASK;
		AC >>= shiftcnt;
		/* Restore sign when done */
		if (f)
		    AC |= AMSIGN;
		break;

	    case OP_LGL:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		/* Save sign */
		if (AC & AMSIGN)
		    f = 1;
		else
		    f = 0;
		/* Clear it for now */
		AC &= AMMASK;
		while (shiftcnt-- > 0) {
		    AC <<= 1;
		    if (MQ & MSIGN)
			AC |= 1;
		    MQ <<= 1;
		    if (AC & APSIGN)
			acoflag = 1;
		}
		/* Restore sign when done */
		AC &= AMMASK;
		MQ &= WMASK;
		if (f)
		    AC |= AMSIGN;
		break;
	    case OP_LGR:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		/* Save sign */
		if (AC & AMSIGN)
		    f = 1;
		else
		    f = 0;
		/* Clear it for now */
		AC &= AMMASK;
		while (shiftcnt-- > 0) {
		    MQ >>= 1;
		    if (AC & 1)
			MQ |= MSIGN;
		    AC >>= 1;
		}
		/* Restore sign when done */
		AC &= AMMASK;
		if (f)
		    AC |= AMSIGN;
		break;
	    case OP_RQL:
		shiftcnt = MA & 0377;
		sim_interval = sim_interval - (shiftcnt >> 6);
		while (shiftcnt-- > 0) {
		    MQ <<= 1;
		    if (MQ & AQSIGN)
			MQ |= 1;
		    MQ &= WMASK;
		}
		break;

/* 704 Input output Instructions */
	    case OP_LDA:
		if (chan_select(0)) {
		    extern DEVICE drm_dev;
		    drum_addr = (uint32)(MQ = SR);
		    sim_debug(DEBUG_DETAIL, &drm_dev,
				 "set address %012llo\n\r", drum_addr);
		    MQ <<= 1;
		    chan_clear(0, DEV_FULL);	/* In case we read something before we
						   got here */
		} else
		    iocheck = 1;
		break;
	    case OP_CPY:
	    case OP_CAD:
		/* If no channel, set Iocheck and treat as nop */
		if (chan_unit[0].flags & UNIT_DIS) {
		    iocheck = 1;
		    break;
		}

		/* If device disconnecting, just wait */
		if (chan_test(0, DEV_DISCO)) {
		    iowait = 1;
		    break;
		}

		/* Instruct is NOP first time */
		/* Incomplete last word leaves result in MQ */
		if (chan_select(0)) {
		    extern uint8 bcnt[NUM_CHAN];
		    chan_set(0, STA_ACTIVE);
		    switch (chan_flags[0] & (DEV_WRITE | DEV_FULL)) {
		    case DEV_WRITE | DEV_FULL:
		    case 0:
			/* On EOR skip 1, on EOF skip two */
			if (chan_test(0, CHS_EOF|CHS_EOT|DEV_REOR))  
			    chan_set(0, DEV_DISCO);
			iowait = 1;
			break;
		    case DEV_WRITE:
			MQ = assembly[0] = SR;
			bcnt[0] = 6;
			chan_set(0, DEV_FULL);
			if (opcode == OP_CAD)
			    goto ladd;
			break;
		    case DEV_FULL:
			SR = MQ;
			WriteP(MA, MQ);
			bcnt[0] = 6;
			chan_clear(0, DEV_FULL);
			if (opcode == OP_CAD)
			    goto ladd;
			break;
		    }
		} else {
		    /* If channel not active, turn on io-check */
		    if (chan_test(0, STA_ACTIVE) == 0) {
		        iocheck = 1;
		        break;
		    }

		    if (chan_stat(0, CHS_EOF|CHS_EOT)) {
			IC++;
		    /* On EOR skip two */
		    } else if (chan_stat(0, DEV_REOR)) {
			IC += 2;
		    /* Advance 1 on Error and set iocheck */
		    } else if (chan_stat(0, CHS_ERR)) {
		        iocheck = 1;
		        IC++;
		    }
		    chan_clear(0, STA_ACTIVE|DEV_REOR|CHS_ERR);
		    break;
		}
		break;

#ifdef I7090	/* Not on 704 */
/* Input/Output Instuctions */
	    case OP_ENB:
		ioflags = SR;
		itrap = 1;
	        sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo\n", ioflags);
		ihold = 1;

		/*
		 * IBSYS can't have an trap right after ENB or it will hang
  		 * on a TTR * in IBNUC.
		 */
		if (CPU_MODEL >= 0x90)
		    break;

		/* Don't wait if EOF or Error is pending but hold if trap */
	        temp = 00000001000001LL;
		for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
		    if (chan_active(shiftcnt) == 0) {
		        if (temp & ioflags & AMASK &&
				iotraps & 1 << shiftcnt)
			    break;
		        if ((temp & ioflags & AMASK &&
				 chan_test(shiftcnt, CHS_EOF)) ||
		            (temp & ioflags & DMASK &&
				 chan_test(shiftcnt, CHS_ERR))) {
			    ihold = 0;
			    break;
			}
		    }
		    temp <<= 1;
		} 
		break;
#endif

	    case OP_RDS:		/* Read select */
		if (CPU_MODEL == 0x4) 
		    MQ = 0;
		else if (first_rdwr == 0) {
		     iotraps &= ~(1 << ((MA >> 9) & 017));
		     first_rdwr = 1;
		}
	        opcode = IO_RDS;
	        goto docmd;
	    case OP_WRS:		/* Write select */
		if (CPU_MODEL != 0x4 && first_rdwr == 0) {
//		     iotraps &= ~(1 << ((MA >> 9) & 017));
		     first_rdwr = 1;
		}
	        opcode = IO_WRS;
	        goto docmd;
	    case OP_WEF:		/* Write EOF */
	        opcode = IO_WEF;
	        goto docmd;
	    case OP_BSR:		/* Backspace */
	        opcode = IO_BSR;
	        goto docmd;
	    case OP_BSF:		/* Backspace File */
	        opcode = IO_BSF;
	        goto docmd;
	    case OP_REW:		/* Rewind */
	        opcode = IO_REW;
	        goto docmd;
	    case OP_RUN:		/* Rewind unload */
	        opcode = IO_RUN;
	        goto docmd;
	    case OP_SDN:		/* Set density */
	        opcode = (MA & 020) ? IO_SDH: IO_SDL;
	        goto docmd;
	    case OP_DRS:		/* Drop ready status */
	        opcode = IO_DRS;
	docmd:
		switch (chan_cmd(MA, opcode)) {
		case SCPE_BUSY:
		    iowait = 1;	/* Channel is active, hold */
		    break;
		case SCPE_OK:
		    ihold = 1;	/* Hold interupts for one cycle */
		    first_rdwr = 0;
		    break;
		case SCPE_IOERR:
		    iocheck = 1;
		    first_rdwr = 0;
		    break;
		case SCPE_NODEV:
		    reason = STOP_IOCHECK;
		    break;
		}
		break;

	    case OP_TRS:		/* Test ready status */
		switch (chan_cmd(MA, IO_TRS)) {
		case SCPE_BUSY:
		    iowait = 1;	/* Channel is active, hold */
		    break;
		case SCPE_OK:	/* Ready, skip one */
		    IC++;
		    ihold = 2;	/* Hold interupts for two */
		case SCPE_IOERR:	/* Not ready, just return */
		    break;
		case SCPE_NODEV:
		    reason = STOP_IOCHECK;
		    break;
		}
		break;

#ifdef I7090	/* Not on 704 */
	    case OP_TRCA:		/* Transfer on Redundancy check */
		if (/*itrap == 0 || */(1LL << 18) & ioflags)
		    break;
		f = chan_stat(1, CHS_ERR);
		goto branch;
	    case OP_TRCB:		/* Transfer on Redundancy check */
		if (/*itrap == 0 || */(1LL << 19) & ioflags)
		    break;
		f = chan_stat(2, CHS_ERR);
		goto branch;
	    case OP_TRCC:
		if (/*itrap == 0 || */(1LL << 20) & ioflags)
		    break;
		f = chan_stat(3, CHS_ERR);
		goto branch;
	    case OP_TRCD:
		if (/*itrap == 0 || */(1LL << 21) & ioflags)
		    break;
		f = chan_stat(4, CHS_ERR);
		goto branch;
	    case OP_TRCE:
		if (/*itrap == 0 || */(1LL << 22) & ioflags)
		    break;
		f = chan_stat(5, CHS_ERR);
		goto branch;
	    case OP_TRCF:
		if (/*itrap == 0 || */(1LL << 23) & ioflags)
		    break;
		f = chan_stat(6, CHS_ERR);
		goto branch;
	    case OP_TRCG:
		if (/*itrap == 0 || */(1LL << 24) & ioflags)
		    break;
		f = chan_stat(7, CHS_ERR);
		goto branch;
	    case OP_TRCH:
		if (/*itrap == 0 || */(1LL << 25) & ioflags)
		    break;
		f = chan_stat(8, CHS_ERR);
		goto branch;
#endif

	    case OP_TEFA:		/* Transfer on channel EOF */
		if ((1LL << 0) & ioflags)
		    break;
		f = chan_stat(1, CHS_EOF);
		goto branch;
#ifdef I7090	/* Not on 704 */
	    case OP_TEFB:		/* Transfer on EOF */
		if ((1LL << 1) & ioflags)
		    break;
		f = chan_stat(2, CHS_EOF);
		goto branch;
	    case OP_TEFC:
		if ((1LL << 2) & ioflags)
		    break;
		f = chan_stat(3, CHS_EOF);
		goto branch;
	    case OP_TEFD:
		if ((1LL << 3) & ioflags)
		    break;
		f = chan_stat(4, CHS_EOF);
		goto branch;
	    case OP_TEFE:
		if ((1LL << 4) & ioflags)
		    break;
		f = chan_stat(5, CHS_EOF);
		goto branch;
	    case OP_TEFF:
		if ((1LL << 5) & ioflags)
		    break;
		f = chan_stat(6, CHS_EOF);
		goto branch;
	    case OP_TEFG:
		if ((1LL << 6) & ioflags)
		    break;
		f = chan_stat(7, CHS_EOF);
		goto branch;
	    case OP_TEFH:
		if ((1LL << 7) & ioflags)
		    break;
		f = chan_stat(8, CHS_EOF);
		goto branch;
	    case OP_TCOA:	/* Transfer if channel in operation */
	    case OP_TCOB:
	    case OP_TCOC:
	    case OP_TCOD:
	    case OP_TCOE:
	    case OP_TCOF:
	    case OP_TCOG:
	    case OP_TCOH:
		f = chan_active((opcode & 017) + 1);
		/* Check if TCOx * */
	        if ((cpu_unit.flags & UNIT_FASTIO) && f && MA == (IC - 1))
		    iowait = 1;
		goto branch;
	    case OP_TCNA:	/* Transfer on channel not in operation */
	    case OP_TCNB:
	    case OP_TCNC:
	    case OP_TCND:
	    case OP_TCNE:
	    case OP_TCNF:
	    case OP_TCNG:
	    case OP_TCNH:
		f = !chan_active((opcode & 017) + 1);
		goto branch;

	    case OP_RSCA:		/* Reset and load channel */
		f = 1;
		goto chanrst;
	    case OP_RSCB:	      /* Reset and load channel */
		f = 2;
		goto chanrst;
	    case OP_RSCC:	     
		f = 3;
		goto chanrst;
	    case OP_RSCD:	
		f = 4;
		goto chanrst;
	    case OP_RSCE:
		f = 5;
		goto chanrst;
	    case OP_RSCF:
		f = 6;
		goto chanrst;
	    case OP_RSCG:
		f = 7;
		goto chanrst;
	    case OP_RSCH:
		f = 8;
	      chanrst:
 		/* 7607 channel, start imedately */
 		/* 7909 channel, wait until channel not active */
		switch (chan_start(f, MA)) {
		case SCPE_IOERR:
		    iocheck = 1;
		    break;
		case SCPE_BUSY:
		    iowait = 1;
		    break;
		case SCPE_OK:
		    break;
		}
		break;
	    case OP_STCA:		/* Load channel, 7909 Start NEA */
		f = 1;
		goto chanst;
	    case OP_STCB:	
		f = 2;
		goto chanst;
	    case OP_STCC:
		f = 3;
		goto chanst;
	    case OP_STCD:
		f = 4;
		goto chanst;
	    case OP_STCE:
		f = 5;
		goto chanst;
	    case OP_STCF:
		f = 6;
		goto chanst;
	    case OP_STCG:
		f = 7;
		goto chanst;
	    case OP_STCH:
		f = 8;
	      chanst:
		/* 7907 channel, set new address */
		/* 7909 channel, wait until channel idle, and start */
		switch (chan_load(f, MA)) {
		case SCPE_IOERR:
		    iocheck = 1;
		    break;
		case SCPE_BUSY:
		    iowait = 1;
		case SCPE_OK:
		    ihold = 1;
		    break;
		}
		break;
	    case OP_SCHA:		/* Store data channel */
		chan_store(1, MA);
		break;
	    case OP_SCHB:	
		chan_store(2, MA);
		break;
	    case OP_SCHC:
		chan_store(3, MA);
		break;
	    case OP_SCHD:
		chan_store(4, MA);
		break;
	    case OP_SCHE:
		chan_store(5, MA);
		break;
	    case OP_SCHF:
		chan_store(6, MA);
		break;
	    case OP_SCHG:
		chan_store(7, MA);
		break;
	    case OP_SCHH:
		chan_store(8, MA);
		break;
	    case OP_SCDA:		/* Store channel diags 7909 */
		chan_store_diag(1, MA);
		break;
	    case OP_SCDB:
		chan_store_diag(2, MA);
		break;
	    case OP_SCDC:
		chan_store_diag(3, MA);
		break;
	    case OP_SCDD:
		chan_store_diag(4, MA);
		break;
	    case OP_SCDE:
		chan_store_diag(5, MA);
		break;
	    case OP_SCDF:
		chan_store_diag(6, MA);
		break;
	    case OP_SCDG:
		chan_store_diag(7, MA);
		break;
	    case OP_SCDH:
		chan_store_diag(8, MA);
		break;

/* Optional RPQ instructions */
/* Extended precision floating point */
	    case OP_ESB:
		SR ^= MSIGN;	/* Reverse sign */
	    case OP_EAD:
	    case OP_EUA:
		if ((cpu_unit.flags & OPTION_EFP) == 0)
		    break;
		temp = 0;	/* Steal temp for errors */
		f = 0;
		/* Extract AC char */
		fptemp = (int)(AC >> 18) & AMASK;	/* Include P&Q? */
		/* Diff SR char */
		fptemp -= (int)(SR >> 18) & AMASK;
		if (AC & AMSIGN)
		    f |= 2;
		if (SR & MSIGN)
		    f |= 1;
		/* Get mem frac */
		MA = memmask & (MA + 1);
		if (bcore)
		    MA |= 0100000;
		ibr = ReadP(MA);
		if (fptemp >= 0) {	/* AC Bigger */
		    /* Exchange MQ and ibr */
		    SR = MQ;
		    MQ = ibr;
		} else {	/* ibr Bigger then MQ, MQ Smaller */
		    fptemp = -fptemp;	/* Change sign */
		    /* Set exponent of result */
		    AC &= ~DMASK;
		    AC |= SR & DMASK;
		    SR = ibr;
		    f = ((f >> 1) & 1) | ((f & 1) << 1);
		}
		AC &= DMASK;
		/* Clear sign */
		MQ &= PMASK;

		/* Adjust smaller number */
		if (fptemp >= 0 && fptemp < 044) {
		    sim_interval--;
		    shiftcnt = fptemp;
		    while (shiftcnt > 0) {
			MQ >>= 1;
			shiftcnt--;
		    }
		} else
		    MQ = 0;
		sim_interval--;

		/* Check signes of SR & AC */
		if (f == 2 || f == 1) {
		    MQ ^= PMASK;
		    MQ += SR & PMASK;
		    /* If MQ < 0 then SR was larger */
		    if (MQ & MSIGN) {
			MQ++;
			MQ &= PMASK;
		    } else {
			MQ ^= PMASK;
			if (MQ != 0)
			    f ^= 2;	/* Change sign of Result */
		    }
		} else
		    MQ += SR & PMASK;

		/* Check for overflow */
		temp = 0;
		if (MQ & MSIGN) {
		    MQ >>= 1;
		    AC += 00000001000000LL;
		    /* OV check */
		    if (AC & APSIGN)
			temp |= FPSPERR | FPACERR | FPOVERR;
		}

		/* Are we normalizing */
		if (opcode == OP_EAD || opcode == OP_ESB) {
		    sim_interval--;
		    while ((MQ & ONEBIT) == 0 && ((MQ & PMASK) != 0)) {
			MQ <<= 1;
			AC -= 00000001000000LL;
		    }
		    if (MQ == 0) {
			AC = 0;
		    }
		}

		/* Check underflow */
		if (AC & AMSIGN) {
		    temp |= FPSPERR | FPMQERR;
		    if (AC & APSIGN)
			temp |= FPSPERR | FPOVERR | FPACERR;
		} else if (AC & (AQSIGN | PREMASK))
		    temp |= FPOVERR | FPACERR;
		AC &= AMMASK;
		/* Set signs */
		if (f & 2) {
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}
		if (temp != 0) {
		  doefptrap:
		    if (FTM && CPU_MODEL != 0x4) {
			sim_interval = sim_interval - 1;	/* count down */
			temp &= ~(FPMQERR | FPACERR);
			M[tbase] &= ~(AMASK | DMASK);
			M[tbase] |= temp | (IC & memmask);
			IC = 010;
		    } else {
			if (temp & FPMQERR)
			    mqoflag = 1;
			if (temp & FPACERR)
			    acoflag = 1;
		    }
		}
		break;
	    case OP_EMP:
		if ((cpu_unit.flags & OPTION_EFP) == 0)
		    break;
		temp = 0;

		/* Result sign */
		if (SR & MSIGN)
		    f = 1;
		else
		    f = 0;
		if (AC & AMSIGN)
		    f ^= 1;

		MQ &= PMASK;
		/* Quick out for times 0 */
		if (MQ == 0) {
		    AC &= RMASK;
		    if (f) {
			MQ |= MSIGN;
			AC |= AMSIGN;
		    }
		    break;
		}

		/* Extract AC char */
		fptemp = (int)(AC >> 18) & AMASK;
		/* Diff SR char */
		fptemp += (int)(SR >> 18) & AMASK;
		fptemp -= 040000;

		/* Get mem frac */
		MA = memmask & (MA + 1);
		if (bcore)
		    MA |= 0100000;
		SR = ReadP(MA);
		SR &= PMASK;

		/* Quick out for times 0 */
		if (SR == 0) {
		    MQ = 0;
		    AC &= RMASK;
		    if (f) {
			MQ |= MSIGN;
			AC |= AMSIGN;
		    }
		    break;
		}

		AC = 0;
		/* Do multiply */
		shiftcnt = 043;
		while (shiftcnt-- > 0) {
		    if (MQ & 1)
			AC += SR;
		    MQ >>= 1;
		    if (AC & 1)
			MQ |= ONEBIT;
		    AC >>= 1;
		}

		/* Normalize result */
		if ((AC & ONEBIT) == 0) {
		    AC <<= 1;
		    if (MQ & ONEBIT)
			AC |= 1;
		    fptemp--;
		}

		/* Move results to MQ. */
		MQ = AC;

		if (MQ == 0) {
		    AC = 0;
		} else {
		    /* Put exponent in place. */
		    AC = ((t_uint64) (fptemp)) << 18;
		    /* Check underflow */
		    if (AC & AMSIGN) {
			temp |= FPSPERR | FPMQERR;
			if (AC & APSIGN)
			    temp |= FPSPERR | FPOVERR | FPACERR;
		    } else if (AC & (AQSIGN | PREMASK))
			temp |= FPOVERR | FPACERR;
		    /* Clear sign */
		    AC &= AMMASK;
		}
		if (f) {
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}
		if (temp != 0)
		    goto doefptrap;
		break;
	    case OP_EDP:
		if ((cpu_unit.flags & OPTION_EFP) == 0)
		    break;

		/* Result sign */
		if (SR & MSIGN)
		    f = 1;
		else
		    f = 0;
		if (AC & AMSIGN)
		    f ^= 1;

		/* Extract AC char */
		fptemp = (int)(AC >> 18) & AMASK;	/* Include P&Q */
		/* Extract SR char */
		fptemp -= (int)(SR >> 18) & AMASK;
		fptemp += 040000;	/* UF check */

		/* Get mem frac */
		MA = memmask & (MA + 1);
		if (bcore)
		    MA |= 0100000;
		SR = ReadP(MA);

		temp = 0;
		/* Check for divide by 0 */
		MQ &= PMASK;
		if (MQ == 0) {
		    AC = MQ = 0;
		} else {
		    SR &= PMASK;
		    if (((MQ - (SR << 1)) & AMSIGN) == 0 || SR == 0) {
			dcheck = 1;
			AC &= DMASK;
			AC |= MQ & RMASK;
			if (f) {
			    MQ |= MSIGN;
			    AC |= AMSIGN;
			}
			break;
		    }

		    /* Move MQ to AC */
		    AC = MQ & PMASK;

		    /* Clear MQ before starting */
		    MQ = 0;
		    shiftcnt = 043;
		    /* Precheck SR less then AC */
		    if (((AC - SR) & AMSIGN) == 0) {
			if (AC & 1)
			    MQ |= ONEBIT;
			AC >>= 1;
			fptemp++;
			f |= 2;
		    }

		    /* Do divide operation */
		    sim_interval = sim_interval - shiftcnt;
		    do {
			AC <<= 1;
			MQ <<= 1;
			if (MQ & MSIGN) {
			    MQ ^= MSIGN;
			    AC |= 1;
			}
			if (SR <= AC) {
			    AC -= SR;
			    MQ |= 1;
			}
		    } while (--shiftcnt != 0);
		    /* Fix things if we didn't preshifted */
		    if ((f & 2) == 0 && AC != 0)
			MQ &= ~1;
		    AC = 0;
		    if (f & 2) {
			if ((MQ & ONEBIT) == 0)
			    MQ <<= 1;
		    } else {
			AC = RMASK;
		    }

		    /* Put exponent in place. */
		    AC |= ((t_uint64) (fptemp)) << 18;
		    /* Check underflow */
		    if (AC & AMSIGN) {
			temp |= FPSPERR | FPMQERR;
			if (AC & APSIGN)
			    temp |= FPSPERR | FPOVERR | FPACERR;
		    } else if (AC & (AQSIGN | PREMASK))
			temp |= FPOVERR | FPACERR;
		    /* Clear sign */
		    AC &= AMMASK;
		}
		/* Fix signs on results */
		if (f & 1) {
		    MQ |= MSIGN;
		    AC |= AMSIGN;
		}
		if (temp != 0)
		    goto doefptrap;
		break;
	    case OP_EST:
		if ((cpu_unit.flags & OPTION_EFP) == 0)
		    break;
		SR &= RMASK;
		if (AC & AMSIGN)
		    SR |= MSIGN;
		SR |= LMASK & PMASK & AC;
		/* Clear P+Q and 18-35 */
		AC &= AMSIGN | (PMASK & LMASK);
		WriteP(MA, SR);
		MA = memmask & (MA + 1);
		if (bcore)	/* Excuting in B core? check address */
		    MA |= 0100000;
		SR = MQ;
		break;
	    case OP_ELD:
		if ((cpu_unit.flags & OPTION_EFP) == 0)
		    break;
		AC = ((SR & MSIGN) << 2) | (SR & PMASK);
		MA = memmask & (MA + 1);
		if (bcore)
		    MA |= 0100000;
		MQ = ReadP(MA);
		break;

/* Special CTSS modes */
	    case OP_TIA:
		/* Regular xfer in A core, B core trap */
		bcore = 0;
		IC = MA;
		break;
	    case OP_TIB:
		/* In A core xfer to B core, B core trap */
		bcore = 3;
		IC = MA;
		break;
	    case OP_LRI:
		/* In B core trap, else load relocation */
		baseaddr = (uint16)SR;
		break;
	    case OP_LPI:
		/* In B core trap, else load protection */
		limitaddr = (uint16)SR;
		break;
	    case OP_SRI:
		/* In B core trap, else store relocation */
		SR = baseaddr;
		break;
	    case OP_SPI:
		/* In B core trap, else store protection */
		SR = limitaddr;
		break;

	    case OP_SPOP:
		switch (MA) {
		    /* Direct data disconnect */
 		case 0:
		    /* Should do disco on channel 0 */
		    break;
		    /* Handle signifigence mode */
		case OP_ESM:
		    if (cpu_unit.flags & OPTION_FPSM)
			smode = 1;
		    break;
		case OP_TSM:
		    if (cpu_unit.flags & OPTION_FPSM && smode)
			IC++;
		    smode = 0;
		    break;
		    /* Special CTSS memory mods */
		case OP_SEA:
		    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
			break;
		    /* CTSS Special, set effective to A, Acore only */
		    if (bcore & 2)
			goto seltrap;
		    bcore &= ~1;
		    break;
		case OP_SEB:
		    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
			break;
		    /* CTSS Special, set effective to B, Acore only */
		    if (bcore & 2)
			goto seltrap;
		    bcore |= 1;
		    break;
		case OP_IFT:
		    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
			break;
		    /* CTSS Special, skip if instruction A, Acore only */
		    if (bcore & 2)
			goto seltrap;
		    if (bcore == 0)
			IC++;
		    break;
		case OP_EFT:
		    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
			break;
		    /* CTSS Special, skip if effective A, Acore only */
		    if (bcore & 2)
			goto seltrap;
		    if (bcore == 1)
			IC++;
		    break;
		}
		break;
#endif

	    default:
		fprintf(stderr, "Invalid opcode %o IC=%o %012llo\n\r",
			opcode, IC, temp);
		reason = STOP_UUO;
		break;
	    }
	    if (opinfo & (S_B | S_F)) {
		if (bcore & 1)	/* Addressing in B core? fix address */
		    MA |= 0100000;
		WriteP(MA, SR);
		sim_interval = sim_interval - 1;	/* count down */
	    }
	    /* Store result into an index register */
	    if ((opinfo & S_X)) {
		SR &= AMASK;
		update_xr(tag, SR);
	    }
	    break;
	}

	chan_proc();		/* process any pending channel events */
    }				/* end while */

/* Simulation halted */

    return reason;
}

/* Nothing special to do, just return true if cmd is write and we got here */
uint32 cpu_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
{
    if (cmd == OP_WRS)
        return 1;
    return -1;
}

    
/* Reset routine */

t_stat
cpu_reset(DEVICE * dptr)
{
    int                 i;

    AC = 0;
    MQ = 0;
    SR = 0;
    dualcore = 0;
    if (cpu_unit.flags & UNIT_DUALCORE)
	dualcore = 1;
    for (i = 0; i < 7; i++)
	XR[i] = 0;
    MTM = 1;
    TM = STM = CTM = nmode = smode = 0;
    FTM = 1;
    itrap = 1;
    iotraps = baseaddr = 0;
	ioflags = 0;
    interval_irq = dcheck = acoflag = mqoflag = iocheck = 0;
    sim_brk_types = sim_brk_dflt = SWMASK('E');
    limitaddr = 077777;
    memmask = MEMMASK;
    if (cpu_unit.flags & OPTION_TIMER) {
	sim_activate(&cpu_unit, cpu_unit.wait);
    }

    return SCPE_OK;
}

/* Interval timer routines */
t_stat
rtc_srv(UNIT * uptr)
{
    if (cpu_unit.flags & OPTION_TIMER) {
	M[5] += 1;
	if (M[5] & MSIGN)
	    interval_irq = 1;
	sim_activate(&cpu_unit, sim_rtcn_calb(uptr->wait, TMR_RTC));
    }
    return SCPE_OK;
}

/* Memory examine */

t_stat
cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, int32 sw)
{
    if (addr >= MEMSIZE)
	return SCPE_NXM;
    if (vptr != NULL)
	*vptr = M[addr] & 0777777777777LL;

    return SCPE_OK;
}

/* Memory deposit */

t_stat
cpu_dep(t_value val, t_addr addr, UNIT * uptr, int32 sw)
{
    if (addr >= MEMSIZE)
	return SCPE_NXM;
    M[addr] = val & 0777777777777LL;
    return SCPE_OK;
}

t_stat
cpu_set_size(UNIT * uptr, int32 val, char *cptr, void *desc)
{
    t_uint64            mc = 0;
    uint32              i;

    cpu_unit.flags &= ~UNIT_MSIZE;
    cpu_unit.flags |= val;
    val >>= UNIT_V_MSIZE;
    val *= 8192;
    if (val == 0)
	val = 4096;
    if ((val < 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0))
	return SCPE_ARG;
    for (i = val; i < MEMSIZE; i++)
	mc |= M[i];
    if ((mc != 0) && (!get_yn("Really truncate memory [N]?", FALSE)))
	return SCPE_OK;
    MEMSIZE = val;
    memmask = val - 1;
    for (i = MEMSIZE; i < MAXMEMSIZE; i++)
	M[i] = 0;
    return SCPE_OK;
}

/* Handle execute history */

/* Set history */
t_stat
cpu_set_hist(UNIT * uptr, int32 val, char *cptr, void *desc)
{
    int32               i, lnt;
    t_stat              r;

    if (cptr == NULL) {
	for (i = 0; i < hst_lnt; i++)
	    hst[i].ic = 0;
	hst_p = 0;
	return SCPE_OK;
    }
    lnt = (int32) get_uint(cptr, 10, HIST_MAX, &r);
    if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN)))
	return SCPE_ARG;
    hst_p = 0;
    if (hst_lnt) {
	free(hst);
	hst_lnt = 0;
	hst = NULL;
    }
    if (lnt) {
	hst = calloc(sizeof(struct InstHistory), lnt);

	if (hst == NULL)
	    return SCPE_MEM;
	hst_lnt = lnt;
    }
    return SCPE_OK;
}

/* Show history */

t_stat
cpu_show_hist(FILE * st, UNIT * uptr, int32 val, void *desc)
{
    int32               k, di, lnt;
    char               *cptr = (char *) desc;
    t_stat              r;
    t_value             sim_eval;
    struct InstHistory *h;
    extern t_stat       fprint_sym(FILE * ofile, t_addr addr,
				   t_value * val, UNIT * uptr, int32 sw);

    if (hst_lnt == 0)
	return SCPE_NOFNC;	/* enabled? */
    if (cptr) {
	lnt = (int32) get_uint(cptr, 10, hst_lnt, &r);
	if ((r != SCPE_OK) || (lnt == 0))
	    return SCPE_ARG;
    } else
	lnt = hst_lnt;
    di = hst_p - lnt;		/* work forward */
    if (di < 0)
	di = di + hst_lnt;
    fprintf(st,
"IC      AC            MQ            EA      SR             XR1    XR2   XR4\n\n");
    for (k = 0; k < lnt; k++) {	/* print specified */
	h = &hst[(++di) % hst_lnt];	/* entry pointer */
	if (h->ic & HIST_PC) {	/* instruction? */
	    fprintf(st, "%06o ", h->ic & 077777);
	    switch ((h->ac & (AMSIGN | AQSIGN | APSIGN)) >> 35L) {
	    case (AMSIGN | AQSIGN | APSIGN) >> 35L:
		fprintf(st, "-QP");
		break;
	    case (AMSIGN | AQSIGN) >> 35L:
		fprintf(st, " -Q");
		break;
	    case (AMSIGN | APSIGN) >> 35L:
		fprintf(st, " -P");
		break;
	    case (AMSIGN) >> 35L:
		fprintf(st, "  -");
		break;
	    case (AQSIGN | APSIGN) >> 35L:
		fprintf(st, " QP");
		break;
	    case (AQSIGN) >> 35L:
		fprintf(st, "  Q");
		break;
	    case (APSIGN) >> 35L:
		fprintf(st, "  P");
		break;
	    case 0:
		fprintf(st, "   ");
		break;
	    }
	    fprint_val(st, h->ac & PMASK, 8, 35, PV_RZRO);
	    fputc(' ', st);
	    if (h->mq & MSIGN)
		fputc('-', st);
	    else
		fputc(' ', st);
	    fprint_val(st, h->mq & PMASK, 8, 35, PV_RZRO);
	    fputc(' ', st);
	    fprint_val(st, h->ea, 8, 16, PV_RZRO);
	    fputc(' ', st);
	    if (h->sr & MSIGN)
		fputc('-', st);
	    else
		fputc(' ', st);
	    fprint_val(st, h->sr & PMASK, 8, 35, PV_RZRO);
	    fputc(' ', st);
	    fprint_val(st, h->xr1, 8, 15, PV_RZRO);
	    fputc(' ', st);
	    fprint_val(st, h->xr2, 8, 15, PV_RZRO);
	    fputc(' ', st);
	    fprint_val(st, h->xr4, 8, 15, PV_RZRO);
	    fputc(' ', st);
	    sim_eval = h->op;
	    if (
		(fprint_sym
		 (st, h->ic & AMASK, &sim_eval, &cpu_unit,
		  SWMASK('M'))) > 0) fprintf(st, "(undefined) %012llo", h->op);
	    fputc('\n', st);	/* end line */
	}			/* end else instruction */
    }				/* end for */
    return SCPE_OK;
}
