/* i7090_cpu.c: IBM 7090 CPU simulator

   Copyright (c) 2005-2016, 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
   RICHARD CORNWELL 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>
#ifdef CPANEL
#include "cpanel.h"
#endif

#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      (0x3 << UNIT_V_CPUMODEL)
#define CPU_MODEL       ((cpu_unit.flags >> UNIT_V_CPUMODEL) & 0x3)
#define MODEL(x)        (x << UNIT_V_CPUMODEL)
#define MEMAMOUNT(x)    (x << UNIT_V_MSIZE)
#define UNIT_DUALCORE   (1 << (UNIT_V_CPUMODEL + 2))
#define UNIT_FASTIO     (1 << (UNIT_V_CPUMODEL + 3))
#define OPTION_EFP      (1 << (UNIT_V_CPUMODEL + 4))
#define OPTION_TIMER    (1 << (UNIT_V_CPUMODEL + 5))
#define OPTION_FPSM     (1 << (UNIT_V_UF_31))

#define CPU_704         0
#define CPU_709         1
#define CPU_7090        2
#define CPU_7094        3

#define TMR_RTC         0

#define HIST_XCT        1       /* instruction */
#define HIST_INT        2       /* interrupt cycle */
#define HIST_TRP        3       /* trap cycle */
#define HIST_MIN        64
#define HIST_MAX        1000000
#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, CONST char *cptr,
                                 void *desc);
t_stat              cpu_show_hist(FILE * st, UNIT * uptr, int32 val,
                                  CONST void *desc);
t_stat              cpu_set_hist(UNIT * uptr, int32 val, CONST char *cptr,
                                 void *desc);
uint32              cpu_cmd(UNIT * uptr, uint16 cmd, uint16 dev);
t_stat              cpu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
                        const char *cptr);
const char          *cpu_description (DEVICE *dptr);

/* Interval timer option */
t_stat              rtc_srv(UNIT * uptr);
t_stat              rtc_reset(DEVICE * dptr);
int32               rtc_tps = 60;

t_uint64            M[MAXMEMSIZE] = { 0 };      /* memory */
t_uint64            AC, MQ;                     /* registers */
uint16              XR[8];                      /* Index registers */
uint16              IC;                         /* program counter */
uint16              IR;                         /* Instruction register */
uint16              MA;                         /* Memory Address resister */
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 = 0;                /* Trap enable flags */
uint8               iocheck;
uint8               prot_pend;                  /* Protection mode pending */
uint8               relo_mode;                  /* Relocation mode */
uint8               relo_pend;                  /* Relocation mode pending */
uint8               hltinst;                    /* Executed halt instruction */
uint8               iowait;                     /* Waiting on io */
uint16              relocaddr = 0;              /* Relocation. */
uint16              baseaddr = 0;               /* Base Address. */
uint16              limitaddr = 077777;         /* High limit */
uint16              memmask = 077777;           /* Mask for memory access */
uint8               bcore;                      /* Access to B core memory */
                                                /* 00 - Execute A Core, Eff A */
                                                /* 01 - Execute A core, Eff B */
                                                /* 10 - Execute B core, Eff A */
                                                /* 11 - Execute B core, Eff B */
                                                /* 1xx - Protection mode */
                                                /* 1xxx - Relocation mode */
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 */
uint8               exe_KEYS = 0;               /* Execute one instruction
                                                   from KEYS, used by CPANEL */

/* History information */
int32               hst_p = 0;                  /* History pointer */
int32               hst_lnt = 0;                /* History length */
struct InstHistory *hst = NULL;                 /* History stack */
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 =
#ifdef I7090
    { UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_7090) | MEMAMOUNT(4),
            MAXMEMSIZE/2 ), 120 };
#else
    { UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_704) | MEMAMOUNT(4),
            MAXMEMSIZE/2 ), 120 };
#endif

REG                 cpu_reg[] = {
    {ORDATAD(IC, IC, 15, "Instruction Counter"), REG_FIT},
    {ORDATAD(IR, IR, 10, "Instruction Register"), REG_FIT},
    {ORDATAD(AC, AC, 38, "Accumulator"), REG_FIT},
    {ORDATAD(MQ, MQ, 36, "Multiplier Quotent"), REG_FIT},
    {BRDATAD(XR, XR, 8, 15, 8, "Index registers"), REG_FIT},
    {ORDATAD(ID, ID, 36, "Indicator Register")},
    {ORDATAD(MA, MA, 15, "Memory Address Register"), REG_FIT},
#ifdef EXTRA_SL
    {ORDATAD(SL, SL, 8, "Sense Lights"), REG_FIT},
#else
    {ORDATAD(SL, SL, 4, "Sense Lights"), REG_FIT},
#endif
#ifdef EXTRA_SW
    {ORDATAD(SW, SW, 12, "Sense Switches"), REG_FIT},
#else
    {ORDATAD(SW, SW, 6, "Sense Switches"), 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
    {ORDATAD(KEYS, KEYS, 36, "Console Key Register"), REG_FIT},
    {ORDATAD(MTM, MTM, 1, "Multi Index registers"), REG_FIT},
    {ORDATAD(TM, TM, 1, "Trap mode"), REG_FIT},
    {ORDATAD(STM, STM, 1, "Select trap mode"), REG_FIT},
    {ORDATAD(CTM, CTM, 1, "Copy Trap Mode"), REG_FIT},
    {ORDATAD(FTM, FTM, 1, "Floating trap mode"), REG_FIT},
    {ORDATAD(NMODE, nmode, 1, "Storage null mode"), REG_FIT},
    {ORDATAD(ACOVF, acoflag, 1, "AC Overflow Flag"), REG_FIT},
    {ORDATAD(MQOVF, mqoflag, 1, "MQ Overflow Flag"), REG_FIT},
    {ORDATAD(IOC, iocheck, 1, "I/O Check flag"), REG_FIT},
    {ORDATAD(DVC, dcheck, 1, "Divide Check flag"), REG_FIT},
    {ORDATAD(RELOC, relocaddr, 14, "Relocation offset"), REG_FIT},
    {ORDATAD(BASE, baseaddr, 14, "Relocation base"), REG_FIT},
    {ORDATAD(LIMIT, limitaddr, 14, "Relocation limit"), REG_FIT},
    {ORDATAD(ENB, ioflags, 36, "I/O Trap Flags"), REG_FIT},
    {FLDATA(INST_BASE, bcore, 0), REG_FIT},
    {FLDATA(DATA_BASE, bcore, 1), REG_FIT},
    {NULL}
};

MTAB                cpu_mod[] = {
    {UNIT_MODEL, MODEL(CPU_704), "704", "704", NULL, NULL, NULL},
#ifdef I7090
    {UNIT_MODEL, MODEL(CPU_709), "709", "709", NULL, NULL, NULL},
    {UNIT_MODEL, MODEL(CPU_7090), "7090", "7090", NULL, NULL, NULL},
    {UNIT_MODEL, MODEL(CPU_7094), "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},
#ifdef I7090
    {UNIT_FASTIO, 0, NULL, "TRUEIO", NULL, NULL, NULL,
       "True I/O mode"},
    {UNIT_FASTIO, UNIT_FASTIO, "FASTIO", "FASTIO", NULL, NULL, NULL,
       "Fast I/O mode"},
    {OPTION_EFP, 0, NULL, "NOEFP", NULL, NULL, NULL},
    {OPTION_EFP, OPTION_EFP, "EFP", "EFP", NULL, NULL, NULL, "Extended FP"},
    {OPTION_FPSM, 0, NULL, "NOFPSM", NULL, NULL, NULL},
    {OPTION_FPSM, OPTION_FPSM, "FPSM", "FPSM", NULL, NULL, NULL, "Signfigance mode"},
    {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, "CTSS support"},
#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, 16, 1, 8, 36,
    &cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL,
    NULL, DEV_DEBUG, 0, dev_debug,
    NULL, NULL, &cpu_help, NULL, NULL, &cpu_description
};


#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 protection */
#define X_P     0x2000          /* Trap if in protection enabled */
#define X_C     0x4000          /* Trap if in copy trap mode or protection */
#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_P|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_P|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 */ T_T,  T_T,   T_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_P|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_P|T_B,  N,      N,      N,
/* 4570 */ N,   N,      N,      N,      N,      N,      N,      N,
        /* STQ  SRI          ORS        DST    SPI*/
/* 4600 */ S_B, I_D|S_B,    T_B|S_B,I_94|S_B,I_D|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 */ T_T,  T_T,   T_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 CORE_B   0100000        /* Core B base address. */

#define do_trapmode  \
     if (TM) { \
          sim_interval = sim_interval - 1;      /* count down */ \
          M[0] &= ~AMASK; \
          M[0] |= (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(ind, reg) \
         /* In address nulify mode, half address */ \
         MA &= memmask; \
         if (bcore & 10)        /* Relocation enabled? adjust address */ \
           MA = AMASK & (MA + relocaddr); \
         if (bcore & 4) {       /* Protection enabled? check address */ \
           if (((MA & 077400) < baseaddr) || ((MA & 077400) >limitaddr)) { \
               /* Trap to A core */ \
               /* bcore to D3,4, IC=ADDR MA is going to DECR */ \
               M[032] = (((t_uint64)bcore & 3) << 31) | (((t_uint64)MA) << 18) | IC;\
                /* store 32, IC = 33 */ \
                IC = 033; \
               bcore = 0; \
               prot_pend = 0; \
               tbase = 0; \
               goto next_exe; \
           } \
         } \
         if ((ind) == 0 && bcore & 1)           /* Data in B core */ \
           MA |= CORE_B; \
         if ((ind) == 1 && bcore & 2)           /* Code in B core */ \
           MA |= CORE_B; \
         sim_interval = sim_interval - 1;               /* count down */ \
         reg = ReadP(MA);


#define WriteMem() \
         /* In address nulify mode, half address */ \
         MA &= memmask; \
         if (bcore & 10)        /* Relocation enabled? adjust address */ \
           MA = AMASK & (MA + relocaddr); \
         if (bcore & 4) {       /* Protection enabled? check address */ \
           if (((MA & 077400) < baseaddr) || ((MA & 077400) >limitaddr)) { \
               /* Trap to A core */ \
               /* bcore to D3,4, IC=ADDR MA is going to DECR */ \
               M[032] = (((t_uint64)bcore & 3) << 31) | (((t_uint64)MA) << 18) | IC;\
                /* store 32, IC = 33 */ \
                IC = 033; \
               bcore = 0; \
               prot_pend = 0; \
               tbase = 0; \
               goto next_exe; \
           } \
         } \
         if (bcore & 1)                 /* Data in B core */ \
           MA |= CORE_B; \
         sim_interval = sim_interval - 1;               /* count down */ \
         WriteP(MA, SR);

t_stat
sim_instr(void)
{
    t_stat              reason;
    t_uint64            temp = 0LL;
#ifdef I7090
    t_uint64            ibr;
#endif
    uint16              opcode;
    uint8               tag;
    uint16              decr;
    uint16              xr;
    uint16              opinfo;
    int                 fptemp = 0, fptemp2;
    uint8               f;
    uint16              tbase;
    int                 xeccnt = 15;
    int                 shiftcnt;
    int                 stopnext = 0;
    int                 instr_count = 0; /* Number of instructions to execute */

    if (sim_step != 0) {
        instr_count = sim_step;
        sim_cancel_step();
    }

    /* Set cycle time for delays */
    switch(CPU_MODEL) {
    case CPU_704: cycle_time = 50; break;    /* Needed to allow SAP to work */
    case CPU_709: cycle_time = 120; break;   /* 83,333 cycles per second */
    default:
    case CPU_7090:  cycle_time = 22; break;  /* 454,545 cycles per second */
    case CPU_7094:  cycle_time = 18; break;  /* 555,555 cycles per second */
    }

    reason = 0;
    hltinst = 0;

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

/* Main instruction fetch/decode loop */
    tbase = 0;
    if (bcore & 010)
        tbase = relocaddr;
    if (bcore & 2)
        tbase |= CORE_B;

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

        if (exe_KEYS) {
           SR = KEYS;
           hltinst = 1;
           exe_KEYS = 0;
           goto next_xec;
        }

   hltloop:
/* 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 defined(CPANEL)
        if (cpanel_interval > 0) {
            if (cpanel_interval > 1) {
                cpanel_interval--;
            } else {
                reason = ControlPanel_Refresh_CPU_Running();
                /* do control panel refresh and user clicks event processing */
                if (reason != SCPE_OK)
                    break;
            }
        }
#endif

        if (iowait == 0 && sim_brk_summ &&
                 sim_brk_test(((bcore & 2)? CORE_B:0)|IC, SWMASK('E'))) {
            reason = STOP_IBKPT;
            break;
        }

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

            MA = 012;
            f = 0;

            sim_debug(DEBUG_TRAP, &cpu_dev,
                          "Checking trap chan IC=%06o %06o\n", IC, iotraps);
            for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
                /* CRC *//* Trap *//* EOF */
                /* Wait until channel stops to trigger interupts */
                if (ioflags & mask) {
                    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) {
//                        iotraps &= ~(1 << (shiftcnt + 18));
                        /* HTR/HPR behave like wait if protected */
                        if (hltinst)
                            temp = (((t_uint64) bcore & 3) << 31) |
                                  (((t_uint64) f) << 18) | (fptemp & memmask);
                        else
                            temp = (((t_uint64) bcore & 3) << 31) |
                                  (((t_uint64) f) << 18) | (IC & memmask);
                        hltinst = 0;
                        sim_interval = sim_interval - 1;        /* count down */
                        WriteP(MA, temp);
                        if (nmode) {
                            memmask <<= 1;
                            memmask |= 1;
                            nmode = 0;
                        }
                        MA++;
                        tbase = 0;
                        prot_pend = itrap = bcore = iowait = 0;
                        ihold = 1;
                        sim_interval = sim_interval - 1;        /* count down */
                        SR = ReadP(MA);
                        sim_debug(DEBUG_TRAP, &cpu_dev,
                          "Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o %06o\n",
                                  shiftcnt + 'A' - 1, f, temp, MA, SR, IC, iotraps);
                        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 | (bcore << 18);
                            hst[hst_p].ea = 0;
                            hst[hst_p].op = SR;
                            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 && (ioflags & 0400000)) {
                /* HTR/HPR behave like wait if protected */
                if (hltinst)
                    temp = (((t_uint64) bcore & 3) << 31) |
                          (fptemp & memmask) | (relo_mode << 21);
                else
                    temp = (((t_uint64) bcore & 3) << 31) |
                          (IC & memmask) | (relo_mode << 21);
                hltinst = 0;
                sim_interval = sim_interval - 1;        /* count down */
                MA = 6;
                WriteP(MA, temp);
                if (nmode) {
                    memmask <<= 1;
                    memmask |= 1;
                    nmode = 0;
                }
                MA++;
                prot_pend = 0;
                interval_irq = prot_pend = itrap = bcore = iowait = 0;
                ihold = 1;
                sim_interval = sim_interval - 1;        /* count down */
                SR = ReadP(MA);
                sim_debug(DEBUG_DETAIL, &cpu_dev,
                          "Doing timer trap >%012llo loc %o %012llo\n", temp,
                          MA, 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 | (bcore << 18);
                    hst[hst_p].ea = 0;
                    hst[hst_p].op = SR;
                    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;
            }
        }

        if (hltinst) {
             t_uint64            mask = 00000001000001LL;
             /* Hold out until all channels have idled out */
             sim_interval = sim_interval - 1;        /* count down */
             chan_proc();
             f = chan_active(0);
             for (shiftcnt = 1; f == 0 && shiftcnt < NUM_CHAN; shiftcnt++)  {
                f = chan_active(shiftcnt);
                /* CRC *//* Trap *//* EOF */
                /* Wait until channel stops to trigger interrupts */
                if (itrap) {
                    /* Check for EOF or IOCT/IORT/IOST */
                    if (mask & AMASK & ioflags &&
                        (chan_test(shiftcnt, CHS_EOF) || iotraps & (1 << shiftcnt)))
                         f = 1;
                    if (mask & DMASK & ioflags && chan_test(shiftcnt, CHS_ERR))
                         f = 1; /* We have device error */
                 }
             }

             /* If all channels idle and not in protected mode, real halt */
             if (f == 0 && (bcore & 4) == 0) {
                reason = STOP_HALT;
                break;
             }
             goto hltloop;
        }
#else                     /* Handle halt on 704 */
        if (hltinst) {
             sim_interval = sim_interval - 1;        /* count down */
             chan_proc();
             if (chan_active(0))
                goto hltloop;
             reason = STOP_HALT;
             break;
        }
#endif

/* Split out current instruction */
      next_exe:
        if (iowait) {
            /* If we are awaiting I/O complete, don't fetch. */
            sim_interval--;
            SR = temp;
            iowait = 0;
        } else {
            xeccnt = 15;
            MA = IC;
            ReadMem(1, SR);
            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 | (bcore << 18);
                hst[hst_p].ea = 0;
                hst[hst_p].op = SR;
                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--;
        else if (relo_pend || prot_pend) {
            bcore = (bcore & 3) | (relo_pend << 3) | (prot_pend << 2);
            relo_pend = 0;
            prot_pend = 0;
        }


      next_xec:
        opcode = (uint16)(SR >> 24);
        IR = opcode;
        if (hst_lnt) {  /* history enabled? */
            hst[hst_p].op = SR;
        }
        MA = (uint16)(SR & AMASK);
        tag = (uint8)(SR >> 15) & 07;
        decr = (uint16)((SR >> 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 == CPU_704)
                break;
            if (opinfo & I_94 && CPU_MODEL != CPU_7094)
                break;
            if (opinfo & (X_P|X_T) && (bcore & 4)) {
                /* Trap to 0 and drop out of B core */
prottrap:
                MA = 032;
                if (nmode) {
                    memmask <<= 1;
                    memmask |= 1;
                }
                temp = ((t_uint64) (bcore & 3) << 31) | IC;
                tbase = 0;
                prot_pend = nmode = bcore = STM = CTM = 0;
                WriteP(MA, temp);
                IC = MA + 1;
                break;
            }
            /* Check for traping conditions */
                /* Check for protection mode */
            if (opinfo & X_T && STM) {
                /* Trap to 40001 */
                MA = MEMSIZE >> 1;
                if (nmode) {
                    memmask <<= 1;
                    memmask |= 1;
                }
                temp = ((t_uint64) (bcore & 3) << 31) | IC;
                tbase = 0;
                prot_pend = nmode = bcore = STM = CTM = 0;
                WriteP(MA, temp);
                IC = MA + 1;
                break;
            }
                /* Check for protection mode */
            if (opinfo & X_C && CTM) {
                /* Trap to 40002 */
                MA = MEMSIZE >> 1;
                if (nmode) {
                    memmask <<= 1;
                    memmask |= 1;
                }
                temp = ((t_uint64) (bcore & 3) << 31) | IC;
                tbase = 0;
                prot_pend = 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 != CPU_704) && ((decr & 060) == 060) &&
                (opinfo & (T_B | T_T | S_B))) {
                ReadMem(1, SR);
                tag = (uint8)((SR >> 15) & 07);
                xr = get_xr(tag);
                MA = (uint16)(memmask & (SR - xr));
            }
            MA &= memmask;
            if (opinfo & (T_B | T_F | S_F)) {
                ReadMem(opcode == OP_XEC, SR);
            }
            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 (CPU_MODEL == CPU_704)
                        break;
                    if ((bcore & 4) || STM)
                        goto seltrap;
                    f = (MA >> 9) & 017;
                    chan_rst(f, 1);
                    break;
                case OP_RICA:   /* Reset channel */
                case OP_RICB:
                case OP_RICC:
                case OP_RICD:
                case OP_RICE:
                case OP_RICF:
                case OP_RICG:
                case OP_RICH:
                    if (CPU_MODEL == CPU_704)
                        break;
                    if ((bcore & 4) || STM)
                        goto seltrap;
                    chan_rst((MA >> 9) & 017, 0);
                    break;
                    /* Not great coding, but keeps multiple copys out of code */
#endif
                  seltrap:
                    /* Trap to 40000 or 0 depending on mode */
                    if (bcore & 4)
                        MA = 032;
                    else
                        MA = MEMSIZE >> 1;
                    if (nmode) {
                        memmask <<= 1;
                        memmask |= 1;
                    }
                    temp = ((t_uint64) (bcore & 3) << 31) | IC;
                    tbase = 0;
                    prot_pend = 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 (CPU_MODEL == CPU_704)
                        break;
                    if ((bcore & 4) || STM)
                        goto seltrap;
                    if (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:
                    if (bcore & 4)
                        goto prottrap;
                    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 != CPU_704) {
                        if (bcore & 4)
                            goto prottrap;
                        sim_debug(DEBUG_TRAP, &cpu_dev, "RCT %012llo\n", ioflags);
                        if ((bcore & 4) || STM)
                            goto seltrap;
                        itrap = 1;
//                        iotraps &= ~(AMASK & (ioflags << 1));
                        if (CPU_MODEL == CPU_709)
                            ihold = 1;
                        else
                            ihold = 2;
                        sim_debug(DEBUG_TRAP, &cpu_dev, "rxt %06o\n", iotraps);
                    }
                    break;
                case OP_LMTM:
                    if (CPU_MODEL != CPU_704)
                        MTM = 0;
                    break;
#endif
                default:
                    if ((bcore & 4) || 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 & 4) || 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 != CPU_704)
                        FTM = 1;
                    break;
                case OP_SSM:
                    AC |= AMSIGN;
                    break;
#ifdef I7090    /* Not on 704 */
                case OP_LFTM:
                    if (bcore & 4)
                        goto prottrap;
                    if (CPU_MODEL != CPU_704)
                        acoflag = mqoflag = FTM = 0;
                    break;
                case OP_ESTM:
                    if (bcore & 4)
                        goto prottrap;
                    if (CPU_MODEL != CPU_704)
                        STM = 1;
                    break;
                case OP_ECTM:
                    if (bcore & 4)
                        goto prottrap;
                    if (CPU_MODEL != CPU_704)
                        CTM = 1;
                    break;
                case OP_EMTM:
                    if (CPU_MODEL != CPU_704)
                        MTM = 1;
                    break;
#endif
                case OP_LTM:
                    if (bcore & 4)
                        goto prottrap;
                    TM = 0;
                    break;
                case OP_LSNM:
                    if (nmode) {
                        memmask <<= 1;
                        memmask |= 1;
                    }
                    nmode = 0;
                    break;
                case OP_ETT:
                    if ((bcore & 4) || STM)
                        goto seltrap;
                    if (chan_stat(0, CHS_EOT) == 0)
                        IC++;
                    break;
                case OP_RTT:
                    if ((bcore & 4) || 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:
                    if (SW & (1 << (6 + MA - OP_SWT7)))
                        IC++;
                    break;
#endif
                default:
                    break;
                }
                break;
/* Transfer opcodes */
            case OP_HTR:
                /* Stop at HTR instruction if trapped */
                IC--;
                /* Fall through */
            case OP_HPR:
              halt:
                hltinst = 1;
                ihold = 0;      /* Kill any hold on traps now */
                if (opcode == OP_HTR) {
                     fptemp = IC;
                     IC = MA;
                } else
                     fptemp = IC;
                break;
            case OP_XEC:
                opcode = (uint16)(SR >> 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 == CPU_704) || 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 ^= SR & RMASK;
                break;
            case OP_IIL:
                ID ^= (SR & RMASK) << 18;
                break;
            case OP_OAI:
                ID |= AC & AQMASK;
                break;
            case OP_OSI:
                ID |= SR;
                break;
            case OP_SIR:
                ID |= (SR & RMASK);
                break;
            case OP_SIL:
                ID |= (SR & RMASK) << 18;
                break;
            case OP_RIA:
                ID &= ~AC;
                break;
            case OP_RIS:
                ID &= ~SR;
                break;
            case OP_RIR:
                ID &= ~(SR & RMASK);
                break;
            case OP_RIL:
                ID &= ~((SR & 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 == (SR & ID & RMASK))
                    IC++;
                break;
            case OP_LFT:
                if (0 == (((SR & RMASK) << 18) & ID))
                    IC++;
                break;
            case OP_RNT:
                if ((SR & RMASK) == (SR & ID & RMASK))
                    IC++;
                break;
            case OP_LNT:
                if ((SR & RMASK) == (SR & (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;
                /* Fall through */

            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;
                /* Fall through */

            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;
                /* Fall through */

            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 < CPU_7090) {
                        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 == CPU_704 && (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 != CPU_704 && FTM) {
                    sim_interval = sim_interval - 1;    /* count down */
                    M[0] &= ~(AMASK | DMASK);
                    M[0] |= temp | (IC & memmask);
                    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 == CPU_7090 && (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 != CPU_704)
                    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 != CPU_704 && 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 != CPU_704)
                        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 != CPU_704 && 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[0] &= ~(AMASK | DMASK);
                    M[0] |= (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;
                MA |= 1;        /* Point to second word */
                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 {
                        t_uint64        t;
                        AC &= ~FPMMASK;
                        AC |= SR & FPMMASK;
                        SR &= ~FPMMASK;
                        SR |= MQ & FPMMASK;
                        MQ &= ~FPMMASK;
                        ReadMem(0, t);
                        MQ |= t & FPMMASK;
                    }
                    /* AC=c, MQ=d SR=b, ID=a */
                } else {        /* ID Bigger then AC, AC Smaller */
                    t_uint64    t;
                    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);
                            ReadMem(0, MQ);
                            goto dpdone;
                        }
                        MQ &= ~FPMMASK;
                        AC &= ~FPMMASK;
                    }
                    ID = SR;
                    SR &= ~FPMMASK;
                    ReadMem(0, t);
                    SR |= t & 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 */
                MA |= 1;
                ReadMem(0, MQ); /* 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 */
                MA |= 1;
                ReadMem(0, ibr);
                ibr &= 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 |=  1;
                ReadMem(0, MQ);
                if (f) {
                    temp = FPDPERR;
                    if (FTM) {
                        goto dofptrap;
                    }
                }
                break;
            case OP_DST:
                SR = (AC & (APSIGN - 1));
                if (AC & AMSIGN)
                    SR |= MSIGN;
                WriteMem();
                MA = (MA + 1);
                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)(SR >> 18L) & 0377;
                if (AC & AMSIGN) {
                    f = 1;
                    AC &= AMMASK;
                } else
                    f = 0;
                while (shiftcnt != 0) {
                    MA += (uint16)(AC & 077);
                    ReadMem(0, SR);
                    MA = (uint16)(AMASK & SR);
                    AC >>= 6;
                    AC |= SR & (077LL << 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)(SR >> 18L) & 0377;
                while (shiftcnt != 0) {
                    MA += (uint16)(MQ >> 30) & 077;
                    ReadMem(0, SR);
                    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)(SR >> 18L) & 0377;
                while (shiftcnt != 0) {
                    MA += (uint16)(MQ >> 30) & 077;
                    ReadMem(0, SR);
                    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)(SR);
                    sim_debug(DEBUG_DETAIL, &drm_dev,
                                 "set address %06o\n", drum_addr);
                    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;
                if (SR)
                   itrap = 1;
                else
                   itrap = 0;
                sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo %06o\n", ioflags, iotraps);
                /*
                 * IBSYS can't have an trap right after ENB or it will hang
                 * on a TTR * in IBNUC.
                 */
                if (CPU_MODEL >= CPU_7090) {
                    ihold = 1;
                    break;
                }
#if 0
                temp = 00000001000001LL;

                for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
                    if ((temp & ioflags & DMASK) == 0)
                        chan_clear(shiftcnt, CHS_ERR);
                    else if (chan_test(shiftcnt,CHS_ERR))
                        ihold = 0;
                    if ((temp & ioflags & AMASK) == 0)
                        chan_clear(shiftcnt, CHS_EOF);
                    else if (chan_test(shiftcnt,CHS_EOF))
                        ihold = 0;
                    temp <<= 1;
                }
#endif
                break;
#endif

            case OP_RDS:                /* Read select */
                opcode = IO_RDS;
                goto docmd;
            case OP_WRS:                /* Write select */
                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 */
                    ihold = 1;  /* Hold interupts for one cycle */
                    break;
                case SCPE_OK:
                    {   uint16 temp16;
                        temp16 = (MA >> 9) & 017;
                        if (temp16 == 0) {
                            if (opcode==IO_RDS)
                                MQ = 0;
                            chan_clear(0, CHS_EOF|CHS_EOT|DEV_REOR);
                        } else {
                            iotraps &= ~(1 << temp16);
                            chan_clear(temp16, CHS_EOF|CHS_EOT|DEV_REOR);
                        }
                    }
                    ihold = 1;  /* Hold interupts for one cycle */
                    break;
                case SCPE_IOERR:
                    iocheck = 1;
                    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 */
                ihold = 2;
                if ((1LL << 18) & ioflags)
                    break;
                f = chan_stat(1, CHS_ERR);
                goto branch;
            case OP_TRCB:               /* Transfer on Redundancy check */
                if ((1LL << 19) & ioflags)
                    break;
                f = chan_stat(2, CHS_ERR);
                goto branch;
            case OP_TRCC:
                if ((1LL << 20) & ioflags)
                    break;
                f = chan_stat(3, CHS_ERR);
                goto branch;
            case OP_TRCD:
                if ((1LL << 21) & ioflags)
                    break;
                f = chan_stat(4, CHS_ERR);
                goto branch;
            case OP_TRCE:
                if ((1LL << 22) & ioflags)
                    break;
                f = chan_stat(5, CHS_ERR);
                goto branch;
            case OP_TRCF:
                if ((1LL << 23) & ioflags)
                    break;
                f = chan_stat(6, CHS_ERR);
                goto branch;
            case OP_TRCG:
                if ((1LL << 24) & ioflags)
                    break;
                f = chan_stat(7, CHS_ERR);
                goto branch;
            case OP_TRCH:
                if ((1LL << 25) & ioflags)
                    break;
                f = chan_stat(8, CHS_ERR);
                goto branch;
#endif

            case OP_TEFA:               /* Transfer on channel EOF */
                ihold = 2;
                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 */
                if (bcore & 1)
                    MA |= CORE_B;
                switch (chan_start(f, MA)) {
                case SCPE_IOERR:
                    iocheck = 1;
                    break;
                case SCPE_BUSY:
                    iowait = 1;
                    break;
                case SCPE_OK:
                    ihold = 1;
                    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 */
                if (bcore & 1)
                    MA |= CORE_B;
                switch (chan_load(f, MA)) {
                case SCPE_IOERR:
                    iocheck = 1;
                    break;
                case SCPE_BUSY:
                    iowait = 1;
                case SCPE_OK:
                    break;
                }
                break;
            case OP_SCHA:               /* Store data channel */
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(1, MA);
                break;
            case OP_SCHB:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(2, MA);
                break;
            case OP_SCHC:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(3, MA);
                break;
            case OP_SCHD:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(4, MA);
                break;
            case OP_SCHE:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(5, MA);
                break;
            case OP_SCHF:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(6, MA);
                break;
            case OP_SCHG:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(7, MA);
                break;
            case OP_SCHH:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store(8, MA);
                break;
            case OP_SCDA:               /* Store channel diags 7909 */
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(1, MA);
                break;
            case OP_SCDB:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(2, MA);
                break;
            case OP_SCDC:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(3, MA);
                break;
            case OP_SCDD:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(4, MA);
                break;
            case OP_SCDE:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(5, MA);
                break;
            case OP_SCDF:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(6, MA);
                break;
            case OP_SCDG:
                if (bcore & 1)
                    MA |= CORE_B;
                chan_store_diag(7, MA);
                break;
            case OP_SCDH:
                if (bcore & 1)
                    MA |= CORE_B;
                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 = (MA + 1);
                ReadMem(0, ibr);
                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 != CPU_704) {
                        sim_interval = sim_interval - 1;        /* count down */
                        temp &= ~(FPMQERR | FPACERR);
                        M[0] &= ~(AMASK | DMASK);
                        M[0] |= 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 = MA + 1;
                ReadMem(0, SR);
                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 = MA + 1;
                ReadMem(0, SR);

                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);
                WriteMem();
                MA = memmask & (MA + 1);
                SR = MQ;
                break;
            case OP_ELD:
                if ((cpu_unit.flags & OPTION_EFP) == 0)
                    break;
                AC = ((SR & MSIGN) << 2) | (SR & PMASK);
                MA = memmask & (MA + 1);
                ReadMem(0, MQ);
                break;

/* Special CTSS modes */
            case OP_TIA:
                /* Regular xfer in A core, B core trap */
                bcore &= ~2;
                sim_debug(DEBUG_PROT, &cpu_dev, "TIA %07o %07o\n", IC, MA);
                IC = MA;
                tbase = (relo_mode)?relocaddr:0;
                break;
            case OP_TIB:
                /* In A core xfer to B core, B core trap */
                bcore |= 2;
                sim_debug(DEBUG_PROT, &cpu_dev, "TIB %07o %07o\n", IC, MA);
                IC = MA;
                tbase = ((relo_mode)?relocaddr:0);
                break;
            case OP_LRI:
                /* In B core trap, else load relocation */
                relocaddr = (uint16)(SR & 077400);
                relo_pend = (SR & MSIGN) ? 0: 1;
                ihold = 1;
                sim_debug(DEBUG_PROT, &cpu_dev, "LRI %07o %012llo\n", IC, SR);
                break;
            case OP_LPI:
                /* In B core trap, else load protection */
                baseaddr = (uint16)(SR & 077400);
                limitaddr = (uint16)((SR >> 18) & 077400);
                ihold = 1;
                prot_pend = (SR & MSIGN)?0:1;
                sim_debug(DEBUG_PROT, &cpu_dev, "LPI %07o %012llo\n", IC, SR);
                break;
            case OP_SRI:
                /* In B core trap, else store relocation */
                SR = relocaddr | ((relo_mode)? (MSIGN >> 1) : 0);
                sim_debug(DEBUG_PROT, &cpu_dev, "SRI %07o %012llo\n", IC, SR);
                break;
            case OP_SPI:
                /* In B core trap, else store protection */
                SR = ((t_uint64)limitaddr) << 18 |
                     ((t_uint64)baseaddr);
                sim_debug(DEBUG_PROT, &cpu_dev, "SPI %07o %012llo\n", IC, SR);
                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 & 4)
                        goto prottrap;
                    bcore &= ~1;
                    ihold = 1;
                    break;
                case OP_SEB:
                    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
                        break;
                    /* CTSS Special, set effective to B, Acore only */
                    if (bcore & 4)
                        goto prottrap;
                    bcore |= 1;
                    ihold = 1;
                    break;
                case OP_IFT:
                    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
                        break;
                    /* CTSS Special, skip if instruction A, Acore only */
                    if (bcore & 4)
                        goto prottrap;
                    if ((bcore & 1) == 0)
                        IC++;
                    break;
                case OP_EFT:
                    if ((cpu_unit.flags & UNIT_DUALCORE) == 0)
                        break;
                    /* CTSS Special, skip if effective A, Acore only */
                    if (bcore & 4)
                        goto prottrap;
                    if ((bcore & 2) == 0)
                        IC++;
                    break;
                }
                break;
#endif

            default:
                sim_printf("Invalid opcode %o IC=%o %012llo\n", opcode, IC, temp);
                reason = STOP_UUO;
                break;
            }
            if (opinfo & (S_B | S_F)) {
                WriteMem();
            }
            /* Store result into an index register */
            if ((opinfo & S_X)) {
                SR &= AMASK;
                update_xr(tag, SR);
            }
            break;
        }

        chan_proc();            /* process any pending channel events */
        if (instr_count != 0 && --instr_count == 0)
            return SCPE_STEP;
    }                           /* 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 = bcore = 0;
    ioflags = 0;
    interval_irq = dcheck = acoflag = mqoflag = iocheck = 0;
    sim_brk_types = sim_brk_dflt = SWMASK('E');
    limitaddr = 077777;
    memmask = MEMSIZE-1;
    if (cpu_unit.flags & OPTION_TIMER) {
        sim_rtcn_init_unit (&cpu_unit, cpu_unit.wait, TMR_RTC);
        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) {
        (void)sim_rtcn_calb (rtc_tps, TMR_RTC);
        sim_activate_after(uptr, 1000000/rtc_tps);
        M[5] += 1;
        if (M[5] & MSIGN)
            interval_irq = 1;
    }
    return SCPE_OK;
}

/* Memory examine */

t_stat
cpu_ex(t_value * vptr, t_addr addr, UNIT * uptr, int32 sw)
{
    if (addr >= MAXMEMSIZE)
        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 >= MAXMEMSIZE)
        return SCPE_NXM;
    M[addr] = val & 0777777777777LL;
    return SCPE_OK;
}

t_stat
cpu_set_size(UNIT * uptr, int32 val, CONST char *cptr, void *desc)
{
    t_uint64            mc = 0;
    uint32              i;
    int32               v;

    v = val >> UNIT_V_MSIZE;
    v *= 8192;
    if (v == 0)
        v = 4096;
    if ((v < 0) || (v > MAXMEMSIZE) || ((v & 07777) != 0))
        return SCPE_ARG;
    for (i = v-1; i < MEMSIZE; i++)
        mc |= M[i];
    if ((mc != 0) && (!get_yn("Really truncate memory [N]?", FALSE)))
        return SCPE_OK;
    MEMSIZE = v;
    memmask = v - 1;
    cpu_unit.flags &= ~UNIT_MSIZE;
    cpu_unit.flags |= val;
    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, CONST 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 = (struct InstHistory *)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, CONST void *desc)
{
    int32               k, di, lnt;
    char               *cptr = (char *) desc;
    t_stat              r;
    t_value             sim_eval;
    struct InstHistory *h;

    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%c", h->ic & 077777, ((h->ic>>19)&1)?'b':' ');
            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(((h->ic>>18)&1)?'b':' ', 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;
}

const char *
cpu_description (DEVICE *dptr)
{
#ifdef I7090
       return "IBM 709x CPU";
#else
       return "IBM 704 CPU";
#endif
}

t_stat
cpu_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
#ifdef I7090
fprintf (st, "The CPU can be set to a IBM 704, IBM 709, IBM 7090 or IBM 7094\n");
fprintf (st, "The type of CPU can be set by one of the following commands\n\n");
fprintf (st, "   sim> set CPU 704         sets IBM 704 emulation\n");
fprintf (st, "   sim> set CPU 709         sets IBM 709 emulation\n");
fprintf (st, "   sim> set CPU 7090        sets IBM 7090 emulation\n");
fprintf (st, "   sim> set CPU 7094        sets IBM 7094 emulation\n\n");
#else
fprintf (st, "The CPU behaves as a IBM 704\n");
#endif
fprintf (st, "These switches are recognized when examining or depositing in CPU memory:\n\n");
fprintf (st, "      -c      examine/deposit characters, 6 per word\n");
fprintf (st, "      -l      examine/deposit half words\n");
fprintf (st, "      -m      examine/deposit IBM 709 instructions\n\n");
fprintf (st, "The memory of the CPU can be set in 4K incrememts from 4K to 32K with the\n\n");
fprintf (st, "   sim> SET CPU xK\n\n");
#ifdef I7090
fprintf (st, "For systems like IBSYS FASTIO can be enabled. This causes the CPU to finish\n");
fprintf (st, "all outstanding I/O requests when it detects an IDLE loop. This is detected\n");
fprintf (st, "by a TCOx to itself. TRUEIO waits until the given timeout. ");
fprintf (st, "For faster\noperation FASTIO can speed up execution, by eliminating");
fprintf (st, "waits on devices.\nThe default is TRUEIO.\n\n");
fprintf (st, "For the IBM 709x the following options can be enabled\n\n");
fprintf (st, "   sim> SET CPU EFP      enables extended Floating Point\n");
fprintf (st, "   sim> SET CPU NOEFP    disables extended Floating Point\n\n");
fprintf (st, "   sim> SET CPU FPSM     enables significance mode Floating Point\n");
fprintf (st, "   sim> SET CPU NOFPSM   disables significance mode Floating Point\n\n");
fprintf (st, "   sim> SET CPU CLOCK    enables clock in memory location 5\n");
fprintf (st, "   sim> SET CPU NOCLOCK  disables the clock in memory location 5\n\n");
fprintf (st, "   sim> SET CPU STANDARD sets generic IBM 709x CPU\n");
fprintf (st, "   sim> SET CPU CTSS     enables RPQ options, DUAL Core and extended memory for\n");
fprintf (st, "                         CTSS support\n\n");
#endif
fprintf (st, "The CPU can maintain a history of the most recently executed instructions.\n"
);
fprintf (st, "This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:\n\n"
);
fprintf (st, "   sim> SET CPU HISTORY                 clear history buffer\n");
fprintf (st, "   sim> SET CPU HISTORY=0               disable history\n");
fprintf (st, "   sim> SET CPU HISTORY=n{:file}        enable history, length = n\n");
fprintf (st, "   sim> SHOW CPU HISTORY                print CPU history\n");
    fprint_set_help(st, dptr);
    fprint_show_help(st, dptr);

return SCPE_OK;
}

