root/src/dps8/dps8_ins.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. elapsedtime
  2. writeOperands
  3. readOperands
  4. read_tra_op
  5. dump_words
  6. scu2words
  7. cu_safe_store
  8. tidy_cu
  9. words2scu
  10. cu_safe_restore
  11. du2words
  12. words2du
  13. initializeTheMatrix
  14. addToTheMatrix
  15. display_the_matrix
  16. fetchInstruction
  17. traceInstruction
  18. chkOVF
  19. tstOVFfault
  20. executeInstruction
  21. overflow
  22. doInstruction
  23. emCall
  24. doABSA
  25. doRCU

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * SPDX-License-Identifier: Multics
   5  * scspell-id: 7f512181-f62e-11ec-ad25-80ee73e9b8e7
   6  *
   7  * ---------------------------------------------------------------------------
   8  *
   9  * Copyright (c) 2007-2013 Michael Mondy
  10  * Copyright (c) 2012-2016 Harry Reed
  11  * Copyright (c) 2013-2016 Charles Anthony
  12  * Copyright (c) 2016 Michal Tomek
  13  * Copyright (c) 2021-2023 Jeffrey H. Johnson
  14  * Copyright (c) 2021-2024 The DPS8M Development Team
  15  *
  16  * This software is made available under the terms of the ICU License.
  17  * See the LICENSE.md file at the top-level directory of this distribution.
  18  *
  19  * ---------------------------------------------------------------------------
  20  *
  21  * This source file may contain code comments that adapt, include, and/or
  22  * incorporate Multics program code and/or documentation distributed under
  23  * the Multics License.  In the event of any discrepancy between code
  24  * comments herein and the original Multics materials, the original Multics
  25  * materials should be considered authoritative unless otherwise noted.
  26  * For more details and historical background, see the LICENSE.md file at
  27  * the top-level directory of this distribution.
  28  *
  29  * ---------------------------------------------------------------------------
  30  */
  31 
  32 #include <stdio.h>
  33 
  34 #include "dps8.h"
  35 #include "dps8_sys.h"
  36 #include "dps8_iom.h"
  37 #include "dps8_cable.h"
  38 #include "dps8_cpu.h"
  39 #include "dps8_addrmods.h"
  40 #include "dps8_faults.h"
  41 #include "dps8_scu.h"
  42 #include "dps8_append.h"
  43 #include "dps8_eis.h"
  44 #include "dps8_ins.h"
  45 #include "dps8_math.h"
  46 #include "dps8_opcodetable.h"
  47 #include "dps8_decimal.h"
  48 #include "dps8_iefp.h"
  49 #include "dps8_utils.h"
  50 
  51 #if defined(THREADZ) || defined(LOCKLESS)
  52 # include "threadz.h"
  53 #endif
  54 
  55 #include "ver.h"
  56 
  57 #define DBG_CTR cpu.cycleCnt
  58 
  59 // Forward declarations
  60 
  61 static int doABSA (cpu_state_t * cpup, word36 * result);
  62 static t_stat doInstruction (cpu_state_t * cpup);
  63 static int emCall (cpu_state_t * cpup);
  64 
  65 #if BARREL_SHIFTER
  66 static word36 barrelLeftMaskTable[37] = {
  67               0000000000000ull,
  68               0400000000000ull, 0600000000000ull, 0700000000000ull,
  69               0740000000000ull, 0760000000000ull, 0770000000000ull,
  70               0774000000000ull, 0776000000000ull, 0777000000000ull,
  71               0777400000000ull, 0777600000000ull, 0777700000000ull,
  72               0777740000000ull, 0777760000000ull, 0777770000000ull,
  73               0777774000000ull, 0777776000000ull, 0777777000000ull,
  74               0777777400000ull, 0777777600000ull, 0777777700000ull,
  75               0777777740000ull, 0777777760000ull, 0777777770000ull,
  76               0777777774000ull, 0777777776000ull, 0777777777000ull,
  77               0777777777400ull, 0777777777600ull, 0777777777700ull,
  78               0777777777740ull, 0777777777760ull, 0777777777770ull,
  79               0777777777774ull, 0777777777776ull, 0777777777777ull
  80             };
  81 static word36 barrelRightMaskTable[37] = {
  82               0000000000000ull,
  83               0000000000001ull, 0000000000003ull, 0000000000007ull,
  84               0000000000017ull, 0000000000037ull, 0000000000077ull,
  85               0000000000177ull, 0000000000377ull, 0000000000777ull,
  86               0000000001777ull, 0000000003777ull, 0000000007777ull,
  87               0000000017777ull, 0000000037777ull, 0000000077777ull,
  88               0000000177777ull, 0000000377777ull, 0000000777777ull,
  89               0000001777777ull, 0000003777777ull, 0000007777777ull,
  90               0000017777777ull, 0000037777777ull, 0000077777777ull,
  91               0000177777777ull, 0000377777777ull, 0000777777777ull,
  92               0001777777777ull, 0003777777777ull, 0007777777777ull,
  93               0017777777777ull, 0037777777777ull, 0077777777777ull,
  94               0177777777777ull, 0377777777777ull, 0777777777777ull,
  95             };
  96 # define BS_COMPL(HI) ((~(HI)) & MASK36)
  97 #endif // BARREL_SHIFTER
  98 
  99 #if defined(LOOPTRC)
 100 void elapsedtime (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 101   {
 102     static bool init = false;
 103     static struct timespec t0;
 104     struct timespec now, delta;
 105 
 106     if (! init)
 107       {
 108         init = true;
 109         clock_gettime (CLOCK_REALTIME, & t0);
 110       }
 111     clock_gettime (CLOCK_REALTIME, & now);
 112     timespec_diff (& t0, & now, & delta);
 113     sim_printf ("%5ld.%03ld", delta.tv_sec, delta.tv_nsec/1000000);
 114   }
 115 #endif
 116 
 117 // CANFAULT
 118 static void writeOperands (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120     char buf [256];
 121     CPT (cpt2U, 0); // write operands
 122     DCDstruct * i = & cpu.currentInstruction;
 123 
 124     sim_debug (DBG_ADDRMOD, & cpu_dev,
 125                "%s (%s):mne=%s flags=%x\n",
 126                __func__, disassemble (buf, IWB_IRODD), i->info->mne, i->info->flags);
 127 
 128     PNL (cpu.prepare_state |= ps_RAW);
 129 
 130     word6 rTAG = 0;
 131     if (! (i->info->flags & NO_TAG))
 132       rTAG = GET_TAG (cpu.cu.IWB);
 133     word6 Td = GET_TD (rTAG);
 134     word6 Tm = GET_TM (rTAG);
 135 
 136 //
 137 // IT CI/SC/SCR
 138 //
 139 
 140     if (Tm == TM_IT && (Td == IT_CI || Td == IT_SC || Td == IT_SCR))
 141       {
 142         //
 143         // Put the character into the data word
 144         //
 145 
 146 #if defined(LOCKLESS)
 147         word36 tmpdata;
 148         core_read(cpup, cpu.char_word_address, &tmpdata, __func__);
 149         if (tmpdata != cpu.ou.character_data)
 150           sim_warn("write char: data changed from %llo to %llo at %o\n",
 151                   (long long unsigned int)cpu.ou.character_data,
 152                   (long long unsigned int)tmpdata, cpu.char_word_address);
 153 #endif
 154 
 155         switch (cpu.ou.characterOperandSize)
 156           {
 157             case TB6:
 158               putChar (& cpu.ou.character_data, cpu.CY & 077, cpu.ou.characterOperandOffset);
 159               break;
 160 
 161             case TB9:
 162               putByte (& cpu.ou.character_data, cpu.CY & 0777, cpu.ou.characterOperandOffset);
 163               break;
 164           }
 165 
 166         //
 167         // Write it
 168         //
 169 
 170         PNL (cpu.prepare_state |= ps_SAW);
 171 
 172 #if defined(LOCKLESSXXX)
 173         // gives warnings as another lock is acquired in between
 174         core_write_unlock (cpup, cpu.char_word_address, cpu.ou.character_data, __func__);
 175 #else
 176         WriteOperandStore (cpup, cpu.ou.character_address, cpu.ou.character_data);
 177 #endif
 178 
 179         sim_debug (DBG_ADDRMOD, & cpu_dev,
 180                    "%s IT wrote char/byte %012"PRIo64" to %06o "
 181                    "tTB=%o tCF=%o\n",
 182                    __func__, cpu.ou.character_data, cpu.ou.character_address,
 183                    cpu.ou.characterOperandSize, cpu.ou.characterOperandOffset);
 184 
 185         // Restore the CA; Read/Write() updates it.
 186         //cpu.TPR.CA = indwordAddress;
 187         cpu.TPR.CA = cpu.ou.character_address;
 188         return;
 189       } // IT
 190 
 191     write_operand (cpup, cpu.TPR.CA, OPERAND_STORE);
 192 
 193     return;
 194 }
 195 
 196 // CANFAULT
 197 static void readOperands (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199     char buf [256];
 200     CPT (cpt2U, 3); // read operands
 201     DCDstruct * i = & cpu.currentInstruction;
 202 
 203     sim_debug (DBG_ADDRMOD, &cpu_dev,
 204                "%s (%s):mne=%s flags=%x\n",
 205                __func__, disassemble (buf, IWB_IRODD), i->info->mne, i->info->flags);
 206     sim_debug (DBG_ADDRMOD, &cpu_dev,
 207               "%s a %d address %08o\n", __func__, i->b29, cpu.TPR.CA);
 208 
 209     PNL (cpu.prepare_state |= ps_POA);
 210 
 211     word6 rTAG = 0;
 212     if (! (i->info->flags & NO_TAG))
 213       rTAG = GET_TAG (cpu.cu.IWB);
 214     word6 Td = GET_TD (rTAG);
 215     word6 Tm = GET_TM (rTAG);
 216 
 217 //
 218 // DU
 219 //
 220 
 221     if (Tm == TM_R && Td == TD_DU)
 222       {
 223         cpu.CY = 0;
 224         SETHI (cpu.CY, cpu.TPR.CA);
 225         sim_debug (DBG_ADDRMOD, & cpu_dev,
 226                    "%s DU CY=%012"PRIo64"\n", __func__, cpu.CY);
 227         return;
 228       }
 229 
 230 //
 231 // DL
 232 //
 233 
 234     if (Tm == TM_R && Td == TD_DL)
 235       {
 236         cpu.CY = 0;
 237         SETLO (cpu.CY, cpu.TPR.CA);
 238         sim_debug (DBG_ADDRMOD, & cpu_dev,
 239                    "%s DL CY=%012"PRIo64"\n", __func__, cpu.CY);
 240         return;
 241       }
 242 
 243 //
 244 // IT CI/SC/SCR
 245 //
 246 
 247     if (Tm == TM_IT && (Td == IT_CI || Td == IT_SC || Td == IT_SCR))
 248       {
 249         //
 250         // Get the character from the data word
 251         //
 252 
 253         switch (cpu.ou.characterOperandSize)
 254           {
 255             case TB6:
 256               cpu.CY = GETCHAR (cpu.ou.character_data, cpu.ou.characterOperandOffset);
 257               break;
 258 
 259             case TB9:
 260               cpu.CY = GETBYTE (cpu.ou.character_data, cpu.ou.characterOperandOffset);
 261               break;
 262           }
 263 
 264         sim_debug (DBG_ADDRMOD, & cpu_dev,
 265                    "%s IT read operand %012"PRIo64" from"
 266                    " %06o char/byte=%"PRIo64"\n",
 267                    __func__, cpu.ou.character_data, cpu.ou.character_address, cpu.CY);
 268 
 269         // Restore the CA; Read/Write() updates it.
 270         cpu.TPR.CA = cpu.ou.character_address;
 271         return;
 272       } // IT
 273 
 274 #if defined(LOCKLESS)
 275     if ((i->info->flags & RMW) == RMW)
 276       readOperandRMW (cpup, cpu.TPR.CA);
 277     else
 278       readOperandRead (cpup, cpu.TPR.CA);
 279 #else
 280     readOperandRead (cpup, cpu.TPR.CA);
 281 #endif
 282 
 283     return;
 284   }
 285 
 286 static void read_tra_op (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
 287   {
 288     if (cpu.TPR.CA & 1)
 289       ReadOperandRead (cpup, cpu.TPR.CA, &cpu.CY);
 290     else
 291       Read2OperandRead (cpup, cpu.TPR.CA, cpu.Ypair);
 292     if (! (get_addr_mode (cpup) == APPEND_mode || cpu.cu.TSN_VALID [0] ||
 293            cpu.cu.XSF || cpu.currentInstruction.b29 /*get_went_appending ()*/))
 294       {
 295         if (cpu.currentInstruction.info->flags & TSPN_INS)
 296           {
 297             word3 n;
 298             if (cpu.currentInstruction.opcode <= 0273)  //-V536
 299               n = (cpu.currentInstruction.opcode & 3);
 300             else
 301               n = (cpu.currentInstruction.opcode & 3) + 4;
 302 
 303             // C(PPR.PRR) -> C(PRn.RNR)
 304             // C(PPR.PSR) -> C(PRn.SNR)
 305             // C(PPR.IC)  -> C(PRn.WORDNO)
 306             // 000000     -> C(PRn.BITNO)
 307             cpu.PR[n].RNR = cpu.PPR.PRR;
 308 // According the AL39, the PSR is 'undefined' in absolute mode.
 309 // ISOLTS thinks it means "don't change the operand"
 310             if (get_addr_mode (cpup) == APPEND_mode)
 311               cpu.PR[n].SNR = cpu.PPR.PSR;
 312             cpu.PR[n].WORDNO = (cpu.PPR.IC + 1) & MASK18;
 313             SET_PR_BITNO (n, 0);
 314 #if defined(TESTING)
 315             HDBGRegPRW (n, "read_tra_op tsp");
 316 #endif
 317           }
 318         cpu.PPR.IC = cpu.TPR.CA;
 319         // ISOLTS 870-02f
 320         //cpu.PPR.PSR = 0;
 321       }
 322     sim_debug (DBG_TRACE, & cpu_dev, "%s %05o:%06o\n",
 323                __func__, cpu.PPR.PSR, cpu.PPR.IC);
 324     if (cpu.PPR.IC & 1)
 325       {
 326         cpu.cu.IWB   = cpu.CY;
 327         cpu.cu.IRODD = cpu.CY;
 328       }
 329     else
 330       {
 331         cpu.cu.IWB   = cpu.Ypair[0];
 332         cpu.cu.IRODD = cpu.Ypair[1];
 333       }
 334   }
 335 
 336 static void dump_words (cpu_state_t * cpup, word36 * words)
     /* [previous][next][first][last][top][bottom][index][help] */
 337   {
 338     sim_debug (DBG_FAULT, & cpu_dev,
 339                "CU: P %d IR %#o PSR %0#o IC %0#o TSR %0#o\n",
 340                getbits36_1  (words[0], 18), getbits36_18 (words[4], 18),
 341                getbits36_15 (words[0], 3), getbits36_18 (words[4], 0),  getbits36_15 (words[2], 3));
 342     sim_debug (DBG_FAULT, & cpu_dev,
 343                "CU: xsf %d rf %d rpt %d rd %d rl %d pot %d xde %d xdo %d itp %d rfi %d its %d fif %d hold %0#o\n",
 344                getbits36_1  (words[0], 19),
 345                getbits36_1  (words[5], 18), getbits36_1  (words[5], 19), getbits36_1  (words[5], 20), getbits36_1  (words[5], 21),
 346                getbits36_1  (words[5], 22), getbits36_1  (words[5], 24), getbits36_1  (words[5], 25), getbits36_1  (words[5], 26),
 347                getbits36_1  (words[5], 27), getbits36_1  (words[5], 28), getbits36_1  (words[5], 29), getbits36_6  (words[5], 30));
 348     sim_debug (DBG_FAULT, & cpu_dev,
 349                "CU: iwb %012"PRIo64" irodd %012"PRIo64"\n",
 350                words[6], words[7]);
 351   }
 352 
 353 static void scu2words (cpu_state_t * cpup, word36 *words)
     /* [previous][next][first][last][top][bottom][index][help] */
 354   {
 355     CPT (cpt2U, 6); // scu2words
 356     (void)memset (words, 0, 8 * sizeof (* words));
 357 
 358     // words[0]
 359 
 360     putbits36_3 (& words[0],  0,  cpu.PPR.PRR);
 361     putbits36_15 (& words[0], 3,  cpu.PPR.PSR);
 362     putbits36_1 (& words[0], 18,  cpu.PPR.P);
 363     putbits36_1 (& words[0], 19,  cpu.cu.XSF);
 364     // 20, 1 SDWAMM Match on SDWAM
 365     putbits36_1 (& words[0], 21,  cpu.cu.SD_ON);
 366     // 22, 1 PTWAMM Match on PTWAM
 367     putbits36_1 (& words[0], 23,  cpu.cu.PT_ON);
 368 
 369 
 370 
 371 
 372 
 373 
 374 
 375 
 376 
 377 
 378 
 379     // XXX Only the top 9 bits are used in APUCycleBits, so this is
 380     // zeroing the 3 FTC bits at the end of the word; on the
 381     // other hand this keeps the values in apuStatusBits clearer.
 382     // If FTC is ever used, be sure to put its save code after this
 383     // line.
 384     putbits36_12 (& words[0], 24, cpu.cu.APUCycleBits);
 385 
 386 
 387     // words[1]
 388 
 389     putbits36_1 (& words[1],  0, cpu.cu.IRO_ISN);
 390     putbits36_1 (& words[1],  1, cpu.cu.OEB_IOC);
 391     putbits36_1 (& words[1],  2, cpu.cu.EOFF_IAIM);
 392     putbits36_1 (& words[1],  3, cpu.cu.ORB_ISP);
 393     putbits36_1 (& words[1],  4, cpu.cu.ROFF_IPR);
 394     putbits36_1 (& words[1],  5, cpu.cu.OWB_NEA);
 395     putbits36_1 (& words[1],  6, cpu.cu.WOFF_OOB);
 396     putbits36_1 (& words[1],  7, cpu.cu.NO_GA);
 397     putbits36_1 (& words[1],  8, cpu.cu.OCB);
 398     putbits36_1 (& words[1],  9, cpu.cu.OCALL);
 399     putbits36_1 (& words[1], 10, cpu.cu.BOC);
 400     putbits36_1 (& words[1], 11, cpu.cu.PTWAM_ER);
 401     putbits36_1 (& words[1], 12, cpu.cu.CRT);
 402     putbits36_1 (& words[1], 13, cpu.cu.RALR);
 403     putbits36_1 (& words[1], 14, cpu.cu.SDWAM_ER);
 404     putbits36_1 (& words[1], 15, cpu.cu.OOSB);
 405     putbits36_1 (& words[1], 16, cpu.cu.PARU);
 406     putbits36_1 (& words[1], 17, cpu.cu.PARL);
 407     putbits36_1 (& words[1], 18, cpu.cu.ONC1);
 408     putbits36_1 (& words[1], 19, cpu.cu.ONC2);
 409     putbits36_4 (& words[1], 20, cpu.cu.IA);
 410     putbits36_3 (& words[1], 24, cpu.cu.IACHN);
 411     putbits36_3 (& words[1], 27, cpu.cu.CNCHN);
 412     putbits36_5 (& words[1], 30, cpu.cu.FI_ADDR);
 413     putbits36_1 (& words[1], 35, cpu.cycle == INTERRUPT_cycle ? 0 : 1);
 414 
 415     // words[2]
 416 
 417     putbits36_3 (& words[2],  0, cpu.TPR.TRR);
 418     putbits36_15 (& words[2], 3, cpu.TPR.TSR);
 419     // 18, 4 PTWAM levels enabled
 420     // 22, 4 SDWAM levels enabled
 421     // 26, 1 0
 422     putbits36_3 (& words[2], 27, (word3) cpu.switches.cpu_num);
 423     putbits36_6 (& words[2], 30, cpu.cu.delta);
 424 
 425     // words[3]
 426 
 427     putbits36_3 (& words[3], 18, cpu.cu.TSN_VALID[0] ? cpu.cu.TSN_PRNO[0] : 0);
 428     putbits36_1 (& words[3], 21, cpu.cu.TSN_VALID[0]);
 429     putbits36_3 (& words[3], 22, cpu.cu.TSN_VALID[1] ? cpu.cu.TSN_PRNO[1] : 0);
 430     putbits36_1 (& words[3], 25, cpu.cu.TSN_VALID[1]);
 431     putbits36_3 (& words[3], 26, cpu.cu.TSN_VALID[2] ? cpu.cu.TSN_PRNO[2] : 0);
 432     putbits36_1 (& words[3], 29, cpu.cu.TSN_VALID[2]);
 433     putbits36_6 (& words[3], 30, cpu.TPR.TBR);
 434 
 435     // words[4]
 436 
 437     putbits36_18 (& words[4],  0, cpu.PPR.IC);
 438 
 439 // According the AL39, the Hex Mode bit should be 0, but ISOLTS pas2 exec checks it;
 440 //  this code does not set it to zero and indicated by AL39.
 441 
 442     putbits36_18 (& words[4], 18, cpu.cu.IR);
 443 
 444     // ISOLTS 887 test-03a
 445     // Adding this makes test03 hang instead of erroring;
 446     // presumably it's stuck on some later test.
 447     // An 'Add Delta' addressing mode will alter the TALLY bit;
 448     // restore it.
 449 
 450     // Breaks ISOLTS 768
 451     //putbits36_1 (& words[4], 25, cpu.currentInstruction.stiTally);
 452 
 453 //#if defined(ISOLTS)
 454 //testing for ipr fault by attempting execution of
 455 //the illegal opcode  000   and bit 27 not set
 456 //in privileged-append-bar mode.
 457 //
 458 //expects ABS to be clear....
 459 //
 460 //testing for ipr fault by attempting execution of
 461 //the illegal opcode  000   and bit 27 not set
 462 //in absolute-bar mode.
 463 //
 464 //expects ABS to be set
 465 
 466 //if (cpu.PPR.P && TST_I_NBAR == 0) fails 101007 absolute-bar mode; s/b set
 467 //if (cpu.PPR.P == 0 && TST_I_NBAR == 0)
 468 //if (TST_I_NBAR == 0 && TST_I_ABS == 1) // If ABS BAR
 469 //{
 470   //putbits36 (& words[4], 31, 1, 0);
 471 //  putbits36 (& words[4], 31, 1, cpu.PPR.P ? 0 : 1);
 472 //if (current_running_cpu_idx)
 473 //sim_printf ("cleared ABS\n");
 474 //}
 475 //#endif
 476 
 477     // words[5]
 478 
 479     putbits36 (& words[5],  0, 18, cpu.TPR.CA);
 480     putbits36 (& words[5], 18,  1, cpu.cu.repeat_first);
 481     putbits36 (& words[5], 19,  1, cpu.cu.rpt);
 482     putbits36 (& words[5], 20,  1, cpu.cu.rd);
 483     putbits36 (& words[5], 21,  1, cpu.cu.rl);
 484     putbits36 (& words[5], 22,  1, cpu.cu.pot);
 485     // 23, 1 PON Prepare operand no tally
 486     putbits36_1 (& words[5], 24, cpu.cu.xde);
 487     putbits36_1 (& words[5], 25, cpu.cu.xdo);
 488     putbits36_1 (& words[5], 26, cpu.cu.itp);
 489     putbits36_1 (& words[5], 27, cpu.cu.rfi);
 490     putbits36_1 (& words[5], 28, cpu.cu.its);
 491     putbits36_1 (& words[5], 29, cpu.cu.FIF);
 492     putbits36_6 (& words[5], 30, cpu.cu.CT_HOLD);
 493 
 494     // words[6]
 495 
 496     words[6] = cpu.cu.IWB;
 497 
 498     // words[7]
 499 
 500     words[7] = cpu.cu.IRODD;
 501 //sim_printf ("scu2words %lld %012llo\n", cpu.cycleCnt, words [6]);
 502 
 503     if_sim_debug (DBG_FAULT, & cpu_dev)
 504         dump_words (cpup, words);
 505 
 506     if (cpu.tweaks.isolts_mode)
 507       {
 508         struct
 509         {
 510           word36 should_be[8];
 511           word36 was[8];
 512           char *name;
 513         }
 514         rewrite_table[] =
 515           {
 516             { { 0000001400021, 0000000000011, 0000001000100, 0000000000000,
 517                 0000016400000, 0110015000500, 0110015011000, 0110015011000 },
 518               { 0000001400011, 0000000000011, 0000001000100, 0000000000000,
 519                 0000016400000, 0110015000100, 0110015011000, 0110015011000 },
 520               "pa865 test-03a inhibit", //                                                          rfi
 521             },
 522             { { 0000000401001, 0000000000041, 0000001000100, 0000000000000,
 523                 0101175000220, 0000006000000, 0100006235100, 0100006235100 },
 524               { 0000000601001, 0000000000041, 0000001000100, 0000000000000,
 525                 0101175000220, 0000006000000, 0100006235100, 0100006235100 },
 526               "pa870 test-01a dir. fault",
 527             },
 528             { { 0000000451001, 0000000000041, 0000001000100, 0000000000000,
 529                 0000000200200, 0000003000000, 0200003716100, 0000005755000 },
 530               { 0000000651001, 0000000000041, 0000001000100, 0000000000000,
 531                 0000000200200, 0000003000000, 0200003716100, 0000005755000 },
 532               "pa885 test-05a xec inst",
 533             },
 534             { { 0000000451001, 0000000000041, 0000001000100, 0000000000000,
 535                 0000000200200, 0000002000000, 0200002717100, 0110002001000 },
 536               { 0000000651001, 0000000000041, 0000001000100, 0000000000000,
 537                 0000000200200, 0000002000000, 0200002717100, 0110002001000 },
 538               "pa885 test-05b xed inst",
 539             },
 540             { { 0000000451001, 0000000000041, 0000001000100, 0000000000000,
 541                 0000000200200, 0000004004000, 0200004235100, 0000005755000 },
 542               { 0000000451001, 0000000000041, 0000001000100, 0000000000000,
 543                 0000000200200, 0000004002000, 0200004235100, 0000005755000 },
 544               "pa885 test-05c xed inst", //                                                         xde/xdo
 545             },
 546             { { 0000000451001, 0000000000041, 0000001000100, 0000000000000,
 547                 0000001200200, 0000004006000, 0200004235100, 0000005755000 },
 548               { 0000000451001, 0000000000041, 0000001000100, 0000000000000,
 549                 0000001200200, 0000004002000, 0200004235100, 0000005755000 },
 550               "pa885 test-05d xed inst", //                                                         xde/xdo
 551             },
 552             { { 0000000454201, 0000000000041, 0000000000100, 0000000000000,
 553                 0001777200200, 0002000000500, 0005600560201, 0005600560201 },
 554               { 0000000450201, 0000000000041, 0000000000100, 0000000000000,
 555                 0001777200200, 0002000000000, 0005600560201, 0005600560201 },
 556               "pa885 test-06a rpd inst", //                                                         rfi/fif
 557             },
 558             { { 0000000451001, 0000000000041, 0000001000101, 0000000000000,
 559                 0002000200200, 0000003500001, 0200003235111, 0002005755012 },
 560               { 0000000651001, 0000000000041, 0000001000101, 0000000000000,
 561                 0002000202200, 0000003500000, 0200003235111, 0002005755012 },
 562               "pa885 test-06b rpd inst", //                                       tro               ct-hold
 563             },
 564             { { 0000000450201, 0000000000041, 0000000000101, 0000000000000,
 565                 0001776200200, 0002015500001, 0002015235031, 0002017755032 },
 566               { 0000000450201, 0000000000041, 0000000000101, 0000000000000,
 567                 0001776202200, 0002015500000, 0002015235031, 0002017755032 },
 568               "pa885 test-06c rpd inst", //                                       tro               ct-hold
 569             },
 570             { { 0000000450201, 0000000000041, 0000000000101, 0000000000000,
 571                 0001776000200, 0002000100012, 0001775235011, 0001775755012 },
 572               { 0000000450201, 0000000000041, 0000000000101, 0000000000000,
 573                 0001776000200, 0002000100000, 0001775235011, 0001775755012 },
 574               "pa885 test-06d rpd inst", //                                                         ct-hold
 575             },
 576             { { 0000000404202, 0000000000041, 0000000000100, 0000000000000,
 577                 0002000202200, 0002000000500, 0001773755000, 0001773755000 },
 578               { 0000000400202, 0000000000041, 0000000000100, 0000000000000,
 579                 0002000202200, 0002000000100, 0001773755000, 0001773755000 },
 580               "pa885 test-10a scu snap (acv fault)", //                                             rfi
 581             }
 582           };
 583         int i;
 584         for (i=0; i < 11; i++)
 585           {
 586             if (memcmp (words, rewrite_table[i].was, 8*sizeof (word36)) == 0)
 587               {
 588                 memcpy (words, rewrite_table[i].should_be, 8*sizeof (word36));
 589                 sim_warn("%s: scu rewrite %d: %s\n", __func__, i, rewrite_table[i].name);
 590                 break;
 591               }
 592           }
 593       }
 594   }
 595 
 596 void cu_safe_store (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
 597 {
 598     // Save current Control Unit Data in hidden temporary so a later SCU
 599     // instruction running in FAULT mode can save the state as it existed at
 600     // the time of the fault rather than as it exists at the time the SCU
 601     //  instruction is executed.
 602     scu2words (cpup, cpu.scu_data);
 603 
 604     cpu.cu_data.PSR = cpu.PPR.PSR;
 605     cpu.cu_data.PRR = cpu.PPR.PRR;
 606     cpu.cu_data.IC  = cpu.PPR.IC;
 607 
 608     tidy_cu (cpup);
 609 }
 610 
 611 void tidy_cu (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
 612   {
 613 // The only places this is called is in fault and interrupt processing;
 614 // once the CU is saved, it needs to be set to a usable state. Refactoring
 615 // that code here so that there is only a single copy to maintain.
 616 
 617     cpu.cu.delta        = 0;
 618     cpu.cu.repeat_first = false;
 619     cpu.cu.rpt          = false;
 620     cpu.cu.rd           = false;
 621     cpu.cu.rl           = false;
 622     cpu.cu.pot          = false;
 623     cpu.cu.itp          = false;
 624     cpu.cu.its          = false;
 625     cpu.cu.xde          = false;
 626     cpu.cu.xdo          = false;
 627   }
 628 
 629 static void words2scu (cpu_state_t * cpup, word36 * words)
     /* [previous][next][first][last][top][bottom][index][help] */
 630 {
 631     CPT (cpt2U, 7); // words2scu
 632     // BUG:  We don't track much of the data that should be tracked
 633 
 634     // words[0]
 635 
 636     cpu.PPR.PRR           = getbits36_3  (words[0], 0);
 637     cpu.PPR.PSR           = getbits36_15 (words[0], 3);
 638     cpu.PPR.P             = getbits36_1  (words[0], 18);
 639     cpu.cu.XSF            = getbits36_1  (words[0], 19);
 640 sim_debug (DBG_TRACEEXT, & cpu_dev, "%s sets XSF to %o\n", __func__, cpu.cu.XSF);
 641     //cpu.cu.SDWAMM       = getbits36_1  (words[0], 20);
 642     //cpu.cu.SD_ON        = getbits36_1  (words[0], 21);
 643     //cpu.cu.PTWAMM       = getbits36_1  (words[0], 22);
 644     //cpu.cu.PT_ON        = getbits36_1  (words[0], 23);
 645 
 646 
 647 
 648 
 649 
 650 
 651 
 652 
 653 
 654 
 655 
 656     //cpu.cu.APUCycleBits = getbits36_12 (words[0], 24);
 657 
 658     // The FCT is stored in APUCycleBits
 659     cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | (word12) getbits36_3 (words[0], 33));
 660 
 661     // words[1]
 662 
 663 
 664 
 665 
 666 
 667 
 668 
 669 
 670 
 671 
 672 
 673 
 674 
 675 
 676 
 677 
 678 
 679 
 680 
 681 
 682 
 683 
 684 
 685 
 686 
 687 
 688 
 689 
 690 
 691     // words[2]
 692 
 693     cpu.TPR.TRR         = getbits36_3  (words[2], 0);
 694     cpu.TPR.TSR         = getbits36_15 (words[2], 3);
 695     // 18-21 PTW
 696     // 22-25 SDW
 697     // 26 0
 698     // 27-29 CPU number
 699     cpu.cu.delta        = getbits36_6  (words[2], 30);
 700 
 701     // words[3]
 702 
 703     // 0-17 0
 704 
 705     cpu.cu.TSN_PRNO[0]  = getbits36_3  (words[3], 18);
 706     cpu.cu.TSN_VALID[0] = getbits36_1  (words[3], 21);
 707     cpu.cu.TSN_PRNO[1]  = getbits36_3  (words[3], 22);
 708     cpu.cu.TSN_VALID[1] = getbits36_1  (words[3], 25);
 709     cpu.cu.TSN_PRNO[2]  = getbits36_3  (words[3], 26);
 710     cpu.cu.TSN_VALID[2] = getbits36_1  (words[3], 29);
 711     cpu.TPR.TBR         = getbits36_6  (words[3], 30);
 712 
 713     // words[4]
 714 
 715     cpu.cu.IR           = getbits36_18 (words[4], 18); // HWR
 716     cpu.PPR.IC          = getbits36_18 (words[4], 0);
 717 
 718     // words[5]
 719 
 720 // AL39 pg 75, RCU does not restore CA
 721     //cpu.TPR.CA          = getbits36_18 (words[5], 0);
 722     cpu.cu.repeat_first = getbits36_1  (words[5], 18);
 723     cpu.cu.rpt          = getbits36_1  (words[5], 19);
 724     cpu.cu.rd           = getbits36_1  (words[5], 20);
 725     cpu.cu.rl           = getbits36_1  (words[5], 21);
 726     cpu.cu.pot          = getbits36_1  (words[5], 22);
 727     // 23 PON
 728     cpu.cu.xde          = getbits36_1  (words[5], 24);
 729     cpu.cu.xdo          = getbits36_1  (words[5], 25);
 730     cpu.cu.itp          = getbits36_1  (words[5], 26);
 731     cpu.cu.rfi          = getbits36_1  (words[5], 27);
 732     cpu.cu.its          = getbits36_1  (words[5], 28);
 733     cpu.cu.FIF          = getbits36_1  (words[5], 29);
 734     cpu.cu.CT_HOLD      = getbits36_6  (words[5], 30);
 735 
 736     // words[6]
 737 
 738     cpu.cu.IWB = words[6];
 739 
 740     // words[7]
 741 
 742     cpu.cu.IRODD = words[7];
 743 }
 744 
 745 void cu_safe_restore (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
 746   {
 747     words2scu (cpup, cpu.scu_data);
 748     decode_instruction (cpup, IWB_IRODD, & cpu.currentInstruction);
 749   }
 750 
 751 static void du2words (cpu_state_t * cpup, word36 * words)
     /* [previous][next][first][last][top][bottom][index][help] */
 752   {
 753     CPT (cpt2U, 7); // du2words
 754 
 755     if (cpu.tweaks.isolts_mode)
 756       {
 757         for (int i = 0; i < 8; i ++)
 758           {
 759             words[i] = cpu.du.image[i];
 760           }
 761       }
 762     else
 763       {
 764         (void)memset (words, 0, 8 * sizeof (* words));
 765       }
 766 
 767     // Word 0
 768 
 769     putbits36_1  (& words[0],  9, cpu.du.Z);
 770     putbits36_1  (& words[0], 10, cpu.du.NOP);
 771     putbits36_24 (& words[0], 12, cpu.du.CHTALLY);
 772 
 773     // Word 1
 774 
 775     if (cpu.tweaks.isolts_mode)
 776       words[1] = words[0];
 777 
 778     // Word 2
 779 
 780     putbits36_18 (& words[2],  0, cpu.du.D1_PTR_W);
 781     putbits36_6  (& words[2], 18, cpu.du.D1_PTR_B);
 782     putbits36_2  (& words[2], 25, cpu.du.TAk[0]);
 783     putbits36_1  (& words[2], 31, cpu.du.F1);
 784     putbits36_1  (& words[2], 32, cpu.du.Ak[0]);
 785 
 786     // Word 3
 787 
 788     putbits36_10 (& words[3],  0, cpu.du.LEVEL1);
 789     putbits36_24 (& words[3], 12, cpu.du.D1_RES);
 790 
 791     // Word 4
 792 
 793     putbits36_18 (& words[4],  0, cpu.du.D2_PTR_W);
 794     putbits36_6  (& words[4], 18, cpu.du.D2_PTR_B);
 795     putbits36_2  (& words[4], 25, cpu.du.TAk[1]);
 796     putbits36_1  (& words[4], 30, cpu.du.R);
 797     putbits36_1  (& words[4], 31, cpu.du.F2);
 798     putbits36_1  (& words[4], 32, cpu.du.Ak[1]);
 799 
 800     // Word 5
 801 
 802     putbits36_10 (& words[5],  0, cpu.du.LEVEL2);
 803     putbits36_24 (& words[5], 12, cpu.du.D2_RES);
 804 
 805     // Word 6
 806 
 807     putbits36_18 (& words[6],  0, cpu.du.D3_PTR_W);
 808     putbits36_6  (& words[6], 18, cpu.du.D3_PTR_B);
 809     putbits36_2  (& words[6], 25, cpu.du.TAk[2]);
 810     putbits36_1  (& words[6], 31, cpu.du.F3);
 811     putbits36_1  (& words[6], 32, cpu.du.Ak[2]);
 812     putbits36_3  (& words[6], 33, cpu.du.JMP);
 813 
 814     // Word 7
 815 
 816     putbits36_24 (& words[7], 12, cpu.du.D3_RES);
 817 
 818   }
 819 
 820 static void words2du (cpu_state_t * cpup, word36 * words)
     /* [previous][next][first][last][top][bottom][index][help] */
 821   {
 822     CPT (cpt2U, 8); // words2du
 823     // Word 0
 824 
 825     cpu.du.Z        = getbits36_1  (words[0],  9);
 826     cpu.du.NOP      = getbits36_1  (words[0], 10);
 827     cpu.du.CHTALLY  = getbits36_24 (words[0], 12);
 828     // Word 1
 829 
 830     // Word 2
 831 
 832     cpu.du.D1_PTR_W = getbits36_18 (words[2],  0);
 833     cpu.du.D1_PTR_B = getbits36_6  (words[2], 18);
 834     cpu.du.TAk[0]   = getbits36_2  (words[2], 25);
 835     cpu.du.F1       = getbits36_1  (words[2], 31);
 836     cpu.du.Ak[0]    = getbits36_1  (words[2], 32);
 837 
 838     // Word 3
 839 
 840     cpu.du.LEVEL1   = getbits36_10 (words[3],  0);
 841     cpu.du.D1_RES   = getbits36_24 (words[3], 12);
 842 
 843     // Word 4
 844 
 845     cpu.du.D2_PTR_W = getbits36_18 (words[4],  0);
 846     cpu.du.D2_PTR_B = getbits36_6  (words[4], 18);
 847     cpu.du.TAk[1]   = getbits36_2  (words[4], 25);
 848     cpu.du.F2       = getbits36_1  (words[4], 31);
 849     cpu.du.Ak[1]    = getbits36_1  (words[4], 32);
 850 
 851     // Word 5
 852 
 853     cpu.du.LEVEL2   = getbits36_1  (words[5],  9);
 854     cpu.du.D2_RES   = getbits36_24 (words[5], 12);
 855 
 856     // Word 6
 857 
 858     cpu.du.D3_PTR_W = getbits36_18 (words[6],  0);
 859     cpu.du.D3_PTR_B = getbits36_6  (words[6], 18);
 860     cpu.du.TAk[2]   = getbits36_2  (words[6], 25);
 861     cpu.du.F3       = getbits36_1  (words[6], 31);
 862     cpu.du.Ak[2]    = getbits36_1  (words[6], 32);
 863     cpu.du.JMP      = getbits36_3  (words[6], 33);
 864 
 865     // Word 7
 866 
 867     cpu.du.D3_RES   = getbits36_24 (words[7], 12);
 868 
 869     if (cpu.tweaks.isolts_mode)
 870       {
 871         for (int i = 0; i < 8; i ++)
 872           {
 873             cpu.du.image[i] = words[i];
 874           }
 875      }
 876   }
 877 
 878 static char *PRalias[] = {"ap", "ab", "bp", "bb", "lp", "lb", "sp", "sb" };
 879 
 880 //=============================================================================
 881 
 882 // illegal modifications for various instructions
 883 
 884 /*
 885 
 886         00  01  02  03  04  05  06  07
 887 
 888  00     --  au  qu  du  ic  al  ql  dl  R
 889  10     0   1   2   3   4   5   6   7
 890 
 891  20     n*  au* qu* --  ic* al* al* --  RI
 892  30     0*  1*  2*  3*  4*  5*  6*  7*
 893 
 894  40     f1  itp --  its sd  scr f2  f3  IT
 895  50     ci  i   sc  ad  di  dic id  idc
 896 
 897  60     *n  *au *qu --  *ic *al *al --  IR
 898  70     *0  *1  *2  *3  *4  *5  *6  *7
 899 
 900  bool _allowed[] = {
 901  // Tm = 0 (register) R
 902  // --   au     qu     du     ic     al     ql     dl
 903  true,  false, false, false, false, false, false, false,
 904  // 0     1      2      3      4      5      6      7
 905  false, false, false, false, false, false, false, false,
 906  // Tm = 1 (register then indirect) RI
 907  // n*   au*    qu*    --     ic*    al*    al*    --
 908  false, false, false, true,  false, false, false, true,
 909  // 0*   1*     2*     3*     4*     5*     6*     7*
 910  false, false, false, false, false, false, false, false,
 911  // Tm = 2 (indirect then tally) IT
 912  // f1   itp    --     its    sd     scr    f2     f3
 913  false, false, true, false, false, false, false, false,
 914  // ci   i      sc     ad     di     dic    id     idc
 915  false, false, false, false, false, false, false, false,
 916  // Tm = 3 (indirect then register) IR
 917  // *n   *au    *qu    --     *ic    *al    *al    --
 918  false, false, false, true,  false, false, false, true,
 919  // *0   *1     *2     *3     *4     *5     *6     *7
 920  false, false, false, false, false, false, false, false,
 921  };
 922 
 923  */
 924 // No DUDL
 925 
 926 static bool _nodudl[] = {
 927     // Tm = 0 (register) R
 928     // --   au     qu     du     ic     al     ql     dl
 929     false,  false, false, true,  false, false, false, true,
 930     // 0      1      2      3      4      5      6      7
 931      false, false, false, false, false, false, false, false,
 932     // Tm = 1 (register then indirect) RI
 933     // n*    au*    qu*    --     ic*    al*    al*    --
 934     false,  false, false, true,  false, false, false, true,
 935     // 0*     1*     2*     3*     4*     5*     6*     7*
 936     false,  false, false, false, false, false, false, false,
 937     // Tm = 2 (indirect then tally) IT
 938     // f1    itp    --     its    sd     scr    f2     f3
 939     false,  false, true,  false, false, false, false, false,
 940     // ci     i      sc     ad     di     dic   id     idc
 941     false,  false, false, false, false, false, false, false,
 942     // Tm = 3 (indirect then register) IR
 943     // *n     *au    *qu    --     *ic   *al    *al    --
 944     false,  false, false, true,  false, false, false, true,
 945     // *0     *1     *2     *3     *4     *5     *6     *7
 946     false,  false, false, false, false, false, false, false,
 947 };
 948 
 949 // No DU
 950 // No DL
 951 
 952 // (NO_CI | NO_SC | NO_SCR)
 953 static bool _nocss[] = {
 954     // Tm = 0 (register) R
 955     // *      au     qu     du     ic     al     ql     dl
 956     false,  false, false, false, false, false, false, false,
 957     // 0      1      2      3      4      5      6      7
 958     false,  false, false, false, false, false, false, false,
 959     // Tm = 1 (register then indirect) RI
 960     // n*    au*    qu*    --     ic*    al*    al*    --
 961     false,  false, false, true,  false, false, false, true,
 962     // 0*     1*     2*     3*     4*     5*     6*     7*
 963     false,  false, false, false, false, false, false, false,
 964     // Tm = 2 (indirect then tally) IT
 965     // f1    itp     --     its    sd     scr    f2     f3
 966     false,  false, true,  false, false, true,  false, false,
 967     // ci     i     sc     ad     di    dic    id     idc
 968     true,   false, true,  false, false, false, false, false,
 969     // Tm = 3 (indirect then register) IR
 970     // *n    *au    *qu    --     *ic   *al    *al     --
 971     false,  false, false, true,  false, false, false, true,
 972     // *0     *1     *2     *3     *4     *5     *6     *7
 973     false,  false, false, false, false, false, false, false,
 974 };
 975 
 976 // (NO_DUDL | NO_CISCSCR)
 977 static bool _noddcss[] = {
 978     // Tm = 0 (register) R
 979     // *      au     qu     du     ic     al     ql    dl
 980     false,  false, false, true,  false, false, false, true,
 981     // 0      1      2      3      4      5      6      7
 982     false,  false, false, false, false, false, false, false,
 983     // Tm = 1 (register then indirect) RI
 984     // n*    au*    qu*    --     ic*    al*    al*    --
 985     false,  false, false, true,  false, false, false, true,
 986     // 0*     1*     2*     3*     4*     5*     6*     7*
 987     false,  false, false, false, false, false, false, false,
 988     // Tm = 2 (indirect then tally) IT
 989     // f1    itp     --     its    sd     scr    f2     f3
 990     false,  false, true,  false, false, true,  false, false,
 991     // ci     i     sc     ad     di    dic    id     idc
 992     true,   false, true,  false, false, false, false, false,
 993     // Tm = 3 (indirect then register) IR
 994     // *n    *au    *qu    --     *ic   *al    *al     --
 995     false,  false, false, true,  false, false, false, true,
 996     // *0     *1     *2     *3     *4     *5     *6     *7
 997     false,  false, false, false, false, false, false, false,
 998 };
 999 
1000 // (NO_DUDL | NO_CISCSCR)
1001 static bool _nodlcss[] = {
1002     // Tm = 0 (register) R
1003     // *     au     qu     du      ic     al     ql    dl
1004     false,  false, false, false, false, false, false, true,
1005     // 0      1      2      3      4      5      6      7
1006     false,  false, false, false, false, false, false, false,
1007     // Tm = 1 (register then indirect) RI
1008     // n*    au*    qu*    --     ic*    al*    al*    --
1009     false,  false, false, true,  false, false, false, true,
1010     // 0*     1*     2*     3*     4*     5*     6*     7*
1011     false,  false, false, false, false, false, false, false,
1012     // Tm = 2 (indirect then tally) IT
1013     // f1    itp     --     its    sd     scr    f2     f3
1014     false,  false, true,  false, false, true,  false, false,
1015     // ci     i     sc     ad     di    dic    id     idc
1016     true,   false, true,  false, false, false, false, false,
1017     // Tm = 3 (indirect then register) IR
1018     // *n    *au    *qu    --     *ic   *al    *al     --
1019     false,  false, false, true,  false, false, false, true,
1020     // *0     *1     *2     *3     *4     *5     *6     *7
1021     false,  false, false, false, false, false, false, false,
1022 };
1023 
1024 static bool _onlyaqxn[] = {
1025     // Tm = 0 (register) R
1026     // --    au     qu     du     ic     al     ql     dl
1027     false,  false, false, true,  true,  false, false, true,
1028     // 0      1      2      3      4      5      6      7
1029      false, false, false, false, false, false, false, false,
1030     // Tm = 1 (register then indirect) RI
1031     // n*    au*    qu*    --     ic*    al*    al*    --
1032     false,  false, false, true,  false, false, false, true,
1033     // 0*     1*     2*     3*     4*     5*     6*     7*
1034     false,  false, false, false, false, false, false, false,
1035     // Tm = 2 (indirect then tally) IT
1036     // f1    itp    --     its    sd     scr    f2     f3
1037     false,  false, true,  false, false, false, false, false,
1038     // ci     i      sc     ad     di     dic   id     idc
1039     false,  false, false, false, false, false, false, false,
1040     // Tm = 3 (indirect then register) IR
1041     // *n    *au    *qu    --     *ic   *al    *al     --
1042     false,  false, false, true,  false, false, false, true,
1043     // *0     *1     *2     *3     *4     *5     *6     *7
1044     false,  false, false, false, false, false, false, false,
1045 };
1046 
1047 #if !defined(QUIET_UNUSED)
1048 static bool _illmod[] = {
1049     // Tm = 0 (register) R
1050     // *     au     qu     du     ic     al     ql     dl
1051     false,  false, false, false, false, false, false, false,
1052     // 0      1      2      3      4      5      6      7
1053     false,  false, false, false, false, false, false, false,
1054     // Tm = 1 (register then indirect) RI
1055     // n*    au*    qu*    --     ic*    al*    al*    --
1056     false,  false, false, true,  false, false, false, true,
1057     // 0*     1*     2*     3*     4*     5*     6*     7*
1058     false,  false, false, false, false, false, false, false,
1059     // Tm = 2 (indirect then tally) IT
1060     // f1    itp    --     its    sd     scr    f2     f3
1061     false,  false, true,  false, false, false, false, false,
1062     // ci      i      sc     ad     di     dic   id     idc
1063     false,  false, false, false, false, false, false, false,
1064     // Tm = 3 (indirect then register) IR
1065     // *n     *au    *qu   --     *ic    *al    *al     --
1066     // *0     *1     *2     *3     *4     *5     *6     *7
1067     false,  false, false, true,  false, false, false, true,
1068     false,  false, false, false, false, false, false, false,
1069 };
1070 #endif
1071 
1072 //=============================================================================
1073 
1074 #if defined(MATRIX)
1075 
1076 static long long theMatrix[1024] // 1024 opcodes (2^10)
1077                           [2]    // opcode extension
1078                           [2]    // bit 29
1079                           [64];  // Tag
1080 
1081 void initializeTheMatrix (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1082 {
1083     (void)memset (theMatrix, 0, sizeof (theMatrix));
1084 }
1085 
1086 void addToTheMatrix (uint32 opcode, bool opcodeX, bool a, word6 tag)
     /* [previous][next][first][last][top][bottom][index][help] */
1087 {
1088     // safety
1089     uint _opcode = opcode & 01777;
1090     int _opcodeX = opcodeX ? 1 : 0;
1091     int _a       = a ? 1 : 0;
1092     int _tag     = tag & 077;
1093     theMatrix[_opcode][_opcodeX][_a][_tag] ++;
1094 }
1095 
1096 t_stat display_the_matrix (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1097 {
1098     long long count;
1099 
1100     for (int opcode  = 0; opcode < 01000; opcode ++)
1101     for (int opcodeX = 0; opcodeX < 2; opcodeX ++)
1102     {
1103     long long total = 0;
1104     for (int a = 0; a < 2; a ++)
1105     for (int tag = 0; tag < 64; tag ++)
1106     if ((count = theMatrix[opcode][opcodeX][a][tag]))
1107     {
1108         // disassemble doesn't quite do what we want so copy the good bits
1109         static char result[132] = "???";
1110         strcpy (result, "???");
1111         // get mnemonic ...
1112         if (opcodes10 [opcode | (opcodeX ? 01000 : 0)].mne)
1113           strcpy (result, opcodes10[opcode | (opcodeX ? 01000 : 0)].mne);
1114         if (a)
1115             strcat (result, " prn|nnnn");
1116         else
1117             strcat (result, " nnnn");
1118 
1119         // get mod
1120         if (extMods[tag].mod)
1121         {
1122             strcat (result, ",");
1123             strcat (result, extMods[tag].mod);
1124         }
1125         if (result[0] == '?')
1126             sim_printf ("%20"PRId64": ? opcode 0%04o X %d a %d tag 0%02do\n",
1127                         count, opcode, opcodeX, a, tag);
1128         else
1129             sim_printf ("%20"PRId64": %s\n", count, result);
1130         total += count;
1131     }
1132     static char result[132] = "???";
1133     strcpy (result, "???");
1134     if (total) {
1135     // get mnemonic ...
1136     if (opcodes10 [opcode | (opcodeX ? 01000 : 0)].mne)
1137       strcpy (result, opcodes10[opcode | (opcodeX ? 01000 : 0)].mne);
1138     sim_printf ("%20"PRId64": %s\n", total, result);
1139     }
1140     }
1141     return SCPE_OK;
1142 }
1143 #endif
1144 
1145 // fetch instruction at address
1146 // CANFAULT
1147 void fetchInstruction (cpu_state_t * cpup, word18 addr)
     /* [previous][next][first][last][top][bottom][index][help] */
1148 {
1149     CPT (cpt2U, 9); // fetchInstruction
1150 
1151     if (get_addr_mode (cpup) == ABSOLUTE_mode)
1152       {
1153         cpu.TPR.TRR  = 0;
1154         cpu.RSDWH_R1 = 0;
1155         //cpu.PPR.P = 1; // XXX this should be already set by set_addr_mode, so no worry here
1156       }
1157 
1158     if (cpu.cu.rd && ((cpu.PPR.IC & 1) != 0))
1159       {
1160         if (cpu.cu.repeat_first)
1161           {
1162             CPT (cpt2U, 10); // fetch rpt odd
1163             //Read (addr, & cpu.cu.IRODD, INSTRUCTION_FETCH);
1164           }
1165       }
1166     else if (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)
1167       {
1168         if (cpu.cu.repeat_first)
1169           {
1170             CPT (cpt2U, 11); // fetch rpt even
1171             if (addr & 1)
1172               ReadInstructionFetch (cpup, addr, & cpu.cu.IWB);
1173             else
1174               {
1175                 word36 tmp[2];
1176                 /* Read2 (addr, tmp, INSTRUCTION_FETCH); */
1177                 /* cpu.cu.IWB   = tmp[0]; */
1178                 Read2InstructionFetch (cpup, addr, tmp);
1179                 cpu.cu.IWB = tmp[0];
1180                 cpu.cu.IRODD = tmp[1];
1181               }
1182           }
1183       }
1184     else
1185       {
1186         CPT (cpt2U, 12); // fetch
1187 
1188         // ISOLTS test pa870 expects IRODD to be set up.
1189         // If we are fetching an even instruction, also fetch the odd.
1190         // If we are fetching an odd instruction, copy it to IRODD as
1191         // if that was where we got it from.
1192 
1193         //Read (addr, & cpu.cu.IWB, INSTRUCTION_FETCH);
1194         if ((cpu.PPR.IC & 1) == 0) // Even
1195           {
1196             word36 tmp[2];
1197             /* Read2 (addr, tmp, INSTRUCTION_FETCH); */
1198             /* cpu.cu.IWB   = tmp[0]; */
1199             Read2InstructionFetch (cpup, addr, tmp);
1200             cpu.cu.IWB = tmp[0];
1201             cpu.cu.IRODD = tmp[1];
1202           }
1203         else // Odd
1204           {
1205             ReadInstructionFetch (cpup, addr, & cpu.cu.IWB);
1206             cpu.cu.IRODD = cpu.cu.IWB;
1207           }
1208       }
1209 }
1210 
1211 #if defined(TESTING)
1212 void traceInstruction (uint flag)
     /* [previous][next][first][last][top][bottom][index][help] */
1213   {
1214     cpu_state_t * cpup = _cpup;
1215     char buf [256];
1216     if (! flag) goto force;
1217     if_sim_debug (flag, &cpu_dev)
1218       {
1219 force:;
1220         char * compname;
1221         word18 compoffset;
1222         char * where = lookup_address (cpu.PPR.PSR, cpu.PPR.IC, & compname,
1223                                        & compoffset);
1224         bool isBAR = TST_I_NBAR ? false : true;
1225         if (where)
1226           {
1227             if (get_addr_mode (cpup) == ABSOLUTE_mode)
1228               {
1229                 if (isBAR)
1230                   {
1231                     sim_debug (flag, &cpu_dev, "%06o|%06o %s\n",
1232                                cpu.BAR.BASE, cpu.PPR.IC, where);
1233                   }
1234                 else
1235                   {
1236                     sim_debug (flag, &cpu_dev, "%06o %s\n", cpu.PPR.IC, where);
1237                   }
1238               }
1239             else if (get_addr_mode (cpup) == APPEND_mode)
1240               {
1241                 if (isBAR)
1242                   {
1243                     sim_debug (flag, &cpu_dev, "%05o:%06o|%06o %s\n",
1244                                cpu.PPR.PSR,
1245                                cpu.BAR.BASE, cpu.PPR.IC, where);
1246                   }
1247                 else
1248                   {
1249                     sim_debug (flag, &cpu_dev, "%05o:%06o %s\n",
1250                                cpu.PPR.PSR, cpu.PPR.IC, where);
1251                   }
1252               }
1253             list_source (compname, compoffset, flag);
1254           }
1255         if (get_addr_mode (cpup) == ABSOLUTE_mode)
1256           {
1257             if (isBAR)
1258               {
1259                 sim_debug (flag, &cpu_dev,
1260                   "%d: "
1261                   "%05o|%06o %012"PRIo64" (%s) %06o %03o(%d) %o %o %o %02o\n",
1262                   current_running_cpu_idx,
1263                   cpu.BAR.BASE,
1264                   cpu.PPR.IC,
1265                   IWB_IRODD,
1266                   disassemble (buf, IWB_IRODD),
1267                   cpu.currentInstruction.address,
1268                   cpu.currentInstruction.opcode,
1269                   cpu.currentInstruction.opcodeX,
1270                   cpu.currentInstruction.b29,
1271                   cpu.currentInstruction.i,
1272                   GET_TM (cpu.currentInstruction.tag) >> 4,
1273                   GET_TD (cpu.currentInstruction.tag) & 017);
1274               }
1275             else
1276               {
1277                 sim_debug (flag, &cpu_dev,
1278                   "%d: "
1279                   "%06o %012"PRIo64" (%s) %06o %03o(%d) %o %o %o %02o\n",
1280                   current_running_cpu_idx,
1281                   cpu.PPR.IC,
1282                   IWB_IRODD,
1283                   disassemble (buf, IWB_IRODD),
1284                   cpu.currentInstruction.address,
1285                   cpu.currentInstruction.opcode,
1286                   cpu.currentInstruction.opcodeX,
1287                   cpu.currentInstruction.b29,
1288                   cpu.currentInstruction.i,
1289                   GET_TM (cpu.currentInstruction.tag) >> 4,
1290                   GET_TD (cpu.currentInstruction.tag) & 017);
1291               }
1292           }
1293         else if (get_addr_mode (cpup) == APPEND_mode)
1294           {
1295             if (isBAR)
1296               {
1297                 sim_debug (flag, &cpu_dev,
1298                   "%d: "
1299                  "%05o:%06o|%06o %o %012"PRIo64" (%s) %06o %03o(%d) %o %o %o %02o\n",
1300                   current_running_cpu_idx,
1301                   cpu.PPR.PSR,
1302                   cpu.BAR.BASE,
1303                   cpu.PPR.IC,
1304                   cpu.PPR.PRR,
1305                   IWB_IRODD,
1306                   disassemble (buf, IWB_IRODD),
1307                   cpu.currentInstruction.address,
1308                   cpu.currentInstruction.opcode,
1309                   cpu.currentInstruction.opcodeX,
1310                   cpu.currentInstruction.b29, cpu.currentInstruction.i,
1311                   GET_TM (cpu.currentInstruction.tag) >> 4,
1312                   GET_TD (cpu.currentInstruction.tag) & 017);
1313               }
1314             else
1315               {
1316                 sim_debug (flag, &cpu_dev,
1317                   "%d: "
1318                   "%05o:%06o %o %012"PRIo64" (%s) %06o %03o(%d) %o %o %o %02o\n",
1319                   current_running_cpu_idx,
1320                   cpu.PPR.PSR,
1321                   cpu.PPR.IC,
1322                   cpu.PPR.PRR,
1323                   IWB_IRODD,
1324                   disassemble (buf, IWB_IRODD),
1325                   cpu.currentInstruction.address,
1326                   cpu.currentInstruction.opcode,
1327                   cpu.currentInstruction.opcodeX,
1328                   cpu.currentInstruction.b29,
1329                   cpu.currentInstruction.i,
1330                   GET_TM (cpu.currentInstruction.tag) >> 4,
1331                   GET_TD (cpu.currentInstruction.tag) & 017);
1332               }
1333           }
1334       }
1335 
1336   }
1337 #endif
1338 
1339 bool chkOVF (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
1340   {
1341     if (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)
1342       {
1343         // a:AL39/rpd2
1344         // Did the repeat instruction inhibit overflow faults?
1345         if ((cpu.rX[0] & 00001) == 0)
1346           return false;
1347       }
1348     return true;
1349   }
1350 
1351 bool tstOVFfault (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
1352   {
1353     // Masked?
1354     if (TST_I_OMASK)
1355       return false;
1356     // Doing a RPT/RPD?
1357     if (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)
1358       {
1359         // a:AL39/rpd2
1360         // Did the repeat instruction inhibit overflow faults?
1361         if ((cpu.rX[0] & 00001) == 0)
1362           return false;
1363       }
1364     return true;
1365   }
1366 
1367 #if defined(TESTING)
1368 # include "tracker.h"
1369 #endif
1370 
1371 t_stat executeInstruction (cpu_state_t * cpup) {
     /* [previous][next][first][last][top][bottom][index][help] */
1372 #if defined(TESTING)
1373   trk (cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, IWB_IRODD);
1374 #endif
1375   CPT (cpt2U, 13); // execute instruction
1376 
1377 //
1378 // Decode the instruction
1379 //
1380 // If not restart
1381 //     if xec/xed
1382 //         check for illegal execute
1383 //     if rpt/rpd
1384 //         check for illegal rpt/rpd modifiers
1385 //     check for illegal modifiers
1386 //     check for privilege
1387 //     initialize CA
1388 //
1389 // Save tally
1390 // Debug trace instruction
1391 // If not restart
1392 //    Initialize TPR
1393 //
1394 // Initialize DU.JMP
1395 // If rpt/rpd
1396 //     If first repeat
1397 //         Initialize Xn
1398 //
1399 // If EIS instruction
1400 //     If not restart
1401 //         Initialize DU.CHTALLY, DU.Z
1402 //     Read operands
1403 //     Parse operands
1404 // Else not EIS instruction
1405 //     If not restart
1406 //         If B29
1407 //             Set TPR from pointer register
1408 //         Else
1409 //             Setup up TPR
1410 //         Initialize CU.CT_HOLD
1411 //     If restart and CU.POT
1412 //         Restore CA from IWB
1413 //     Do CAF if needed
1414 //     Read operand if needed
1415 //
1416 // Execute the instruction
1417 //
1418 // Write operand if needed
1419 // Update IT tally if needed
1420 // If XEC/XED, move instructions into IWB/IRODD
1421 // If instruction was repeated
1422 //     Update Xn
1423 //     Check for repeat termination
1424 // Post-instruction debug
1425 
1426 ///
1427 /// executeInstruction: Decode the instruction
1428 ///
1429 
1430   DCDstruct * ci = & cpu.currentInstruction;
1431   decode_instruction (cpup, IWB_IRODD, ci);
1432   const struct opcode_s *info = ci->info;
1433 
1434 // Local caches of frequently accessed data
1435 
1436   const uint ndes         = info->ndes;
1437   const bool restart      = cpu.cu.rfi;   // instruction is to be restarted
1438   cpu.cu.rfi              = 0;
1439   const opc_flag flags    = info->flags;
1440   const enum opc_mod mods = info->mods;
1441   const uint32 opcode     = ci->opcode;   // opcode
1442   const bool opcodeX      = ci->opcodeX;  // opcode extension
1443   const word6 tag         = ci->tag;      // instruction tag
1444 
1445 #if defined(MATRIX)
1446   {
1447     const uint32  opcode = ci->opcode;   // opcode
1448     const bool   opcodeX = ci->opcodeX;  // opcode extension
1449                                          // XXX replace with rY
1450     const bool   b29 = ci->b29;          // bit-29 - addressing via pointer
1451                                          // register
1452     const word6  tag = ci->tag;          // instruction tag
1453                                          //  XXX replace withrTAG
1454     addToTheMatrix (opcode, opcodeX, b29, tag);
1455   }
1456 #endif
1457 
1458   if (ci->b29)
1459     ci->address = SIGNEXT15_18 (ci->address & MASK15);
1460 
1461   L68_ (
1462     CPTUR (cptUseMR);
1463     if (UNLIKELY (cpu.MR.emr && cpu.MR.OC_TRAP)) {
1464       if (cpu.MR.OPCODE == opcode && cpu.MR.OPCODEX == opcodeX) {
1465         if (cpu.MR.ihrrs) {
1466           cpu.MR.ihr = 0;
1467         }
1468         CPT (cpt2U, 14); // opcode trap
1469         //set_FFV_fault (2); // XXX According to AL39
1470         do_FFV_fault (cpup, 1, "OC TRAP");
1471       }
1472     }
1473   )
1474 
1475 ///
1476 /// executeInstruction: Non-restart processing
1477 ///
1478 
1479   if (LIKELY (!restart) || UNLIKELY (ndes > 0)) { // until we implement EIS restart
1480     cpu.cu.TSN_VALID[0] = 0;
1481     cpu.cu.TSN_VALID[1] = 0;
1482     cpu.cu.TSN_VALID[2] = 0;
1483     cpu.cu.TSN_PRNO[0]  = 0;
1484     cpu.cu.TSN_PRNO[1]  = 0;
1485     cpu.cu.TSN_PRNO[2]  = 0;
1486   }
1487 
1488   if (UNLIKELY (restart))
1489     goto restart_1;
1490 
1491 //
1492 // not restart
1493 //
1494 
1495   cpu.cu.XSF = 0;
1496 
1497   cpu.cu.pot = 0;
1498   cpu.cu.its = 0;
1499   cpu.cu.itp = 0;
1500 
1501   CPT (cpt2U, 14); // non-restart processing
1502   // Set Address register empty
1503   PNL (L68_ (cpu.AR_F_E = false;))
1504 
1505   // Reset the fault counter
1506   cpu.cu.APUCycleBits &= 07770;
1507 
1508   //cpu.cu.TSN_VALID[0] = 0;
1509   //cpu.cu.TSN_VALID[1] = 0;
1510   //cpu.cu.TSN_VALID[2] = 0;
1511 
1512   // If executing the target of XEC/XED, check the instruction is allowed
1513   if (UNLIKELY (cpu.isXED)) {
1514     if (flags & NO_XED)
1515       doFault (FAULT_IPR, fst_ill_proc,
1516                "Instruction not allowed in XEC/XED");
1517     // The even instruction from C(Y-pair) must not alter
1518     // C(Y-pair)36,71, and must not be another xed instruction.
1519     if (opcode == 0717 && !opcodeX && cpu.cu.xde && cpu.cu.xdo /* even instruction being executed */)
1520       doFault (FAULT_IPR, fst_ill_proc,
1521                "XED of XED on even word");
1522     // ISOLTS 791 03k, 792 03k
1523     if (opcode == 0560 && !opcodeX) {
1524       // To Execute Double (XED) the RPD instruction, the RPD must be the second
1525       // instruction at an odd-numbered address.
1526       if (cpu.cu.xde && cpu.cu.xdo /* even instr being executed */)
1527         doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC},
1528                  "XED of RPD on even word");
1529       // To execute an instruction pair having an rpd instruction as the odd
1530       // instruction, the xed instruction must be located at an odd address.
1531       if (!cpu.cu.xde && cpu.cu.xdo /* odd instr being executed */ && !(cpu.PPR.IC & 1))
1532         doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC},
1533                  "XED of RPD on odd word, even IC");
1534     }
1535   } else if (UNLIKELY (cpu.isExec)) {
1536     // To execute a rpd instruction, the xec instruction must be in an odd location.
1537     // ISOLTS 768 01w
1538     if (opcode == 0560 && !opcodeX && cpu.cu.xde && !(cpu.PPR.IC & 1))
1539       doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC},
1540                "XEC of RPx on even word");
1541   }
1542 
1543   // ISOLTS wants both the not allowed in RPx and RPx illegal modifier
1544   // tested.
1545   fault_ipr_subtype_ RPx_fault = 0;
1546 
1547   // RPT/RPD illegal modifiers
1548   // a:AL39/rpd3
1549   if (UNLIKELY (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)) {
1550     if (! (flags & NO_TAG)) {
1551       // check for illegal modifiers:
1552       //    only R & RI are allowed
1553       //    only X1..X7
1554       switch (GET_TM (tag)) {
1555         case TM_RI:
1556           if (cpu.cu.rl)
1557             RPx_fault |= FR_ILL_MOD;
1558           break;
1559         case TM_R:
1560           break;
1561         default:
1562           // generate fault. Only R & RI allowed
1563           RPx_fault |= FR_ILL_MOD;
1564       }
1565 
1566       word6 Td = GET_TD (tag);
1567       if (Td == TD_X0)
1568         RPx_fault |= FR_ILL_MOD;
1569       if (Td < TD_X0)
1570         RPx_fault |= FR_ILL_MOD;
1571     }
1572 
1573     DPS8M_ (
1574       // ISOLTS 792 03e
1575       // this is really strange. possibly a bug in DPS8M HW (L68 handles it the same as all other instructions)
1576       if (RPx_fault && !opcodeX && opcode==0413) // rscr
1577         doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=RPx_fault},
1578                  "DPS8M rscr early raise");
1579     )
1580 
1581     // Instruction not allowed in RPx?
1582 
1583     if (UNLIKELY (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)) {
1584       if (flags & NO_RPT)
1585         RPx_fault |= FR_ILL_PROC;
1586     }
1587 
1588     if (UNLIKELY (cpu.cu.rl)) {
1589       if (flags & NO_RPL)
1590         RPx_fault |= FR_ILL_PROC;
1591     }
1592 
1593     L68_ (
1594       // ISOLTS 791 03d, 792 03d
1595       // L68 wants ILL_MOD here - stca,stcq,stba,stbq,scpr,lcpr
1596       // all these instructions have a nonstandard TAG field interpretation. probably a HW bug in decoder
1597       if (RPx_fault && !opcodeX && (opcode==0751 || opcode==0752 || opcode==0551 || opcode==0552 || opcode==0452 || opcode==0674))
1598         RPx_fault |= FR_ILL_MOD;
1599     )
1600   }
1601 
1602   // PVS-Studio says: Expression 'RPx_fault != 0' is always false.
1603   if (UNLIKELY (RPx_fault != 0)) //-V547
1604     doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=RPx_fault},
1605              "RPx test fail");
1606 
1607   ///                     check for illegal addressing mode(s) ...
1608   ///
1609   // ISOLTS wants both the IPR and illegal modifier tested.
1610   fault_ipr_subtype_ mod_fault = 0;
1611 
1612   // No CI/SC/SCR allowed
1613   if (mods == NO_CSS) {
1614     if (_nocss[tag])
1615       mod_fault |= FR_ILL_MOD; // "Illegal CI/SC/SCR modification"
1616   }
1617   // No DU/DL/CI/SC/SCR allowed
1618   else if (mods == NO_DDCSS) {
1619     if (_noddcss[tag])
1620       mod_fault |= FR_ILL_MOD; // "Illegal DU/DL/CI/SC/SCR modification"
1621   }
1622   // No DL/CI/SC/SCR allowed
1623   else if (mods == NO_DLCSS) {
1624     if (_nodlcss[tag])
1625       mod_fault |= FR_ILL_MOD; // "Illegal DL/CI/SC/SCR modification"
1626   }
1627   // No DU/DL allowed
1628   else if (mods == NO_DUDL) {
1629     if (_nodudl[tag])
1630       mod_fault |= FR_ILL_MOD; // "Illegal DU/DL modification"
1631   }
1632   else if ((unsigned long long)mods == (unsigned long long)ONLY_AU_QU_AL_QL_XN) {
1633     if (_onlyaqxn[tag])
1634       mod_fault |= FR_ILL_MOD; // "Illegal DU/DL/IC modification"
1635   }
1636 
1637   L68_ (
1638     // L68 raises it immediately
1639     if (mod_fault)
1640       doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=mod_fault},
1641                "Illegal modifier");
1642    )
1643 
1644   // check for priv ins - Attempted execution in normal or BAR modes causes a
1645   // illegal procedure fault.
1646   if (UNLIKELY (flags & PRIV_INS)) {
1647     DPS8M_ (
1648       // DPS8M illegal instructions lptp,lptr,lsdp,lsdr
1649       // ISOLTS 890 05abc
1650       if (((opcode == 0232 || opcode == 0173) && opcodeX ) || (opcode == 0257))
1651         doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault},
1652                  "Attempted execution of multics privileged instruction.");
1653     )
1654 
1655     if (!is_priv_mode (cpup)) {
1656       // Multics privileged instructions: absa,ldbr,lra,rcu,scu,sdbr,ssdp,ssdr,sptp,sptr
1657       // ISOLTS 890 05abc,06abc
1658       bool prv;
1659       DPS8M_ (
1660         prv =((opcode == 0212 || opcode == 0232 || opcode == 0613 || opcode == 0657) && !opcodeX ) ||
1661              ((opcode == 0254 || opcode == 0774) && opcodeX ) ||
1662               (opcode == 0557 || opcode == 0154);
1663       )
1664       L68_ (
1665         // on L68, lptp,lptr,lsdp,lsdr instructions are not illegal, so handle them here
1666         prv = ((opcode == 0212 || opcode == 0232 || opcode == 0613 || opcode == 0657) && !opcodeX ) ||
1667               ((opcode == 0254 || opcode == 0774 || opcode == 0232 || opcode == 0173) && opcodeX ) ||
1668                (opcode == 0557 || opcode == 0154 || opcode == 0257);
1669       )
1670       if (prv) {
1671         if (!get_bar_mode (cpup)) {
1672           // ISOLTS-890 05ab
1673           doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_SLV|mod_fault},
1674                    "Attempted execution of multics privileged instruction.");
1675         } else {
1676           doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault},
1677                    "Attempted execution of multics privileged instruction.");
1678         }
1679       }
1680       doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_SLV|mod_fault},
1681                "Attempted execution of privileged instruction.");
1682     }
1683   }
1684 
1685   if (UNLIKELY (flags & NO_BAR)) {
1686     if (get_bar_mode(cpup)) {
1687       // lbar
1688       // ISOLTS 890 06a
1689       // ISOLTS says that L68 handles this in the same way
1690       if (opcode == 0230 && !opcodeX)
1691         doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_SLV|mod_fault},
1692                  "Attempted BAR execution of nonprivileged instruction.");
1693       else
1694         doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault},
1695                  "Attempted BAR execution of nonprivileged instruction.");
1696     }
1697   }
1698 
1699   DPS8M_ (
1700     // DPS8M raises it delayed
1701     if (UNLIKELY (mod_fault != 0))
1702       doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=mod_fault},
1703                "Illegal modifier");
1704   )
1705 
1706 ///
1707 /// executeInstruction: Restart or Non-restart processing
1708 ///                     Initialize address registers
1709 ///
1710 
1711 restart_1:
1712   CPT (cpt2U, 15); // instruction processing
1713 
1714 ///
1715 /// executeInstruction: Initialize state saving registers
1716 ///
1717 
1718   // XXX this may be wrong; make sure that the right value is used
1719   // if a page fault occurs. (i.e. this may belong above restart_1.
1720   // This is also used by the SCU instruction. ISOLTS tst887 does
1721   // a 'SCU n,ad' with a tally of 1; the tally is decremented, setting
1722   // the IR tally bit as part of the CA calculation; this is not
1723   // the machine conditions that the SCU instruction is saving.
1724 
1725   ci->stiTally = TST_I_TALLY;   // for sti instruction
1726 
1727 ///
1728 /// executeInstruction: scp hooks
1729 ///
1730 
1731 #if !defined(SPEED)
1732   // Don't trace Multics idle loop
1733   //if (cpu.PPR.PSR != 061 || cpu.PPR.IC != 0307)
1734 
1735   {
1736     traceInstruction (DBG_TRACE);
1737 # if defined(DBGEVENT)
1738     int dbgevt;
1739     if (n_dbgevents && (dbgevt = (dbgevent_lookup (cpu.PPR.PSR, cpu.PPR.IC))) >= 0) {
1740       if (dbgevents[dbgevt].t0)
1741         clock_gettime (CLOCK_REALTIME, & dbgevent_t0);
1742       struct timespec now, delta;
1743       clock_gettime (CLOCK_REALTIME, & now);
1744       timespec_diff (& dbgevent_t0, & now, & delta);
1745       sim_printf ("[%d] %5ld.%03ld %s\r\n", dbgevt, delta.tv_sec, delta.tv_nsec/1000000, dbgevents[dbgevt].tag);
1746     }
1747 # endif
1748 # if defined(TESTING)
1749     HDBGTrace ("");
1750 # endif
1751   }
1752 #else  // !SPEED
1753   // Don't trace Multics idle loop
1754   //if (cpu.PPR.PSR != 061 || cpu.PPR.IC != 0307)
1755 # if defined(TESTING)
1756   HDBGTrace ("");
1757 # endif
1758 #endif // !SPEED
1759 
1760 ///
1761 /// executeInstruction: Initialize misc.
1762 ///
1763 
1764   cpu.du.JMP = (word3) ndes;
1765   cpu.dlyFlt = false;
1766 
1767 ///
1768 /// executeInstruction: RPT/RPD/RPL special processing for 'first time'
1769 ///
1770 
1771   if (UNLIKELY (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)) {
1772     CPT (cpt2U, 15); // RPx processing
1773 
1774 //
1775 // RPT:
1776 //
1777 // The computed address, y, of the operand (in the case of R modification) or
1778 // indirect word (in the case of RI modification) is determined as follows:
1779 //
1780 // For the first execution of the repeated instruction:
1781 //      C(C(PPR.IC)+1)0,17 + C(Xn) -> y, y -> C(Xn)
1782 //
1783 // For all successive executions of the repeated instruction:
1784 //      C(Xn) + Delta -> y, y -> C(Xn);
1785 //
1786 //
1787 // RPD:
1788 //
1789 // The computed addresses, y-even and y-odd, of the operands (in the case of
1790 // R modification) or indirect words (in the case of RI modification) are
1791 // determined as follows:
1792 //
1793 // For the first execution of the repeated instruction pair:
1794 //      C(C(PPR.IC)+1)0,17 + C(X-even) -> y-even, y-even -> C(X-even)
1795 //      C(C(PPR.IC)+2)0,17 + C(X-odd) -> y-odd, y-odd -> C(X-odd)
1796 //
1797 // For all successive executions of the repeated instruction pair:
1798 //      if C(X0)8 = 1, then C(X-even) + Delta -> y-even,
1799 //           y-even -> C(X-even);
1800 //      otherwise, C(X-even) -> y-even
1801 //      if C(X0)9 = 1, then C(X-odd) + Delta -> y-odd,
1802 //           y-odd -> C(X-odd);
1803 //      otherwise, C(X-odd) -> y-odd
1804 //
1805 // C(X0)8,9 correspond to control bits A and B, respectively, of the rpd
1806 // instruction word.
1807 //
1808 //
1809 // RL:
1810 //
1811 // The computed address, y, of the operand is determined as follows:
1812 //
1813 // For the first execution of the repeated instruction:
1814 //
1815 //      C(C(PPR.IC)+1)0,17 + C(Xn) -> y, y -> C(Xn)
1816 //
1817 // For all successive executions of the repeated instruction:
1818 //
1819 //      C(Xn) -> y
1820 //
1821 //      if C(Y)0,17 != 0, then C (y)0,17 -> C(Xn);
1822 //
1823 //      otherwise, no change to C(Xn)
1824 //
1825 //  C(Y)0,17 is known as the link address and is the computed address of the
1826 //  next entry in a threaded list of operands to be referenced by the repeated
1827 //  instruction.
1828 //
1829 
1830     sim_debug (DBG_TRACEEXT, & cpu_dev,
1831                "RPT/RPD first %d rpt %d rd %d e/o %d X0 %06o a %d b %d\n",
1832                cpu.cu.repeat_first, cpu.cu.rpt, cpu.cu.rd, cpu.PPR.IC & 1, cpu.rX[0],
1833                !! (cpu.rX[0] & 01000), !! (cpu.rX[0] & 0400));
1834     sim_debug (DBG_TRACEEXT, & cpu_dev,
1835                "RPT/RPD CA %06o\n", cpu.TPR.CA);
1836 
1837 // Handle first time of a RPT or RPD
1838 
1839     if (cpu.cu.repeat_first) {
1840       CPT (cpt2U, 16); // RPx first processing
1841       // The semantics of these are that even is the first instruction of
1842       // and RPD, and odd the second.
1843 
1844       bool icOdd  = !! (cpu.PPR.IC & 1);
1845       bool icEven = ! icOdd;
1846 
1847       // If RPT or (RPD and the odd instruction)
1848       if (cpu.cu.rpt || (cpu.cu.rd && icOdd) || cpu.cu.rl)
1849         cpu.cu.repeat_first = false;
1850 
1851       // a:RJ78/rpd6
1852       // For the first execution of the repeated instruction:
1853       // C(C(PPR.IC)+1)0,17 + C(Xn) -> y, y -> C(Xn)
1854       if (cpu.cu.rpt ||              // rpt
1855          (cpu.cu.rd && icEven) ||   // rpd & even
1856          (cpu.cu.rd && icOdd)  ||   // rpd & odd
1857           cpu.cu.rl) {               // rl
1858         word18 offset = ci->address;
1859         offset &= AMASK;
1860 
1861         sim_debug (DBG_TRACEEXT, & cpu_dev, "rpt/rd/rl repeat first; offset is %06o\n", offset);
1862 
1863         word6 Td = GET_TD (tag);
1864         uint Xn = X (Td);  // Get Xn of next instruction
1865         sim_debug (DBG_TRACEEXT, & cpu_dev, "rpt/rd/rl repeat first; X%d was %06o\n", Xn, cpu.rX[Xn]);
1866         // a:RJ78/rpd5
1867         cpu.TPR.CA = (cpu.rX[Xn] + offset) & AMASK;
1868         cpu.rX[Xn] = cpu.TPR.CA;
1869 #if defined(TESTING)
1870         HDBGRegXW (Xn, "rpt 1st");
1871 #endif
1872         sim_debug (DBG_TRACEEXT, & cpu_dev, "rpt/rd/rl repeat first; X%d now %06o\n", Xn, cpu.rX[Xn]);
1873       } // rpt or rd or rl
1874 
1875     } // repeat first
1876   } // cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl
1877 
1878 ///
1879 /// Restart or Non-restart
1880 ///
1881 
1882 ///
1883 /// executeInstruction: EIS operand processing
1884 ///
1885 
1886   if (UNLIKELY (ndes > 0)) {
1887     CPT (cpt2U, 27); // EIS operand processing
1888     sim_debug (DBG_APPENDING, &cpu_dev, "initialize EIS descriptors\n");
1889     // This must not happen on instruction restart
1890     if (!restart) {
1891       CPT (cpt2U, 28); // EIS not restart
1892       cpu.du.CHTALLY = 0;
1893       cpu.du.Z = 1;
1894     }
1895     for (uint n = 0; n < ndes; n += 1) {
1896       CPT (cpt2U, 29 + n); // EIS operand fetch (29, 30, 31)
1897 // XXX This is a bit of a hack; In general the code is good about
1898 // setting up for bit29 or PR operations by setting up TPR, but
1899 // assumes that the 'else' case can be ignored when it should set
1900 // TPR to the canonical values. Here, in the case of a EIS instruction
1901 // restart after page fault, the TPR is in an unknown state. Ultimately,
1902 // this should not be an issue, as this folderol would be in the DU, and
1903 // we would not be re-executing that code, but until then, set the TPR
1904 // to the condition we know it should be in.
1905             cpu.TPR.TRR = cpu.PPR.PRR;
1906             cpu.TPR.TSR = cpu.PPR.PSR;
1907 
1908 
1909 
1910 
1911 
1912 
1913 
1914             // append cycles updates cpu.PPR.IC to TPR.CA
1915             word18 saveIC = cpu.PPR.IC;
1916             //Read (cpu.PPR.IC + 1 + n, & cpu.currentEISinstruction.op[n], INSTRUCTION_FETCH);
1917             ReadInstructionFetch (cpup, cpu.PPR.IC + 1 + n, & cpu.currentEISinstruction.op[n]);
1918             cpu.PPR.IC = saveIC;
1919             //Read (cpu.PPR.IC + 1 + n, & cpu.currentEISinstruction.op[n], APU_DATA_READ);
1920 
1921           }
1922         PNL (cpu.IWRAddr = cpu.currentEISinstruction.op[0]);
1923         setupEISoperands (cpup);
1924       }
1925 
1926 ///
1927 /// Restart or Non-restart
1928 ///
1929 
1930 ///
1931 /// executeInstruction: non-EIS operand processing
1932 ///
1933 
1934   else {
1935     CPT (cpt2U, 32); // non-EIS operand processing
1936     CPT (cpt2U, 33); // not restart non-EIS operand processing
1937     if (ci->b29) {   // if A bit set set-up TPR stuff ...
1938       CPT (cpt2U, 34); // B29
1939 
1940 // AL39 says that RCU does not restore CA, so words to SCU does not.
1941 // So we do it here, even if restart
1942       word3 n = GET_PRN(IWB_IRODD);  // get PRn
1943       word15 offset = GET_OFFSET(IWB_IRODD);
1944       CPTUR (cptUsePRn + n);
1945 
1946       sim_debug (DBG_APPENDING, &cpu_dev,
1947                  "doPtrReg: PR[%o] SNR=%05o RNR=%o WORDNO=%06o " "BITNO=%02o\n",
1948                  n, cpu.PAR[n].SNR, cpu.PAR[n].RNR, cpu.PAR[n].WORDNO, GET_PR_BITNO (n));
1949 
1950 // Fix tst880: 'call6 pr1|0'. The instruction does a DF1; the fault handler
1951 // updates PRR in the CU save data. On restart, TRR is not updated.
1952 // Removing the 'if' appears to resolve the problem without regressions.
1953       //if (!restart) {
1954 // Not EIS, bit 29 set, !restart
1955       cpu.TPR.TBR = GET_PR_BITNO (n);
1956 
1957       cpu.TPR.TSR = cpu.PAR[n].SNR;
1958       if (ci->info->flags & TRANSFER_INS)
1959         cpu.TPR.TRR = max (cpu.PAR[n].RNR, cpu.PPR.PRR);
1960       else
1961         cpu.TPR.TRR = max3 (cpu.PAR[n].RNR, cpu.TPR.TRR, cpu.PPR.PRR);
1962 
1963       sim_debug (DBG_APPENDING, &cpu_dev,
1964                  "doPtrReg: n=%o offset=%05o TPR.CA=%06o " "TPR.TBR=%o TPR.TSR=%05o TPR.TRR=%o\n",
1965                  n, offset, cpu.TPR.CA, cpu.TPR.TBR, cpu.TPR.TSR, cpu.TPR.TRR);
1966       //}
1967 
1968 // Putting the a29 clear here makes sense, but breaks the emulator for unclear
1969 // reasons (possibly ABSA?). Do it in updateIWB instead
1970 //                ci->a = false;
1971 //                // Don't clear a; it is needed to detect change to appending
1972 //                //  mode
1973 //                //a = false;
1974 //                putbits36_1 (& cpu.cu.IWB, 29, 0);
1975     } else {
1976 // not eis, not bit b29
1977       if (!restart) {
1978         CPT (cpt2U, 35); // not B29
1979         cpu.cu.TSN_VALID [0] = 0;
1980         cpu.TPR.TBR = 0;
1981         if (get_addr_mode (cpup) == ABSOLUTE_mode) {
1982           cpu.TPR.TSR  = cpu.PPR.PSR;
1983           cpu.TPR.TRR  = 0;
1984           cpu.RSDWH_R1 = 0;
1985         }
1986       }
1987     }
1988 
1989     // This must not happen on instruction restart
1990     if (!restart)
1991       cpu.cu.CT_HOLD = 0; // Clear interrupted IR mode flag
1992 
1993     // These are set by do_caf
1994     cpu.ou.directOperandFlag = false;
1995     cpu.ou.directOperand = 0;
1996     cpu.ou.characterOperandSize = 0;
1997     cpu.ou.characterOperandOffset = 0;
1998     cpu.ou.crflag = false;
1999 
2000     if ((flags & PREPARE_CA) || WRITEOP (ci) || READOP (ci)) {
2001       CPT (cpt2L, 1); // CAF
2002       do_caf (cpup);
2003       PNL (L68_ (cpu.AR_F_E = true;))
2004       cpu.iefpFinalAddress = cpu.TPR.CA;
2005     }
2006 
2007     if (READOP (ci)) {
2008       CPT (cpt2L, 2); // Read operands
2009       readOperands (cpup);
2010 #if defined(LOCKLESS)
2011       cpu.rmw_address = cpu.iefpFinalAddress;
2012 #endif
2013       if (cpu.cu.rl) {
2014         switch (operand_size (cpup)) {
2015           case 1:
2016             cpu.lnk = GETHI36 (cpu.CY);
2017             cpu.CY &= MASK18;
2018             break;
2019 
2020           case 2:
2021             cpu.lnk = GETHI36 (cpu.Ypair[0]);
2022             cpu.Ypair[0] &= MASK18;
2023             break;
2024 
2025           default:
2026             break;
2027         }
2028       }
2029     }
2030     PNL (cpu.IWRAddr = 0);
2031   }
2032 
2033 // Initialize zone to 'entire word'
2034 
2035   cpu.useZone = false;
2036   cpu.zone = MASK36;
2037 
2038 ///
2039 /// executeInstruction: Execute the instruction
2040 ///
2041 
2042   t_stat ret = doInstruction (cpup);
2043 
2044 ///
2045 /// executeInstruction: Write operand
2046 ///
2047 
2048   cpu.last_write = 0;
2049   if (WRITEOP (ci)) {
2050     CPT (cpt2L, 3); // Write operands
2051     cpu.last_write = cpu.TPR.CA;
2052 #if defined(LOCKLESS)
2053     if ((ci->info->flags & RMW) == RMW) {
2054       if (operand_size(cpup) != 1)
2055         sim_warn("executeInstruction: operand_size!= 1\n");
2056       if (cpu.iefpFinalAddress != cpu.rmw_address)
2057         sim_warn("executeInstruction: write addr changed %o %d\n", cpu.iefpFinalAddress, cpu.rmw_address);
2058       core_write_unlock (cpup, cpu.iefpFinalAddress, cpu.CY, __func__);
2059 # if defined(TESTING)
2060       HDBGMWrite (cpu.iefpFinalAddress, cpu.CY, "Write RMW");
2061 # endif
2062     } else
2063       writeOperands (cpup);
2064 #else
2065     writeOperands (cpup);
2066 #endif
2067   }
2068 
2069   else if (flags & PREPARE_CA) {
2070     // 'EPP ITS; TRA' confuses the APU by leaving last_cycle
2071     // at INDIRECT_WORD_FETCH; defoobarize the APU:
2072     fauxDoAppendCycle (cpup, OPERAND_READ);
2073     cpu.TPR.TRR = cpu.PPR.PRR;
2074     cpu.TPR.TSR = cpu.PPR.PSR;
2075     cpu.TPR.TBR = 0;
2076   }
2077 
2078 ///
2079 /// executeInstruction: RPT/RPD/RPL processing
2080 ///
2081 
2082   // The semantics of these are that even is the first instruction of
2083   // and RPD, and odd the second.
2084 
2085   bool icOdd = !! (cpu.PPR.IC & 1);
2086   bool icEven = ! icOdd;
2087 
2088   // Here, repeat_first means that the instruction just executed was the
2089   // RPT or RPD; but when the even instruction of a RPD is executed,
2090   // repeat_first is still set, since repeat_first cannot be cleared
2091   // until the odd instruction gets its first execution. Put some
2092   // ugly logic in to detect that condition.
2093 
2094   bool rf = cpu.cu.repeat_first;
2095   if (rf && cpu.cu.rd && icEven)
2096     rf = false;
2097 
2098   if (UNLIKELY ((! rf) && (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl))) {
2099     CPT (cpt2L, 7); // Post execution RPx
2100     // If we get here, the instruction just executed was a
2101     // RPT, RPD or RPL target instruction, and not the RPT or RPD
2102     // instruction itself
2103 
2104     if (cpu.cu.rpt || cpu.cu.rd) {
2105       // Add delta to index register.
2106 
2107       bool rptA = !! (cpu.rX[0] & 01000);
2108       bool rptB = !! (cpu.rX[0] & 00400);
2109 
2110       sim_debug (DBG_TRACEEXT, & cpu_dev,
2111                  "RPT/RPD delta first %d rf %d rpt %d rd %d " "e/o %d X0 %06o a %d b %d\n",
2112                  cpu.cu.repeat_first, rf, cpu.cu.rpt, cpu.cu.rd, icOdd, cpu.rX[0], rptA, rptB);
2113 
2114       if (cpu.cu.rpt) { // rpt
2115         CPT (cpt2L, 8); // RPT delta
2116         uint Xn = (uint) getbits36_3 (cpu.cu.IWB, 36 - 3);
2117         cpu.TPR.CA = (cpu.rX[Xn] + cpu.cu.delta) & AMASK;
2118         cpu.rX[Xn] = cpu.TPR.CA;
2119 #if defined(TESTING)
2120         HDBGRegXW (Xn, "rpt delta");
2121 #endif
2122         sim_debug (DBG_TRACEEXT, & cpu_dev, "RPT/RPD delta; X%d now %06o\n", Xn, cpu.rX[Xn]);
2123       }
2124 
2125       // a:RJ78/rpd6
2126       // We know that the X register is not to be incremented until
2127       // after both instructions have executed, so the following
2128       // if uses icOdd instead of the more sensical icEven.
2129       if (cpu.cu.rd && icOdd && rptA) { // rpd, even instruction
2130         CPT (cpt2L, 9); // RD even
2131         // a:RJ78/rpd7
2132         uint Xn = (uint) getbits36_3 (cpu.cu.IWB, 36 - 3);
2133         cpu.TPR.CA = (cpu.rX[Xn] + cpu.cu.delta) & AMASK;
2134         cpu.rX[Xn] = cpu.TPR.CA;
2135 #if defined(TESTING)
2136         HDBGRegXW (Xn, "rpd delta even");
2137 #endif
2138         sim_debug (DBG_TRACEEXT, & cpu_dev, "RPT/RPD delta; X%d now %06o\n", Xn, cpu.rX[Xn]);
2139       }
2140 
2141       if (cpu.cu.rd && icOdd && rptB) { // rpdb, odd instruction
2142         CPT (cpt2L, 10); // RD odd
2143         // a:RJ78/rpd8
2144         uint Xn = (uint) getbits36_3 (cpu.cu.IRODD, 36 - 3);
2145         cpu.TPR.CA = (cpu.rX[Xn] + cpu.cu.delta) & AMASK;
2146         cpu.rX[Xn] = cpu.TPR.CA;
2147 #if defined(TESTING)
2148         HDBGRegXW (Xn, "rpd delta odd");
2149 #endif
2150         sim_debug (DBG_TRACEEXT, & cpu_dev, "RPT/RPD delta; X%d now %06o\n", Xn, cpu.rX[Xn]);
2151       }
2152     } // rpt || rd
2153 
2154     // Check for termination conditions.
2155 
2156 ///////
2157 //
2158 // ISOLTS test 769 claims in test-02a that 'rpt;div' with a divide
2159 // fault should delay the divide fault until after the termination
2160 // check (it checks that the tally should be decremented) and in test-02b
2161 // that 'rpl;div' with a divide fault should not due the termination
2162 // check (the tally should not be decremented).
2163 //
2164 // This implies that rpt and rpl are handled differently; as a test
2165 // trying:
2166 
2167     bool flt;
2168     if (cpu.tweaks.l68_mode)
2169       flt = (cpu.cu.rl || cpu.cu.rpt || cpu.cu.rd) && cpu.dlyFlt; // L68
2170     else
2171       flt = cpu.cu.rl && cpu.dlyFlt;
2172     if (flt) {
2173       CPT (cpt2L, 14); // Delayed fault
2174       doFault (cpu.dlyFltNum, cpu.dlySubFltNum, cpu.dlyCtx);
2175     }
2176 
2177 // Sadly, it fixes ISOLTS 769 test 02a and 02b.
2178 //
2179 ///////
2180 
2181     if (cpu.cu.rpt || (cpu.cu.rd && icOdd) || cpu.cu.rl) {
2182       CPT (cpt2L, 12); // RPx termination check
2183       bool exit = false;
2184       // The repetition cycle consists of the following steps:
2185       //  a. Execute the repeated instruction
2186       //  b. C(X0)0,7 - 1 -> C(X0)0,7
2187       // a:AL39/rpd9
2188       uint x = (uint) getbits18 (cpu.rX[0], 0, 8);
2189       //x -= 1;
2190       // ubsan
2191       x = (uint) (((int) x) - 1);
2192       x &= MASK8;
2193       putbits18 (& cpu.rX[0], 0, 8, x);
2194 #if defined(TESTING)
2195       HDBGRegXW (0, "rpt term");
2196 #endif
2197 
2198       // a:AL39/rpd10
2199       //  c. If C(X0)0,7 = 0, then set the tally runout indicator ON
2200       //     and terminate
2201 
2202       sim_debug (DBG_TRACEEXT, & cpu_dev, "tally %d\n", x);
2203       if (x == 0) {
2204         sim_debug (DBG_TRACEEXT, & cpu_dev, "tally runout\n");
2205         SET_I_TALLY;
2206         exit = true;
2207       } else {
2208         sim_debug (DBG_TRACEEXT, & cpu_dev, "not tally runout\n");
2209         CLR_I_TALLY;
2210       }
2211 
2212       //  d. If a terminate condition has been met, then set
2213       //     the tally runout indicator OFF and terminate
2214 
2215       if (TST_I_ZERO && (cpu.rX[0] & 0100)) {
2216         sim_debug (DBG_TRACEEXT, & cpu_dev, "is zero terminate\n");
2217         CLR_I_TALLY;
2218         exit = true;
2219       }
2220       if (!TST_I_ZERO && (cpu.rX[0] & 040)) {
2221         sim_debug (DBG_TRACEEXT, & cpu_dev, "is not zero terminate\n");
2222         CLR_I_TALLY;
2223         exit = true;
2224       }
2225       if (TST_I_NEG && (cpu.rX[0] & 020)) {
2226         sim_debug (DBG_TRACEEXT, & cpu_dev, "is neg terminate\n");
2227         CLR_I_TALLY;
2228         exit = true;
2229       }
2230       if (!TST_I_NEG && (cpu.rX[0] & 010)) {
2231         sim_debug (DBG_TRACEEXT, & cpu_dev, "is not neg terminate\n");
2232         CLR_I_TALLY;
2233         exit = true;
2234       }
2235       if (TST_I_CARRY && (cpu.rX[0] & 04)) {
2236         sim_debug (DBG_TRACEEXT, & cpu_dev, "is carry terminate\n");
2237         CLR_I_TALLY;
2238         exit = true;
2239       }
2240       if (!TST_I_CARRY && (cpu.rX[0] & 02)) {
2241         sim_debug (DBG_TRACEEXT, & cpu_dev, "is not carry terminate\n");
2242         CLR_I_TALLY;
2243         exit = true;
2244       }
2245       if (TST_I_OFLOW && (cpu.rX[0] & 01)) {
2246         sim_debug (DBG_TRACEEXT, & cpu_dev, "is overflow terminate\n");
2247 // ISOLTS test ps805 says that on overflow the tally should be set.
2248         //CLR_I_TALLY;
2249         SET_I_TALLY;
2250         exit = true;
2251       }
2252 
2253       if (exit) {
2254         CPT (cpt2L, 13); // RPx terminated
2255         cpu.cu.rpt = false;
2256         cpu.cu.rd = false;
2257         cpu.cu.rl = false;
2258       } else {
2259         sim_debug (DBG_TRACEEXT, & cpu_dev, "not terminate\n");
2260       }
2261     } // if (cpu.cu.rpt || cpu.cu.rd & (cpu.PPR.IC & 1))
2262 
2263     if (cpu.cu.rl) {
2264       CPT (cpt2L, 11); // RL
2265       if (cpu.lnk == 0) {
2266         CPT (cpt2L, 13); // RPx terminated
2267         cpu.cu.rpt = false;
2268         cpu.cu.rd = false;
2269         cpu.cu.rl = false;
2270         SET_I_TALLY;
2271       } else {
2272         // C(Xn) -> y
2273         uint Xn = (uint) getbits36_3 (cpu.cu.IWB, 36 - 3);
2274         //word18 lnk = GETHI36 (cpu.CY);
2275         //cpu.CY &= MASK18;
2276         cpu.rX[Xn] = cpu.lnk;
2277 #if defined(TESTING)
2278         HDBGRegXW (Xn, "rl");
2279 #endif
2280       }
2281     } // rl
2282   } // (! rf) && (cpu.cu.rpt || cpu.cu.rd)
2283 
2284   if (UNLIKELY (cpu.dlyFlt)) {
2285     CPT (cpt2L, 14); // Delayed fault
2286     doFault (cpu.dlyFltNum, cpu.dlySubFltNum, cpu.dlyCtx);
2287   }
2288 
2289 ///
2290 /// executeInstruction: scp hooks
2291 ///
2292 
2293   cpu.instrCnt ++;
2294 
2295   if_sim_debug (DBG_REGDUMP, & cpu_dev) {
2296     char buf [256];
2297     sim_debug (DBG_REGDUMPAQI, &cpu_dev, "A=%012"PRIo64" Q=%012"PRIo64" IR:%s\n",
2298                cpu.rA, cpu.rQ, dump_flags (buf, cpu.cu.IR));
2299 #if !defined(__MINGW64__) || !defined(__MINGW32__)
2300     sim_debug (DBG_REGDUMPFLT, &cpu_dev, "E=%03o A=%012"PRIo64" Q=%012"PRIo64" %.10Lg\n",
2301                cpu.rE, cpu.rA, cpu.rQ, EAQToIEEElongdouble (cpup));
2302 #else
2303     sim_debug (DBG_REGDUMPFLT, &cpu_dev, "E=%03o A=%012"PRIo64" Q=%012"PRIo64" %.10g\n",
2304                cpu.rE, cpu.rA, cpu.rQ, EAQToIEEEdouble (cpup));
2305 #endif
2306     sim_debug (DBG_REGDUMPIDX, &cpu_dev, "X[0]=%06o X[1]=%06o X[2]=%06o X[3]=%06o\n",
2307                cpu.rX[0], cpu.rX[1], cpu.rX[2], cpu.rX[3]);
2308     sim_debug (DBG_REGDUMPIDX, &cpu_dev, "X[4]=%06o X[5]=%06o X[6]=%06o X[7]=%06o\n",
2309                cpu.rX[4], cpu.rX[5], cpu.rX[6], cpu.rX[7]);
2310     for (int n = 0 ; n < 8 ; n++) {
2311       sim_debug (DBG_REGDUMPPR, &cpu_dev, "PR%d/%s: SNR=%05o RNR=%o WORDNO=%06o BITNO:%02o ARCHAR:%o ARBITNO:%02o\n",
2312                  n, PRalias[n], cpu.PR[n].SNR, cpu.PR[n].RNR, cpu.PR[n].WORDNO,
2313                  GET_PR_BITNO (n), GET_AR_CHAR (n), GET_AR_BITNO (n));
2314     }
2315     sim_debug (DBG_REGDUMPPPR, &cpu_dev, "PRR:%o PSR:%05o P:%o IC:%06o\n",
2316                cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
2317     sim_debug (DBG_REGDUMPDSBR, &cpu_dev, "ADDR:%08o BND:%05o U:%o STACK:%04o\n",
2318                cpu.DSBR.ADDR, cpu.DSBR.BND, cpu.DSBR.U, cpu.DSBR.STACK);
2319   }
2320 
2321 ///
2322 /// executeInstruction: done. (Whew!)
2323 ///
2324 
2325   return ret;
2326 }
2327 
2328 //static t_stat DoBasicInstruction (void);
2329 //static t_stat DoEISInstruction (void);
2330 
2331 static inline void overflow (cpu_state_t * cpup, bool ovf, bool dly, const char * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
2332   {
2333     CPT (cpt2L, 15); // overflow check
2334     // If an overflow occurred and the repeat instruction is not inhibiting
2335     // overflow checking.
2336     if (ovf && chkOVF (cpup))
2337       {
2338         SET_I_OFLOW;
2339         // If overflows are not masked
2340         if (tstOVFfault (cpup))
2341           {
2342             CPT (cpt2L, 16); // overflow
2343             // ISOLTS test ps768: Overflows set TRO.
2344             if (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)
2345               {
2346                 SET_I_TALLY;
2347               }
2348             if (dly)
2349               dlyDoFault (FAULT_OFL, fst_zero, msg);
2350             else
2351               doFault (FAULT_OFL, fst_zero, msg);
2352           }
2353       }
2354   }
2355 
2356 // Return values
2357 //  CONT_TRA
2358 //  STOP_UNIMP
2359 //  STOP_ILLOP
2360 //  emCall()
2361 //     STOP_HALT
2362 //  scu_sscr()
2363 //     STOP_BUG
2364 //     STOP_WARN
2365 //  scu_rmcm()
2366 //     STOP_BUG
2367 //  scu_smcm()
2368 //  STOP_DIS
2369 //  simh_hooks()
2370 //    hard to document what this can return....
2371 //  0
2372 //
2373 
2374 // CANFAULT
2375 static t_stat doInstruction (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
2376 {
2377     DCDstruct * i = & cpu.currentInstruction;
2378     // AL39 says it is always cleared, but that makes no sense (what good
2379     // is an indicator bit if it is always 0 when you check it?). Clear it if
2380     // an multiword EIS is at bat.
2381     // NB: Never clearing it renders Multics unbootable.
2382     if (i->info->ndes > 0)
2383       CLR_I_MIF;
2384 
2385     L68_ (
2386       cpu.ou.eac = 0;
2387       cpu.ou.RB1_FULL = 0;
2388       cpu.ou.RP_FULL = 0;
2389       cpu.ou.RS_FULL = 0;
2390       cpu.ou.STR_OP = 0;
2391       cpu.ou.cycle = 0;
2392     )
2393     PNL (cpu.ou.RS = (word9) i->opcode);
2394     PNL (L68_ (DU_CYCLE_FDUD;)) // set DU idle
2395     cpu.skip_cu_hist = false;
2396     memcpy (& cpu.MR_cache, & cpu.MR, sizeof (cpu.MR_cache));
2397 
2398 // This mapping keeps nonEIS/EIS ordering, making various tables cleaner
2399 #define x0(n) (n)
2400 #define x1(n) (n|01000)
2401 
2402     //t_stat ret =  i->opcodeX ? DoEISInstruction () : DoBasicInstruction ();
2403     uint32 opcode10 = i->opcode10;
2404 
2405 #if defined(PANEL68)
2406     if (insGrp [opcode10])
2407       {
2408         word8 grp = insGrp [opcode10] - 1;
2409         uint row  = grp / 36;
2410         uint col  = grp % 36;
2411         CPT (cpt3U + row, col); // 3U 0-35, 3L 0-17
2412       }
2413 #endif
2414     bool is_ou = false;
2415     bool is_du = false;
2416     if (cpu.tweaks.l68_mode) { // L68
2417       if (opcodes10[opcode10].reg_use & is_OU) {
2418         is_ou = true;
2419 #if defined(PANEL68)
2420     // XXX Punt on RP FULL, RS FULL
2421         cpu.ou.RB1_FULL  = cpu.ou.RP_FULL = cpu.ou.RS_FULL = 1;
2422         cpu.ou.cycle    |= ou_GIN;
2423         cpu.ou.opsz      = (opcodes10[i->opcode10].reg_use >> 12) & 037;
2424         word10 reguse    = (opcodes10[i->opcode10].reg_use) & MASK10;
2425         cpu.ou.reguse    = reguse;
2426         if (reguse & ru_A)  CPT (cpt5U, 4);
2427         if (reguse & ru_Q)  CPT (cpt5U, 5);
2428         if (reguse & ru_X0) CPT (cpt5U, 6);
2429         if (reguse & ru_X1) CPT (cpt5U, 7);
2430         if (reguse & ru_X2) CPT (cpt5U, 8);
2431         if (reguse & ru_X3) CPT (cpt5U, 9);
2432         if (reguse & ru_X4) CPT (cpt5U, 10);
2433         if (reguse & ru_X5) CPT (cpt5U, 11);
2434         if (reguse & ru_X6) CPT (cpt5U, 12);
2435         if (reguse & ru_X7) CPT (cpt5U, 13);
2436 #endif // PANEL68
2437       }
2438       if (opcodes10[opcode10].reg_use & is_DU) {
2439         is_du = true;
2440         PNL (DU_CYCLE_nDUD;) // set not idle
2441       }
2442     }
2443 
2444     switch (opcode10)
2445       {
2446 // Operations sorted by frequency of use; should help with caching issues
2447 
2448 // Operations counts from booting and build a boot tape from source:
2449 //          1605873148: eppn
2450 //           845109778: sprin
2451 //           702257337: lda
2452 //           637613648: tra
2453 //           555520875: ldq
2454 //           462569862: tze
2455 //           322979813: tnz
2456 //           288200618: stq
2457 //           260400300: cmpq
2458 //           192454329: anaq
2459 //           187283749: sta
2460 //           170691055: lprpn
2461 //           167568868: eaxn
2462 //           166842812: tsxn
2463 //           161542573: stz
2464 //           155129792: epbpn
2465 //           153639462: cmpa
2466 //           144804232: aos
2467 //           133559646: cana
2468 //           127230192: ldaq
2469 //           119988496: tpnz
2470 //           113295654: lxln
2471 //           109645303: staq
2472 //           109417021: tspn
2473 //           108352453: als
2474 //            96267840: rtcd
2475 //            93570029: tmi
2476 //            93161815: stxn
2477 //            90485871: ldi
2478 //            87421892: eraq
2479 //            76632891: ora
2480 //            75372023: adq
2481 //            75036448: tmoz
2482 //            64921645: spbpn
2483 //            63595794: ana
2484 //            62621406: fld
2485 //            57281513: epaq
2486 //            56066122: qls
2487 //            55861962: sti
2488 //            55186331: mlr
2489 //            54388393: call6
2490 //            50000721: lrl
2491 //            49736026: sbq
2492 //            49552594: tpl
2493 //            46097756: cmpb
2494 //            44484993: szn
2495 //            41295856: arl
2496 //            40019677: lrs
2497 //            39386119: sprpn
2498 //            36130580: ldxn
2499 //            32168708: ersa
2500 //            31817270: cmpxn
2501 //            31280696: a9bd
2502 //            29383886: era
2503 //            29282465: lls
2504 //            28714658: mpy
2505 //            28508378: sba
2506 //            24067324: anq
2507 //            23963178: asq
2508 //            23953122: nop
2509 //            23643534: orsa
2510 //            23083282: csl
2511 //            20970795: sbxn
2512 //            20109045: tct
2513 //            18504719: stba
2514 //            18297461: eaq
2515 //            17130040: eaa
2516 //            16035441: cmpc
2517 //            15762874: sxln
2518 //            15109836: lca
2519 //            15013924: adxn
2520 //            14159104: lcq
2521 //            14049597: div
2522 //            14043543: cmpaq
2523 //            13528591: ada
2524 //            12778888: ansa
2525 //            12534711: trc
2526 //            11710149: sbaq
2527 //            11584853: neg
2528 //            11456885: ttn
2529 //            11356918: canq
2530 //            10797383: rccl
2531 //            10743245: asa
2532 //            10100949: ttf
2533 //             9691628: orq
2534 //             9332512: adwp0-3
2535 //             9251904: anxn
2536 //             8076030: ldac
2537 //             8061536: scd
2538 //             7779639: adaq
2539 //             7586713: xec
2540 //             7506406: qrl
2541 //             7442522: adl
2542 //             6535658: stca
2543 //             6359531: adlxn
2544 //             6255134: sbla
2545 //             5936484: stacq
2546 //             5673345: eawp2
2547 //             4671545: tnc
2548 //             4230412: scm
2549 //             4040255: sarn
2550 //             4006015: oraq
2551 //             3918690: adlq
2552 //             3912600: stbq
2553 //             3449053: lcxn
2554 //             3368670: adla
2555 //             3290057: qrs
2556 //             3252438: ars
2557 //             3143543: qlr
2558 //             3098158: stac
2559 //             2838451: mvne
2560 //             2739787: lde
2561 //             2680484: btd
2562 //             2573170: erq
2563 //             2279433: fno
2564 //             2273692: smcm
2565 //             2240713: ersq
2566 //             2173455: sreg
2567 //             2173196: lreg
2568 //             2112784: mrl
2569 //             2030237: mvt
2570 //             2010819: stc2
2571 //             2008675: fmp
2572 //             1981148: llr
2573 //             1915081: mvn
2574 //             1846728: sblxn
2575 //             1820604: fcmp
2576 //             1765253: lcpr
2577 //             1447485: stc1
2578 //             1373184: ansxn
2579 //             1337744: negl
2580 //             1264062: rscr
2581 //             1201563: adwp4-7
2582 //             1198321: rmcm
2583 //             1182814: sznc
2584 //             1171307: sblq
2585 //             1140227: spri
2586 //             1139968: lpri
2587 //             1133946: dvf
2588 //             1059600: scpr
2589 //              958321: stcq
2590 //              837695: tctr
2591 //              820615: s9bd
2592 //              812523: rsw
2593 //              769275: fad
2594 //              729737: orsq
2595 //              651623: scu
2596 //              651612: rcu
2597 //              606518: abd
2598 //              603591: eawp1
2599 //              555935: orsxn
2600 //              525680: scmr
2601 //              467605: spl
2602 //              467405: lpl
2603 //              463927: lra
2604 //              416700: awd
2605 //              384090: dtb
2606 //              383544: cmk
2607 //              382254: fst
2608 //              378820: ssa
2609 //              370308: sra
2610 //              326432: alr
2611 //              321319: ldt
2612 //              319911: ldbr
2613 //              319908: sbar
2614 //              319907: lbar
2615 //              310379: cams
2616 //              303041: eawp7
2617 //              299122: xed
2618 //              294724: easp2
2619 //              270712: sztl
2620 //              252001: dfst
2621 //              241844: ste
2622 //              226970: absa
2623 //              218891: cioc
2624 //              184535: dfld
2625 //              182347: camp
2626 //              174567: ansq
2627 //              169317: rpt
2628 //              124972: erx2
2629 //              121933: fneg
2630 //              114697: cnaaq
2631 //              111728: rpd
2632 //              106892: dis
2633 //               96801: tov
2634 //               92283: fsb
2635 //               86209: erx4
2636 //               80564: eawp3
2637 //               76911: canaq
2638 //               65706: ufa
2639 //               65700: dfcmp
2640 //               64530: fdv
2641 //               48215: ldqc
2642 //               45994: dfad
2643 //               37790: awca
2644 //               27218: asxn
2645 //               23203: eawp5
2646 //               16947: gtb
2647 //               11431: ersxn
2648 //                9527: erx3
2649 //                8888: ssdr
2650 //                8888: ssdp
2651 //                8888: sptr
2652 //                8888: sptp
2653 //                8170: ssq
2654 //                7116: mp3d
2655 //                6969: cmg
2656 //                6878: dv3d
2657 //                5615: eawp6
2658 //                4859: easp1
2659 //                4726: easp3
2660 //                3157: ad2d
2661 //                2807: eawp4
2662 //                2807: easp4
2663 //                2411: cwl
2664 //                1912: teu
2665 //                1912: teo
2666 //                1798: cmpn
2667 //                1625: easp6
2668 //                 931: adlaq
2669 //                 659: erx1
2670 //                 500: ???
2671 //                 388: csr
2672 //                 215: sb3d
2673 //                 176: dfdv
2674 //                  93: stcd
2675 //                  92: mp2d
2676 //                  41: sscr
2677 //                  26: dfmp
2678 //                  14: ad3d
2679 //                  12: mve
2680 //                  11: dfsb
2681 //                   5: sdbr
2682 //                   4: trtf
2683 //                   4: orxn
2684 //                   3: sb2d
2685 //                   2: scdr
2686 //                   1: stt
2687 //                   1: ret
2688 //                   1: drl
2689 
2690         case x0 (0350):  // epp0
2691         case x1 (0351):  // epp1
2692         case x0 (0352):  // epp2
2693         case x1 (0353):  // epp3
2694         case x0 (0370):  // epp4
2695         case x1 (0371):  // epp5
2696         case x0 (0372):  // epp6
2697         case x1 (0373):  // epp7
2698           // For n = 0, 1, ..., or 7 as determined by operation code
2699           //   C(TPR.TRR) -> C(PRn.RNR)
2700           //   C(TPR.TSR) -> C(PRn.SNR)
2701           //   C(TPR.CA) -> C(PRn.WORDNO)
2702           //   C(TPR.TBR) -> C(PRn.BITNO)
2703           {
2704             // epp0 0350  101 000
2705             // epp1 1351  101 001
2706             // epp2 0352  101 010
2707             // epp3 1353  101 011
2708             // epp4 0370  111 000
2709             // epp5 1371  111 001
2710             // epp6 0372  111 010
2711             // epp7 1373  111 011
2712             //n = ((opcode10 & 020) ? 4 : 0) + (opcode10 & 03);
2713             uint n = ((opcode10 & 020) >> 2) | (opcode10 & 03);
2714             CPTUR (cptUsePRn + n);
2715             cpu.PR[n].RNR    = cpu.TPR.TRR;
2716             cpu.PR[n].SNR    = cpu.TPR.TSR;
2717             cpu.PR[n].WORDNO = cpu.TPR.CA;
2718             SET_PR_BITNO (n, cpu.TPR.TBR);
2719 #if defined(TESTING)
2720             HDBGRegPRW (n, "epp");
2721 #endif
2722           }
2723           break;
2724 
2725         case x0 (0250):  // spri0
2726         case x1 (0251):  // spri1
2727         case x0 (0252):  // spri2
2728         case x1 (0253):  // spri3
2729         case x0 (0650):  // spri4
2730         case x1 (0651):  // spri5
2731         case x0 (0652):  // spri6
2732         case x1 (0653):  // spri7
2733 
2734           // For n = 0, 1, ..., or 7 as determined by operation code
2735           //  000 -> C(Y-pair)0,2
2736           //  C(PRn.SNR) -> C(Y-pair)3,17
2737           //  C(PRn.RNR) -> C(Y-pair)18,20
2738           //  00...0 -> C(Y-pair)21,29
2739           //  (43)8 -> C(Y-pair)30,35
2740           //  C(PRn.WORDNO) -> C(Y-pair)36,53
2741           //  000 -> C(Y-pair)54,56
2742           //  C(PRn.BITNO) -> C(Y-pair)57,62
2743           //  00...0 -> C(Y-pair)63,71
2744           {
2745             // spri0 0250 0 010 101 000
2746             // spri1 1251 1 010 101 001
2747             // spri2 0252 0 010 101 010
2748             // spri3 1253 1 010 101 011
2749             // spri4 0650 0 110 101 000
2750             // spri5 1651 1 110 101 001
2751             // spri6 0652 0 110 101 010
2752             // spri7 1653 1 110 101 011
2753             //uint n = ((opcode10 & 0400) ? 4 : 0) + (opcode10 & 03);
2754             uint n = ((opcode10 & 0400) >> 6) | (opcode10 & 03);
2755             CPTUR (cptUsePRn + n);
2756 #if defined(TESTING)
2757             HDBGRegPRR (n, "spri");
2758 #endif
2759             cpu.Ypair[0]  = 043;
2760             cpu.Ypair[0] |= ((word36) cpu.PR[n].SNR) << 18;
2761             cpu.Ypair[0] |= ((word36) cpu.PR[n].RNR) << 15;
2762 
2763             cpu.Ypair[1]  = (word36) cpu.PR[n].WORDNO << 18;
2764             cpu.Ypair[1] |= (word36) GET_PR_BITNO (n) << 9;
2765           }
2766           break;
2767 
2768         case x0 (0235):  // lda
2769           cpu.rA = cpu.CY;
2770 #if defined(TESTING)
2771           HDBGRegAW ("lda");
2772 #endif
2773           SC_I_ZERO (cpu.rA == 0);
2774           SC_I_NEG (cpu.rA & SIGN36);
2775           break;
2776 
2777         case x0 (0710):  // tra
2778           // C(TPR.CA) -> C(PPR.IC)
2779           // C(TPR.TSR) -> C(PPR.PSR)
2780           do_caf (cpup);
2781           read_tra_op (cpup);
2782           return CONT_TRA;
2783 
2784         case x0 (0236):  // ldq
2785           cpu.rQ = cpu.CY;
2786 #if defined(TESTING)
2787           HDBGRegQW ("ldq");
2788 #endif
2789           SC_I_ZERO (cpu.rQ == 0);
2790           SC_I_NEG (cpu.rQ & SIGN36);
2791           break;
2792 
2793         case x0 (0600):  // tze
2794           // If zero indicator ON then
2795           //   C(TPR.CA) -> C(PPR.IC)
2796           //   C(TPR.TSR) -> C(PPR.PSR)
2797           // otherwise, no change to C(PPR)
2798           if (TST_I_ZERO)
2799             {
2800               do_caf (cpup);
2801               read_tra_op (cpup);
2802               return CONT_TRA;
2803             }
2804           break;
2805 
2806         case x0 (0601):  // tnz
2807           // If zero indicator OFF then
2808           //     C(TPR.CA) -> C(PPR.IC)
2809           //     C(TPR.TSR) -> C(PPR.PSR)
2810           if (!TST_I_ZERO)
2811             {
2812               do_caf (cpup);
2813               read_tra_op (cpup);
2814               return CONT_TRA;
2815             }
2816           break;
2817 
2818         case x0 (0756): // stq
2819           cpu.CY = cpu.rQ;
2820 #if defined(TESTING)
2821           HDBGRegQR ("stq");
2822 #endif
2823           break;
2824 
2825         case x0 (0116):  // cmpq
2826           // C(Q) :: C(Y)
2827           cmp36 (cpup, cpu.rQ, cpu.CY, &cpu.cu.IR);
2828 #if defined(TESTING)
2829           HDBGRegQR ("cmpq");
2830 #endif
2831           break;
2832 
2833         case x0 (0377):  //< anaq
2834           // C(AQ)i & C(Y-pair)i -> C(AQ)i for i = (0, 1, ..., 71)
2835           {
2836               word72 tmp72 = YPAIRTO72 (cpu.Ypair);
2837               word72 trAQ = convert_to_word72 (cpu.rA, cpu.rQ);
2838 #if defined(TESTING)
2839               HDBGRegAR ("anaq");
2840               HDBGRegQR ("anaq");
2841 #endif
2842 #if defined(NEED_128)
2843               trAQ = and_128 (trAQ, tmp72);
2844               trAQ = and_128 (trAQ, MASK72);
2845 
2846               SC_I_ZERO (iszero_128 (trAQ));
2847               SC_I_NEG (isnonzero_128 (and_128 (trAQ, SIGN72)));
2848 #else
2849               trAQ = trAQ & tmp72;
2850               trAQ &= MASK72;
2851 
2852               SC_I_ZERO (trAQ == 0);
2853               SC_I_NEG (trAQ & SIGN72);
2854 #endif
2855               convert_to_word36 (trAQ, &cpu.rA, &cpu.rQ);
2856 #if defined(TESTING)
2857               HDBGRegAW ("anaq");
2858               HDBGRegQW ("anaq");
2859 #endif
2860           }
2861           break;
2862 
2863         case x0 (0755):  // sta
2864           cpu.CY = cpu.rA;
2865 #if defined(TESTING)
2866           HDBGRegAR ("sta");
2867 #endif
2868           break;
2869 
2870                          // lprpn
2871         case x0 (0760):  // lprp0
2872         case x0 (0761):  // lprp1
2873         case x0 (0762):  // lprp2
2874         case x0 (0763):  // lprp3
2875         case x0 (0764):  // lprp4
2876         case x0 (0765):  // lprp5
2877         case x0 (0766):  // lprp6
2878         case x0 (0767):  // lprp7
2879           // For n = 0, 1, ..., or 7 as determined by operation code
2880           //  C(TPR.TRR) -> C(PRn.RNR)
2881           //  If C(Y)0,1 != 11, then
2882           //    C(Y)0,5 -> C(PRn.BITNO);
2883           //  otherwise,
2884           //    generate command fault
2885           // If C(Y)6,17 = 11...1, then 111 -> C(PRn.SNR)0,2
2886           //  otherwise,
2887           // 000 -> C(PRn.SNR)0,2
2888           // C(Y)6,17 -> C(PRn.SNR)3,14
2889           // C(Y)18,35 -> C(PRn.WORDNO)
2890           {
2891               uint32 n = opcode10 & 07;  // get n
2892               CPTUR (cptUsePRn + n);
2893               cpu.PR[n].RNR = cpu.TPR.TRR;
2894 
2895 // [CAC] sprpn says: If C(PRn.SNR) 0,2 are nonzero, and C(PRn.SNR) != 11...1,
2896 // then a store fault (illegal pointer) will occur and C(Y) will not be changed.
2897 // I interpret this has meaning that only the high bits should be set here
2898 
2899               if (((cpu.CY >> 34) & 3) != 3)
2900                 {
2901                   word6 bitno = (cpu.CY >> 30) & 077;
2902                   SET_PR_BITNO (n, bitno);
2903                 }
2904               else
2905                 {
2906 // fim.alm
2907 // command_fault:
2908 //           eax7      com       assume normal command fault
2909 //           ldq       bp|mc.scu.port_stat_word check illegal action
2910 //           canq      scu.ial_mask,dl
2911 //           tnz       fixindex            nonzero, treat as normal case
2912 //           ldq       bp|scu.even_inst_word check for LPRPxx instruction
2913 //           anq       =o770400,dl
2914 //           cmpq      lprp_insts,dl
2915 //           tnz       fixindex            isn't LPRPxx, treat as normal
2916 
2917 // ial_mask is checking SCU word 1, field IA: 0 means "no illegal action"
2918 
2919                     // Therefore the subfault well no illegal action, and
2920                     // Multics will peek it the instruction to deduce that it
2921                     // is a lprpn fault.
2922                   doFault (FAULT_CMD, fst_cmd_lprpn, "lprpn");
2923                 }
2924 // The SPRPn instruction stores only the low 12 bits of the 15 bit SNR.
2925 // A special case is made for an SNR of all ones; it is stored as 12 1's.
2926 // The pcode in AL39 handles this awkwardly; I believe this is
2927 // the same, but in a more straightforward manner
2928 
2929              // Get the 12 bit operand SNR
2930              word12 oSNR = getbits36_12 (cpu.CY, 6);
2931              // Test for special case
2932              if (oSNR == 07777)
2933                cpu.PR[n].SNR = 077777;
2934              else
2935                cpu.PR[n].SNR = oSNR; // unsigned word will 0-extend.
2936               //C(Y)18,35 -> C(PRn.WORDNO)
2937               cpu.PR[n].WORDNO = GETLO (cpu.CY);
2938 
2939               sim_debug (DBG_APPENDING, & cpu_dev,
2940                          "lprp%d CY 0%012"PRIo64", PR[n].RNR 0%o, "
2941                          "PR[n].BITNO 0%o, PR[n].SNR 0%o, PR[n].WORDNO %o\n",
2942                          n, cpu.CY, cpu.PR[n].RNR, GET_PR_BITNO (n),
2943                          cpu.PR[n].SNR, cpu.PR[n].WORDNO);
2944 #if defined(TESTING)
2945               HDBGRegPRW (n, "lprp");
2946 #endif
2947           }
2948           break;
2949 
2950                          // eaxn
2951         case x0 (0620):  // eax0
2952         case x0 (0621):  // eax1
2953         case x0 (0622):  // eax2
2954         case x0 (0623):  // eax3
2955         case x0 (0624):  // eax4
2956         case x0 (0625):  // eax5
2957         case x0 (0626):  // eax6
2958         case x0 (0627):  // eax7
2959           {
2960             uint32 n = opcode10 & 07;  // get n
2961             cpu.rX[n] = cpu.TPR.CA;
2962 #if defined(TESTING)
2963             HDBGRegXW (n, "eaxn");
2964 #endif
2965 
2966             SC_I_ZERO (cpu.TPR.CA == 0);
2967             SC_I_NEG (cpu.TPR.CA & SIGN18);
2968 
2969           }
2970           break;
2971 
2972                          // tsxn
2973         case x0 (0700):  // tsx0
2974         case x0 (0701):  // tsx1
2975         case x0 (0702):  // tsx2
2976         case x0 (0703):  // tsx3
2977         case x0 (0704):  // tsx4
2978         case x0 (0705):  // tsx5
2979         case x0 (0706):  // tsx6
2980         case x0 (0707):  // tsx7
2981           // For n = 0, 1, ..., or 7 as determined by operation code
2982           //   C(PPR.IC) + 1 -> C(Xn)
2983           // C(TPR.CA) -> C(PPR.IC)
2984           // C(TPR.TSR) -> C(PPR.PSR)
2985           {
2986             // We can't set Xn yet as the CAF may refer to Xn
2987             word18 ret = (cpu.PPR.IC + 1) & MASK18;
2988             do_caf (cpup);
2989             read_tra_op (cpup);
2990             cpu.rX[opcode10 & 07] = ret;
2991 #if defined(TESTING)
2992             HDBGRegXW (opcode10 & 07, "tsxn");
2993 #endif
2994           }
2995           return CONT_TRA;
2996 
2997         case x0 (0450): // stz
2998           cpu.CY = 0;
2999           break;
3000 
3001                          // epbpn
3002         case x1 (0350):  // epbp0
3003         case x0 (0351):  // epbp1
3004         case x1 (0352):  // epbp2
3005         case x0 (0353):  // epbp3
3006         case x1 (0370):  // epbp4
3007         case x0 (0371):  // epbp5
3008         case x1 (0372):  // epbp6
3009         case x0 (0373):  // epbp7
3010           // For n = 0, 1, ..., or 7 as determined by operation code
3011           //  C(TPR.TRR) -> C(PRn.RNR)
3012           //  C(TPR.TSR) -> C(PRn.SNR)
3013           //  00...0 -> C(PRn.WORDNO)
3014           //  0000 -> C(PRn.BITNO)
3015           {
3016             // epbp0 1350 101 000
3017             // epbp1 0351 101 000
3018             // epbp2 1352 101 000
3019             // epbp3 0353 101 000
3020             // epbp4 1370 111 000
3021             // epbp4 0371 111 000
3022             // epbp6 1372 111 000
3023             // epbp7 0373 111 000
3024             //n = ((opcode10 & 020) ? 4 : 0) + (opcode10 & 03);
3025             uint n = ((opcode10 & 020) >> 2) | (opcode10 & 03);
3026             CPTUR (cptUsePRn + n);
3027             cpu.PR[n].RNR    = cpu.TPR.TRR;
3028             cpu.PR[n].SNR    = cpu.TPR.TSR;
3029             cpu.PR[n].WORDNO = 0;
3030             SET_PR_BITNO (n, 0);
3031 #if defined(TESTING)
3032             HDBGRegPRW (n, "epbp");
3033 #endif
3034           }
3035           break;
3036 
3037         case x0 (0115):  // cmpa
3038           // C(A) :: C(Y)
3039           cmp36 (cpup, cpu.rA, cpu.CY, &cpu.cu.IR);
3040 #if defined(TESTING)
3041           HDBGRegAR ("cmpa");
3042 #endif
3043           break;
3044 
3045         case x0 (0054):   // aos
3046           {
3047             // C(Y)+1->C(Y)
3048 
3049             L68_ (cpu.ou.cycle |= ou_GOS;)
3050             bool ovf;
3051             cpu.CY = Add36b (cpup, cpu.CY, 1, 0, I_ZNOC,
3052                                  & cpu.cu.IR, & ovf);
3053             overflow (cpup, ovf, true, "aos overflow fault");
3054           }
3055           break;
3056 
3057         case x0 (0315):  // cana
3058           // C(Z)i = C(A)i & C(Y)i for i = (0, 1, ..., 35)
3059           {
3060 #if defined(TESTING)
3061             HDBGRegAR ("cana");
3062 #endif
3063             word36 trZ = cpu.rA & cpu.CY;
3064             trZ &= MASK36;
3065 
3066             SC_I_ZERO (trZ == 0);
3067             SC_I_NEG (trZ & SIGN36);
3068           }
3069           break;
3070 
3071         case x0 (0237):  // ldaq
3072           cpu.rA = cpu.Ypair[0];
3073 #if defined(TESTING)
3074           HDBGRegAW ("ldaq");
3075 #endif
3076           cpu.rQ = cpu.Ypair[1];
3077 #if defined(TESTING)
3078           HDBGRegQW ("ldaq");
3079 #endif
3080           SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0)
3081           SC_I_NEG (cpu.rA & SIGN36);
3082           break;
3083 
3084         case x1 (0605):  // tpnz
3085             // If negative and zero indicators are OFF then
3086             //  C(TPR.CA) -> C(PPR.IC)
3087             //  C(TPR.TSR) -> C(PPR.PSR)
3088             if (! (cpu.cu.IR & I_NEG) && ! (cpu.cu.IR & I_ZERO))
3089             {
3090                 do_caf (cpup);
3091                 read_tra_op (cpup);
3092                 return CONT_TRA;
3093             }
3094             break;
3095 
3096                          // lxln
3097         case x0 (0720):  // lxl0
3098         case x0 (0721):  // lxl1
3099         case x0 (0722):  // lxl2
3100         case x0 (0723):  // lxl3
3101         case x0 (0724):  // lxl4
3102         case x0 (0725):  // lxl5
3103         case x0 (0726):  // lxl6
3104         case x0 (0727):  // lxl7
3105           {
3106             uint32 n = opcode10 & 07;  // get n
3107             cpu.rX[n] = GETLO (cpu.CY);
3108 #if defined(TESTING)
3109             HDBGRegXW (n, "lxln");
3110 #endif
3111             SC_I_ZERO (cpu.rX[n] == 0);
3112             SC_I_NEG (cpu.rX[n] & SIGN18);
3113           }
3114           break;
3115 
3116         case x0 (0757):  // staq
3117           cpu.Ypair[0] = cpu.rA;
3118           cpu.Ypair[1] = cpu.rQ;
3119           break;
3120 
3121                          // tspn
3122         case x0 (0270):  // tsp0
3123         case x0 (0271):  // tsp1
3124         case x0 (0272):  // tsp2
3125         case x0 (0273):  // tsp3
3126         case x0 (0670):  // tsp4
3127         case x0 (0671):  // tsp5
3128         case x0 (0672):  // tsp6
3129         case x0 (0673):  // tsp7
3130           // For n = 0, 1, ..., or 7 as determined by operation code
3131           //  C(PPR.PRR) -> C(PRn.RNR)
3132           //  C(PPR.PSR) -> C(PRn.SNR)
3133           //  C(PPR.IC) + 1 -> C(PRn.WORDNO)
3134           //  00...0 -> C(PRn.BITNO)
3135           //  C(TPR.CA) -> C(PPR.IC)
3136           //  C(TPR.TSR) -> C(PPR.PSR)
3137           {
3138 #if defined(PANEL68)
3139             uint32 n;
3140             if (opcode10 <= 0273)
3141               n = (opcode10 & 3);
3142             else
3143               n = (opcode10 & 3) + 4;
3144             CPTUR (cptUsePRn + n);
3145 #endif
3146 
3147             do_caf (cpup);
3148             // PR[n] is set in read_tra_op().
3149             read_tra_op (cpup);
3150           }
3151           return CONT_TRA;
3152 
3153         case x0 (0735):  // als
3154           {
3155 #if defined(TESTING)
3156             HDBGRegAR ("als");
3157 #endif
3158 #if BARREL_SHIFTER
3159             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
3160 
3161             // Capture the bits shifted through A0
3162             word36 capture;
3163             // If count is > 36, than all of the bits will rotate through A
3164             if (cnt < 36) {
3165               // +1 is A0 plus the bits that will get shifted into A0
3166               capture = cpu.rA & barrelLeftMaskTable[cnt + 1];
3167 
3168               // Do the shift
3169               cpu.rA <<= cnt;
3170               cpu.rA &= DMASK;    // keep to 36-bits
3171 
3172               // If the captured bits are all 0 or all 1, then
3173               // A0 will not have changed during the rotate
3174 
3175             } else {
3176               capture = cpu.rA;
3177               cpu.rA = 0;
3178             }
3179 
3180             if (capture == 0 || capture == (MASK36 & barrelLeftMaskTable[cnt + 1]))
3181               CLR_I_CARRY;
3182             else
3183               SET_I_CARRY;
3184 #else // !BARREL_SHIFTER
3185             word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
3186 
3187             word36 tmpSign = cpu.rA & SIGN36;
3188             CLR_I_CARRY;
3189 
3190             for (uint j = 0; j < tmp36; j ++)
3191               {
3192                 cpu.rA <<= 1;
3193                 if (tmpSign != (cpu.rA & SIGN36))
3194                   SET_I_CARRY;
3195               }
3196             cpu.rA &= DMASK;    // keep to 36-bits
3197 #endif // BARREL_SHIFTER
3198 #if defined(TESTING)
3199             HDBGRegAW ("als");
3200 #endif
3201 
3202             SC_I_ZERO (cpu.rA == 0);
3203             SC_I_NEG (cpu.rA & SIGN36);
3204           }
3205           break;
3206 
3207         case x0 (0610):  // rtcd
3208           // If an access violation fault occurs when fetching the SDW for
3209           // the Y-pair, the C(PPR.PSR) and C(PPR.PRR) are not altered.
3210 
3211           do_caf (cpup);
3212           Read2RTCDOperandFetch (cpup, cpu.TPR.CA, cpu.Ypair);
3213           // RTCD always ends up in append mode.
3214           set_addr_mode (cpup, APPEND_mode);
3215 
3216           return CONT_RET;
3217 
3218         case x0 (0604):  // tmi
3219           // If negative indicator ON then
3220           //  C(TPR.CA) -> C(PPR.IC)
3221           //  C(TPR.TSR) -> C(PPR.PSR)
3222           if (TST_I_NEG)
3223             {
3224               do_caf (cpup);
3225               read_tra_op (cpup);
3226               return CONT_TRA;
3227             }
3228           break;
3229 
3230                          // stxn
3231         case x0 (0740):  // stx0
3232         case x0 (0741):  // stx1
3233         case x0 (0742):  // stx2
3234         case x0 (0743):  // stx3
3235         case x0 (0744):  // stx4
3236         case x0 (0745):  // stx5
3237         case x0 (0746):  // stx6
3238         case x0 (0747):  // stx7
3239           {
3240             uint32 n = opcode10 & 07;  // get n
3241             //SETHI (cpu.CY, cpu.rX[n]);
3242             cpu.CY      = ((word36) cpu.rX[n]) << 18;
3243             cpu.zone    = 0777777000000;
3244             cpu.useZone = true;
3245           }
3246           break;
3247 
3248         case x0 (0634):  // ldi
3249           {
3250             CPTUR (cptUseIR);
3251             // C(Y)18,31 -> C(IR)
3252 
3253             // Indicators:
3254             //  Parity Mask:
3255             //      If C(Y)27 = 1, and the processor is in absolute or
3256             //      instruction privileged mode, then ON; otherwise OFF.
3257             //      This indicator is not affected in the normal or BAR modes.
3258             //  Not BAR mode:
3259             //      Cannot be changed by the ldi instruction
3260             //  MIF:
3261             //      If C(Y)30 = 1, and the processor is in absolute or
3262             //      instruction privileged mode, then ON; otherwise OFF.
3263             //      This indicator is not affected in normal or BAR modes.
3264             //  Absolute mode:
3265             //      Cannot be changed by the ldi instruction
3266             //  All others: If corresponding bit in C(Y) is 1, then ON;
3267             //  otherwise, OFF
3268 
3269             // upper 14-bits of lower 18-bits
3270 
3271             // AL39 ldi says that HEX is ignored, but the mode register
3272             // description says that it isn't
3273             word18 tmp18;
3274             if (cpu.tweaks.l68_mode)
3275                tmp18 = GETLO (cpu.CY) & 0777760; // L68
3276             else
3277               tmp18 = GETLO (cpu.CY) & 0777770; // DPS8M
3278 
3279             bool bAbsPriv = is_priv_mode (cpup);
3280 
3281             SC_I_ZERO  (tmp18 & I_ZERO);
3282             SC_I_NEG   (tmp18 & I_NEG);
3283             SC_I_CARRY (tmp18 & I_CARRY);
3284             SC_I_OFLOW (tmp18 & I_OFLOW);
3285             SC_I_EOFL  (tmp18 & I_EOFL);
3286             SC_I_EUFL  (tmp18 & I_EUFL);
3287             SC_I_OMASK (tmp18 & I_OMASK);
3288             SC_I_TALLY (tmp18 & I_TALLY);
3289             SC_I_PERR  (tmp18 & I_PERR);
3290             // I_PMASK handled below
3291             // LDI cannot change I_NBAR
3292             SC_I_TRUNC (tmp18 & I_TRUNC);
3293             // I_MIF handled below
3294             // LDI cannot change I_ABS
3295             DPS8M_ (SC_I_HEX  (tmp18 & I_HEX);)
3296 
3297             if (bAbsPriv)
3298               {
3299                 SC_I_PMASK (tmp18 & I_PMASK);
3300                 SC_I_MIF (tmp18 & I_MIF);
3301               }
3302             else
3303               {
3304                 CLR_I_PMASK;
3305                 CLR_I_MIF;
3306               }
3307           }
3308           break;
3309 
3310         case x0 (0677):  // eraq
3311           // C(AQ)i XOR C(Y-pair)i -> C(AQ)i for i = (0, 1, ..., 71)
3312           {
3313 #if defined(TESTING)
3314             HDBGRegAR ("eraq");
3315             HDBGRegQR ("eraq");
3316 #endif
3317             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
3318             word72 trAQ = convert_to_word72 (cpu.rA, cpu.rQ);
3319 #if defined(NEED_128)
3320             trAQ = xor_128 (trAQ, tmp72);
3321             trAQ = and_128 (trAQ, MASK72);
3322 
3323             SC_I_ZERO (iszero_128 (trAQ));
3324             SC_I_NEG (isnonzero_128 (and_128 (trAQ, SIGN72)));
3325 #else
3326             trAQ = trAQ ^ tmp72;
3327             trAQ &= MASK72;
3328 
3329             SC_I_ZERO (trAQ == 0);
3330             SC_I_NEG (trAQ & SIGN72);
3331 #endif
3332 
3333             convert_to_word36 (trAQ, &cpu.rA, &cpu.rQ);
3334 #if defined(TESTING)
3335             HDBGRegAW ("eraq");
3336             HDBGRegQW ("eraq");
3337 #endif
3338           }
3339           break;
3340 
3341         case x0 (0275):  // ora
3342           // C(A)i | C(Y)i -> C(A)i for i = (0, 1, ..., 35)
3343 #if defined(TESTING)
3344           HDBGRegAR ("ora");
3345 #endif
3346           cpu.rA = cpu.rA | cpu.CY;
3347           cpu.rA &= DMASK;
3348 #if defined(TESTING)
3349           HDBGRegAW ("ora");
3350 #endif
3351 
3352           SC_I_ZERO (cpu.rA == 0);
3353           SC_I_NEG (cpu.rA & SIGN36);
3354           break;
3355 
3356         case x0 (0076):   // adq
3357           {
3358             L68_ (cpu.ou.cycle |= ou_GOS;)
3359             bool ovf;
3360 #if defined(TESTING)
3361             HDBGRegQR ("adq");
3362 #endif
3363             cpu.rQ = Add36b (cpup, cpu.rQ, cpu.CY, 0, I_ZNOC,
3364                                  & cpu.cu.IR, & ovf);
3365 #if defined(TESTING)
3366             HDBGRegQW ("adq");
3367 #endif
3368             overflow (cpup, ovf, false, "adq overflow fault");
3369           }
3370           break;
3371 
3372         case x1 (0604):  // tmoz
3373             // If negative or zero indicator ON then
3374             // C(TPR.CA) -> C(PPR.IC)
3375             // C(TPR.TSR) -> C(PPR.PSR)
3376             if (cpu.cu.IR & (I_NEG | I_ZERO))
3377               {
3378                 do_caf (cpup);
3379                 read_tra_op (cpup);
3380                 return CONT_TRA;
3381               }
3382             break;
3383 
3384         case x1 (0250):  // spbp0
3385         case x0 (0251):  // spbp1
3386         case x1 (0252):  // spbp2
3387         case x0 (0253):  // spbp3
3388         case x1 (0650):  // spbp4
3389         case x0 (0651):  // spbp5
3390         case x1 (0652):  // spbp6
3391         case x0 (0653):  // spbp7
3392             // For n = 0, 1, ..., or 7 as determined by operation code
3393             //  C(PRn.SNR) -> C(Y-pair)3,17
3394             //  C(PRn.RNR) -> C(Y-pair)18,20
3395             //  000 -> C(Y-pair)0,2
3396             //  00...0 -> C(Y-pair)21,29
3397             //  (43)8 -> C(Y-pair)30,35
3398             //  00...0 -> C(Y-pair)36,71
3399             {
3400               // spbp0 1250  010 101 000
3401               // spbp1 0251  010 101 001
3402               // spbp2 1252  010 101 010
3403               // spbp3 0253  010 101 011
3404               // spbp4 1650  110 101 000
3405               // spbp5 0651  110 101 001
3406               // spbp6 1652  110 101 010
3407               // spbp8 0653  110 101 011
3408               uint n = ((opcode10 & 0400) >> 6) | (opcode10 & 03);
3409               CPTUR (cptUsePRn + n);
3410               cpu.Ypair[0] = 043;
3411               cpu.Ypair[0] |= ((word36) cpu.PR[n].SNR) << 18;
3412               cpu.Ypair[0] |= ((word36) cpu.PR[n].RNR) << 15;
3413               cpu.Ypair[1] = 0;
3414             }
3415             break;
3416 
3417         case x0 (0375):  // ana
3418           // C(A)i & C(Y)i -> C(A)i for i = (0, 1, ..., 35)
3419 #if defined(TESTING)
3420           HDBGRegAR ("ana");
3421 #endif
3422           cpu.rA = cpu.rA & cpu.CY;
3423           cpu.rA &= DMASK;
3424 #if defined(TESTING)
3425           HDBGRegAW ("ana");
3426 #endif
3427           SC_I_ZERO (cpu.rA == 0);
3428           SC_I_NEG (cpu.rA & SIGN36);
3429           break;
3430 
3431         case x0 (0431):  // fld
3432           // C(Y)0,7 -> C(E)
3433           // C(Y)8,35 -> C(AQ)0,27
3434           // 00...0 -> C(AQ)30,71
3435           // Zero: If C(AQ) = 0, then ON; otherwise OFF
3436           // Neg: If C(AQ)0 = 1, then ON; otherwise OFF
3437 
3438           CPTUR (cptUseE);
3439           cpu.CY &= DMASK;
3440           cpu.rE = (cpu.CY >> 28) & 0377;
3441           cpu.rA = (cpu.CY & FLOAT36MASK) << 8;
3442 #if defined(TESTING)
3443           HDBGRegAW ("fld");
3444 #endif
3445           cpu.rQ = 0;
3446 #if defined(TESTING)
3447           HDBGRegQW ("fld");
3448 #endif
3449 
3450           SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
3451           SC_I_NEG (cpu.rA & SIGN36);
3452           break;
3453 
3454         case x0 (0213):  // epaq
3455           // 000 -> C(AQ)0,2
3456           // C(TPR.TSR) -> C(AQ)3,17
3457           // 00...0 -> C(AQ)18,32
3458           // C(TPR.TRR) -> C(AQ)33,35
3459 
3460           // C(TPR.CA) -> C(AQ)36,53
3461           // 00...0 -> C(AQ)54,65
3462           // C(TPR.TBR) -> C(AQ)66,71
3463 
3464           cpu.rA  = cpu.TPR.TRR & MASK3;
3465           cpu.rA |= (word36) (cpu.TPR.TSR & MASK15) << 18;
3466 #if defined(TESTING)
3467           HDBGRegAW ("epaq");
3468 #endif
3469 
3470           cpu.rQ  = cpu.TPR.TBR & MASK6;
3471           cpu.rQ |= (word36) (cpu.TPR.CA & MASK18) << 18;
3472 #if defined(TESTING)
3473           HDBGRegQW ("epaq");
3474 #endif
3475 
3476           SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
3477 
3478           break;
3479 
3480         case x0 (0736):  // qls
3481           // Shift C(Q) left the number of positions given in
3482           // C(TPR.CA)11,17; fill vacated positions with zeros.
3483           {
3484 #if defined(TESTING)
3485             HDBGRegQR ("qls");
3486 #endif
3487 #if BARREL_SHIFTER
3488             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
3489 
3490             // Capture the bits shifted through Q0
3491             word36 capture;
3492             // If count is > 36, than all of the bits will rotate through Q
3493             if (cnt < 36) {
3494               // +1 is Q0 plus the bits that will get shifted into Q0
3495               capture = cpu.rQ & barrelLeftMaskTable[cnt + 1];
3496 
3497               // Do the shift
3498               cpu.rQ <<= cnt;
3499               cpu.rQ &= DMASK;    // keep to 36-bits
3500 
3501               // If the captured bits are all 0 or all 1, then
3502               // Q0 will not have changed during the rotate
3503 
3504             } else {
3505               capture = cpu.rQ;
3506               cpu.rQ = 0;
3507             }
3508 
3509             if (capture == 0 || capture == (MASK36 & barrelLeftMaskTable[cnt + 1]))
3510               CLR_I_CARRY;
3511             else
3512               SET_I_CARRY;
3513 #else // !BARREL_SHIFTER
3514             word36 tmp36   = cpu.TPR.CA & 0177;   // CY bits 11-17
3515             word36 tmpSign = cpu.rQ & SIGN36;
3516             CLR_I_CARRY;
3517 
3518             for (uint j = 0; j < tmp36; j ++)
3519               {
3520                 cpu.rQ <<= 1;
3521                 if (tmpSign != (cpu.rQ & SIGN36))
3522                   SET_I_CARRY;
3523               }
3524             cpu.rQ &= DMASK;    // keep to 36-bits
3525 #endif // BARREL_SHIFTER
3526 #if defined(TESTING)
3527             HDBGRegQW ("qls");
3528 #endif
3529 
3530             SC_I_ZERO (cpu.rQ == 0);
3531             SC_I_NEG (cpu.rQ & SIGN36);
3532           }
3533           break;
3534 
3535         case x0 (0754): // sti
3536 
3537           // C(IR) -> C(Y)18,31
3538           // 00...0 -> C(Y)32,35
3539 
3540           // The contents of the indicator register after address
3541           // preparation are stored in C(Y)18,31  C(Y)18,31 reflects the
3542           // state of the tally runout indicator prior to address
3543           // preparation. The relation between C(Y)18,31 and the indicators
3544           // is given in Table 4-5.
3545 
3546           CPTUR (cptUseIR);
3547             // AL39 sti says that HEX is ignored, but the mode register
3548             // description says that it isn't
3549 
3550           //SETLO (cpu.CY, (cpu.cu.IR & 0000000777770LL));
3551           DPS8M_ (cpu.CY = cpu.cu.IR & 0000000777770LL; )
3552           //SETLO (cpu.CY, (cpu.cu.IR & 0000000777760LL));
3553           L68_ (cpu.CY = cpu.cu.IR & 0000000777760LL;)
3554 
3555           if (cpu.switches.procMode == procModeGCOS)
3556             cpu.CY = cpu.cu.IR & 0000000777600LL;
3557           cpu.zone    = 0000000777777;
3558           cpu.useZone = true;
3559           SCF (i->stiTally, cpu.CY, I_TALLY);
3560           break;
3561 
3562         ///    FIXED-POINT ARITHMETIC INSTRUCTIONS
3563 
3564         /// Fixed-Point Data Movement Load
3565 
3566         case x0 (0635):  // eaa
3567           cpu.rA = 0;
3568           SETHI (cpu.rA, cpu.TPR.CA);
3569 #if defined(TESTING)
3570           HDBGRegAW ("eea");
3571 #endif
3572           SC_I_ZERO (cpu.TPR.CA == 0);
3573           SC_I_NEG (cpu.TPR.CA & SIGN18);
3574 
3575           break;
3576 
3577         case x0 (0636):  // eaq
3578           cpu.rQ = 0;
3579           SETHI (cpu.rQ, cpu.TPR.CA);
3580 #if defined(TESTING)
3581           HDBGRegQW ("eaq");
3582 #endif
3583 
3584           SC_I_ZERO (cpu.TPR.CA == 0);
3585           SC_I_NEG (cpu.TPR.CA & SIGN18);
3586 
3587           break;
3588 
3589 // Optimized to the top of the loop
3590 //        case x0 (0620):  // eax0
3591 //        case x0 (0621):  // eax1
3592 //        case x0 (0622):  // eax2
3593 //        case x0 (0623):  // eax3
3594 //        case x0 (0624):  // eax4
3595 //        case x0 (0625):  // eax5
3596 //        case x0 (0626):  // eax6
3597 //        case x0 (0627):  // eax7
3598 
3599         case x0 (0335):  // lca
3600           {
3601             bool ovf;
3602             cpu.rA = compl36 (cpup, cpu.CY, & cpu.cu.IR, & ovf);
3603 #if defined(TESTING)
3604             HDBGRegAW ("lca");
3605 #endif
3606             overflow (cpup, ovf, false, "lca overflow fault");
3607           }
3608           break;
3609 
3610         case x0 (0336):  // lcq
3611           {
3612             bool ovf;
3613             cpu.rQ = compl36 (cpup, cpu.CY, & cpu.cu.IR, & ovf);
3614 #if defined(TESTING)
3615             HDBGRegQW ("lcq");
3616 #endif
3617             overflow (cpup, ovf, false, "lcq overflow fault");
3618           }
3619           break;
3620 
3621                          // lcxn
3622         case x0 (0320):  // lcx0
3623         case x0 (0321):  // lcx1
3624         case x0 (0322):  // lcx2
3625         case x0 (0323):  // lcx3
3626         case x0 (0324):  // lcx4
3627         case x0 (0325):  // lcx5
3628         case x0 (0326):  // lcx6
3629         case x0 (0327):  // lcx7
3630           {
3631             bool ovf;
3632             uint32 n  = opcode10 & 07;  // get n
3633             cpu.rX[n] = compl18 (cpup, GETHI (cpu.CY), & cpu.cu.IR, & ovf);
3634 #if defined(TESTING)
3635             HDBGRegXW (n, "lcxn");
3636 #endif
3637             overflow (cpup, ovf, false, "lcxn overflow fault");
3638           }
3639           break;
3640 
3641         case x0 (0337):  // lcaq
3642           {
3643             // The lcaq instruction changes the number to its negative while
3644             // moving it from Y-pair to AQ. The operation is executed by
3645             // forming the twos complement of the string of 72 bits. In twos
3646             // complement arithmetic, the value 0 is its own negative. An
3647             // overflow condition exists if C(Y-pair) = -2**71.
3648 
3649             if (cpu.Ypair[0] == 0400000000000LL && cpu.Ypair[1] == 0)
3650               {
3651                 cpu.rA = cpu.Ypair[0];
3652 #if defined(TESTING)
3653                 HDBGRegAW ("lcaq");
3654 #endif
3655                 cpu.rQ = cpu.Ypair[1];
3656 #if defined(TESTING)
3657                 HDBGRegQW ("lcaq");
3658 #endif
3659                 SET_I_NEG;
3660                 CLR_I_ZERO;
3661                 overflow (cpup, true, false, "lcaq overflow fault");
3662               }
3663             else if (cpu.Ypair[0] == 0 && cpu.Ypair[1] == 0)
3664               {
3665                 cpu.rA = 0;
3666 #if defined(TESTING)
3667                 HDBGRegAW ("lcaq");
3668 #endif
3669                 cpu.rQ = 0;
3670 #if defined(TESTING)
3671                 HDBGRegQW ("lcaq");
3672 #endif
3673 
3674                 SET_I_ZERO;
3675                 CLR_I_NEG;
3676               }
3677             else
3678               {
3679                 word72 tmp72 = convert_to_word72 (cpu.Ypair[0], cpu.Ypair[1]);
3680 #if defined(NEED_128)
3681                 tmp72 = negate_128 (tmp72);
3682 #else
3683                 tmp72 = ~tmp72 + 1;
3684 #endif
3685                 convert_to_word36 (tmp72, & cpu.rA, & cpu.rQ);
3686 #if defined(TESTING)
3687                 HDBGRegAW ("lcaq");
3688                 HDBGRegQW ("lcaq");
3689 #endif
3690 
3691                 SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
3692                 SC_I_NEG (cpu.rA & SIGN36);
3693               }
3694           }
3695           break;
3696 
3697 // Optimized to the top of the loop
3698 //        case x0 (0235):  // lda
3699 
3700         case x0 (0034): // ldac
3701           cpu.rA = cpu.CY;
3702 #if defined(TESTING)
3703           HDBGRegAW ("ldac");
3704 #endif
3705           SC_I_ZERO (cpu.rA == 0);
3706           SC_I_NEG (cpu.rA & SIGN36);
3707           cpu.CY = 0;
3708           break;
3709 
3710 // Optimized to the top of the loop
3711 //        case x0 (0237):  // ldaq
3712 
3713 // Optimized to the top of the loop
3714 //        case x0 (0634):  // ldi
3715 
3716 // Optimized to the top of the loop
3717 //         case x0 (0236):  // ldq
3718 
3719         case x0 (0032): // ldqc
3720           cpu.rQ = cpu.CY;
3721 #if defined(TESTING)
3722           HDBGRegQW ("ldqc");
3723 #endif
3724           SC_I_ZERO (cpu.rQ == 0);
3725           SC_I_NEG (cpu.rQ & SIGN36);
3726           cpu.CY = 0;
3727           break;
3728 
3729                          // ldxn
3730         case x0 (0220):  // ldx0
3731         case x0 (0221):  // ldx1
3732         case x0 (0222):  // ldx2
3733         case x0 (0223):  // ldx3
3734         case x0 (0224):  // ldx4
3735         case x0 (0225):  // ldx5
3736         case x0 (0226):  // ldx6
3737         case x0 (0227):  // ldx7
3738           {
3739             uint32 n  = opcode10 & 07;  // get n
3740             cpu.rX[n] = GETHI (cpu.CY);
3741 #if defined(TESTING)
3742             HDBGRegXW (n, "ldxn");
3743 #endif
3744             SC_I_ZERO (cpu.rX[n] == 0);
3745             SC_I_NEG (cpu.rX[n] & SIGN18);
3746           }
3747           break;
3748 
3749         case x0 (0073):   // lreg
3750           CPTUR (cptUseE);
3751           L68_ (cpu.ou.cycle |= ou_GOS;)
3752           L68_ (cpu.ou.eac = 0;)
3753           cpu.rX[0] = GETHI (cpu.Yblock8[0]);
3754 #if defined(TESTING)
3755           HDBGRegXW (0, "lreg");
3756 #endif
3757           cpu.rX[1] = GETLO (cpu.Yblock8[0]);
3758 #if defined(TESTING)
3759           HDBGRegXW (1, "lreg");
3760 #endif
3761           L68_ (cpu.ou.eac ++;)
3762           cpu.rX[2] = GETHI (cpu.Yblock8[1]);
3763 #if defined(TESTING)
3764           HDBGRegXW (2, "lreg");
3765 #endif
3766           cpu.rX[3] = GETLO (cpu.Yblock8[1]);
3767 #if defined(TESTING)
3768           HDBGRegXW (3, "lreg");
3769 #endif
3770           L68_ (cpu.ou.eac ++;)
3771           cpu.rX[4] = GETHI (cpu.Yblock8[2]);
3772 #if defined(TESTING)
3773           HDBGRegXW (4, "lreg");
3774 #endif
3775           cpu.rX[5] = GETLO (cpu.Yblock8[2]);
3776 #if defined(TESTING)
3777           HDBGRegXW (5, "lreg");
3778 #endif
3779           L68_ (cpu.ou.eac ++;)
3780           cpu.rX[6] = GETHI (cpu.Yblock8[3]);
3781 #if defined(TESTING)
3782           HDBGRegXW (6, "lreg");
3783 #endif
3784           cpu.rX[7] = GETLO (cpu.Yblock8[3]);
3785 #if defined(TESTING)
3786           HDBGRegXW (7, "lreg");
3787 #endif
3788           L68_ (cpu.ou.eac ++;)
3789           cpu.rA = cpu.Yblock8[4];
3790 #if defined(TESTING)
3791           HDBGRegAW ("lreg");
3792 #endif
3793           cpu.rQ = cpu.Yblock8[5];
3794 #if defined(TESTING)
3795           HDBGRegQW ("lreg");
3796 #endif
3797           cpu.rE = (GETHI (cpu.Yblock8[6]) >> 10) & 0377;   // need checking
3798           break;
3799 
3800 // Optimized to the top of the loop
3801 //                         // lxln
3802 //        case x0 (0720):  // lxl0
3803 //        case x0 (0721):  // lxl1
3804 //        case x0 (0722):  // lxl2
3805 //        case x0 (0723):  // lxl3
3806 //        case x0 (0724):  // lxl4
3807 //        case x0 (0725):  // lxl5
3808 //        case x0 (0726):  // lxl6
3809 //        case x0 (0727):  // lxl7
3810 
3811         /// Fixed-Point Data Movement Store
3812 
3813         case x0 (0753):  // sreg
3814           CPTUR (cptUseE);
3815           CPTUR (cptUseRALR);
3816           // clear block (changed to memset() per DJ request)
3817           //(void)memset (cpu.Yblock8, 0, sizeof (cpu.Yblock8));
3818           L68_ (cpu.ou.cycle |= ou_GOS;)
3819           L68_ (cpu.ou.eac = 0;)
3820           SETHI (cpu.Yblock8[0], cpu.rX[0]);
3821           SETLO (cpu.Yblock8[0], cpu.rX[1]);
3822           L68_ (cpu.ou.eac ++;)
3823           SETHI (cpu.Yblock8[1], cpu.rX[2]);
3824           SETLO (cpu.Yblock8[1], cpu.rX[3]);
3825           L68_ (cpu.ou.eac ++;)
3826           SETHI (cpu.Yblock8[2], cpu.rX[4]);
3827           SETLO (cpu.Yblock8[2], cpu.rX[5]);
3828           L68_ (cpu.ou.eac ++;)
3829           SETHI (cpu.Yblock8[3], cpu.rX[6]);
3830           SETLO (cpu.Yblock8[3], cpu.rX[7]);
3831           L68_ (cpu.ou.eac ++;)
3832           cpu.Yblock8[4] = cpu.rA;
3833           cpu.Yblock8[5] = cpu.rQ;
3834           cpu.Yblock8[6] = ((word36)(cpu.rE & MASK8)) << 28;
3835           if (cpu.tweaks.isolts_mode)
3836             cpu.Yblock8[7] = (((-- cpu.shadowTR) & MASK27) << 9) | (cpu.rRALR & 07);
3837           else
3838             cpu.Yblock8[7] = ((cpu.rTR & MASK27) << 9) | (cpu.rRALR & 07);
3839 #if defined(TESTING)
3840           HDBGRegXR (0, "sreg");
3841           HDBGRegXR (1, "sreg");
3842           HDBGRegXR (2, "sreg");
3843           HDBGRegXR (3, "sreg");
3844           HDBGRegXR (4, "sreg");
3845           HDBGRegXR (5, "sreg");
3846           HDBGRegXR (6, "sreg");
3847           HDBGRegXR (7, "sreg");
3848           HDBGRegAR ("sreg");
3849           HDBGRegQR ("sreg");
3850 #endif
3851           break;
3852 
3853 // Optimized to the top of the loop
3854 //        case x0 (0755):  // sta
3855 
3856         case x0 (0354):  // stac
3857           if (cpu.CY == 0)
3858             {
3859 #if defined(TESTING)
3860               HDBGRegAR ("stac");
3861 #endif
3862               SET_I_ZERO;
3863               cpu.CY = cpu.rA;
3864             }
3865           else
3866             CLR_I_ZERO;
3867           break;
3868 
3869         case x0 (0654):  // stacq
3870 #if defined(TESTING)
3871           HDBGRegQR ("stacq");
3872 #endif
3873           if (cpu.CY == cpu.rQ)
3874             {
3875 #if defined(TESTING)
3876               HDBGRegAR ("stacq");
3877 #endif
3878               cpu.CY = cpu.rA;
3879               SET_I_ZERO;
3880             }
3881           else
3882             CLR_I_ZERO;
3883           break;
3884 
3885 // Optimized to the top of the loop
3886 //        case x0 (0757):  // staq
3887 
3888         case x0 (0551):  // stba
3889           // 9-bit bytes of C(A) -> corresponding bytes of C(Y), the byte
3890           // positions affected being specified in the TAG field.
3891           // copyBytes ((i->tag >> 2) & 0xf, cpu.rA, &cpu.CY);
3892 #if defined(TESTING)
3893           HDBGRegAR ("stba");
3894 #endif
3895           cpu.CY = cpu.rA;
3896           cpu.zone =
3897              /*LINTED E_CONST_PROMOTED_UNSIGNED_LONG*/
3898              ((i->tag & 040) ? 0777000000000u : 0) |
3899              ((i->tag & 020) ? 0000777000000u : 0) |
3900              ((i->tag & 010) ? 0000000777000u : 0) |
3901              ((i->tag & 004) ? 0000000000777u : 0);
3902           cpu.useZone = true;
3903           cpu.ou.crflag = true;
3904           break;
3905 
3906         case x0 (0552):  // stbq
3907           // 9-bit bytes of C(Q) -> corresponding bytes of C(Y), the byte
3908           // positions affected being specified in the TAG field.
3909           // copyBytes ((i->tag >> 2) & 0xf, cpu.rQ, &cpu.CY);
3910 #if defined(TESTING)
3911           HDBGRegQR ("stbq");
3912 #endif
3913           cpu.CY = cpu.rQ;
3914           cpu.zone =
3915              /*LINTED E_CONST_PROMOTED_UNSIGNED_LONG*/
3916              ((i->tag & 040) ? 0777000000000u : 0) |
3917              ((i->tag & 020) ? 0000777000000u : 0) |
3918              ((i->tag & 010) ? 0000000777000u : 0) |
3919              ((i->tag & 004) ? 0000000000777u : 0);
3920           cpu.useZone   = true;
3921           cpu.ou.crflag = true;
3922           break;
3923 
3924         case x0 (0554):  // stc1
3925           // "C(Y)25 reflects the state of the tally runout indicator
3926           // prior to modification.
3927           SETHI (cpu.CY, (cpu.PPR.IC + 1) & MASK18);
3928           // AL39 stc1 says that HEX is ignored, but the mode register
3929           // description says that it isn't
3930           DPS8M_ (SETLO (cpu.CY, cpu.cu.IR & 0777770);)
3931           L68_ (SETLO (cpu.CY, cpu.cu.IR & 0777760);)
3932           SCF (i->stiTally, cpu.CY, I_TALLY);
3933           break;
3934 
3935         case x0 (0750):  // stc2
3936           // AL-39 doesn't specify if the low half is set to zero,
3937           // set to IR, or left unchanged
3938           // RJ78 specifies unchanged
3939           // SETHI (cpu.CY, (cpu.PPR.IC + 2) & MASK18);
3940           cpu.CY      = ((word36) ((cpu.PPR.IC + 2) & MASK18)) << 18;
3941           cpu.zone    = 0777777000000;
3942           cpu.useZone = true;
3943           break;
3944 
3945         case x0 (0751): // stca
3946           // Characters of C(A) -> corresponding characters of C(Y),
3947           // the character positions affected being specified in the TAG
3948           // field.
3949           // copyChars (i->tag, cpu.rA, &cpu.CY);
3950 #if defined(TESTING)
3951           HDBGRegAR ("stca");
3952 #endif
3953           cpu.CY = cpu.rA;
3954           cpu.zone =
3955              /*LINTED E_CONST_PROMOTED_UNSIGNED_LONG*/
3956              ((i->tag & 040) ? 0770000000000u : 0) |
3957              ((i->tag & 020) ? 0007700000000u : 0) |
3958              ((i->tag & 010) ? 0000077000000u : 0) |
3959              ((i->tag & 004) ? 0000000770000u : 0) |
3960              ((i->tag & 002) ? 0000000007700u : 0) |
3961              ((i->tag & 001) ? 0000000000077u : 0);
3962           cpu.useZone = true;
3963           cpu.ou.crflag = true;
3964           break;
3965 
3966         case x0 (0752): // stcq
3967           // Characters of C(Q) -> corresponding characters of C(Y), the
3968           // character positions affected being specified in the TAG field.
3969           // copyChars (i->tag, cpu.rQ, &cpu.CY);
3970 #if defined(TESTING)
3971           HDBGRegQR ("stcq");
3972 #endif
3973           cpu.CY = cpu.rQ;
3974           cpu.zone =
3975              /*LINTED E_CONST_PROMOTED_UNSIGNED_LONG*/
3976              ((i->tag & 040) ? 0770000000000u : 0) |
3977              ((i->tag & 020) ? 0007700000000u : 0) |
3978              ((i->tag & 010) ? 0000077000000u : 0) |
3979              ((i->tag & 004) ? 0000000770000u : 0) |
3980              ((i->tag & 002) ? 0000000007700u : 0) |
3981              ((i->tag & 001) ? 0000000000077u : 0);
3982           cpu.useZone = true;
3983           cpu.ou.crflag = true;
3984           break;
3985 
3986         case x0 (0357): //< stcd
3987           // C(PPR) -> C(Y-pair) as follows:
3988 
3989           //  000 -> C(Y-pair)0,2
3990           //  C(PPR.PSR) -> C(Y-pair)3,17
3991           //  C(PPR.PRR) -> C(Y-pair)18,20
3992           //  00...0 -> C(Y-pair)21,29
3993           //  (43)8 -> C(Y-pair)30,35
3994 
3995           //  C(PPR.IC)+2 -> C(Y-pair)36,53
3996           //  00...0 -> C(Y-pair)54,71
3997 
3998           // ISOLTS 880 5a has an STCD in an XED in a fault pair;
3999           // it reports the wrong ring number. This was fixed by
4000           // emulating the SCU instruction (different behavior in fault
4001           // pair).
4002 
4003           if (cpu.cycle == EXEC_cycle)
4004             {
4005               cpu.Ypair[0] = 0;
4006               putbits36_15 (& cpu.Ypair[0],  3, cpu.PPR.PSR);
4007               putbits36_3  (& cpu.Ypair[0], 18, cpu.PPR.PRR);
4008               putbits36_6  (& cpu.Ypair[0], 30, 043);
4009 
4010               cpu.Ypair[1] = 0;
4011               putbits36_18 (& cpu.Ypair[1],  0, cpu.PPR.IC + 2);
4012             }
4013           else
4014             {
4015               cpu.Ypair[0] = 0;
4016               putbits36_15 (& cpu.Ypair[0],  3, cpu.cu_data.PSR);
4017               putbits36_3  (& cpu.Ypair[0], 18, cpu.cu_data.PRR);
4018               //putbits36_6  (& cpu.Ypair[0], 30, 043);
4019 
4020               cpu.Ypair[1] = 0;
4021               putbits36_18 (& cpu.Ypair[1],  0, cpu.cu_data.IC + 2);
4022             }
4023           break;
4024 
4025 // Optimized to the top of the loop
4026 //        case x0 (0754): // sti
4027 
4028 // Optimized to the top of the loop
4029 //         case x0 (0756): // stq
4030 
4031         case x0 (0454):  // stt
4032           CPTUR (cptUseTR);
4033           if (cpu.tweaks.isolts_mode)
4034             //cpu.CY = ((-- cpu.shadowTR) & MASK27) << 9;
4035             // ubsan
4036             cpu.CY = (((uint) (((int) cpu.shadowTR) - 1)) & MASK27) << 9;
4037           else
4038             cpu.CY = (cpu.rTR & MASK27) << 9;
4039           break;
4040 
4041 // Optimized to the top of the loop
4042 //                         // stxn
4043 //        case x0 (0740):  // stx0
4044 //        case x0 (0741):  // stx1
4045 //        case x0 (0742):  // stx2
4046 //        case x0 (0743):  // stx3
4047 //        case x0 (0744):  // stx4
4048 //        case x0 (0745):  // stx5
4049 //        case x0 (0746):  // stx6
4050 //        case x0 (0747):  // stx7
4051 
4052 // Optimized to the top of the loop
4053 //        case x0 (0450): // stz
4054 
4055                          // sxln
4056         case x0 (0440):  // sxl0
4057         case x0 (0441):  // sxl1
4058         case x0 (0442):  // sxl2
4059         case x0 (0443):  // sxl3
4060         case x0 (0444):  // sxl4
4061         case x0 (0445):  // sxl5
4062         case x0 (0446):  // sxl6
4063         case x0 (0447):  // sxl7
4064           //SETLO (cpu.CY, cpu.rX[opcode10 & 07]);
4065           cpu.CY      = cpu.rX[opcode10 & 07];
4066           cpu.zone    = 0000000777777;
4067           cpu.useZone = true;
4068           break;
4069 
4070         /// Fixed-Point Data Movement Shift
4071 
4072         case x0 (0775):  // alr
4073           {
4074 #if defined(TESTING)
4075               HDBGRegAR ("alr");
4076 #endif
4077 #if BARREL_SHIFTER
4078             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4079             cnt %= 36;
4080 
4081             word36 highA = cpu.rA & barrelLeftMaskTable[cnt];
4082             cpu.rA <<= cnt;
4083             highA >>= (36 - cnt);
4084             highA &= barrelRightMaskTable[cnt];
4085             cpu.rA |= highA;
4086             cpu.rA &= DMASK;    // keep to 36-bits
4087 #else // !BARREL_SHIFTER
4088               word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
4089               for (uint j = 0 ; j < tmp36 ; j++)
4090               {
4091                   bool a0 = cpu.rA & SIGN36;    // A0
4092                   cpu.rA <<= 1;               // shift left 1
4093                   if (a0)                 // rotate A0 -> A35
4094                       cpu.rA |= 1;
4095               }
4096               cpu.rA &= DMASK;    // keep to 36-bits
4097 #endif // BARREL_SHIFTER
4098 #if defined(TESTING)
4099               HDBGRegAW ("alr");
4100 #endif
4101 
4102               SC_I_ZERO (cpu.rA == 0);
4103               SC_I_NEG (cpu.rA & SIGN36);
4104           }
4105           break;
4106 
4107 // Optimized to the top of the loop
4108 //        case x0 (0735):  // als
4109 
4110         case x0 (0771):  // arl
4111           // Shift C(A) right the number of positions given in
4112           // C(TPR.CA)11,17; filling vacated positions with zeros.
4113           {
4114 #if defined(TESTING)
4115             HDBGRegAR ("arl");
4116 #endif
4117             cpu.rA &= DMASK; // Make sure the shifted in bits are 0
4118             word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
4119 
4120             cpu.rA >>= tmp36;
4121             cpu.rA &= DMASK;    // keep to 36-bits
4122 #if defined(TESTING)
4123             HDBGRegAW ("arl");
4124 #endif
4125 
4126             SC_I_ZERO (cpu.rA == 0);
4127             SC_I_NEG (cpu.rA & SIGN36);
4128           }
4129           break;
4130 
4131         case x0 (0731):  // ars
4132           {
4133             // Shift C(A) right the number of positions given in
4134             // C(TPR.CA)11,17; filling vacated positions with initial C(A)0.
4135 
4136 #if defined(TESTING)
4137             HDBGRegAR ("ars");
4138 #endif
4139 #if BARREL_SHIFTER
4140             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4141             bool A0 = (cpu.rA & SIGN36) != 0;
4142 
4143             if (cnt >= 36) {
4144               cpu.rA = A0 ? MASK36 : 0;
4145             } else {
4146               // Shift rA
4147               cpu.rA >>= cnt;
4148               // Mask out the high bits
4149               if (A0) {
4150                 cpu.rA |= barrelLeftMaskTable[cnt];
4151               } else {
4152                 cpu.rA &= BS_COMPL (barrelLeftMaskTable[cnt]);
4153               }
4154             }
4155             cpu.rA &= DMASK;    // keep to 36-bits
4156 #else // !BARREL_SHIFTER
4157             cpu.rA &= DMASK; // Make sure the shifted in bits are 0
4158             word18 tmp18 = cpu.TPR.CA & 0177;   // CY bits 11-17
4159 
4160             bool a0 = cpu.rA & SIGN36;    // A0
4161             for (uint j = 0 ; j < tmp18 ; j ++)
4162               {
4163                 cpu.rA >>= 1;               // shift right 1
4164                 if (a0)                 // propagate sign bit
4165                     cpu.rA |= SIGN36;
4166               }
4167             cpu.rA &= DMASK;    // keep to 36-bits
4168 #endif // BARREL_SHIFTER
4169 #if defined(TESTING)
4170             HDBGRegAW ("ars");
4171 #endif
4172 
4173             SC_I_ZERO (cpu.rA == 0);
4174             SC_I_NEG (cpu.rA & SIGN36);
4175           }
4176           break;
4177 
4178         case x0 (0777):  // llr
4179           // Shift C(AQ) left by the number of positions given in
4180           // C(TPR.CA)11,17; entering each bit leaving AQ0 into AQ71.
4181 
4182           {
4183 #if defined(TESTING)
4184             HDBGRegAR ("llr");
4185             HDBGRegQR ("llr");
4186 #endif
4187 #if BARREL_SHIFTER
4188             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4189             cnt = cnt % 72;  // 0-71
4190             if (cnt > 35) {
4191               cnt = cnt - 36;
4192               word36 tmp = cpu.rA;
4193               cpu.rA = cpu.rQ;
4194               cpu.rQ = tmp;
4195             }
4196             word36 highA = cpu.rA & barrelLeftMaskTable[cnt];
4197             word36 lowA  = cpu.rA & BS_COMPL(barrelLeftMaskTable[cnt]);
4198             word36 highQ = cpu.rQ & barrelLeftMaskTable[cnt];
4199             word36 lowQ  = cpu.rQ & BS_COMPL(barrelLeftMaskTable[cnt]);
4200             cpu.rA = (lowA << cnt) | (highQ >> (36 - cnt));
4201             cpu.rQ = (lowQ << cnt) | (highA >> (36 - cnt));
4202 #else // !BARREL_SHIFTER
4203             word36 tmp36 = cpu.TPR.CA & 0177;      // CY bits 11-17
4204             for (uint j = 0 ; j < tmp36 ; j++)
4205               {
4206                 bool a0 = cpu.rA & SIGN36;         // A0
4207 
4208                 cpu.rA <<= 1;                      // shift left 1
4209 
4210                 bool b0 = cpu.rQ & SIGN36;         // Q0
4211                 if (b0)
4212                   cpu.rA |= 1;                     // Q0 => A35
4213 
4214                 cpu.rQ <<= 1;                      // shift left 1
4215 
4216                 if (a0)                            // propagate A sign bit
4217                   cpu.rQ |= 1;
4218               }
4219 
4220 #endif // BARREL_SHIFTER
4221             cpu.rA &= DMASK;    // keep to 36-bits
4222             cpu.rQ &= DMASK;
4223 #if defined(TESTING)
4224             HDBGRegAW ("llr");
4225             HDBGRegQW ("llr");
4226 #endif
4227 
4228             SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
4229             SC_I_NEG (cpu.rA & SIGN36);
4230           }
4231           break;
4232 
4233         case x0 (0737):  // lls
4234           {
4235             // Shift C(AQ) left the number of positions given in
4236             // C(TPR.CA)11,17; filling vacated positions with zeros.
4237 #if BARREL_SHIFTER
4238             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4239 
4240             // Capture the bits shifted through A0
4241             word36 captureA, captureQ;
4242             // If count > 72, tan all of the bits will rotate through A0
4243             if (cnt < 36) {
4244                // Only bits in A will rotate through A0
4245                captureA = cpu.rA & barrelLeftMaskTable[cnt + 1];
4246                if (captureA == 0 || captureA == (MASK36 & barrelLeftMaskTable[cnt + 1]))
4247                  CLR_I_CARRY;
4248                else
4249                  SET_I_CARRY;
4250             } else {
4251                // All of A and some or all of b
4252                uint cnt72 = cnt < 72 ? cnt : 71;
4253                captureA = cpu.rA;
4254                captureQ = cpu.rQ & barrelLeftMaskTable[cnt72 + 1 - 36];
4255                if (captureA == 0 && ((captureQ & barrelLeftMaskTable[cnt72 + 1 - 36]) == 0))
4256                  CLR_I_CARRY;
4257                else if (captureA == MASK36 &&
4258                         ((captureQ & barrelLeftMaskTable[cnt72 + 1 - 36]) == (MASK36 & barrelLeftMaskTable[cnt72 + 1 - 36])))
4259                  CLR_I_CARRY;
4260                else
4261                  SET_I_CARRY;
4262             }
4263             cnt = cnt % 72;  // 0-71
4264             if (cnt > 35) {
4265               cnt = cnt - 36;
4266               cpu.rA = cpu.rQ;
4267               cpu.rQ = 0;
4268             }
4269             //word36 highA = cpu.rA & barrelLeftMaskTable[cnt];
4270             word36 lowA  = cpu.rA & BS_COMPL(barrelLeftMaskTable[cnt]);
4271             word36 highQ = cpu.rQ & barrelLeftMaskTable[cnt];
4272             word36 lowQ  = cpu.rQ & BS_COMPL(barrelLeftMaskTable[cnt]);
4273             cpu.rA = (lowA << cnt) | (highQ >> (36 - cnt));
4274             cpu.rQ = (lowQ << cnt) /*| (highA >> (36 - cnt)) */;
4275 #else // !BARREL_SHIFTER
4276 
4277             CLR_I_CARRY;
4278 
4279 # if defined(TESTING)
4280             HDBGRegAR ("lls");
4281             HDBGRegQR ("lls");
4282 # endif
4283             word36 tmp36   = cpu.TPR.CA & 0177;   // CY bits 11-17
4284             word36 tmpSign = cpu.rA & SIGN36;
4285             for (uint j = 0 ; j < tmp36 ; j ++)
4286               {
4287                 cpu.rA <<= 1;               // shift left 1
4288 
4289                 if (tmpSign != (cpu.rA & SIGN36))
4290                   SET_I_CARRY;
4291 
4292                 bool b0 = cpu.rQ & SIGN36;    // Q0
4293                 if (b0)
4294                   cpu.rA |= 1;            // Q0 => A35
4295 
4296                 cpu.rQ <<= 1;               // shift left 1
4297               }
4298 
4299             cpu.rA &= DMASK;    // keep to 36-bits
4300             cpu.rQ &= DMASK;
4301 #endif // BARREL_SHIFTER
4302 #if defined(TESTING)
4303             HDBGRegAW ("lls");
4304             HDBGRegQW ("lls");
4305 #endif
4306 
4307             SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
4308             SC_I_NEG (cpu.rA & SIGN36);
4309           }
4310           break;
4311 
4312         case x0 (0773):  // lrl
4313           // Shift C(AQ) right the number of positions given in
4314           // C(TPR.CA)11,17; filling vacated positions with zeros.
4315           {
4316 #if defined(TESTING)
4317             HDBGRegAR ("lrl");
4318             HDBGRegQR ("lrl");
4319 #endif
4320 #if BARREL_SHIFTER
4321             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4322             if (cnt >= 72) {
4323                cpu.rA = 0;
4324                cpu.rQ = 0;
4325             } else if (cnt < 36) {
4326               // Shift rQ
4327               cpu.rQ >>= cnt;
4328               // Mask out the high bits
4329               cpu.rQ &= BS_COMPL (barrelLeftMaskTable[cnt]);
4330               // Capture the low bits in A
4331               word36 lowA = cpu.rA & barrelRightMaskTable[cnt];
4332               // Shift A
4333               cpu.rA >>= cnt;
4334               // Mask out the high bits
4335               cpu.rA &= BS_COMPL (barrelLeftMaskTable[cnt]);
4336               // Move the low A bits left
4337               lowA <<= (36 - cnt);
4338               // Put them in high Q
4339               cpu.rQ |= lowA;
4340             } else { // 36-71
4341               // Shift rQ
4342               cpu.rQ = cpu.rA >> (cnt - 36);
4343               // Mask out the high bits
4344               cpu.rQ &= BS_COMPL (barrelLeftMaskTable[cnt - 36]);
4345               cpu.rA = 0;
4346             }
4347             cpu.rA &= DMASK;    // keep to 36-bits
4348             cpu.rQ &= DMASK;
4349 #else // !BARREL_SHIFTER
4350             cpu.rA &= DMASK; // Make sure the shifted in bits are 0
4351             cpu.rQ &= DMASK; // Make sure the shifted in bits are 0
4352             word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
4353             for (uint j = 0 ; j < tmp36 ; j++)
4354               {
4355                 bool a35 = cpu.rA & 1;      // A35
4356                 cpu.rA >>= 1;               // shift right 1
4357 
4358                 cpu.rQ >>= 1;               // shift right 1
4359 
4360                 if (a35)                // propagate sign bit
4361                   cpu.rQ |= SIGN36;
4362               }
4363             cpu.rA &= DMASK;    // keep to 36-bits
4364             cpu.rQ &= DMASK;
4365 #endif // BARREL_SHIFTER
4366 #if defined(TESTING)
4367             HDBGRegAW ("lrl");
4368             HDBGRegQW ("lrl");
4369 #endif
4370 
4371             SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
4372             SC_I_NEG (cpu.rA & SIGN36);
4373           }
4374           break;
4375 
4376         case x0 (0733):  // lrs
4377           {
4378             // Shift C(AQ) right the number of positions given in
4379             // C(TPR.CA)11,17; filling vacated positions with initial C(AQ)0.
4380 
4381 #if defined(TESTING)
4382             HDBGRegAR ("lrs");
4383             HDBGRegQR ("lrs");
4384 #endif
4385 #if BARREL_SHIFTER
4386             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4387             bool AQ0 = (cpu.rA & SIGN36) != 0;
4388             if (cnt >= 72) {
4389                cpu.rA = cpu.rQ = AQ0 ? MASK36 : 0;
4390             } else if (cnt < 36) {
4391               // Shift rQ
4392               cpu.rQ >>= cnt;
4393               // Mask out the high bits
4394               cpu.rQ &= BS_COMPL (barrelLeftMaskTable[cnt]);
4395               // Capture the low bits in A
4396               word36 lowA = cpu.rA & barrelRightMaskTable[cnt];
4397               // Shift A
4398               cpu.rA >>= cnt;
4399               // Set the high bits to AQ0
4400               if (AQ0)
4401                 cpu.rA |= barrelLeftMaskTable[cnt];
4402               else
4403                 cpu.rA &= BS_COMPL (barrelLeftMaskTable[cnt]);
4404               // Move the low A bits left
4405               lowA <<= (36 - cnt);
4406               // Put them in high Q
4407               cpu.rQ |= lowA;
4408             } else { // 36-71
4409               // Shift rQ
4410               cpu.rQ = cpu.rA >> (cnt - 36);
4411               // Mask out the high bits
4412               if (AQ0) {
4413                 cpu.rQ |= barrelLeftMaskTable[cnt - 36];
4414                 cpu.rA = MASK36;
4415               } else {
4416                 cpu.rQ &= BS_COMPL (barrelLeftMaskTable[cnt - 36]);
4417                 cpu.rA = 0;
4418               }
4419             }
4420             cpu.rA &= DMASK;    // keep to 36-bits
4421             cpu.rQ &= DMASK;
4422 #else // !BARREL_SHIFTER
4423             word36 tmp36  = cpu.TPR.CA & 0177;   // CY bits 11-17
4424             cpu.rA       &= DMASK; // Make sure the shifted in bits are 0
4425             cpu.rQ       &= DMASK; // Make sure the shifted in bits are 0
4426             bool a0       = cpu.rA & SIGN36;    // A0
4427 
4428             for (uint j = 0 ; j < tmp36 ; j ++)
4429               {
4430                 bool a35 = cpu.rA & 1;      // A35
4431 
4432                 cpu.rA >>= 1;               // shift right 1
4433                 if (a0)
4434                   cpu.rA |= SIGN36;
4435 
4436                 cpu.rQ >>= 1;               // shift right 1
4437                 if (a35)                // propagate sign bit1
4438                   cpu.rQ |= SIGN36;
4439               }
4440             cpu.rA &= DMASK;    // keep to 36-bits (probably ain't necessary)
4441             cpu.rQ &= DMASK;
4442 #endif // BARREL_SHIFTER
4443 #if defined(TESTING)
4444             HDBGRegAW ("lrs");
4445             HDBGRegQW ("lrs");
4446 #endif
4447 
4448             SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
4449             SC_I_NEG (cpu.rA & SIGN36);
4450           }
4451           break;
4452 
4453         case x0 (0776):  // qlr
4454           // Shift C(Q) left the number of positions given in
4455           // C(TPR.CA)11,17; entering each bit leaving Q0 into Q35.
4456           {
4457 #if defined(TESTING)
4458             HDBGRegQR ("qlr");
4459 #endif
4460 #if BARREL_SHIFTER
4461             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4462             cnt %= 36;
4463 
4464             word36 highQ = cpu.rQ & barrelLeftMaskTable[cnt];
4465             cpu.rQ <<= cnt;
4466             highQ >>= (36 - cnt);
4467             highQ &= barrelRightMaskTable[cnt];
4468             cpu.rQ |= highQ;
4469             cpu.rQ &= DMASK;    // keep to 36-bits
4470 #else // !BARREL_SHIFTER
4471             word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
4472             for (uint j = 0 ; j < tmp36 ; j++)
4473               {
4474                 bool q0 = cpu.rQ & SIGN36;    // Q0
4475                 cpu.rQ <<= 1;               // shift left 1
4476                 if (q0)                 // rotate A0 -> A35
4477                   cpu.rQ |= 1;
4478               }
4479             cpu.rQ &= DMASK;    // keep to 36-bits
4480 #endif // BARREL_SHIFTER
4481 #if defined(TESTING)
4482             HDBGRegQW ("qlr");
4483 #endif
4484 
4485             SC_I_ZERO (cpu.rQ == 0);
4486             SC_I_NEG (cpu.rQ & SIGN36);
4487           }
4488           break;
4489 
4490 // Optimized to the top of the loop
4491 //        case x0 (0736):  // qls
4492 
4493         case x0 (0772):  // qrl
4494           // Shift C(Q) right the number of positions specified by
4495           // Y11,17; fill vacated positions with zeros.
4496           {
4497 #if defined(TESTING)
4498             HDBGRegQR ("qrl");
4499 #endif
4500             word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
4501 
4502             cpu.rQ  &= DMASK;    // Make sure the shifted in bits are 0
4503             cpu.rQ >>= tmp36;
4504             cpu.rQ  &= DMASK;    // keep to 36-bits
4505 #if defined(TESTING)
4506             HDBGRegQW ("qrl");
4507 #endif
4508 
4509             SC_I_ZERO (cpu.rQ == 0);
4510             SC_I_NEG (cpu.rQ & SIGN36);
4511 
4512           }
4513           break;
4514 
4515         case x0 (0732):  // qrs
4516           {
4517             // Shift C(Q) right the number of positions given in
4518             // C(TPR.CA)11,17; filling vacated positions with initial C(Q)0.
4519 
4520 #if defined(TESTING)
4521             HDBGRegQR ("qrs");
4522 #endif
4523 #if BARREL_SHIFTER
4524             uint cnt = (uint) cpu.TPR.CA & 0177;   // 0-127
4525             bool Q0 = (cpu.rQ & SIGN36) != 0;
4526 
4527             if (cnt >= 36) {
4528               cpu.rQ = Q0 ? MASK36 : 0;
4529             } else {
4530               // Shift rQ
4531               cpu.rQ >>= cnt;
4532               // Mask out the high bits
4533               if (Q0) {
4534                 cpu.rQ |= barrelLeftMaskTable[cnt];
4535               } else {
4536                 cpu.rQ &= BS_COMPL (barrelLeftMaskTable[cnt]);
4537               }
4538             }
4539             cpu.rQ &= DMASK;    // keep to 36-bits
4540 #else // !BARREL_SHIFTER
4541             cpu.rQ &= DMASK; // Make sure the shifted in bits are 0
4542             word36 tmp36 = cpu.TPR.CA & 0177;   // CY bits 11-17
4543             bool q0 = cpu.rQ & SIGN36;    // Q0
4544             for (uint j = 0 ; j < tmp36 ; j++)
4545               {
4546                 cpu.rQ >>= 1;               // shift right 1
4547                 if (q0)                 // propagate sign bit
4548                   cpu.rQ |= SIGN36;
4549               }
4550             cpu.rQ &= DMASK;    // keep to 36-bits
4551 #endif // BARREL_SHIFTER
4552 #if defined(TESTING)
4553             HDBGRegQW ("qrs");
4554 #endif
4555 
4556             SC_I_ZERO (cpu.rQ == 0);
4557             SC_I_NEG (cpu.rQ & SIGN36);
4558           }
4559           break;
4560 
4561         /// Fixed-Point Addition
4562 
4563         case x0 (0075):  // ada
4564           {
4565             // C(A) + C(Y) -> C(A)
4566             // Modifications: All
4567             //
4568             //  (Indicators not listed are not affected)
4569             //  ZERO: If C(A) = 0, then ON; otherwise OFF
4570             //  NEG: If C(A)0 = 1, then ON; otherwise OFF
4571             //  OVR: If range of A is exceeded, then ON
4572             //  CARRY: If a carry out of A0 is generated, then ON; otherwise OFF
4573 
4574             L68_ (cpu.ou.cycle |= ou_GOS;)
4575 #if defined(TESTING)
4576             HDBGRegAR ("ada");
4577 #endif
4578             bool ovf;
4579             cpu.rA = Add36b (cpup, cpu.rA, cpu.CY, 0, I_ZNOC, & cpu.cu.IR, & ovf);
4580 #if defined(TESTING)
4581             HDBGRegAW ("ada");
4582 #endif
4583             overflow (cpup, ovf, false, "ada overflow fault");
4584           }
4585           break;
4586 
4587         case x0 (0077):   // adaq
4588           {
4589             // C(AQ) + C(Y-pair) -> C(AQ)
4590             L68_ (cpu.ou.cycle |= ou_GOS;)
4591 #if defined(TESTING)
4592             HDBGRegAR ("adaq");
4593             HDBGRegQR ("adaq");
4594 #endif
4595             bool ovf;
4596             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
4597             tmp72        = Add72b (cpup, convert_to_word72 (cpu.rA, cpu.rQ),
4598                                    tmp72, 0, I_ZNOC, & cpu.cu.IR, & ovf);
4599             convert_to_word36 (tmp72, & cpu.rA, & cpu.rQ);
4600 #if defined(TESTING)
4601             HDBGRegAW ("adaq");
4602             HDBGRegQW ("adaq");
4603 #endif
4604             overflow (cpup, ovf, false, "adaq overflow fault");
4605           }
4606           break;
4607 
4608         case x0 (0033):   // adl
4609           {
4610             // C(AQ) + C(Y) sign extended -> C(AQ)
4611             L68_ (cpu.ou.cycle |= ou_GOS;)
4612 #if defined(TESTING)
4613             HDBGRegAR ("adl");
4614             HDBGRegQR ("adl");
4615 #endif
4616             bool ovf;
4617             word72 tmp72 = SIGNEXT36_72 (cpu.CY); // sign extend Cy
4618             tmp72        = Add72b (cpup, convert_to_word72 (cpu.rA, cpu.rQ),
4619                                    tmp72, 0, I_ZNOC, & cpu.cu.IR, & ovf);
4620             convert_to_word36 (tmp72, & cpu.rA, & cpu.rQ);
4621 #if defined(TESTING)
4622             HDBGRegAW ("adl");
4623             HDBGRegQW ("adl");
4624 #endif
4625             overflow (cpup, ovf, false, "adl overflow fault");
4626           }
4627           break;
4628 
4629         case x0 (0037):   // adlaq
4630           {
4631             // The adlaq instruction is identical to the adaq instruction with
4632             // the exception that the overflow indicator is not affected by the
4633             // adlaq instruction, nor does an overflow fault occur. Operands
4634             // and results are treated as unsigned, positive binary integers.
4635             L68_ (cpu.ou.cycle |= ou_GOS;)
4636 #if defined(TESTING)
4637             HDBGRegAR ("adlaq");
4638             HDBGRegQR ("adlaq");
4639 #endif
4640             bool ovf;
4641             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
4642 
4643             tmp72 = Add72b (cpup, convert_to_word72 (cpu.rA, cpu.rQ),
4644                             tmp72, 0, I_ZNC, & cpu.cu.IR, & ovf);
4645             convert_to_word36 (tmp72, & cpu.rA, & cpu.rQ);
4646 #if defined(TESTING)
4647             HDBGRegAW ("adlaq");
4648             HDBGRegQW ("adlaq");
4649 #endif
4650           }
4651           break;
4652 
4653         case x0 (0035):   // adla
4654           {
4655             L68_ (cpu.ou.cycle |= ou_GOS;)
4656             // The adla instruction is identical to the ada instruction with
4657             // the exception that the overflow indicator is not affected by the
4658             // adla instruction, nor does an overflow fault occur. Operands and
4659             // results are treated as unsigned, positive binary integers. */
4660 
4661 #if defined(TESTING)
4662             HDBGRegAR ("adla");
4663 #endif
4664             bool ovf;
4665             cpu.rA = Add36b (cpup, cpu.rA, cpu.CY, 0, I_ZNC, & cpu.cu.IR, & ovf);
4666 #if defined(TESTING)
4667             HDBGRegAW ("adla");
4668 #endif
4669           }
4670           break;
4671 
4672         case x0 (0036):   // adlq
4673           {
4674             // The adlq instruction is identical to the adq instruction with
4675             // the exception that the overflow indicator is not affected by the
4676             // adlq instruction, nor does an overflow fault occur. Operands and
4677             // results are treated as unsigned, positive binary integers. */
4678 
4679             L68_ (cpu.ou.cycle |= ou_GOS;)
4680 #if defined(TESTING)
4681             HDBGRegQR ("adlq");
4682 #endif
4683             bool ovf;
4684             cpu.rQ = Add36b (cpup, cpu.rQ, cpu.CY, 0, I_ZNC, & cpu.cu.IR, & ovf);
4685 #if defined(TESTING)
4686             HDBGRegQW ("adlq");
4687 #endif
4688           }
4689           break;
4690 
4691                           // adlxn
4692         case x0 (0020):   // adlx0
4693         case x0 (0021):   // adlx1
4694         case x0 (0022):   // adlx2
4695         case x0 (0023):   // adlx3
4696         case x0 (0024):   // adlx4
4697         case x0 (0025):   // adlx5
4698         case x0 (0026):   // adlx6
4699         case x0 (0027):   // adlx7
4700           {
4701             L68_ (cpu.ou.cycle |= ou_GOS;)
4702             uint32 n = opcode10 & 07;  // get n
4703 #if defined(TESTING)
4704             HDBGRegXR (n, "adlxn");
4705 #endif
4706             bool ovf;
4707             cpu.rX[n] = Add18b (cpup, cpu.rX[n], GETHI (cpu.CY), 0, I_ZNC,
4708                              & cpu.cu.IR, & ovf);
4709 #if defined(TESTING)
4710             HDBGRegXW (n, "adlxn");
4711 #endif
4712           }
4713           break;
4714 
4715 // Optimized to the top of the loop
4716 //        case x0 (0076):   // adq
4717 
4718                           // adxn
4719         case x0 (0060):   // adx0
4720         case x0 (0061):   // adx1
4721         case x0 (0062):   // adx2
4722         case x0 (0063):   // adx3
4723         case x0 (0064):   // adx4
4724         case x0 (0065):   // adx5
4725         case x0 (0066):   // adx6
4726         case x0 (0067):   // adx7
4727           {
4728             L68_ (cpu.ou.cycle |= ou_GOS;)
4729             uint32 n = opcode10 & 07;  // get n
4730 #if defined(TESTING)
4731             HDBGRegXR (n, "adxn");
4732 #endif
4733             bool ovf;
4734             cpu.rX[n] = Add18b (cpup, cpu.rX[n], GETHI (cpu.CY), 0,
4735                                  I_ZNOC,
4736                                  & cpu.cu.IR, & ovf);
4737 #if defined(TESTING)
4738             HDBGRegXW (n, "adxn");
4739 #endif
4740             overflow (cpup, ovf, false, "adxn overflow fault");
4741           }
4742           break;
4743 
4744 // Optimized to the top of the loop
4745 //        case x0 (0054):   // aos
4746 
4747         case x0 (0055):   // asa
4748           {
4749             // C(A) + C(Y) -> C(Y)
4750 
4751             L68_ (cpu.ou.cycle |= ou_GOS;)
4752 #if defined(TESTING)
4753             HDBGRegAR ("asa");
4754 #endif
4755             bool ovf;
4756             cpu.CY = Add36b (cpup, cpu.rA, cpu.CY, 0, I_ZNOC,
4757                              & cpu.cu.IR, & ovf);
4758             overflow (cpup, ovf, true, "asa overflow fault");
4759           }
4760           break;
4761 
4762         case x0 (0056):   // asq
4763           {
4764             // C(Q) + C(Y) -> C(Y)
4765             L68_ (cpu.ou.cycle |= ou_GOS;)
4766 #if defined(TESTING)
4767             HDBGRegQR ("asa");
4768 #endif
4769             bool ovf;
4770             cpu.CY = Add36b (cpup, cpu.rQ, cpu.CY, 0, I_ZNOC, & cpu.cu.IR, & ovf);
4771             overflow (cpup, ovf, true, "asq overflow fault");
4772           }
4773           break;
4774 
4775                           // asxn
4776         case x0 (0040):   // asx0
4777         case x0 (0041):   // asx1
4778         case x0 (0042):   // asx2
4779         case x0 (0043):   // asx3
4780         case x0 (0044):   // asx4
4781         case x0 (0045):   // asx5
4782         case x0 (0046):   // asx6
4783         case x0 (0047):   // asx7
4784           {
4785             // For n = 0, 1, ..., or 7 as determined by operation code
4786             //    C(Xn) + C(Y)0,17 -> C(Y)0,17
4787             L68_ (cpu.ou.cycle |= ou_GOS;)
4788             uint32 n = opcode10 & 07;  // get n
4789 #if defined(TESTING)
4790             HDBGRegXR (n, "asxn");
4791 #endif
4792             bool ovf;
4793             word18 tmp18 = Add18b (cpup, cpu.rX[n], GETHI (cpu.CY), 0,
4794                                    I_ZNOC, & cpu.cu.IR, & ovf);
4795             SETHI (cpu.CY, tmp18);
4796             overflow (cpup, ovf, true, "asxn overflow fault");
4797           }
4798           break;
4799 
4800         case x0 (0071):   // awca
4801           {
4802             // If carry indicator OFF, then C(A) + C(Y) -> C(A)
4803             // If carry indicator ON, then C(A) + C(Y) + 1 -> C(A)
4804 
4805             L68_ (cpu.ou.cycle |= ou_GOS;)
4806 #if defined(TESTING)
4807             HDBGRegAR ("awca");
4808 #endif
4809             bool ovf;
4810             cpu.rA = Add36b (cpup, cpu.rA, cpu.CY, TST_I_CARRY ? 1 : 0,
4811                                  I_ZNOC, & cpu.cu.IR, & ovf);
4812 #if defined(TESTING)
4813             HDBGRegAW ("awca");
4814 #endif
4815             overflow (cpup, ovf, false, "awca overflow fault");
4816           }
4817           break;
4818 
4819         case x0 (0072):   // awcq
4820           {
4821             // If carry indicator OFF, then C(Q) + C(Y) -> C(Q)
4822             // If carry indicator ON, then C(Q) + C(Y) + 1 -> C(Q)
4823 
4824             L68_ (cpu.ou.cycle |= ou_GOS;)
4825 #if defined(TESTING)
4826             HDBGRegQR ("awcq");
4827 #endif
4828             bool ovf;
4829             cpu.rQ = Add36b (cpup, cpu.rQ, cpu.CY, TST_I_CARRY ? 1 : 0,
4830                              I_ZNOC, & cpu.cu.IR, & ovf);
4831 #if defined(TESTING)
4832             HDBGRegQW ("awcq");
4833 #endif
4834             overflow (cpup, ovf, false, "awcq overflow fault");
4835           }
4836           break;
4837 
4838         /// Fixed-Point Subtraction
4839 
4840         case x0 (0175):  // sba
4841           {
4842             // C(A) - C(Y) -> C(A)
4843 
4844             L68_ (cpu.ou.cycle |= ou_GOS;)
4845 #if defined(TESTING)
4846             HDBGRegAR ("sba");
4847 #endif
4848             bool ovf;
4849             cpu.rA = Sub36b (cpup, cpu.rA, cpu.CY, 1, I_ZNOC, & cpu.cu.IR, & ovf);
4850 #if defined(TESTING)
4851             HDBGRegAW ("sba");
4852 #endif
4853             overflow (cpup, ovf, false, "sba overflow fault");
4854           }
4855           break;
4856 
4857         case x0 (0177):  // sbaq
4858           {
4859             // C(AQ) - C(Y-pair) -> C(AQ)
4860             L68_ (cpu.ou.cycle |= ou_GOS;)
4861 #if defined(TESTING)
4862             HDBGRegAR ("sbaq");
4863             HDBGRegQR ("sbaq");
4864 #endif
4865             bool ovf;
4866             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
4867             tmp72 = Sub72b (cpup, convert_to_word72 (cpu.rA, cpu.rQ), tmp72, 1,
4868                             I_ZNOC, & cpu.cu.IR,
4869                             & ovf);
4870             convert_to_word36 (tmp72, & cpu.rA, & cpu.rQ);
4871 #if defined(TESTING)
4872             HDBGRegAW ("sbaq");
4873             HDBGRegQW ("sbaq");
4874 #endif
4875             overflow (cpup, ovf, false, "sbaq overflow fault");
4876           }
4877           break;
4878 
4879         case x0 (0135):  // sbla
4880           {
4881             // C(A) - C(Y) -> C(A) logical
4882 
4883             L68_ (cpu.ou.cycle |= ou_GOS;)
4884 #if defined(TESTING)
4885             HDBGRegAR ("sbla");
4886 #endif
4887             bool ovf;
4888             cpu.rA = Sub36b (cpup, cpu.rA, cpu.CY, 1, I_ZNC, & cpu.cu.IR, & ovf);
4889 #if defined(TESTING)
4890             HDBGRegAW ("sbla");
4891 #endif
4892           }
4893           break;
4894 
4895         case x0 (0137):  // sblaq
4896           {
4897             // The sblaq instruction is identical to the sbaq instruction with
4898             // the exception that the overflow indicator is not affected by the
4899             // sblaq instruction, nor does an overflow fault occur. Operands
4900             // and results are treated as unsigned, positive binary integers.
4901             // C(AQ) - C(Y-pair) -> C(AQ)
4902 
4903             L68_ (cpu.ou.cycle |= ou_GOS;)
4904 #if defined(TESTING)
4905             HDBGRegAR ("sblaq");
4906             HDBGRegQR ("sblaq");
4907 #endif
4908             bool ovf;
4909             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
4910 
4911             tmp72 = Sub72b (cpup, convert_to_word72 (cpu.rA, cpu.rQ), tmp72, 1,
4912                             I_ZNC, & cpu.cu.IR, & ovf);
4913             convert_to_word36 (tmp72, & cpu.rA, & cpu.rQ);
4914 #if defined(TESTING)
4915             HDBGRegAW ("sblaq");
4916             HDBGRegQW ("sblaq");
4917 #endif
4918           }
4919           break;
4920 
4921         case x0 (0136):  // sblq
4922           {
4923             // C(Q) - C(Y) -> C(Q)
4924             L68_ (cpu.ou.cycle |= ou_GOS;)
4925 #if defined(TESTING)
4926             HDBGRegQR ("sblq");
4927 #endif
4928             bool ovf;
4929             cpu.rQ = Sub36b (cpup, cpu.rQ, cpu.CY, 1, I_ZNC, & cpu.cu.IR, & ovf);
4930 #if defined(TESTING)
4931             HDBGRegQW ("sblq");
4932 #endif
4933           }
4934           break;
4935 
4936                          // sblxn
4937         case x0 (0120):  // sblx0
4938         case x0 (0121):  // sblx1
4939         case x0 (0122):  // sblx2
4940         case x0 (0123):  // sblx3
4941         case x0 (0124):  // sblx4
4942         case x0 (0125):  // sblx5
4943         case x0 (0126):  // sblx6
4944         case x0 (0127):  // sblx7
4945           {
4946             // For n = 0, 1, ..., or 7 as determined by operation code
4947             // C(Xn) - C(Y)0,17 -> C(Xn)
4948 
4949             L68_ (cpu.ou.cycle |= ou_GOS;)
4950             uint32 n = opcode10 & 07;  // get n
4951 #if defined(TESTING)
4952             HDBGRegXR (n, "sblxn");
4953 #endif
4954             bool ovf;
4955             cpu.rX[n] = Sub18b (cpup, cpu.rX[n], GETHI (cpu.CY), 1,
4956                              I_ZNC, & cpu.cu.IR, & ovf);
4957 #if defined(TESTING)
4958             HDBGRegXW (n, "sblxn");
4959 #endif
4960           }
4961           break;
4962 
4963         case x0 (0176):  // sbq
4964           {
4965             // C(Q) - C(Y) -> C(Q)
4966             L68_ (cpu.ou.cycle |= ou_GOS;)
4967 #if defined(TESTING)
4968             HDBGRegQR ("sbq");
4969 #endif
4970             bool ovf;
4971             cpu.rQ = Sub36b (cpup, cpu.rQ, cpu.CY, 1, I_ZNOC, & cpu.cu.IR, & ovf);
4972 #if defined(TESTING)
4973             HDBGRegQW ("sbq");
4974 #endif
4975             overflow (cpup, ovf, false, "sbq overflow fault");
4976           }
4977           break;
4978 
4979                          // sbxn
4980         case x0 (0160):  // sbx0
4981         case x0 (0161):  // sbx1
4982         case x0 (0162):  // sbx2
4983         case x0 (0163):  // sbx3
4984         case x0 (0164):  // sbx4
4985         case x0 (0165):  // sbx5
4986         case x0 (0166):  // sbx6
4987         case x0 (0167):  // sbx7
4988           {
4989             // For n = 0, 1, ..., or 7 as determined by operation code
4990             // C(Xn) - C(Y)0,17 -> C(Xn)
4991 
4992             L68_ (cpu.ou.cycle |= ou_GOS;)
4993             uint32 n = opcode10 & 07;  // get n
4994 #if defined(TESTING)
4995             HDBGRegXR (n, "sbxn");
4996 #endif
4997             bool ovf;
4998             cpu.rX[n] = Sub18b (cpup, cpu.rX[n], GETHI (cpu.CY), 1,
4999                                  I_ZNOC, & cpu.cu.IR, & ovf);
5000 #if defined(TESTING)
5001             HDBGRegXW (n, "sbxn");
5002 #endif
5003             overflow (cpup, ovf, false, "sbxn overflow fault");
5004           }
5005           break;
5006 
5007         case x0 (0155):  // ssa
5008           {
5009             // C(A) - C(Y) -> C(Y)
5010 
5011             L68_ (cpu.ou.cycle |= ou_GOS;)
5012 #if defined(TESTING)
5013             HDBGRegAR ("ssa");
5014 #endif
5015             bool ovf;
5016             cpu.CY = Sub36b (cpup, cpu.rA, cpu.CY, 1, I_ZNOC, & cpu.cu.IR, & ovf);
5017             overflow (cpup, ovf, true, "ssa overflow fault");
5018           }
5019           break;
5020 
5021         case x0 (0156):  // ssq
5022           {
5023             // C(Q) - C(Y) -> C(Y)
5024 
5025             L68_ (cpu.ou.cycle |= ou_GOS;)
5026 #if defined(TESTING)
5027             HDBGRegQR ("ssq");
5028 #endif
5029             bool ovf;
5030             cpu.CY = Sub36b (cpup, cpu.rQ, cpu.CY, 1, I_ZNOC, & cpu.cu.IR, & ovf);
5031             overflow (cpup, ovf, true, "ssq overflow fault");
5032           }
5033           break;
5034 
5035                          // ssxn
5036         case x0 (0140):  // ssx0
5037         case x0 (0141):  // ssx1
5038         case x0 (0142):  // ssx2
5039         case x0 (0143):  // ssx3
5040         case x0 (0144):  // ssx4
5041         case x0 (0145):  // ssx5
5042         case x0 (0146):  // ssx6
5043         case x0 (0147):  // ssx7
5044           {
5045             // For uint32 n = 0, 1, ..., or 7 as determined by operation code
5046             // C(Xn) - C(Y)0,17 -> C(Y)0,17
5047 
5048             L68_ (cpu.ou.cycle |= ou_GOS;)
5049             uint32 n = opcode10 & 07;  // get n
5050 #if defined(TESTING)
5051             HDBGRegXR (n, "ssxn");
5052 #endif
5053             bool ovf;
5054             word18 tmp18 = Sub18b (cpup, cpu.rX[n], GETHI (cpu.CY), 1,
5055                                    I_ZNOC, & cpu.cu.IR, & ovf);
5056             SETHI (cpu.CY, tmp18);
5057             overflow (cpup, ovf, true, "ssxn overflow fault");
5058           }
5059           break;
5060 
5061         case x0 (0171):  // swca
5062           {
5063             // If carry indicator ON, then C(A)- C(Y) -> C(A)
5064             // If carry indicator OFF, then C(A) - C(Y) - 1 -> C(A)
5065 
5066             L68_ (cpu.ou.cycle |= ou_GOS;)
5067 #if defined(TESTING)
5068             HDBGRegAR ("swca");
5069 #endif
5070             bool ovf;
5071             cpu.rA = Sub36b (cpup, cpu.rA, cpu.CY, TST_I_CARRY ? 1 : 0,
5072                              I_ZNOC, & cpu.cu.IR, & ovf);
5073 #if defined(TESTING)
5074             HDBGRegAW ("swca");
5075 #endif
5076             overflow (cpup, ovf, false, "swca overflow fault");
5077           }
5078           break;
5079 
5080         case x0 (0172):  // swcq
5081           {
5082             // If carry indicator ON, then C(Q) - C(Y) -> C(Q)
5083             // If carry indicator OFF, then C(Q) - C(Y) - 1 -> C(Q)
5084 
5085             L68_ (cpu.ou.cycle |= ou_GOS;)
5086 #if defined(TESTING)
5087             HDBGRegQR ("swcq");
5088 #endif
5089             bool ovf;
5090             cpu.rQ = Sub36b (cpup, cpu.rQ, cpu.CY, TST_I_CARRY ? 1 : 0,
5091                                  I_ZNOC, & cpu.cu.IR, & ovf);
5092 #if defined(TESTING)
5093             HDBGRegQW ("swcq");
5094 #endif
5095             overflow (cpup, ovf, false, "swcq overflow fault");
5096           }
5097           break;
5098 
5099         /// Fixed-Point Multiplication
5100 
5101         case x0 (0401):  // mpf
5102           {
5103             // C(A) * C(Y) -> C(AQ), left adjusted
5104             //
5105             // Two 36-bit fractional factors (including sign) are multiplied
5106             // to form a 71- bit fractional product (including sign), which
5107             // is stored left-adjusted in the AQ register. AQ71 contains a
5108             // zero. Overflow can occur only in the case of A and Y
5109             // containing negative 1 and the result exceeding the range of
5110             // the AQ register.
5111 
5112             L68_ (cpu.ou.cycle |= ou_GD1;)
5113 #if defined(NEED_128)
5114 # if defined(TESTING)
5115             HDBGRegAR ("mpf");
5116             HDBGRegQR ("mpf");
5117 # endif
5118             word72 tmp72 = multiply_128 (SIGNEXT36_72 (cpu.rA), SIGNEXT36_72 (cpu.CY));
5119             tmp72        = and_128 (tmp72, MASK72);
5120             tmp72        = lshift_128 (tmp72, 1);
5121 #else
5122             // word72 tmp72 = SIGNEXT36_72 (cpu.rA) * SIGNEXT36_72 (cpu.CY);
5123             // ubsan
5124             word72 tmp72 = (word72) (((word72s) SIGNEXT36_72 (cpu.rA)) * ((word72s) SIGNEXT36_72 (cpu.CY)));
5125             tmp72 &= MASK72;
5126             tmp72 <<= 1;    // left adjust so AQ71 contains 0
5127 #endif
5128             L68_ (cpu.ou.cycle |= ou_GD2;)
5129             // Overflow can occur only in the case of A and Y containing
5130             // negative 1
5131             if (cpu.rA == MAXNEG && cpu.CY == MAXNEG)
5132               {
5133                 SET_I_NEG;
5134                 CLR_I_ZERO;
5135                 overflow (cpup, true, false, "mpf overflow fault");
5136               }
5137 
5138             convert_to_word36 (tmp72, &cpu.rA, &cpu.rQ);
5139 #if defined(TESTING)
5140             HDBGRegAW ("mpf");
5141             HDBGRegQW ("mpf");
5142 #endif
5143             SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
5144             SC_I_NEG (cpu.rA & SIGN36);
5145           }
5146           break;
5147 
5148         case x0 (0402):  // mpy
5149           // C(Q) * C(Y) -> C(AQ), right adjusted
5150 
5151           {
5152             L68_ (cpu.ou.cycle |= ou_GOS;)
5153 #if defined(NEED_128)
5154 # if defined(TESTING)
5155             HDBGRegQR ("mpy");
5156 # endif
5157             int128 prod = multiply_s128 (
5158               SIGNEXT36_128 (cpu.rQ & DMASK),
5159               SIGNEXT36_128 (cpu.CY & DMASK));
5160             convert_to_word36 (cast_128 (prod), &cpu.rA, &cpu.rQ);
5161 #else
5162             int64_t t0 = SIGNEXT36_64 (cpu.rQ & DMASK);
5163             int64_t t1 = SIGNEXT36_64 (cpu.CY & DMASK);
5164 
5165             __int128_t prod = (__int128_t) t0 * (__int128_t) t1;
5166 
5167             convert_to_word36 ((word72)prod, &cpu.rA, &cpu.rQ);
5168 #endif
5169 #if defined(TESTING)
5170             HDBGRegAW ("mpy");
5171             HDBGRegQW ("mpy");
5172 #endif
5173 
5174             SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
5175             SC_I_NEG (cpu.rA & SIGN36);
5176           }
5177           break;
5178 
5179 //#define DIV_TRACE
5180 
5181         /// Fixed-Point Division
5182 
5183         case x0 (0506):  // div
5184           // C(Q) / (Y) integer quotient -> C(Q), integer remainder -> C(A)
5185           //
5186           // A 36-bit integer dividend (including sign) is divided by a
5187           // 36-bit integer divisor (including sign) to form a 36-bit integer
5188           // * quotient (including sign) and a 36-bit integer remainder
5189           // * (including sign). The remainder sign is equal to the dividend
5190           // * sign unless the remainder is zero.
5191           // *
5192           // * If the dividend = -2**35 and the divisor = -1 or if the divisor
5193           // * = 0, then division does not take place. Instead, a divide check
5194           // * fault occurs, C(Q) contains the dividend magnitude, and the
5195           // * negative indicator reflects the dividend sign.
5196 
5197           L68_ (cpu.ou.cycle |= ou_GD1;)
5198           // RJ78: If the dividend = -2**35 and the divisor = +/-1, or if
5199           // the divisor is 0
5200 
5201 #if defined(TESTING)
5202           HDBGRegQR ("div");
5203 #endif
5204           if ((cpu.rQ == MAXNEG && (cpu.CY == 1 || cpu.CY == NEG136)) ||
5205               (cpu.CY == 0))
5206             {
5207 //sim_printf ("DIV Q %012"PRIo64" Y %012"PRIo64"\n", cpu.rQ, cpu.CY);
5208 // case 1  400000000000 000000000000 --> 000000000000
5209 // case 2  000000000000 000000000000 --> 400000000000
5210               //cpu.rA = 0;  // works for case 1
5211               cpu.rA = (cpu.rQ & SIGN36) ? 0 : SIGN36; // works for case 1,2
5212 #if defined(TESTING)
5213               HDBGRegAW ("div");
5214 #endif
5215 
5216               // no division takes place
5217               SC_I_ZERO (cpu.CY == 0);
5218               SC_I_NEG (cpu.rQ & SIGN36);
5219 
5220               if (cpu.rQ & SIGN36)
5221                 {
5222                   // cpu.rQ = (- cpu.rQ) & MASK36;
5223                   // ubsan
5224                   cpu.rQ = ((word36) (- (word36s) cpu.rQ)) & MASK36;
5225 #if defined(TESTING)
5226                   HDBGRegQW ("div");
5227 #endif
5228                 }
5229 
5230               dlyDoFault (FAULT_DIV,
5231                           fst_ill_op,
5232                           "div divide check");
5233             }
5234           else
5235             {
5236               t_int64 dividend = (t_int64) (SIGNEXT36_64 (cpu.rQ));
5237               t_int64 divisor  = (t_int64) (SIGNEXT36_64 (cpu.CY));
5238 #if defined(TESTING)
5239 # if defined(DIV_TRACE)
5240               sim_debug (DBG_CAC, & cpu_dev, "\n");
5241               sim_debug (DBG_CAC, & cpu_dev,
5242                          ">>> dividend cpu.rQ %"PRId64" (%012"PRIo64")\n",
5243                          dividend, cpu.rQ);
5244               sim_debug (DBG_CAC, & cpu_dev,
5245                          ">>> divisor  CY %"PRId64" (%012"PRIo64")\n",
5246                          divisor, cpu.CY);
5247 # endif
5248 #endif
5249 
5250               t_int64 quotient = dividend / divisor;
5251               L68_ (cpu.ou.cycle |= ou_GD2;)
5252               t_int64 remainder = dividend % divisor;
5253 #if defined(TESTING)
5254 # if defined(DIV_TRACE)
5255               sim_debug (DBG_CAC, & cpu_dev, ">>> quot 1 %"PRId64"\n", quotient);
5256               sim_debug (DBG_CAC, & cpu_dev, ">>> rem 1 %"PRId64"\n", remainder);
5257 # endif
5258 #endif
5259 
5260 // Evidence is that DPS8M rounds toward zero; if it turns out that it
5261 // rounds toward -inf, try this code:
5262 
5263 
5264 
5265 
5266 
5267 
5268 
5269 
5270 
5271 
5272 
5273 
5274 
5275 
5276 
5277 
5278 
5279 #if defined(TESTING)
5280 # if defined(DIV_TRACE)
5281               //  (a/b)*b + a%b is equal to a.
5282               sim_debug (DBG_CAC, & cpu_dev,
5283                          "dividend was                   = %"PRId64"\n", dividend);
5284               sim_debug (DBG_CAC, & cpu_dev,
5285                          "quotient * divisor + remainder = %"PRId64"\n",
5286                          quotient * divisor + remainder);
5287               if (dividend != quotient * divisor + remainder)
5288                 {
5289                   sim_debug (DBG_CAC, & cpu_dev,
5290                      "---------------------------------^^^^^^^^^^^^^^^\n");
5291                 }
5292 # endif
5293 #endif
5294 
5295               if (dividend != quotient * divisor + remainder)
5296                 {
5297                   sim_debug (DBG_ERR, & cpu_dev,
5298                              "Internal division error;"
5299                              " rQ %012"PRIo64" CY %012"PRIo64"\n", cpu.rQ, cpu.CY);
5300                 }
5301 
5302               cpu.rA = (word36) remainder & DMASK;
5303               cpu.rQ = (word36) quotient & DMASK;
5304 #if defined(TESTING)
5305               HDBGRegAW ("div");
5306               HDBGRegQW ("div");
5307 
5308 # if defined(DIV_TRACE)
5309               sim_debug (DBG_CAC, & cpu_dev, "rA (rem)  %012"PRIo64"\n", cpu.rA);
5310               sim_debug (DBG_CAC, & cpu_dev, "rQ (quot) %012"PRIo64"\n", cpu.rQ);
5311 # endif
5312 #endif
5313 
5314               SC_I_ZERO (cpu.rQ == 0);
5315               SC_I_NEG (cpu.rQ & SIGN36);
5316             }
5317 
5318           break;
5319 
5320         case x0 (0507):  // dvf
5321           // C(AQ) / (Y)
5322           //  fractional quotient -> C(A)
5323           //  fractional remainder -> C(Q)
5324 
5325           // A 71-bit fractional dividend (including sign) is divided by a
5326           // 36-bit fractional divisor yielding a 36-bit fractional quotient
5327           // (including sign) and a 36-bit fractional remainder (including
5328           // sign). C(AQ)71 is ignored; bit position 35 of the remainder
5329           // corresponds to bit position 70 of the dividend. The remainder
5330           // sign is equal to the dividend sign unless the remainder is zero.
5331 
5332           // If | dividend | >= | divisor | or if the divisor = 0, division
5333           // does not take place. Instead, a divide check fault occurs, C(AQ)
5334           // contains the dividend magnitude in absolute, and the negative
5335           // indicator reflects the dividend sign.
5336 
5337           dvf (cpup);
5338 
5339           break;
5340 
5341         /// Fixed-Point Negate
5342 
5343         case x0 (0531):  // neg
5344           // -C(A) -> C(A) if C(A) != 0
5345 
5346 #if defined(TESTING)
5347           HDBGRegAR ("neg");
5348 #endif
5349           cpu.rA &= DMASK;
5350           if (cpu.rA == 0400000000000ULL)
5351             {
5352               CLR_I_ZERO;
5353               SET_I_NEG;
5354               overflow (cpup, true, false, "neg overflow fault");
5355             }
5356 
5357           //cpu.rA = -cpu.rA;
5358           // ubsan
5359           cpu.rA = (word36) (- (word36s) cpu.rA);
5360 
5361           cpu.rA &= DMASK;    // keep to 36-bits
5362 #if defined(TESTING)
5363           HDBGRegAW ("neg");
5364 #endif
5365 
5366           SC_I_ZERO (cpu.rA == 0);
5367           SC_I_NEG (cpu.rA & SIGN36);
5368 
5369           break;
5370 
5371         case x0 (0533):  // negl
5372           // -C(AQ) -> C(AQ) if C(AQ) != 0
5373           {
5374 #if defined(TESTING)
5375             HDBGRegAR ("negl");
5376             HDBGRegQR ("negl");
5377 #endif
5378             cpu.rA &= DMASK;
5379             cpu.rQ &= DMASK;
5380 
5381             if (cpu.rA == 0400000000000ULL && cpu.rQ == 0)
5382             {
5383                 CLR_I_ZERO;
5384                 SET_I_NEG;
5385                 overflow (cpup, true, false, "negl overflow fault");
5386             }
5387 
5388             word72 tmp72 = convert_to_word72 (cpu.rA, cpu.rQ);
5389 #if defined(NEED_128)
5390             tmp72 = negate_128 (tmp72);
5391 
5392             SC_I_ZERO (iszero_128 (tmp72));
5393             SC_I_NEG (isnonzero_128 (and_128 (tmp72, SIGN72)));
5394 #else
5395             //tmp72 = -tmp72;
5396             // ubsan
5397             tmp72 = (word72) (-(word72s) tmp72);
5398 
5399             SC_I_ZERO (tmp72 == 0);
5400             SC_I_NEG (tmp72 & SIGN72);
5401 #endif
5402 
5403             convert_to_word36 (tmp72, &cpu.rA, &cpu.rQ);
5404 #if defined(TESTING)
5405             HDBGRegAW ("negl");
5406             HDBGRegQW ("negl");
5407 #endif
5408           }
5409           break;
5410 
5411         /// Fixed-Point Comparison
5412 
5413         case x0 (0405):  // cmg
5414           // | C(A) | :: | C(Y) |
5415           // Zero:     If | C(A) | = | C(Y) | , then ON; otherwise OFF
5416           // Negative: If | C(A) | < | C(Y) | , then ON; otherwise OFF
5417           {
5418             // This is wrong for MAXNEG
5419             //word36 a = cpu.rA & SIGN36 ? -cpu.rA : cpu.rA;
5420             //word36 y = cpu.CY & SIGN36 ? -cpu.CY : cpu.CY;
5421 
5422               // If we do the 64 math, the MAXNEG case works
5423 #if defined(TESTING)
5424               HDBGRegAR ("cmg");
5425 #endif
5426               t_int64 a = SIGNEXT36_64 (cpu.rA);
5427               if (a < 0)
5428                 a = -a;
5429               t_int64 y = SIGNEXT36_64 (cpu.CY);
5430               if (y < 0)
5431                 y = -y;
5432 
5433               SC_I_ZERO (a == y);
5434               SC_I_NEG (a < y);
5435           }
5436           break;
5437 
5438         case x0 (0211):  // cmk
5439           // For i = 0, 1, ..., 35
5440           // C(Z)i = ~C(Q)i & ( C(A)i XOR C(Y)i )
5441 
5442           /*
5443            * The cmk instruction compares the contents of bit positions of A
5444            * and Y for identity that are not masked by a 1 in the
5445            * corresponding bit position of Q.
5446            *
5447            * The zero indicator is set ON if the comparison is successful for
5448            * all bit positions; i.e., if for all i = 0, 1, ..., 35 there is
5449            * either: C(A)i = C(Y)i (the identical case) or C(Q)i = 1 (the
5450            * masked case); otherwise, the zero indicator is set OFF.
5451            *
5452            * The negative indicator is set ON if the comparison is
5453            * unsuccessful for bit position 0; i.e., if C(A)0 XOR C(Y)0 (they
5454            * are nonidentical) as well as C(Q)0 = 0 (they are unmasked);
5455            * otherwise, the negative indicator is set OFF.
5456            */
5457           {
5458 #if defined(TESTING)
5459             HDBGRegAR ("cmk");
5460             HDBGRegQR ("cmk");
5461             HDBGRegYR ("cmk");
5462 #endif
5463             word36 Z = ~cpu.rQ & (cpu.rA ^ cpu.CY);
5464             Z &= DMASK;
5465 #if defined(TESTING)
5466             HDBGRegZW (Z, "cmk");
5467             HDBGRegIR ("cmk");
5468 #endif
5469 
5470 // Q  A  Y   ~Q   A^Y   Z
5471 // 0  0  0    1     0   0
5472 // 0  0  1    1     1   1
5473 // 0  1  0    1     1   1
5474 // 0  1  1    1     0   0
5475 // 1  0  0    0     0   0
5476 // 1  0  1    0     1   0
5477 // 1  1  0    0     1   0
5478 // 1  1  1    0     0   0
5479 
5480             SC_I_ZERO (Z == 0);
5481             SC_I_NEG (Z & SIGN36);
5482           }
5483           break;
5484 
5485 // Optimized to the top of the loop
5486 //        case x0 (0115):  // cmpa
5487 
5488         case x0 (0117):  // cmpaq
5489           // C(AQ) :: C(Y-pair)
5490           {
5491 #if defined(TESTING)
5492             HDBGRegAR ("cmpaq");
5493             HDBGRegQR ("cmpaq");
5494 #endif
5495             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
5496             word72 trAQ = convert_to_word72 (cpu.rA, cpu.rQ);
5497 #if defined(NEED_128)
5498             trAQ = and_128 (trAQ, MASK72);
5499 #else
5500             trAQ &= MASK72;
5501 #endif
5502             cmp72 (cpup, trAQ, tmp72, &cpu.cu.IR);
5503           }
5504           break;
5505 
5506 // Optimized to the top of the loop
5507 //         case x0 (0116):  // cmpq
5508 
5509                          // cmpxn
5510         case x0 (0100):  // cmpx0
5511         case x0 (0101):  // cmpx1
5512         case x0 (0102):  // cmpx2
5513         case x0 (0103):  // cmpx3
5514         case x0 (0104):  // cmpx4
5515         case x0 (0105):  // cmpx5
5516         case x0 (0106):  // cmpx6
5517         case x0 (0107):  // cmpx7
5518           // For n = 0, 1, ..., or 7 as determined by operation code
5519           // C(Xn) :: C(Y)0,17
5520           {
5521             uint32 n = opcode10 & 07;  // get n
5522 #if defined(TESTING)
5523             HDBGRegXR (n, "cmpxn");
5524 #endif
5525             cmp18 (cpup, cpu.rX[n], GETHI (cpu.CY), &cpu.cu.IR);
5526           }
5527           break;
5528 
5529         case x0 (0111):  // cwl
5530           // C(Y) :: closed interval [C(A);C(Q)]
5531           /*
5532            * The cwl instruction tests the value of C(Y) to determine if it
5533            * is within the range of values set by C(A) and C(Q). The
5534            * comparison of C(Y) with C(Q) locates C(Y) with respect to the
5535            * interval if C(Y) is not contained within the interval.
5536            */
5537 #if defined(TESTING)
5538           HDBGRegAR ("cwl");
5539           HDBGRegQR ("cwl");
5540 #endif
5541           cmp36wl (cpup, cpu.rA, cpu.CY, cpu.rQ, &cpu.cu.IR);
5542           break;
5543 
5544         /// Fixed-Point Miscellaneous
5545 
5546         case x0 (0234):  // szn
5547           // Set indicators according to C(Y)
5548           cpu.CY &= DMASK;
5549           SC_I_ZERO (cpu.CY == 0);
5550           SC_I_NEG (cpu.CY & SIGN36);
5551           break;
5552 
5553         case x0 (0214):  // sznc
5554           // Set indicators according to C(Y)
5555           cpu.CY &= DMASK;
5556           SC_I_ZERO (cpu.CY == 0);
5557           SC_I_NEG (cpu.CY & SIGN36);
5558           // ... and clear
5559           cpu.CY = 0;
5560           break;
5561 
5562         /// BOOLEAN OPERATION INSTRUCTIONS
5563 
5564         /// Boolean And
5565 
5566 // Optimized to the top of the loop
5567 //        case x0 (0375):  // ana
5568 
5569 // Optimized to the top of the loop
5570 //        case x0 (0377):  //< anaq
5571 
5572         case x0 (0376):  // anq
5573           // C(Q)i & C(Y)i -> C(Q)i for i = (0, 1, ..., 35)
5574 #if defined(TESTING)
5575           HDBGRegQR ("anq");
5576 #endif
5577           cpu.rQ  = cpu.rQ & cpu.CY;
5578           cpu.rQ &= DMASK;
5579 #if defined(TESTING)
5580           HDBGRegQW ("anq");
5581 #endif
5582 
5583           SC_I_ZERO (cpu.rQ == 0);
5584           SC_I_NEG (cpu.rQ & SIGN36);
5585           break;
5586 
5587         case x0 (0355):  // ansa
5588           // C(A)i & C(Y)i -> C(Y)i for i = (0, 1, ..., 35)
5589           {
5590 #if defined(TESTING)
5591             HDBGRegAR ("ansa");
5592 #endif
5593             cpu.CY  = cpu.rA & cpu.CY;
5594             cpu.CY &= DMASK;
5595 
5596             SC_I_ZERO (cpu.CY == 0);
5597             SC_I_NEG (cpu.CY & SIGN36);
5598           }
5599           break;
5600 
5601         case x0 (0356):  // ansq
5602           // C(Q)i & C(Y)i -> C(Y)i for i = (0, 1, ..., 35)
5603           {
5604 #if defined(TESTING)
5605             HDBGRegQR ("ansq");
5606 #endif
5607             cpu.CY  = cpu.rQ & cpu.CY;
5608             cpu.CY &= DMASK;
5609 
5610             SC_I_ZERO (cpu.CY == 0);
5611             SC_I_NEG (cpu.CY & SIGN36);
5612           }
5613           break;
5614 
5615                          // ansxn
5616         case x0 (0340):  // ansx0
5617         case x0 (0341):  // ansx1
5618         case x0 (0342):  // ansx2
5619         case x0 (0343):  // ansx3
5620         case x0 (0344):  // ansx4
5621         case x0 (0345):  // ansx5
5622         case x0 (0346):  // ansx6
5623         case x0 (0347):  // ansx7
5624           // For n = 0, 1, ..., or 7 as determined by operation code
5625           // C(Xn)i & C(Y)i -> C(Y)i for i = (0, 1, ..., 17)
5626           {
5627             uint32 n = opcode10 & 07;  // get n
5628 #if defined(TESTING)
5629             HDBGRegXR (n, "ansxn");
5630 #endif
5631             word18 tmp18 = cpu.rX[n] & GETHI (cpu.CY);
5632             tmp18 &= MASK18;
5633 
5634             SC_I_ZERO (tmp18 == 0);
5635             SC_I_NEG (tmp18 & SIGN18);
5636 
5637             SETHI (cpu.CY, tmp18);
5638           }
5639 
5640           break;
5641 
5642                          // anxn
5643         case x0 (0360):  // anx0
5644         case x0 (0361):  // anx1
5645         case x0 (0362):  // anx2
5646         case x0 (0363):  // anx3
5647         case x0 (0364):  // anx4
5648         case x0 (0365):  // anx5
5649         case x0 (0366):  // anx6
5650         case x0 (0367):  // anx7
5651           // For n = 0, 1, ..., or 7 as determined by operation code
5652           // C(Xn)i & C(Y)i -> C(Xn)i for i = (0, 1, ..., 17)
5653           {
5654               uint32 n = opcode10 & 07;  // get n
5655 #if defined(TESTING)
5656               HDBGRegXR (n, "anxn");
5657 #endif
5658               cpu.rX[n] &= GETHI (cpu.CY);
5659               cpu.rX[n] &= MASK18;
5660 #if defined(TESTING)
5661               HDBGRegXW (n, "anxn");
5662 #endif
5663 
5664               SC_I_ZERO (cpu.rX[n] == 0);
5665               SC_I_NEG (cpu.rX[n] & SIGN18);
5666           }
5667           break;
5668 
5669         /// Boolean Or
5670 
5671 // Optimized to the top of the loop
5672 //        case x0 (0275):  // ora
5673 
5674         case x0 (0277):  // oraq
5675           // C(AQ)i | C(Y-pair)i -> C(AQ)i for i = (0, 1, ..., 71)
5676           {
5677 #if defined(TESTING)
5678               HDBGRegAR ("oraq");
5679               HDBGRegQR ("oraq");
5680 #endif
5681               word72 tmp72 = YPAIRTO72 (cpu.Ypair);
5682               word72 trAQ  = convert_to_word72 (cpu.rA, cpu.rQ);
5683 #if defined(NEED_128)
5684               trAQ = or_128 (trAQ, tmp72);
5685               trAQ = and_128 (trAQ, MASK72);
5686 
5687               SC_I_ZERO (iszero_128 (trAQ));
5688               SC_I_NEG (isnonzero_128 (and_128 (trAQ, SIGN72)));
5689 #else
5690               trAQ  = trAQ | tmp72;
5691               trAQ &= MASK72;
5692 
5693               SC_I_ZERO (trAQ == 0);
5694               SC_I_NEG (trAQ & SIGN72);
5695 #endif
5696               convert_to_word36 (trAQ, &cpu.rA, &cpu.rQ);
5697 #if defined(TESTING)
5698               HDBGRegAW ("oraq");
5699               HDBGRegQW ("oraq");
5700 #endif
5701           }
5702           break;
5703 
5704         case x0 (0276):  // orq
5705           // C(Q)i | C(Y)i -> C(Q)i for i = (0, 1, ..., 35)
5706 #if defined(TESTING)
5707           HDBGRegQR ("orq");
5708 #endif
5709           cpu.rQ  = cpu.rQ | cpu.CY;
5710           cpu.rQ &= DMASK;
5711 #if defined(TESTING)
5712           HDBGRegQW ("orq");
5713 #endif
5714 
5715           SC_I_ZERO (cpu.rQ == 0);
5716           SC_I_NEG (cpu.rQ & SIGN36);
5717 
5718           break;
5719 
5720         case x0 (0255):  // orsa
5721           // C(A)i | C(Y)i -> C(Y)i for i = (0, 1, ..., 35)
5722 #if defined(TESTING)
5723           HDBGRegAR ("orsa");
5724 #endif
5725           cpu.CY  = cpu.rA | cpu.CY;
5726           cpu.CY &= DMASK;
5727 
5728           SC_I_ZERO (cpu.CY == 0);
5729           SC_I_NEG (cpu.CY & SIGN36);
5730           break;
5731 
5732         case x0 (0256):  // orsq
5733           // C(Q)i | C(Y)i -> C(Y)i for i = (0, 1, ..., 35)
5734 #if defined(TESTING)
5735           HDBGRegQR ("orsq");
5736 #endif
5737           cpu.CY  = cpu.rQ | cpu.CY;
5738           cpu.CY &= DMASK;
5739 
5740           SC_I_ZERO (cpu.CY == 0);
5741           SC_I_NEG (cpu.CY & SIGN36);
5742           break;
5743 
5744                          // orsxn
5745         case x0 (0240):  // orsx0
5746         case x0 (0241):  // orsx1
5747         case x0 (0242):  // orsx2
5748         case x0 (0243):  // orsx3
5749         case x0 (0244):  // orsx4
5750         case x0 (0245):  // orsx5
5751         case x0 (0246):  // orsx6
5752         case x0 (0247):  // orsx7
5753           // For n = 0, 1, ..., or 7 as determined by operation code
5754           // C(Xn)i | C(Y)i -> C(Y)i for i = (0, 1, ..., 17)
5755           {
5756             uint32 n = opcode10 & 07;  // get n
5757 
5758             word18 tmp18  = cpu.rX[n] | GETHI (cpu.CY);
5759             tmp18        &= MASK18;
5760 
5761             SC_I_ZERO (tmp18 == 0);
5762             SC_I_NEG (tmp18 & SIGN18);
5763 
5764             SETHI (cpu.CY, tmp18);
5765           }
5766           break;
5767 
5768                          // orxn
5769         case x0 (0260):  // orx0
5770         case x0 (0261):  // orx1
5771         case x0 (0262):  // orx2
5772         case x0 (0263):  // orx3
5773         case x0 (0264):  // orx4
5774         case x0 (0265):  // orx5
5775         case x0 (0266):  // orx6
5776         case x0 (0267):  // orx7
5777           // For n = 0, 1, ..., or 7 as determined by operation code
5778           // C(Xn)i | C(Y)i -> C(Xn)i for i = (0, 1, ..., 17)
5779           {
5780               uint32 n = opcode10 & 07;  // get n
5781 #if defined(TESTING)
5782               HDBGRegXR (n, "orxn");
5783 #endif
5784               cpu.rX[n] |= GETHI (cpu.CY);
5785               cpu.rX[n] &= MASK18;
5786 #if defined(TESTING)
5787               HDBGRegXW (n, "orxn");
5788 #endif
5789 
5790               SC_I_ZERO (cpu.rX[n] == 0);
5791               SC_I_NEG (cpu.rX[n] & SIGN18);
5792           }
5793           break;
5794 
5795         /// Boolean Exclusive Or
5796 
5797         case x0 (0675):  // era
5798           // C(A)i XOR C(Y)i -> C(A)i for i = (0, 1, ..., 35)
5799 #if defined(TESTING)
5800           HDBGRegAR ("era");
5801 #endif
5802           cpu.rA  = cpu.rA ^ cpu.CY;
5803           cpu.rA &= DMASK;
5804 #if defined(TESTING)
5805           HDBGRegAW ("era");
5806 #endif
5807 
5808           SC_I_ZERO (cpu.rA == 0);
5809           SC_I_NEG (cpu.rA & SIGN36);
5810 
5811           break;
5812 
5813 // Optimized to the top of the loop
5814 //        case x0 (0677):  // eraq
5815 
5816         case x0 (0676):  // erq
5817           // C(Q)i XOR C(Y)i -> C(Q)i for i = (0, 1, ..., 35)
5818 #if defined(TESTING)
5819           HDBGRegQR ("eraq");
5820 #endif
5821           cpu.rQ  = cpu.rQ ^ cpu.CY;
5822           cpu.rQ &= DMASK;
5823 #if defined(TESTING)
5824           HDBGRegQW ("eraq");
5825 #endif
5826           SC_I_ZERO (cpu.rQ == 0);
5827           SC_I_NEG (cpu.rQ & SIGN36);
5828           break;
5829 
5830         case x0 (0655):  // ersa
5831           // C(A)i XOR C(Y)i -> C(Y)i for i = (0, 1, ..., 35)
5832 #if defined(TESTING)
5833           HDBGRegAR ("ersa");
5834 #endif
5835           cpu.CY  = cpu.rA ^ cpu.CY;
5836           cpu.CY &= DMASK;
5837 
5838           SC_I_ZERO (cpu.CY == 0);
5839           SC_I_NEG (cpu.CY & SIGN36);
5840           break;
5841 
5842         case x0 (0656):  // ersq
5843           // C(Q)i XOR C(Y)i -> C(Y)i for i = (0, 1, ..., 35)
5844 #if defined(TESTING)
5845           HDBGRegQR ("ersq");
5846 #endif
5847           cpu.CY  = cpu.rQ ^ cpu.CY;
5848           cpu.CY &= DMASK;
5849 
5850           SC_I_ZERO (cpu.CY == 0);
5851           SC_I_NEG (cpu.CY & SIGN36);
5852 
5853           break;
5854 
5855                           // ersxn
5856         case x0 (0640):   // ersx0
5857         case x0 (0641):   // ersx1
5858         case x0 (0642):   // ersx2
5859         case x0 (0643):   // ersx3
5860         case x0 (0644):   // ersx4
5861         case x0 (0645):   // ersx5
5862         case x0 (0646):   // ersx6
5863         case x0 (0647):   // ersx7
5864           // For n = 0, 1, ..., or 7 as determined by operation code
5865           // C(Xn)i XOR C(Y)i -> C(Y)i for i = (0, 1, ..., 17)
5866           {
5867             uint32 n = opcode10 & 07;  // get n
5868 #if defined(TESTING)
5869             HDBGRegXR (n, "ersxn");
5870 #endif
5871 
5872             word18 tmp18  = cpu.rX[n] ^ GETHI (cpu.CY);
5873             tmp18        &= MASK18;
5874 
5875             SC_I_ZERO (tmp18 == 0);
5876             SC_I_NEG (tmp18 & SIGN18);
5877 
5878             SETHI (cpu.CY, tmp18);
5879           }
5880           break;
5881 
5882                          // erxn
5883         case x0 (0660):  // erx0
5884         case x0 (0661):  // erx1
5885         case x0 (0662):  // erx2
5886         case x0 (0663):  // erx3
5887         case x0 (0664):  // erx4
5888         case x0 (0665):  // erx5
5889         case x0 (0666):  // erx6  !!!! Beware !!!!
5890         case x0 (0667):  // erx7
5891           // For n = 0, 1, ..., or 7 as determined by operation code
5892           // C(Xn)i XOR C(Y)i -> C(Xn)i for i = (0, 1, ..., 17)
5893           {
5894             uint32 n = opcode10 & 07;  // get n
5895 #if defined(TESTING)
5896             HDBGRegXR (n, "erxn");
5897 #endif
5898             cpu.rX[n] ^= GETHI (cpu.CY);
5899             cpu.rX[n] &= MASK18;
5900 #if defined(TESTING)
5901             HDBGRegXW (n, "erxn");
5902 #endif
5903 
5904             SC_I_ZERO (cpu.rX[n] == 0);
5905             SC_I_NEG (cpu.rX[n] & SIGN18);
5906           }
5907           break;
5908 
5909         /// Boolean Comparative And
5910 
5911 // Optimized to the top of the loop
5912 //        case x0 (0315):  // cana
5913 
5914         case x0 (0317):  // canaq
5915           // C(Z)i = C(AQ)i & C(Y-pair)i for i = (0, 1, ..., 71)
5916           {
5917 #if defined(TESTING)
5918             HDBGRegAR ("canaq");
5919             HDBGRegQR ("canaq");
5920 #endif
5921             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
5922             word72 trAQ  = convert_to_word72 (cpu.rA, cpu.rQ);
5923 #if defined(NEED_128)
5924             trAQ = and_128 (trAQ, tmp72);
5925             trAQ = and_128 (trAQ, MASK72);
5926 
5927             SC_I_ZERO (iszero_128 (trAQ));
5928             SC_I_NEG (isnonzero_128 (and_128 (trAQ, SIGN72)));
5929 #else
5930             trAQ = trAQ & tmp72;
5931             trAQ &= MASK72;
5932 
5933             SC_I_ZERO (trAQ == 0);
5934             SC_I_NEG (trAQ & SIGN72);
5935 #endif
5936           }
5937             break;
5938 
5939         case x0 (0316):  // canq
5940           // C(Z)i = C(Q)i & C(Y)i for i = (0, 1, ..., 35)
5941           {
5942 #if defined(TESTING)
5943             HDBGRegQR ("canq");
5944 #endif
5945             word36 trZ = cpu.rQ & cpu.CY;
5946             trZ &= DMASK;
5947 
5948             SC_I_ZERO (trZ == 0);
5949             SC_I_NEG (trZ & SIGN36);
5950           }
5951           break;
5952 
5953                          // canxn
5954         case x0 (0300):  // canx0
5955         case x0 (0301):  // canx1
5956         case x0 (0302):  // canx2
5957         case x0 (0303):  // canx3
5958         case x0 (0304):  // canx4
5959         case x0 (0305):  // canx5
5960         case x0 (0306):  // canx6
5961         case x0 (0307):  // canx7
5962           // For n = 0, 1, ..., or 7 as determined by operation code
5963           // C(Z)i = C(Xn)i & C(Y)i for i = (0, 1, ..., 17)
5964           {
5965             uint32 n = opcode10 & 07;  // get n
5966 #if defined(TESTING)
5967             HDBGRegXR (n, "canxn");
5968 #endif
5969             word18 tmp18  = cpu.rX[n] & GETHI (cpu.CY);
5970             tmp18        &= MASK18;
5971             sim_debug (DBG_TRACEEXT, & cpu_dev,
5972                        "n %o rX %06o HI %06o tmp %06o\n",
5973                        n, cpu.rX[n], (word18) (GETHI (cpu.CY) & MASK18),
5974                        tmp18);
5975 
5976             SC_I_ZERO (tmp18 == 0);
5977             SC_I_NEG (tmp18 & SIGN18);
5978           }
5979           break;
5980 
5981         /// Boolean Comparative Not
5982 
5983         case x0 (0215):  // cnaa
5984           // C(Z)i = C(A)i & ~C(Y)i for i = (0, 1, ..., 35)
5985           {
5986 #if defined(TESTING)
5987             HDBGRegAR ("cnaa");
5988 #endif
5989             word36 trZ = cpu.rA & ~cpu.CY;
5990             trZ &= DMASK;
5991 
5992             SC_I_ZERO (trZ == 0);
5993             SC_I_NEG (trZ & SIGN36);
5994           }
5995           break;
5996 
5997         case x0 (0217):  // cnaaq
5998           // C(Z)i = C (AQ)i & ~C(Y-pair)i for i = (0, 1, ..., 71)
5999           {
6000 #if defined(TESTING)
6001             HDBGRegAR ("cnaaq");
6002             HDBGRegQR ("cnaaq");
6003 #endif
6004             word72 tmp72 = YPAIRTO72 (cpu.Ypair);
6005 
6006             word72 trAQ = convert_to_word72 (cpu.rA, cpu.rQ);
6007 #if defined(NEED_128)
6008             trAQ = and_128 (trAQ, complement_128 (tmp72));
6009             trAQ = and_128 (trAQ, MASK72);
6010 
6011             SC_I_ZERO (iszero_128 (trAQ));
6012             SC_I_NEG (isnonzero_128 (and_128 (trAQ, SIGN72)));
6013 #else
6014             trAQ = trAQ & ~tmp72;
6015             trAQ &= MASK72;
6016 
6017             SC_I_ZERO (trAQ == 0);
6018             SC_I_NEG (trAQ & SIGN72);
6019 #endif
6020           }
6021           break;
6022 
6023         case x0 (0216):  // cnaq
6024           // C(Z)i = C(Q)i & ~C(Y)i for i = (0, 1, ..., 35)
6025           {
6026 #if defined(TESTING)
6027             HDBGRegQR ("cnaq");
6028 #endif
6029             word36 trZ = cpu.rQ & ~cpu.CY;
6030             trZ &= DMASK;
6031             SC_I_ZERO (trZ == 0);
6032             SC_I_NEG (trZ & SIGN36);
6033           }
6034           break;
6035 
6036                          // cnaxn
6037         case x0 (0200):  // cnax0
6038         case x0 (0201):  // cnax1
6039         case x0 (0202):  // cnax2
6040         case x0 (0203):  // cnax3
6041         case x0 (0204):  // cnax4
6042         case x0 (0205):  // cnax5
6043         case x0 (0206):  // cnax6
6044         case x0 (0207):  // cnax7
6045           // C(Z)i = C(Xn)i & ~C(Y)i for i = (0, 1, ..., 17)
6046           {
6047             uint32 n = opcode10 & 07;  // get n
6048 #if defined(TESTING)
6049             HDBGRegXR (n, "cnaxn");
6050 #endif
6051             word18 tmp18 = cpu.rX[n] & ~GETHI (cpu.CY);
6052             tmp18 &= MASK18;
6053 
6054             SC_I_ZERO (tmp18 == 0);
6055             SC_I_NEG (tmp18 & SIGN18);
6056           }
6057           break;
6058 
6059         /// FLOATING-POINT ARITHMETIC INSTRUCTIONS
6060 
6061         /// Floating-Point Data Movement Load
6062 
6063         case x0 (0433):  // dfld
6064           // C(Y-pair)0,7 -> C(E)
6065           // C(Y-pair)8,71 -> C(AQ)0,63
6066           // 00...0 -> C(AQ)64,71
6067           // Zero: If C(AQ) = 0, then ON; otherwise OFF
6068           // Neg: If C(AQ)0 = 1, then ON; otherwise OFF
6069 
6070           CPTUR (cptUseE);
6071           cpu.rE  = (cpu.Ypair[0] >> 28) & MASK8;
6072 
6073           cpu.rA  = (cpu.Ypair[0] & FLOAT36MASK) << 8;
6074           cpu.rA |= (cpu.Ypair[1] >> 28) & MASK8;
6075 
6076           cpu.rQ  = (cpu.Ypair[1] & FLOAT36MASK) << 8;
6077 
6078 #if defined(TESTING)
6079           HDBGRegAW ("dfld");
6080           HDBGRegQW ("dfld");
6081 #endif
6082 
6083           SC_I_ZERO (cpu.rA == 0 && cpu.rQ == 0);
6084           SC_I_NEG (cpu.rA & SIGN36);
6085           break;
6086 
6087 // Optimized to the top of the loop
6088 //        case x0 (0431):  // fld
6089 
6090         /// Floating-Point Data Movement Store
6091 
6092         case x0 (0457):  // dfst
6093           // C(E) -> C(Y-pair)0,7
6094           // C(AQ)0,63 -> C(Y-pair)8,71
6095 
6096           CPTUR (cptUseE);
6097 #if defined(TESTING)
6098           HDBGRegAR ("dfst");
6099           HDBGRegQR ("dfst");
6100 #endif
6101           cpu.Ypair[0] = ((word36)cpu.rE << 28) |
6102                          ((cpu.rA & 0777777777400LLU) >> 8);
6103           cpu.Ypair[1] = ((cpu.rA & 0377) << 28) |
6104                          ((cpu.rQ & 0777777777400LLU) >> 8);
6105 
6106           break;
6107 
6108         case x0 (0472):  // dfstr
6109 
6110           dfstr (cpup, cpu.Ypair);
6111           break;
6112 
6113         case x0 (0455):  // fst
6114           // C(E) -> C(Y)0,7
6115           // C(A)0,27 -> C(Y)8,35
6116           CPTUR (cptUseE);
6117 #if defined(TESTING)
6118           HDBGRegAR ("fst");
6119 #endif
6120           cpu.rE &= MASK8;
6121           cpu.rA &= DMASK;
6122           cpu.CY = ((word36)cpu.rE << 28) | (((cpu.rA >> 8) & 01777777777LL));
6123           break;
6124 
6125         case x0 (0470):  // fstr
6126           // The fstr instruction performs a true round and normalization on
6127           // C(EAQ) as it is stored.
6128 
6129 //            frd ();
6130 //
6131 //            // C(E) -> C(Y)0,7
6132 //            // C(A)0,27 -> C(Y)8,35
6133 //            cpu.CY = ((word36)cpu.rE << 28) |
6134 //                     (((cpu.rA >> 8) & 01777777777LL));
6135 //
6136 //            // Zero: If C(Y) = floating point 0, then ON; otherwise OFF
6137 //            //SC_I_ZERO ((cpu.CY & 01777777777LL) == 0);
6138 //            bool isZero = cpu.rE == -128 && cpu.rA == 0;
6139 //            SC_I_ZERO (isZero);
6140 //
6141 //            // Neg: If C(Y)8 = 1, then ON; otherwise OFF
6142 //            //SC_I_NEG (cpu.CY & 01000000000LL);
6143 //            SC_I_NEG (cpu.rA & SIGN36);
6144 //
6145 //            // Exp Ovr: If exponent is greater than +127, then ON
6146 //            // Exp Undr: If exponent is less than -128, then ON
6147 //            // XXX: not certain how these can occur here ....
6148 
6149           fstr (cpup, &cpu.CY);
6150 
6151           break;
6152 
6153         /// Floating-Point Addition
6154 
6155         case x0 (0477):  // dfad
6156           // The dfad instruction may be thought of as a dufa instruction
6157           // followed by a fno instruction.
6158 
6159           CPTUR (cptUseE);
6160 #if defined(TESTING)
6161           HDBGRegAR ("dfad");
6162           HDBGRegQR ("dfad");
6163 #endif
6164           dufa (cpup, false, true);
6165 #if defined(TESTING)
6166           HDBGRegAW ("dfad");
6167           HDBGRegQW ("dfad");
6168 #endif
6169           break;
6170 
6171         case x0 (0437):  // dufa
6172           dufa (cpup, false, false);
6173           break;
6174 
6175         case x0 (0475):  // fad
6176           // The fad instruction may be thought of a an ufa instruction
6177           // followed by a fno instruction.
6178           // (Heh, heh. We'll see....)
6179 
6180           CPTUR (cptUseE);
6181 #if defined(TESTING)
6182           HDBGRegAR ("fad");
6183           HDBGRegQR ("fad");
6184 #endif
6185           ufa (cpup, false, true);
6186 #if defined(TESTING)
6187           HDBGRegAW ("fad");
6188           HDBGRegQW ("fad");
6189 #endif
6190 
6191           break;
6192 
6193         case x0 (0435):  // ufa
6194             // C(EAQ) + C(Y) -> C(EAQ)
6195 
6196           ufa (cpup, false, false);
6197           break;
6198 
6199         /// Floating-Point Subtraction
6200 
6201         case x0 (0577):  // dfsb
6202           // The dfsb instruction is identical to the dfad instruction with
6203           // the exception that the twos complement of the mantissa of the
6204           // operand from main memory is used.
6205 
6206           CPTUR (cptUseE);
6207 #if defined(TESTING)
6208           HDBGRegAR ("dfsb");
6209           HDBGRegQR ("dfsb");
6210 #endif
6211           dufa (cpup, true, true);
6212 #if defined(TESTING)
6213           HDBGRegAW ("dfsb");
6214           HDBGRegQW ("dfsb");
6215 #endif
6216           break;
6217 
6218         case x0 (0537):  // dufs
6219           dufa (cpup, true, false);
6220           break;
6221 
6222         case x0 (0575):  // fsb
6223           // The fsb instruction may be thought of as an ufs instruction
6224           // followed by a fno instruction.
6225 #if defined(TESTING)
6226           HDBGRegAR ("fsb");
6227           HDBGRegQR ("fsb");
6228 #endif
6229           CPTUR (cptUseE);
6230           ufa (cpup, true, true);
6231 #if defined(TESTING)
6232           HDBGRegAW ("fsb");
6233           HDBGRegQW ("fsb");
6234 #endif
6235           break;
6236 
6237         case x0 (0535):  // ufs
6238           // C(EAQ) - C(Y) -> C(EAQ)
6239           ufa (cpup, true, false);
6240           break;
6241 
6242         /// Floating-Point Multiplication
6243 
6244         case x0 (0463):  // dfmp
6245           // The dfmp instruction may be thought of as a dufm instruction
6246           // followed by a fno instruction.
6247 
6248           CPTUR (cptUseE);
6249 #if defined(TESTING)
6250           HDBGRegAR ("dfmp");
6251           HDBGRegQR ("dfmp");
6252 #endif
6253           dufm (cpup, true);
6254 #if defined(TESTING)
6255           HDBGRegAW ("dfmp");
6256           HDBGRegQW ("dfmp");
6257 #endif
6258           break;
6259 
6260         case x0 (0423):  // dufm
6261 
6262           dufm (cpup, false);
6263           break;
6264 
6265         case x0 (0461):  // fmp
6266           // The fmp instruction may be thought of as a ufm instruction
6267           // followed by a fno instruction.
6268 
6269           CPTUR (cptUseE);
6270           ufm (cpup, true);
6271 #if defined(TESTING)
6272           HDBGRegAW ("fmp");
6273           HDBGRegQW ("fmp");
6274 #endif
6275           break;
6276 
6277         case x0 (0421):  // ufm
6278           // C(EAQ)* C(Y) -> C(EAQ)
6279           ufm (cpup, false);
6280           break;
6281 
6282         /// Floating-Point Division
6283 
6284         case x0 (0527):  // dfdi
6285 
6286           dfdi (cpup);
6287           break;
6288 
6289         case x0 (0567):  // dfdv
6290 
6291           dfdv (cpup);
6292           break;
6293 
6294         case x0 (0525):  // fdi
6295           // C(Y) / C(EAQ) -> C(EA)
6296 
6297           fdi (cpup);
6298           break;
6299 
6300         case x0 (0565):  // fdv
6301           // C(EAQ) /C(Y) -> C(EA)
6302           // 00...0 -> C(Q)
6303           fdv (cpup);
6304           break;
6305 
6306         /// Floating-Point Negation
6307 
6308         case x0 (0513):  // fneg
6309           // -C(EAQ) normalized -> C(EAQ)
6310           fneg (cpup);
6311           break;
6312 
6313         /// Floating-Point Normalize
6314 
6315         case x0 (0573):  // fno
6316           // The fno instruction normalizes the number in C(EAQ) if C(AQ)
6317           // != 0 and the overflow indicator is OFF.
6318           //
6319           // A normalized floating number is defined as one whose mantissa
6320           // lies in the interval [0.5,1.0) such that 0.5<= |C(AQ)| <1.0
6321           // which, in turn, requires that C(AQ)0 != C(AQ)1.list
6322           //
6323           // !!!! For personal reasons the following 3 lines of comment must
6324           // never be removed from this program or any code derived
6325           // there from. HWR 25 Aug 2014
6326           ///Charles Is the coolest
6327           ///true story y'all
6328           //you should get me darksisers 2 for christmas
6329 
6330           CPTUR (cptUseE);
6331           fno (cpup, & cpu.rE, & cpu.rA, & cpu.rQ);
6332 #if defined(TESTING)
6333           HDBGRegAW ("fno");
6334           HDBGRegQW ("fno");
6335 #endif
6336           break;
6337 
6338         /// Floating-Point Round
6339 
6340         case x0 (0473):  // dfrd
6341           // C(EAQ) rounded to 64 bits -> C(EAQ)
6342           // 0 -> C(AQ)64,71 (See notes in dps8_math.c on dfrd())
6343 
6344           dfrd (cpup);
6345           break;
6346 
6347         case x0 (0471):  // frd
6348           // C(EAQ) rounded to 28 bits -> C(EAQ)
6349           // 0 -> C(AQ)28,71 (See notes in dps8_math.c on frd())
6350 
6351           frd (cpup);
6352           break;
6353 
6354         /// Floating-Point Compare
6355 
6356         case x0 (0427):  // dfcmg
6357           // C(E) :: C(Y-pair)0,7
6358           // | C(AQ)0,63 | :: | C(Y-pair)8,71 |
6359 
6360           dfcmg (cpup);
6361           break;
6362 
6363         case x0 (0517):  // dfcmp
6364           // C(E) :: C(Y-pair)0,7
6365           // C(AQ)0,63 :: C(Y-pair)8,71
6366 
6367           dfcmp (cpup);
6368           break;
6369 
6370         case x0 (0425):  // fcmg
6371           // C(E) :: C(Y)0,7
6372           // | C(AQ)0,27 | :: | C(Y)8,35 |
6373 
6374           fcmg (cpup);
6375           break;
6376 
6377         case x0 (0515):  // fcmp
6378           // C(E) :: C(Y)0,7
6379           // C(AQ)0,27 :: C(Y)8,35
6380 
6381           fcmp (cpup);
6382           break;
6383 
6384         /// Floating-Point Miscellaneous
6385 
6386         case x0 (0415):  // ade
6387           // C(E) + C(Y)0,7 -> C(E)
6388           {
6389             CPTUR (cptUseE);
6390             int y = SIGNEXT8_int ((cpu.CY >> 28) & 0377);
6391             int e = SIGNEXT8_int (cpu.rE);
6392             e = e + y;
6393 
6394             cpu.rE = e & 0377;
6395             CLR_I_ZERO;
6396             CLR_I_NEG;
6397 
6398             if (e > 127)
6399               {
6400                 SET_I_EOFL;
6401                 if (tstOVFfault (cpup))
6402                   doFault (FAULT_OFL, fst_zero, "ade exp overflow fault");
6403               }
6404 
6405             if (e < -128)
6406               {
6407                 SET_I_EUFL;
6408                 if (tstOVFfault (cpup))
6409                   doFault (FAULT_OFL, fst_zero, "ade exp underflow fault");
6410               }
6411           }
6412           break;
6413 
6414         case x0 (0430):  // fszn
6415 
6416           // Zero: If C(Y)8,35 = 0, then ON; otherwise OFF
6417           // Negative: If C(Y)8 = 1, then ON; otherwise OFF
6418 
6419           SC_I_ZERO ((cpu.CY & 001777777777LL) == 0);
6420           SC_I_NEG (cpu.CY & 001000000000LL);
6421 
6422           break;
6423 
6424         case x0 (0411):  // lde
6425           // C(Y)0,7 -> C(E)
6426 
6427           CPTUR (cptUseE);
6428           cpu.rE = (cpu.CY >> 28) & 0377;
6429           CLR_I_ZERO;
6430           CLR_I_NEG;
6431 
6432           break;
6433 
6434         case x0 (0456):  // ste
6435           // C(E) -> C(Y)0,7
6436           // 00...0 -> C(Y)8,17
6437 
6438           CPTUR (cptUseE);
6439           //putbits36_18 (& cpu.CY, 0, ((word18) (cpu.rE & 0377) << 10));
6440           cpu.CY = ((word36) (cpu.rE & 0377)) << 28;
6441           cpu.zone = 0777777000000;
6442           cpu.useZone = true;
6443           break;
6444 
6445         /// TRANSFER INSTRUCTIONS
6446 
6447         case x0 (0713):  // call6
6448 
6449           CPTUR (cptUsePRn + 7);
6450 
6451           do_caf (cpup);
6452           read_tra_op (cpup);
6453           sim_debug (DBG_TRACEEXT, & cpu_dev,
6454                      "call6 PRR %o PSR %o\n", cpu.PPR.PRR, cpu.PPR.PSR);
6455 
6456           return CONT_TRA;
6457 
6458         case x0 (0630):  // ret
6459           {
6460             // Parity mask: If C(Y)27 = 1, and the processor is in absolute or
6461             // mask privileged mode, then ON; otherwise OFF. This indicator is
6462             // not affected in the normal or BAR modes.
6463             // Not BAR mode: Can be set OFF but not ON by the ret instruction
6464             // Absolute mode: Can be set OFF but not ON by the ret instruction
6465             // All other indicators: If corresponding bit in C(Y) is 1, then ON;
6466             // otherwise, OFF
6467 
6468             // C(Y)0,17 -> C(PPR.IC)
6469             // C(Y)18,31 -> C(IR)
6470             do_caf (cpup);
6471             ReadOperandRead (cpup, cpu.TPR.CA, & cpu.CY);
6472 
6473             cpu.PPR.IC = GETHI (cpu.CY);
6474             word18 tempIR = GETLO (cpu.CY) & 0777770;
6475             // Assuming 'mask privileged mode' is 'temporary absolute mode'
6476             if (is_priv_mode (cpup)) // abs. or temp. abs. or priv.
6477               {
6478                 // if abs, copy existing parity mask to tempIR
6479                 // According to ISOLTS pm785, not the case.
6480                 //SCF (TST_I_PMASK, tempIR, I_PMASK);
6481                 // if abs, copy existing I_MIF to tempIR
6482                 SCF (TST_I_MIF, tempIR, I_MIF);
6483               }
6484             else
6485               {
6486                 CLRF (tempIR, I_MIF);
6487               }
6488             // can be set OFF but not on
6489             //  IR   ret   result
6490             //  off  off   off
6491             //  off  on    off
6492             //  on   on    on
6493             //  on   off   off
6494             // "If it was on, set it to on"
6495             //SCF (TST_I_NBAR, tempIR, I_NBAR);
6496             if (! (TST_I_NBAR && TSTF (tempIR, I_NBAR)))
6497               {
6498                 CLRF (tempIR, I_NBAR);
6499               }
6500             if (! (TST_I_ABS && TSTF (tempIR, I_ABS)))
6501               {
6502                 CLRF (tempIR, I_ABS);
6503               }
6504 
6505             //sim_debug (DBG_TRACEEXT, & cpu_dev,
6506             //           "RET NBAR was %d now %d\n",
6507             //           TST_NBAR ? 1 : 0,
6508             //           TSTF (tempIR, I_NBAR) ? 1 : 0);
6509             //sim_debug (DBG_TRACEEXT, & cpu_dev,
6510             //           "RET ABS  was %d now %d\n",
6511             //           TST_I_ABS ? 1 : 0,
6512             //           TSTF (tempIR, I_ABS) ? 1 : 0);
6513             CPTUR (cptUseIR);
6514             cpu.cu.IR = tempIR;
6515             return CONT_RET;
6516           }
6517 
6518 // Optimized to the top of the loop
6519 //        case x0 (0610):  // rtcd
6520 
6521         case x0 (0614):  // teo
6522           // If exponent overflow indicator ON then
6523           //  C(TPR.CA) -> C(PPR.IC)
6524           //  C(TPR.TSR) -> C(PPR.PSR)
6525           // otherwise, no change to C(PPR)
6526           if (TST_I_EOFL)
6527             {
6528               CLR_I_EOFL;
6529               do_caf (cpup);
6530               read_tra_op (cpup);
6531               return CONT_TRA;
6532             }
6533           break;
6534 
6535         case x0 (0615):  // teu
6536           // If exponent underflow indicator ON then
6537           //  C(TPR.CA) -> C(PPR.IC)
6538           //  C(TPR.TSR) -> C(PPR.PSR)
6539           if (TST_I_EUFL)
6540             {
6541               CLR_I_EUFL;
6542               do_caf (cpup);
6543               read_tra_op (cpup);
6544               return CONT_TRA;
6545             }
6546           break;
6547 
6548 // Optimized to the top of the loop
6549 //        case x0 (0604):  // tmi
6550 
6551 // Optimized to the top of the loop
6552 //        case x1 (0604):  // tmoz
6553 
6554         case x0 (0602):  // tnc
6555           // If carry indicator OFF then
6556           //   C(TPR.CA) -> C(PPR.IC)
6557           //   C(TPR.TSR) -> C(PPR.PSR)
6558           if (!TST_I_CARRY)
6559             {
6560               do_caf (cpup);
6561               read_tra_op (cpup);
6562               return CONT_TRA;
6563             }
6564           break;
6565 
6566 // Optimized to the top of the loop
6567 //         case x0 (0601):  // tnz
6568 
6569         case x0 (0617):  // tov
6570           // If overflow indicator ON then
6571           //   C(TPR.CA) -> C(PPR.IC)
6572           //   C(TPR.TSR) -> C(PPR.PSR)
6573           if (TST_I_OFLOW)
6574             {
6575               CLR_I_OFLOW;
6576               do_caf (cpup);
6577               read_tra_op (cpup);
6578               return CONT_TRA;
6579             }
6580           break;
6581 
6582         case x0 (0605):  // tpl
6583           // If negative indicator OFF, then
6584           //   C(TPR.CA) -> C(PPR.IC)
6585           //   C(TPR.TSR) -> C(PPR.PSR)
6586           if (! (TST_I_NEG))
6587             {
6588               do_caf (cpup);
6589               read_tra_op (cpup);
6590               return CONT_TRA;
6591             }
6592           break;
6593 
6594 // Optimized to the top of the loop
6595 //        case x1 (0605):  // tpnz
6596 
6597 // Optimized to the top of the loop
6598 //        case x0 (0710):  // tra
6599 
6600         case x0 (0603):  // trc
6601           //  If carry indicator ON then
6602           //    C(TPR.CA) -> C(PPR.IC)
6603           //    C(TPR.TSR) -> C(PPR.PSR)
6604           if (TST_I_CARRY)
6605             {
6606               do_caf (cpup);
6607               read_tra_op (cpup);
6608               return CONT_TRA;
6609             }
6610           break;
6611 
6612         case x1 (0601):  // trtf
6613             // If truncation indicator OFF then
6614             //  C(TPR.CA) -> C(PPR.IC)
6615             //  C(TPR.TSR) -> C(PPR.PSR)
6616             if (!TST_I_TRUNC)
6617             {
6618                 do_caf (cpup);
6619                 read_tra_op (cpup);
6620                 return CONT_TRA;
6621             }
6622             break;
6623 
6624         case x1 (0600):  // trtn
6625             // If truncation indicator ON then
6626             //  C(TPR.CA) -> C(PPR.IC)
6627             //  C(TPR.TSR) -> C(PPR.PSR)
6628             if (TST_I_TRUNC)
6629             {
6630                 CLR_I_TRUNC;
6631                 do_caf (cpup);
6632                 read_tra_op (cpup);
6633                 return CONT_TRA;
6634             }
6635             break;
6636 
6637 // Optimized to the top of the loop
6638 //                         // tspn
6639 //        case x0 (0270):  // tsp0
6640 //        case x0 (0271):  // tsp1
6641 //        case x0 (0272):  // tsp2
6642 //        case x0 (0273):  // tsp3
6643 //        case x0 (0670):  // tsp4
6644 //        case x0 (0671):  // tsp5
6645 //        case x0 (0672):  // tsp6
6646 //        case x0 (0673):  // tsp7
6647 
6648         case x0 (0715):  // tss
6649           CPTUR (cptUseBAR);
6650           do_caf (cpup);
6651           if (get_bar_mode (cpup))
6652             read_tra_op (cpup);
6653           else
6654             {
6655               cpu.TPR.CA = get_BAR_address (cpup, cpu.TPR.CA);
6656               read_tra_op (cpup);
6657               CLR_I_NBAR;
6658             }
6659           return CONT_TRA;
6660 
6661 // Optimized to the top of the loop
6662 //                         // tsxn
6663 //        case x0 (0700):  // tsx0
6664 //        case x0 (0701):  // tsx1
6665 //        case x0 (0702):  // tsx2
6666 //        case x0 (0703):  // tsx3
6667 //        case x0 (0704):  // tsx4
6668 //        case x0 (0705):  // tsx5
6669 //        case x0 (0706):  // tsx6
6670 //        case x0 (0707):  // tsx7
6671 
6672         case x0 (0607):  // ttf
6673           // If tally runout indicator OFF then
6674           //   C(TPR.CA) -> C(PPR.IC)
6675           //  C(TPR.TSR) -> C(PPR.PSR)
6676           // otherwise, no change to C(PPR)
6677           if (TST_I_TALLY == 0)
6678             {
6679               do_caf (cpup);
6680               read_tra_op (cpup);
6681               return CONT_TRA;
6682             }
6683           break;
6684 
6685         case x1 (0606):  // ttn
6686             // If tally runout indicator ON then
6687             //  C(TPR.CA) -> C(PPR.IC)
6688             //  C(TPR.TSR) -> C(PPR.PSR)
6689             // otherwise, no change to C(PPR)
6690             if (TST_I_TALLY)
6691             {
6692                 do_caf (cpup);
6693                 read_tra_op (cpup);
6694                 return CONT_TRA;
6695             }
6696             break;
6697 
6698 // Optimized to the top of the loop
6699 //        case x0 (0600):  // tze
6700 
6701         /// POINTER REGISTER INSTRUCTIONS
6702 
6703         /// Pointer Register Data Movement Load
6704 
6705                          // easpn
6706 
6707         case x0 (0311):  // easp0
6708           // C(TPR.CA) -> C(PRn.SNR)
6709           CPTUR (cptUsePRn + 0);
6710           cpu.PR[0].SNR = cpu.TPR.CA & MASK15;
6711 #if defined(TESTING)
6712           HDBGRegPRW (0, "easp0");
6713 #endif
6714           break;
6715 
6716         case x1 (0310):  // easp1
6717           // C(TPR.CA) -> C(PRn.SNR)
6718           CPTUR (cptUsePRn + 1);
6719           cpu.PR[1].SNR = cpu.TPR.CA & MASK15;
6720 #if defined(TESTING)
6721           HDBGRegPRW (1, "easp1");
6722 #endif
6723           break;
6724 
6725         case x0 (0313):  // easp2
6726           // C(TPR.CA) -> C(PRn.SNR)
6727           CPTUR (cptUsePRn + 2);
6728           cpu.PR[2].SNR = cpu.TPR.CA & MASK15;
6729 #if defined(TESTING)
6730           HDBGRegPRW (2, "easp2");
6731 #endif
6732           break;
6733 
6734         case x1 (0312):  // easp3
6735           // C(TPR.CA) -> C(PRn.SNR)
6736           CPTUR (cptUsePRn + 3);
6737           cpu.PR[3].SNR = cpu.TPR.CA & MASK15;
6738 #if defined(TESTING)
6739           HDBGRegPRW (3, "easp3");
6740 #endif
6741           break;
6742 
6743         case x0 (0331):  // easp4
6744           // C(TPR.CA) -> C(PRn.SNR)
6745           CPTUR (cptUsePRn + 4);
6746           cpu.PR[4].SNR = cpu.TPR.CA & MASK15;
6747 #if defined(TESTING)
6748           HDBGRegPRW (4, "easp4");
6749 #endif
6750           break;
6751 
6752         case x1 (0330):  // easp5
6753           // C(TPR.CA) -> C(PRn.SNR)
6754           CPTUR (cptUsePRn + 5);
6755           cpu.PR[5].SNR = cpu.TPR.CA & MASK15;
6756 #if defined(TESTING)
6757           HDBGRegPRW (5, "easp5");
6758 #endif
6759           break;
6760 
6761         case x0 (0333):  // easp6
6762           // C(TPR.CA) -> C(PRn.SNR)
6763           CPTUR (cptUsePRn + 6);
6764           cpu.PR[6].SNR = cpu.TPR.CA & MASK15;
6765 #if defined(TESTING)
6766           HDBGRegPRW (6, "easp6");
6767 #endif
6768           break;
6769 
6770         case x1 (0332):  // easp7
6771           // C(TPR.CA) -> C(PRn.SNR)
6772           CPTUR (cptUsePRn + 7);
6773           cpu.PR[7].SNR = cpu.TPR.CA & MASK15;
6774 #if defined(TESTING)
6775           HDBGRegPRW (7, "easp7");
6776 #endif
6777           break;
6778 
6779                          // eawpn
6780 
6781         case x0 (0310):  // eawp0
6782           // For n = 0, 1, ..., or 7 as determined by operation code
6783           //  C(TPR.CA) -> C(PRn.WORDNO)
6784           //  C(TPR.TBR) -> C(PRn.BITNO)
6785           CPTUR (cptUsePRn + 0);
6786           cpu.PR[0].WORDNO = cpu.TPR.CA;
6787           SET_PR_BITNO (0, cpu.TPR.TBR);
6788 #if defined(TESTING)
6789           HDBGRegPRW (0, "eawp0");
6790 #endif
6791           break;
6792 
6793         case x1 (0311):  // eawp1
6794           // For n = 0, 1, ..., or 7 as determined by operation code
6795           //  C(TPR.CA) -> C(PRn.WORDNO)
6796           //  C(TPR.TBR) -> C(PRn.BITNO)
6797           CPTUR (cptUsePRn + 1);
6798           cpu.PR[1].WORDNO = cpu.TPR.CA;
6799           SET_PR_BITNO (1, cpu.TPR.TBR);
6800 #if defined(TESTING)
6801           HDBGRegPRW (1, "eawp1");
6802 #endif
6803           break;
6804 
6805         case x0 (0312):  // eawp2
6806           // For n = 0, 1, ..., or 7 as determined by operation code
6807           //  C(TPR.CA) -> C(PRn.WORDNO)
6808           //  C(TPR.TBR) -> C(PRn.BITNO)
6809           CPTUR (cptUsePRn + 2);
6810           cpu.PR[2].WORDNO = cpu.TPR.CA;
6811           SET_PR_BITNO (2, cpu.TPR.TBR);
6812 #if defined(TESTING)
6813           HDBGRegPRW (2, "eawp2");
6814 #endif
6815           break;
6816 
6817         case x1 (0313):  // eawp3
6818           // For n = 0, 1, ..., or 7 as determined by operation code
6819           //  C(TPR.CA) -> C(PRn.WORDNO)
6820           //  C(TPR.TBR) -> C(PRn.BITNO)
6821           CPTUR (cptUsePRn + 3);
6822           cpu.PR[3].WORDNO = cpu.TPR.CA;
6823           SET_PR_BITNO (3, cpu.TPR.TBR);
6824 #if defined(TESTING)
6825           HDBGRegPRW (3, "eawp3");
6826 #endif
6827           break;
6828 
6829         case x0 (0330):  // eawp4
6830           // For n = 0, 1, ..., or 7 as determined by operation code
6831           //  C(TPR.CA) -> C(PRn.WORDNO)
6832           //  C(TPR.TBR) -> C(PRn.BITNO)
6833           CPTUR (cptUsePRn + 4);
6834           cpu.PR[4].WORDNO = cpu.TPR.CA;
6835           SET_PR_BITNO (4, cpu.TPR.TBR);
6836 #if defined(TESTING)
6837           HDBGRegPRW (4, "eawp4");
6838 #endif
6839           break;
6840 
6841         case x1 (0331):  // eawp5
6842           // For n = 0, 1, ..., or 7 as determined by operation code
6843           //  C(TPR.CA) -> C(PRn.WORDNO)
6844           //  C(TPR.TBR) -> C(PRn.BITNO)
6845           CPTUR (cptUsePRn + 5);
6846           cpu.PR[5].WORDNO = cpu.TPR.CA;
6847           SET_PR_BITNO (5, cpu.TPR.TBR);
6848 #if defined(TESTING)
6849           HDBGRegPRW (5, "eawp5");
6850 #endif
6851           break;
6852 
6853         case x0 (0332):  // eawp6
6854           // For n = 0, 1, ..., or 7 as determined by operation code
6855           //  C(TPR.CA) -> C(PRn.WORDNO)
6856           //  C(TPR.TBR) -> C(PRn.BITNO)
6857           CPTUR (cptUsePRn + 6);
6858           cpu.PR[6].WORDNO = cpu.TPR.CA;
6859           SET_PR_BITNO (6, cpu.TPR.TBR);
6860 #if defined(TESTING)
6861           HDBGRegPRW (6, "eawp6");
6862 #endif
6863           break;
6864 
6865         case x1 (0333):  // eawp7
6866           // For n = 0, 1, ..., or 7 as determined by operation code
6867           //  C(TPR.CA) -> C(PRn.WORDNO)
6868           //  C(TPR.TBR) -> C(PRn.BITNO)
6869           CPTUR (cptUsePRn + 7);
6870           cpu.PR[7].WORDNO = cpu.TPR.CA;
6871           SET_PR_BITNO (7, cpu.TPR.TBR);
6872 #if defined(TESTING)
6873           HDBGRegPRW (7, "eawp7");
6874 #endif
6875           break;
6876 
6877 // Optimized to the top of the loop
6878 //        case x1 (0350):  // epbp0
6879 //        case x0 (0351):  // epbp1
6880 //        case x1 (0352):  // epbp2
6881 //        case x0 (0353):  // epbp3
6882 //        case x1 (0370):  // epbp4
6883 //        case x0 (0371):  // epbp5
6884 //        case x1 (0372):  // epbp6
6885 //        case x0 (0373):  // epbp7
6886 
6887 // Optimized to the top of the switch
6888 //        case x0 (0350):  // epp0
6889 //        case x1 (0351):  // epp1
6890 //        case x0 (0352):  // epp2
6891 //        case x1 (0353):  // epp3
6892 //        case x0 (0374):  // epp4
6893 //        case x1 (0371):  // epp5
6894 //        case x0 (0376):  // epp6
6895 //        case x1 (0373):  // epp7
6896 
6897         case x0 (0173):  // lpri
6898           // For n = 0, 1, ..., 7
6899           //  Y-pair = Y-block16 + 2n
6900           //  Maximum of C(Y-pair)18,20; C(SDW.R1); C(TPR.TRR) -> C(PRn.RNR)
6901           //  C(Y-pair) 3,17 -> C(PRn.SNR)
6902           //  C(Y-pair)36,53 -> C(PRn.WORDNO)
6903           //  C(Y-pair)57,62 -> C(PRn.BITNO)
6904 
6905           for (uint32 n = 0 ; n < 8 ; n ++)
6906             {
6907               CPTUR (cptUsePRn + n);
6908               // Even word of ITS pointer pair
6909               cpu.Ypair[0] = cpu.Yblock16[n * 2 + 0];
6910               // Odd word of ITS pointer pair
6911               cpu.Ypair[1] = cpu.Yblock16[n * 2 + 1];
6912 
6913               // RNR from ITS pair
6914               word3 Crr = (GETLO (cpu.Ypair[0]) >> 15) & 07;
6915               if (get_addr_mode (cpup) == APPEND_mode)
6916                 cpu.PR[n].RNR = max3 (Crr, cpu.SDW->R1, cpu.TPR.TRR);
6917               else
6918                 cpu.PR[n].RNR = Crr;
6919               cpu.PR[n].SNR    = (cpu.Ypair[0] >> 18) & MASK15;
6920               cpu.PR[n].WORDNO = GETHI (cpu.Ypair[1]);
6921               word6 bitno      = (GETLO (cpu.Ypair[1]) >> 9) & 077;
6922 // According to ISOLTS, loading a 077 into bitno results in 037
6923 // pa851    test-04b    lpri test       bar-100176
6924 // test start 105321   patch 105461   subtest loop point 105442
6925 // s/b 77777737
6926 // was 77777733
6927               if (bitno == 077)
6928                 bitno = 037;
6929               SET_PR_BITNO (n, bitno);
6930 #if defined(TESTING)
6931               HDBGRegPRW (n, "lpri");
6932 #endif
6933             }
6934 
6935           break;
6936 
6937 // Optimized to the top of the loop
6938 //                         // lprpn
6939 //        case x0 (0760):  // lprp0
6940 //        case x0 (0761):  // lprp1
6941 //        case x0 (0762):  // lprp2
6942 //        case x0 (0763):  // lprp3
6943 //        case x0 (0764):  // lprp4
6944 //        case x0 (0765):  // lprp5
6945 //        case x0 (0766):  // lprp6
6946 //        case x0 (0767):  // lprp7
6947 
6948         /// Pointer Register Data Movement Store
6949 
6950 // Optimized to the top of the loop
6951 //        case x1 (0250):  // spbp0
6952 //        case x0 (0251):  // spbp1
6953 //        case x1 (0252):  // spbp2
6954 //        case x0 (0253):  // spbp3
6955 //        case x1 (0650):  // spbp4
6956 //        case x0 (0651):  // spbp5
6957 //        case x1 (0652):  // spbp6
6958 //        case x0 (0653):  // spbp7
6959 
6960         case x0 (0254):  // spri
6961           // For n = 0, 1, ..., 7
6962           //  Y-pair = Y-block16 + 2n
6963 
6964           //  000 -> C(Y-pair)0,2
6965           //  C(PRn.SNR) -> C(Y-pair)3,17
6966           //  C(PRn.RNR) -> C(Y-pair)18,20
6967           //  00...0 -> C(Y-pair)21,29
6968           //  (43)8 -> C(Y-pair)30,35
6969 
6970           //  C(PRn.WORDNO) -> C(Y-pair)36,53
6971           //  000 -> C(Y-pair)54,56
6972           //  C(PRn.BITNO) -> C(Y-pair)57,62
6973           //  00...0 -> C(Y-pair)63,71
6974 
6975           for (uint32 n = 0 ; n < 8 ; n++)
6976             {
6977               CPTUR (cptUsePRn + n);
6978               cpu.Yblock16[2 * n]      = 043;
6979               cpu.Yblock16[2 * n]     |= ((word36) cpu.PR[n].SNR) << 18;
6980               cpu.Yblock16[2 * n]     |= ((word36) cpu.PR[n].RNR) << 15;
6981 
6982               cpu.Yblock16[2 * n + 1]  = (word36) cpu.PR[n].WORDNO << 18;
6983               cpu.Yblock16[2 * n + 1] |= (word36) GET_PR_BITNO(n) << 9;
6984             }
6985 
6986           break;
6987 
6988 // Optimized to the top of the loop
6989 //        case x0 (0250):  // spri0
6990 //        case x1 (0251):  // spri1
6991 //        case x0 (0252):  // spri2
6992 //        case x1 (0253):  // spri3
6993 //        case x0 (0650):  // spri4
6994 //        case x1 (0255):  // spri5
6995 //        case x0 (0652):  // spri6
6996 //        case x1 (0257):  // spri7
6997 
6998                          // sprpn
6999         case x0 (0540):  // sprp0
7000         case x0 (0541):  // sprp1
7001         case x0 (0542):  // sprp2
7002         case x0 (0543):  // sprp3
7003         case x0 (0544):  // sprp4
7004         case x0 (0545):  // sprp5
7005         case x0 (0546):  // sprp6
7006         case x0 (0547):  // sprp7
7007           // For n = 0, 1, ..., or 7 as determined by operation code
7008           //  C(PRn.BITNO) -> C(Y)0,5
7009           //  C(PRn.SNR)3,14 -> C(Y)6,17
7010           //  C(PRn.WORDNO) -> C(Y)18,35
7011           {
7012             uint32 n = opcode10 & 07;  // get n
7013             CPTUR (cptUsePRn + n);
7014 
7015             // If C(PRn.SNR)0,2 are nonzero, and C(PRn.SNR) != 11...1, then
7016             // a store fault (illegal pointer) will occur and C(Y) will not
7017             // be changed.
7018 
7019             if ((cpu.PR[n].SNR & 070000) != 0 && cpu.PR[n].SNR != MASK15)
7020               doFault (FAULT_STR, fst_str_ptr, "sprpn");
7021 
7022             cpu.CY  =  ((word36) (GET_PR_BITNO(n) & 077)) << 30;
7023             // lower 12- of 15-bits
7024             cpu.CY |=  ((word36) (cpu.PR[n].SNR & 07777)) << 18;
7025             cpu.CY |=  cpu.PR[n].WORDNO & PAMASK;
7026             cpu.CY &= DMASK;    // keep to 36-bits
7027           }
7028           break;
7029 
7030         /// Pointer Register Address Arithmetic
7031 
7032                           // adwpn
7033         case x0 (0050):   // adwp0
7034         case x0 (0051):   // adwp1
7035         case x0 (0052):   // adwp2
7036         case x0 (0053):   // adwp3
7037           // For n = 0, 1, ..., or 7 as determined by operation code
7038           //   C(Y)0,17 + C(PRn.WORDNO) -> C(PRn.WORDNO)
7039           //   00...0 -> C(PRn.BITNO)
7040           {
7041               uint32 n = opcode10 & 03;  // get n
7042               CPTUR (cptUsePRn + n);
7043               cpu.PR[n].WORDNO += GETHI (cpu.CY);
7044               cpu.PR[n].WORDNO &= MASK18;
7045               SET_PR_BITNO (n, 0);
7046 #if defined(TESTING)
7047               HDBGRegPRW (n, "adwpn");
7048 #endif
7049           }
7050           break;
7051 
7052         case x0 (0150):   // adwp4
7053         case x0 (0151):   // adwp5
7054         case x0 (0152):   // adwp6
7055         case x0 (0153):   // adwp7
7056           // For n = 0, 1, ..., or 7 as determined by operation code
7057           //   C(Y)0,17 + C(PRn.WORDNO) -> C(PRn.WORDNO)
7058           //   00...0 -> C(PRn.BITNO)
7059           {
7060               uint32 n = (opcode10 & MASK3) + 4U;  // get n
7061               CPTUR (cptUsePRn + n);
7062               cpu.PR[n].WORDNO += GETHI (cpu.CY);
7063               cpu.PR[n].WORDNO &= MASK18;
7064               SET_PR_BITNO (n, 0);
7065 #if defined(TESTING)
7066               HDBGRegPRW (n, "adwpn");
7067 #endif
7068           }
7069           break;
7070 
7071         /// Pointer Register Miscellaneous
7072 
7073 // Optimized to the top of the loop
7074 //        case x0 (0213):  // epaq
7075 
7076         /// MISCELLANEOUS INSTRUCTIONS
7077 
7078         case x0 (0633):  // rccl
7079           // 00...0 -> C(AQ)0,19
7080           // C(calendar clock) -> C(AQ)20,71
7081           {
7082             // For the rccl instruction, the first 2 or 3 bits of the addr
7083             // field of the instruction are used to specify which SCU.
7084             // init_processor.alm systematically steps through the SCUs,
7085             // using addresses 000000 100000 200000 300000.
7086             uint cpu_port_num;
7087             if (cpu.tweaks.l68_mode)
7088               cpu_port_num = (cpu.TPR.CA >> 15) & 07;
7089             else
7090               cpu_port_num = (cpu.TPR.CA >> 15) & 03;
7091             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
7092               {
7093                 sim_warn ("rccl on CPU %u port %d has no SCU; faulting\n",
7094                           current_running_cpu_idx, cpu_port_num);
7095                 doFault (FAULT_ONC, fst_onc_nem, "(rccl)");
7096               }
7097             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
7098 
7099             t_stat rc = scu_rscr (cpup, (uint) scuUnitIdx, current_running_cpu_idx,
7100                                   040, & cpu.rA, & cpu.rQ);
7101 #if defined(TESTING)
7102             HDBGRegAW ("rccl");
7103             HDBGRegQW ("rccl");
7104 #endif
7105             if (rc > 0)
7106               return rc;
7107 #if !defined(SPEED)
7108             if_sim_debug (DBG_TRACEEXT, & cpu_dev)
7109               {
7110                 // Clock at initialization
7111                 // date -d "Tue Jul 22 16:39:38 PDT 1999" +%s
7112                 // 932686778
7113                 uint64 UnixSecs     = 932686778;
7114                 uint64 UnixuSecs    = UnixSecs * 1000000LL;
7115                 // now determine uSecs since Jan 1, 1901 ...
7116                 uint64 MulticsuSecs = 2177452800000000LL + UnixuSecs;
7117 
7118                 // Back into 72 bits
7119                word72 big           = convert_to_word72 (cpu.rA, cpu.rQ);
7120 # if defined(NEED_128)
7121                 // Convert to time since boot
7122                 big             = subtract_128 (big, construct_128 (0, MulticsuSecs));
7123                 uint32_t remainder;
7124                 uint128 bigsecs = divide_128_32 (big, 1000000u, & remainder);
7125                 uint64_t uSecs  = remainder;
7126                 uint64_t secs   = bigsecs.l;
7127                 sim_debug (DBG_TRACEEXT, & cpu_dev,
7128                            "Clock time since boot %4llu.%06llu seconds\n",
7129                            secs, uSecs);
7130 # else
7131                 // Convert to time since boot
7132                 big                 -= MulticsuSecs;
7133                 unsigned long uSecs  = big % 1000000u;
7134                 unsigned long secs   = (unsigned long) (big / 1000000u);
7135                 sim_debug (DBG_TRACEEXT, & cpu_dev,
7136                            "Clock time since boot %4lu.%06lu seconds\n",
7137                            secs, uSecs);
7138 # endif
7139               }
7140 #endif
7141           }
7142           break;
7143 
7144         case x0 (0002):   // drl
7145           // Causes a fault which fetches and executes, in absolute mode, the
7146           // instruction pair at main memory location C+(14)8. The value of C
7147           // is obtained from the FAULT VECTOR switches on the processor
7148           // configuration panel.
7149 
7150           if (cpu.tweaks.drl_fatal)
7151             {
7152               return STOP_STOP;
7153             }
7154           doFault (FAULT_DRL, fst_zero, "drl");
7155 
7156         /*FALLTHRU*/
7157         case x0 (0716):  // xec
7158           cpu.cu.xde = 1;
7159           cpu.cu.xdo = 0;
7160 // XXX NB. This used to be done in executeInstruction post-execution
7161 // processing; moving it here means that post-execution code cannot inspect IWB
7162 // to determine what the instruction or it flags were.
7163           cpu.cu.IWB = cpu.CY;
7164           return CONT_XEC;
7165 
7166         case x0 (0717):  // xed
7167           // The xed instruction itself does not affect any indicator.
7168           // However, the execution of the instruction pair from C(Y-pair)
7169           // may affect indicators.
7170           //
7171           // The even instruction from C(Y-pair) must not alter
7172           // C(Y-pair)36,71, and must not be another xed instruction.
7173           //
7174           // If the execution of the instruction pair from C(Y-pair) alters
7175           // C(PPR.IC), then a transfer of control occurs; otherwise, the
7176           // next instruction to be executed is fetched from C(PPR.IC)+1. If
7177           // the even instruction from C(Y-pair) alters C(PPR.IC), then the
7178           // transfer of control is effective immediately and the odd
7179           // instruction is not executed.
7180           //
7181           // To execute an instruction pair having an rpd instruction as the
7182           // odd instruction, the xed instruction must be located at an odd
7183           // address. The instruction pair repeated is that instruction pair
7184           // at C PPR.IC)+1, that is, the instruction pair immediately
7185           // following the xed instruction. C(PPR.IC) is adjusted during the
7186           // execution of the repeated instruction pair so the next
7187           // instruction fetched for execution is from the first word
7188           // following the repeated instruction pair.
7189           //
7190           // The instruction pair at C(Y-pair) may cause any of the processor
7191           // defined fault conditions, but only the directed faults (0,1,2,3)
7192           // and the access violation fault may be restarted successfully by
7193           // the hardware. Note that the software induced fault tag (1,2,3)
7194           // faults cannot be properly restarted.
7195           //
7196           //  An attempt to execute an EIS multiword instruction causes an
7197           //  illegal procedure fault.
7198           //
7199           //  Attempted repetition with the rpt, rpd, or rpl instructions
7200           //  causes an illegal procedure fault.
7201 
7202           cpu.cu.xde = 1;
7203           cpu.cu.xdo = 1;
7204 // XXX NB. This used to be done in executeInstruction post-execution
7205 // processing; moving it here means that post-execution code cannot inspect IWB
7206 // to determine what the instruction or it flags were.
7207           cpu.cu.IWB   = cpu.Ypair[0];
7208           cpu.cu.IRODD = cpu.Ypair[1];
7209           return CONT_XEC;
7210 
7211         case x0 (0001):   // mme
7212 #if defined(TESTING)
7213           if (sim_deb_mme_cntdwn > 0)
7214             sim_deb_mme_cntdwn --;
7215 #endif
7216           // Causes a fault that fetches and executes, in absolute mode, the
7217           // instruction pair at main memory location C+4. The value of C is
7218           // obtained from the FAULT VECTOR switches on the processor
7219           // configuration panel.
7220           doFault (FAULT_MME, fst_zero, "Master Mode Entry (mme)");
7221 
7222         /*FALLTHRU*/
7223         case x0 (0004):   // mme2
7224           // Causes a fault that fetches and executes, in absolute mode, the
7225           // instruction pair at main memory location C+(52)8. The value of C
7226           // is obtained from the FAULT VECTOR switches on the processor
7227           // configuration panel.
7228           doFault (FAULT_MME2, fst_zero, "Master Mode Entry 2 (mme2)");
7229 
7230         /*FALLTHRU*/
7231         case x0 (0005):   // mme3
7232           // Causes a fault that fetches and executes, in absolute mode, the
7233           // instruction pair at main memory location C+(54)8. The value of C
7234           // is obtained from the FAULT VECTOR switches on the processor
7235           // configuration panel.
7236           doFault (FAULT_MME3, fst_zero, "Master Mode Entry 3 (mme3)");
7237 
7238         /*FALLTHRU*/
7239         case x0 (0007):   // mme4
7240           // Causes a fault that fetches and executes, in absolute mode, the
7241           // instruction pair at main memory location C+(56)8. The value of C
7242           // is obtained from the FAULT VECTOR switches on the processor
7243           // configuration panel.
7244           doFault (FAULT_MME4, fst_zero, "Master Mode Entry 4 (mme4)");
7245 
7246         /*FALLTHRU*/
7247         case x0 (0011):   // nop
7248           break;
7249 
7250         case x0 (0012):   // puls1
7251           break;
7252 
7253         case x0 (0013):   // puls2
7254           break;
7255 
7256         /// Repeat
7257 
7258         case x0 (0560):  // rpd
7259           {
7260             if ((cpu.PPR.IC & 1) == 0)
7261               doFault (FAULT_IPR, fst_ill_proc, "rpd odd");
7262             cpu.cu.delta = i->tag;
7263             // a:AL39/rpd1
7264             word1 c = (i->address >> 7) & 1;
7265             if (c)
7266               {
7267                 cpu.rX[0] = i->address;    // Entire 18 bits
7268 #if defined(TESTING)
7269                 HDBGRegXW (0, "rpd");
7270 #endif
7271               }
7272             cpu.cu.rd = 1;
7273             cpu.cu.repeat_first = 1;
7274           }
7275           break;
7276 
7277         case x0 (0500):  // rpl
7278           {
7279             uint c       = (i->address >> 7) & 1;
7280             cpu.cu.delta = i->tag;
7281             if (c)
7282               {
7283                 cpu.rX[0] = i->address;    // Entire 18 bits
7284 #if defined(TESTING)
7285                 HDBGRegXW (0, "rpl");
7286 #endif
7287               }
7288             cpu.cu.rl           = 1;
7289             cpu.cu.repeat_first = 1;
7290           }
7291           break;
7292 
7293         case x0 (0520):  // rpt
7294           {
7295             uint c       = (i->address >> 7) & 1;
7296             cpu.cu.delta = i->tag;
7297             if (c)
7298               {
7299                 cpu.rX[0] = i->address;    // Entire 18 bits
7300 #if defined(TESTING)
7301                 HDBGRegXW (0, "rpt");
7302 #endif
7303               }
7304             cpu.cu.rpt          = 1;
7305             cpu.cu.repeat_first = 1;
7306           }
7307           break;
7308 
7309         /// Ring Alarm Register
7310 
7311         case x1 (0754):  // sra
7312             // 00...0 -> C(Y)0,32
7313             // C(RALR) -> C(Y)33,35
7314 
7315             CPTUR (cptUseRALR);
7316             cpu.CY = (word36)cpu.rRALR;
7317 
7318             break;
7319 
7320         /// Store Base Address Register
7321 
7322         case x0 (0550):  // sbar
7323           // C(BAR) -> C(Y) 0,17
7324           CPTUR (cptUseBAR);
7325           //SETHI (cpu.CY, (cpu.BAR.BASE << 9) | cpu.BAR.BOUND);
7326           cpu.CY      = ((((word36) cpu.BAR.BASE) << 9) | cpu.BAR.BOUND) << 18;
7327           cpu.zone    = 0777777000000;
7328           cpu.useZone = true;
7329           break;
7330 
7331         /// Translation
7332 
7333         case x0 (0505):  // bcd
7334           // Shift C(A) left three positions
7335           // | C(A) | / C(Y) -> 4-bit quotient
7336           // C(A) - C(Y) * quotient -> remainder
7337           // Shift C(Q) left six positions
7338           // 4-bit quotient -> C(Q)32,35
7339           // remainder -> C(A)
7340 
7341           {
7342             word36 tmp1   = cpu.rA & SIGN36; // A0
7343             word36 tmp36  = (cpu.rA << 3) & DMASK;
7344             word36 tmp36q = tmp36 / cpu.CY;  // this may be more than 4 bits, keep it for remainder calculation
7345             word36 tmp36r = 0;
7346             if (!tmp1) {
7347                 tmp36r = tmp36 - tmp36q * cpu.CY;
7348             } else {
7349                 // ISOLTS-745 05i: bcd when rA is negative.
7350                 // Note that this only gets called in the first round of the bcd
7351                 // conversion; the rA sign bit will get shifted out.
7352                 // Looking at the expected results, it appears that a 'borrow'
7353                 // is represented in a residue style notation -- an unborrow
7354                 // result is 0-9 (000 - 011), a borrowed digit as 6-15 (006-017)
7355                 tmp36q += 6;
7356                 tmp36r  = tmp36 + tmp36q * cpu.CY;
7357             }
7358 
7359             cpu.rQ <<= 6;       // Shift C(Q) left six positions
7360             cpu.rQ &= DMASK;
7361 
7362             //cpu.rQ &= (word36) ~017;     // 4-bit quotient -> C(Q)32,35  lo6 bits already zeroed out
7363             cpu.rQ |= (tmp36q & 017);
7364 #if defined(TESTING)
7365             HDBGRegQW ("bcd");
7366 #endif
7367 
7368             cpu.rA = tmp36r & DMASK;    // remainder -> C(A)
7369 #if defined(TESTING)
7370             HDBGRegAW ("bcd");
7371 #endif
7372 
7373             SC_I_ZERO (cpu.rA == 0);  // If C(A) = 0, then ON;
7374                                             // otherwise OFF
7375             SC_I_NEG (tmp1);   // If C(A)0 = 1 before execution,
7376                                             // then ON; otherwise OFF
7377           }
7378           break;
7379 
7380         case x0 (0774):  // gtb
7381           // C(A)0 -> C(A)0
7382           // C(A)i XOR C(A)i-1 -> C(A)i for i = 1, 2, ..., 35
7383           {
7384             word36 tmp = cpu.rA & MASK36;
7385             word36 mask = SIGN36;
7386 
7387             for (int n=1;n<=35;n++) {
7388                 tmp ^= (tmp & mask) >> 1;
7389                 mask >>= 1;
7390             }
7391 
7392             cpu.rA = tmp;
7393 #if defined(TESTING)
7394             HDBGRegAW ("gtb");
7395 #endif
7396 
7397             SC_I_ZERO (cpu.rA == 0);  // If C(A) = 0, then ON;
7398                                       // otherwise OFF
7399             SC_I_NEG (cpu.rA & SIGN36);   // If C(A)0 = 1, then ON;
7400                                           // otherwise OFF
7401           }
7402           break;
7403 
7404         /// REGISTER LOAD
7405 
7406         case x0 (0230):  // lbar
7407           // C(Y)0,17 -> C(BAR)
7408           CPTUR (cptUseBAR);
7409           // BAR.BASE is upper 9-bits (0-8)
7410           cpu.BAR.BASE  = (GETHI (cpu.CY) >> 9) & 0777;
7411           // BAR.BOUND is next lower 9-bits (9-17)
7412           cpu.BAR.BOUND = GETHI (cpu.CY) & 0777;
7413           break;
7414 
7415         /// PRIVILEGED INSTRUCTIONS
7416 
7417         /// Privileged - Register Load
7418 
7419         case x0 (0674):  // lcpr
7420           // DPS8M interpretation
7421           switch (i->tag)
7422             {
7423               // Extract bits from 'from' under 'mask' shifted to where (where
7424               // is dps8 '0 is the msbit.
7425 
7426               case 02: // cache mode register
7427                 {
7428                   //cpu.CMR = cpu.CY;
7429                   // cpu.CMR.cache_dir_address = <ignored for lcpr>
7430                   // cpu.CMR.par_bit = <ignored for lcpr>
7431                   // cpu.CMR.lev_ful = <ignored for lcpr>
7432 
7433                   CPTUR (cptUseCMR);
7434                   // a:AL39/cmr2  If either cache enable bit c or d changes
7435                   // from disable state to enable state, the entire cache is
7436                   // cleared.
7437                   uint csh1_on    = getbits36_1 (cpu.CY, 54 - 36);
7438                   uint csh2_on    = getbits36_1 (cpu.CY, 55 - 36);
7439                   //bool clear = (cpu.CMR.csh1_on == 0 && csh1_on != 0) ||
7440                                //(cpu.CMR.csh1_on == 0 && csh1_on != 0);
7441                   cpu.CMR.csh1_on = (word1) csh1_on;
7442                   cpu.CMR.csh2_on = (word1) csh2_on;
7443                   //if (clear) // a:AL39/cmr2
7444                     //{
7445                     //}
7446                   L68_ (cpu.CMR.opnd_on = getbits36_1 (cpu.CY, 56 - 36);)
7447                   cpu.CMR.inst_on = getbits36_1 (cpu.CY, 57 - 36);
7448                   cpu.CMR.csh_reg = getbits36_1 (cpu.CY, 59 - 36);
7449                   if (cpu.CMR.csh_reg)
7450                     sim_warn ("LCPR set csh_reg\n");
7451                   // cpu.CMR.str_asd = <ignored for lcpr>
7452                   // cpu.CMR.col_ful = <ignored for lcpr>
7453                   // cpu.CMR.rro_AB = getbits36_1 (cpu.CY, 18);
7454                   DPS8M_ (cpu.CMR.bypass_cache = getbits36_1 (cpu.CY, 68 - 36);)
7455                   cpu.CMR.luf = getbits36_2 (cpu.CY, 70 - 36);
7456                 }
7457                 break;
7458 
7459               case 04: // mode register
7460                 {
7461                   CPTUR (cptUseMR);
7462                   cpu.MR.r = cpu.CY;
7463 // XXX TEST/NORMAL switch is set to NORMAL
7464                   putbits36_1 (& cpu.MR.r, 32, 0);
7465 // SBZ
7466                   putbits36_2 (& cpu.MR.r, 33, 0);
7467                   L68_ (
7468                     cpu.MR.FFV = getbits36_15 (cpu.CY, 0);
7469                     cpu.MR.OC_TRAP = getbits36_1 (cpu.CY, 16);
7470                     cpu.MR.ADR_TRAP = getbits36_1 (cpu.CY, 17);
7471                     cpu.MR.OPCODE = getbits36_9 (cpu.CY, 18);
7472                     cpu.MR.OPCODEX = getbits36_1 (cpu.CY, 27);
7473                   )
7474                   cpu.MR.sdpap = getbits36_1 (cpu.CY, 20);
7475                   cpu.MR.separ = getbits36_1 (cpu.CY, 21);
7476                   cpu.MR.hrhlt = getbits36_1 (cpu.CY, 28);
7477                   DPS8M_ (cpu.MR.hrxfr = getbits36_1 (cpu.CY, 29);)
7478                   cpu.MR.ihr = getbits36_1 (cpu.CY, 30);
7479                   cpu.MR.ihrrs = getbits36_1 (cpu.CY, 31);
7480                   cpu.MR.emr = getbits36_1 (cpu.CY, 35);
7481                   if (! cpu.tweaks.l68_mode) // DPS8M
7482                     cpu.MR.hexfp = getbits36_1 (cpu.CY, 33);
7483                   else // L68
7484                     cpu.MR.hexfp = 0;
7485 
7486                   // Stop HR Strobe on HR Counter Overflow. (Setting bit 28
7487                   // shall cause the HR counter to be reset to zero.)
7488                   // CAC: It is unclear if bit 28 is edge or level
7489                   // triggered; assuming level for simplicity.
7490                   if (cpu.MR.hrhlt)
7491                     {
7492                       for (uint hset = 0; hset < N_HIST_SETS; hset ++)
7493                          cpu.history_cyclic[hset] = 0;
7494                     }
7495 
7496 
7497 
7498 
7499 
7500 
7501 
7502 
7503 
7504 
7505 
7506 
7507                 }
7508                 break;
7509 
7510               case 03: // 0's -> history
7511                 {
7512                   for (uint i = 0; i < N_HIST_SETS; i ++)
7513                     add_history_force (cpup, i, 0, 0);
7514 // XXX ISOLTS pm700 test-01n
7515 // The test clears the history registers but with ihr & emr set, causing
7516 // the registers to fill with alternating 0's and lcpr instructions.
7517 // Set flag to prevent the LCPR from being recorded.
7518                     //cpu.MR.ihr = 0;
7519                     cpu.skip_cu_hist = true;
7520 
7521                 }
7522                 break;
7523 
7524               case 07: // 1's -> history
7525                 {
7526                   for (uint i = 0; i < N_HIST_SETS; i ++)
7527                     add_history_force (cpup, i, MASK36, MASK36);
7528 // XXX ISOLTS pm700 test-01n
7529 // The test clears the history registers but with ihr & emr set, causing
7530 // the registers to fill with alternating 0's and lcpr instructions.
7531 // Set flag to prevent the LCPR from being recorded.
7532                     //cpu.MR.ihr = 0;
7533                     cpu.skip_cu_hist = true;
7534                 }
7535                 break;
7536 
7537               default:
7538                 doFault (FAULT_IPR,
7539                          fst_ill_mod,
7540                          "lcpr tag invalid");
7541 
7542             }
7543             break;
7544 
7545         case x0 (0232):  // ldbr
7546           do_ldbr (cpup, cpu.Ypair);
7547           ucInvalidate (cpup);
7548           break;
7549 
7550         case x0 (0637):  // ldt
7551           CPTUR (cptUseTR);
7552           cpu.rTR = (cpu.CY >> 9) & MASK27;
7553           cpu.rTRticks = 0;
7554           if (cpu.tweaks.isolts_mode)
7555             {
7556               cpu.shadowTR = cpu.TR0 = cpu.rTR;
7557               cpu.rTRlsb = 0;
7558             }
7559           sim_debug (DBG_TRACEEXT, & cpu_dev, "ldt TR %d (%o)\n",
7560                      cpu.rTR, cpu.rTR);
7561 #if defined(LOOPTRC)
7562 elapsedtime ();
7563  sim_printf (" ldt %d  PSR:IC %05o:%06o\r\n", cpu.rTR, cpu.PPR.PSR, cpu.PPR.IC);
7564 #endif
7565           // Undocumented feature. return to bce has been observed to
7566           // experience TRO while masked, setting the TR to -1, and
7567           // experiencing an unexpected TRo interrupt when unmasking.
7568           // Reset any pending TRO fault when the TR is loaded.
7569           clearTROFault (cpup);
7570           break;
7571 
7572         case x1 (0257):  // lptp
7573 
7574           if (cpu.tweaks.l68_mode) {
7575             // For i = 0, 1, ..., 15
7576             //   m = C(PTWAM(i).USE)
7577             //   C(Y-block16+m)0,14 -> C(PTWAM(m).POINTER)
7578             //   C(Y-block16+m)15,26 -> C(PTWAM(m).PAGE)
7579             //   C(Y-block16+m)27 -> C(PTWAM(m).F)
7580 
7581             for (uint i = 0; i < 16; i ++)
7582               {
7583                 word4 m              = cpu.PTWAM[i].USE;
7584                 cpu.PTWAM[m].POINTER = getbits36_15 (cpu.Yblock16[i],  0);
7585                 cpu.PTWAM[m].PAGENO  = getbits36_12 (cpu.Yblock16[i], 15);
7586                 cpu.PTWAM[m].FE      = getbits36_1  (cpu.Yblock16[i], 27);
7587               }
7588           }
7589           break;
7590 
7591         case x1 (0173):  // lptr
7592           if (cpu.tweaks.l68_mode) {
7593             // For i = 0, 1, ..., 15
7594             //   m = C(PTWAM(i).USE)
7595             //   C(Y-block16+m)0,17 -> C(PTWAM(m).ADDR)
7596             //   C(Y-block16+m)29 -> C(PTWAM(m).M)
7597             for (uint i = 0; i < 16; i ++)
7598               {
7599                 word4 m           = cpu.PTWAM[i].USE;
7600                 cpu.PTWAM[m].ADDR = getbits36_18 (cpu.Yblock16[i],  0);
7601                 cpu.PTWAM[m].M    = getbits36_1  (cpu.Yblock16[i], 29);
7602               }
7603           }
7604           break;
7605 
7606         case x1 (0774):  // lra
7607             CPTUR (cptUseRALR);
7608             cpu.rRALR = cpu.CY & MASK3;
7609             sim_debug (DBG_TRACEEXT, & cpu_dev, "RALR set to %o\n", cpu.rRALR);
7610 #if defined(LOOPTRC)
7611 {
7612 void elapsedtime (void);
7613 elapsedtime ();
7614  sim_printf (" RALR set to %o  PSR:IC %05o:%06o\r\n", cpu.rRALR, cpu.PPR.PSR, cpu.PPR.IC);
7615 }
7616 #endif
7617             break;
7618 
7619         case x0 (0257):  // lsdp
7620           if (cpu.tweaks.l68_mode) {
7621             // For i = 0, 1, ..., 15
7622             //   m = C(SDWAM(i).USE)
7623             //   C(Y-block16+m)0,14 -> C(SDWAM(m).POINTER)
7624             //   C(Y-block16+m)27 -> C(SDWAM(m).F) Note: typo in AL39, P(17) should be F(27)
7625             for (uint i = 0; i < 16; i ++)
7626               {
7627                 word4 m              = cpu.SDWAM[i].USE;
7628                 cpu.SDWAM[m].POINTER = getbits36_15 (cpu.Yblock16[i],  0);
7629                 cpu.SDWAM[m].FE      = getbits36_1  (cpu.Yblock16[i], 27);
7630               }
7631           }
7632           break;
7633 
7634         case x1 (0232):  // lsdr
7635           if (cpu.tweaks.l68_mode) {
7636             // For i = 0, 1, ..., 15
7637             //   m = C(SDWAM(i).USE)
7638             //   C(Y-block32+2m)0,23  -> C(SDWAM(m).ADDR)
7639             //   C(Y-block32+2m)24,32 -> C(SDWAM(m).R1, R2, R3)
7640             //   C(Y-block32+2m)37,50 -> C(SDWAM(m).BOUND)
7641             //   C(Y-block32+2m)51,57 -> C(SDWAM(m).R, E, W, P, U, G, C) Note: typo in AL39, 52 should be 51
7642             //   C(Y-block32+2m)58,71 -> C(SDWAM(m).CL)
7643             for (uint i = 0; i < 16; i ++)
7644               {
7645                 word4 m            = cpu.SDWAM[i].USE;
7646                 uint j             = (uint)m * 2;
7647                 cpu.SDWAM[m].ADDR  = getbits36_24 (cpu.Yblock32[j],  0);
7648                 cpu.SDWAM[m].R1    = getbits36_3  (cpu.Yblock32[j], 24);
7649                 cpu.SDWAM[m].R2    = getbits36_3  (cpu.Yblock32[j], 27);
7650                 cpu.SDWAM[m].R3    = getbits36_3  (cpu.Yblock32[j], 30);
7651 
7652                 cpu.SDWAM[m].BOUND = getbits36_14 (cpu.Yblock32[j + 1], 37 - 36);
7653                 cpu.SDWAM[m].R     = getbits36_1  (cpu.Yblock32[j + 1], 51 - 36);
7654                 cpu.SDWAM[m].E     = getbits36_1  (cpu.Yblock32[j + 1], 52 - 36);
7655                 cpu.SDWAM[m].W     = getbits36_1  (cpu.Yblock32[j + 1], 53 - 36);
7656                 cpu.SDWAM[m].P     = getbits36_1  (cpu.Yblock32[j + 1], 54 - 36);
7657                 cpu.SDWAM[m].U     = getbits36_1  (cpu.Yblock32[j + 1], 55 - 36);
7658                 cpu.SDWAM[m].G     = getbits36_1  (cpu.Yblock32[j + 1], 56 - 36);
7659                 cpu.SDWAM[m].C     = getbits36_1  (cpu.Yblock32[j + 1], 57 - 36);
7660                 cpu.SDWAM[m].EB    = getbits36_14 (cpu.Yblock32[j + 1], 58 - 36);
7661               }
7662           }
7663           break;
7664 
7665         case x0 (0613):  // rcu
7666           doRCU (cpup); // never returns!
7667 
7668         /// Privileged - Register Store
7669 
7670         /*FALLTHRU*/ /* fall through */ /* fallthrough */
7671         case x0 (0452):  // scpr
7672           {
7673             uint tag = (i->tag) & MASK6;
7674             switch (tag)
7675               {
7676                 case 000: // C(APU history register#1) -> C(Y-pair)
7677                   {
7678                     uint reg = cpu.tweaks.l68_mode ? L68_APU_HIST_REG : DPS8M_APU_HIST_REG;
7679                     cpu.Ypair[0] = cpu.history[reg] [cpu.history_cyclic[reg]][0];
7680                     cpu.Ypair[1] = cpu.history[reg] [cpu.history_cyclic[reg]][1];
7681                     cpu.history_cyclic[reg] = (cpu.history_cyclic[reg] + 1) % N_MODEL_HIST_SIZE;
7682                   }
7683                   break;
7684 
7685                 case 001: // C(fault register) -> C(Y-pair)0,35
7686                           // 00...0 -> C(Y-pair)36,71
7687                   {
7688                     CPTUR (cptUseFR);
7689                     cpu.Ypair[0]         = cpu.faultRegister[0];
7690                     cpu.Ypair[1]         = cpu.faultRegister[1];
7691                     cpu.faultRegister[0] = 0;
7692                     cpu.faultRegister[1] = 0;
7693                   }
7694                   break;
7695 
7696                 case 006: // C(mode register) -> C(Y-pair)0,35
7697                           // C(cache mode register) -> C(Y-pair)36,72
7698                   {
7699                     CPTUR (cptUseMR);
7700                     cpu.Ypair[0] = cpu.MR.r;
7701                     putbits36_1 (& cpu.Ypair[0], 20, cpu.MR.sdpap);
7702                     putbits36_1 (& cpu.Ypair[0], 21, cpu.MR.separ);
7703                     putbits36_1 (& cpu.Ypair[0], 30, cpu.MR.ihr);
7704                     DPS8M_ (putbits36_1 (& cpu.Ypair[0], 33, cpu.MR.hexfp);)
7705                     CPTUR (cptUseCMR);
7706                     cpu.Ypair[1] = 0;
7707                     putbits36_15 (& cpu.Ypair[1], 36 - 36,
7708                                   cpu.CMR.cache_dir_address);
7709                     putbits36_1 (& cpu.Ypair[1], 51 - 36, cpu.CMR.par_bit);
7710                     putbits36_1 (& cpu.Ypair[1], 52 - 36, cpu.CMR.lev_ful);
7711                     putbits36_1 (& cpu.Ypair[1], 54 - 36, cpu.CMR.csh1_on);
7712                     putbits36_1 (& cpu.Ypair[1], 55 - 36, cpu.CMR.csh2_on);
7713                     L68_ (putbits36_1 (& cpu.Ypair[1], 56 - 36, cpu.CMR.opnd_on);)
7714                     putbits36_1 (& cpu.Ypair[1], 57 - 36, cpu.CMR.inst_on);
7715                     putbits36_1 (& cpu.Ypair[1], 59 - 36, cpu.CMR.csh_reg);
7716                     putbits36_1 (& cpu.Ypair[1], 60 - 36, cpu.CMR.str_asd);
7717                     putbits36_1 (& cpu.Ypair[1], 61 - 36, cpu.CMR.col_ful);
7718                     putbits36_2 (& cpu.Ypair[1], 62 - 36, cpu.CMR.rro_AB);
7719                     DPS8M_ (putbits36_1 (& cpu.Ypair[1], 68 - 36, cpu.CMR.bypass_cache);)
7720                     putbits36_2 (& cpu.Ypair[1], 70 - 36, cpu.CMR.luf);
7721                   }
7722                   break;
7723 
7724                 case 010: // C(APU history register#2) -> C(Y-pair)
7725                   {
7726                     uint reg = cpu.tweaks.l68_mode ? L68_DU_HIST_REG : DPS8M_EAPU_HIST_REG;
7727                     cpu.Ypair[0] = cpu.history[reg] [cpu.history_cyclic[reg]][0];
7728                     cpu.Ypair[1] = cpu.history[reg] [cpu.history_cyclic[reg]][1];
7729                     cpu.history_cyclic[reg] = (cpu.history_cyclic[reg] + 1) % N_MODEL_HIST_SIZE;
7730                   }
7731                   break;
7732 
7733                 case 020: // C(CU history register) -> C(Y-pair)
7734                   {
7735                     cpu.Ypair[0] =
7736                       cpu.history[CU_HIST_REG]
7737                                  [cpu.history_cyclic[CU_HIST_REG]][0];
7738                     cpu.Ypair[1] =
7739                       cpu.history[CU_HIST_REG]
7740                                  [cpu.history_cyclic[CU_HIST_REG]][1];
7741                     cpu.history_cyclic[CU_HIST_REG] =
7742                       (cpu.history_cyclic[CU_HIST_REG] + 1) % N_MODEL_HIST_SIZE;
7743                   }
7744                   break;
7745 
7746                 case 040: // C(OU/DU history register) -> C(Y-pair)
7747                   {
7748                     uint reg = cpu.tweaks.l68_mode ? L68_OU_HIST_REG : DPS8M_DU_OU_HIST_REG;
7749                     cpu.Ypair[0] = cpu.history[reg] [cpu.history_cyclic[reg]][0];
7750                     cpu.Ypair[1] = cpu.history[reg] [cpu.history_cyclic[reg]][1];
7751                     cpu.history_cyclic[reg] = (cpu.history_cyclic[reg] + 1) % N_MODEL_HIST_SIZE;
7752                   }
7753                   break;
7754 
7755                 default:
7756                   {
7757                     doFault (FAULT_IPR,
7758                              fst_ill_mod,
7759                              "SCPR Illegal register select value");
7760                   }
7761               }
7762           }
7763           break;
7764 
7765         case x0 (0657):  // scu
7766           // AL-39 defines the behavior of SCU during fault/interrupt
7767           // processing, but not otherwise.
7768           // The T&D tape uses SCU during normal processing, and apparently
7769           // expects the current CU state to be saved.
7770 
7771           if (cpu.cycle == EXEC_cycle)
7772             {
7773               // T&D behavior
7774 
7775               // An 'Add Delta' addressing mode will alter the TALLY bit;
7776               // restore it.
7777               //SC_I_TALLY (cpu.currentInstruction.stiTally == 0);
7778 
7779               scu2words (cpup, cpu.Yblock8);
7780             }
7781           else
7782             {
7783               // AL-39 behavior
7784               for (int j = 0; j < 8; j ++)
7785                 cpu.Yblock8[j] = cpu.scu_data[j];
7786             }
7787           break;
7788 
7789         case x0 (0154):  // sdbr
7790           {
7791             CPTUR (cptUseDSBR);
7792             // C(DSBR.ADDR) -> C(Y-pair) 0,23
7793             // 00...0 -> C(Y-pair) 24,36
7794             cpu.Ypair[0] = ((word36) (cpu.DSBR.ADDR & PAMASK)) << (35 - 23);
7795 
7796             // C(DSBR.BOUND) -> C(Y-pair) 37,50
7797             // 0000 -> C(Y-pair) 51,54
7798             // C(DSBR.U) -> C(Y-pair) 55
7799             // 000 -> C(Y-pair) 56,59
7800             // C(DSBR.STACK) -> C(Y-pair) 60,71
7801             cpu.Ypair[1] = ((word36) (cpu.DSBR.BND & 037777)) << (71 - 50) |
7802                            ((word36) (cpu.DSBR.U & 1)) << (71 - 55) |
7803                            ((word36) (cpu.DSBR.STACK & 07777)) << (71 - 71);
7804           }
7805           break;
7806 
7807         case x1 (0557):  // sptp
7808           {
7809 // XXX AL39 The associative memory is ignored (forced to "no match") during address
7810 // preparation.
7811             // Level j is selected by C(TPR.CA)12,13
7812             uint level;
7813             L68_ (level = 0;)
7814             DPS8M_ (level = (cpu.TPR.CA >> 4) & 03;)
7815             uint toffset = level * 16;
7816             for (uint j = 0; j < 16; j ++)
7817               {
7818                 cpu.Yblock16[j] = 0;
7819                 putbits36_15 (& cpu.Yblock16[j],  0,
7820                            cpu.PTWAM[toffset + j].POINTER);
7821                 DPS8M_ (
7822                   putbits36_12 (& cpu.Yblock16[j], 15, cpu.PTWAM[toffset + j].PAGENO & 07760);
7823 
7824                   uint parity = 0;
7825                   if (cpu.PTWAM[toffset + j].FE) {
7826                     // calculate parity
7827                     // 58009997-040 p.101,111
7828                     parity = ((uint) cpu.PTWAM[toffset + j].POINTER << 4) | (cpu.PTWAM[toffset + j].PAGENO >> 8);
7829                     parity = parity ^ (parity >>16);
7830                     parity = parity ^ (parity >> 8);
7831                     parity = parity ^ (parity >> 4);
7832                     parity = ~ (0x6996u >> (parity & 0xf));
7833                   }
7834                   putbits36_1 (& cpu.Yblock16[j], 23, (word1) (parity & 1));
7835                 )
7836                 L68_ (putbits36_12 (& cpu.Yblock16[j], 15, cpu.PTWAM[toffset + j].PAGENO); )
7837                 putbits36_1 (& cpu.Yblock16[j], 27,
7838                            cpu.PTWAM[toffset + j].FE);
7839                 DPS8M_ (putbits36_6 (& cpu.Yblock16[j], 30, cpu.PTWAM[toffset + j].USE);)
7840                 L68_ (putbits36_4 (& cpu.Yblock16[j], 32, cpu.PTWAM[toffset + j].USE);)
7841               }
7842           }
7843           break;
7844 
7845         case x1 (0154):  // sptr
7846           {
7847 // XXX The associative memory is ignored (forced to "no match") during address
7848 // preparation.
7849 
7850             // Level j is selected by C(TPR.CA)12,13
7851             uint level;
7852             DPS8M_ (level = (cpu.TPR.CA >> 4) & 03;)
7853             L68_ (level = 0;)
7854             uint toffset = level * 16;
7855             for (uint j = 0; j < 16; j ++)
7856               {
7857                 cpu.Yblock16[j] = 0;
7858                 DPS8M_ (putbits36_18 (& cpu.Yblock16[j], 0, cpu.PTWAM[toffset + j].ADDR & 0777760);)
7859                 L68_ (putbits36_18 (& cpu.Yblock16[j], 0, cpu.PTWAM[toffset + j].ADDR);)
7860                 putbits36_1 (& cpu.Yblock16[j], 29,
7861                              cpu.PTWAM[toffset + j].M);
7862               }
7863           }
7864           break;
7865 
7866         case x0 (0557):  // ssdp
7867           {
7868             // XXX AL39: The associative memory is ignored (forced to "no match")
7869             // during address preparation.
7870             // Level j is selected by C(TPR.CA)12,13
7871             uint level;
7872             DPS8M_ (level = (cpu.TPR.CA >> 4) & 03;)
7873             L68_ (level = 0;)
7874             uint toffset = level * 16;
7875             for (uint j = 0; j < 16; j ++)
7876               {
7877                 cpu.Yblock16[j] = 0;
7878                 putbits36_15 (& cpu.Yblock16[j], 0,
7879                            cpu.SDWAM[toffset + j].POINTER);
7880                 putbits36_1 (& cpu.Yblock16[j], 27,
7881                            cpu.SDWAM[toffset + j].FE);
7882                 DPS8M_ (
7883                   uint parity = 0;
7884                   if (cpu.SDWAM[toffset + j].FE) {
7885                     // calculate parity
7886                     // 58009997-040 p.112
7887                     parity = cpu.SDWAM[toffset + j].POINTER >> 4;
7888                     //parity = parity ^ (parity >>16);
7889                     parity = parity ^ (parity >> 8);
7890                     parity = parity ^ (parity >> 4);
7891                     parity = ~ (0x6996u >> (parity & 0xf));
7892                   }
7893                   putbits36_1 (& cpu.Yblock16[j], 15, (word1) (parity & 1));
7894 
7895                   putbits36_6 (& cpu.Yblock16[j], 30, cpu.SDWAM[toffset + j].USE);
7896                 )
7897                 L68_ (putbits36_4 (& cpu.Yblock16[j], 32, cpu.SDWAM[toffset + j].USE);)
7898               }
7899           }
7900           break;
7901 
7902         case x1 (0254):  // ssdr
7903           {
7904 // XXX AL39: The associative memory is ignored (forced to "no match") during
7905 // address preparation.
7906 
7907             // Level j is selected by C(TPR.CA)11,12
7908             // Note: not bits 12,13. This is due to operand being Yblock32
7909             uint level = 0;
7910             DPS8M_ (level = (cpu.TPR.CA >> 5) & 03;)
7911             L68_ (level = 0;)
7912             uint toffset = level * 16;
7913             for (uint j = 0; j < 16; j ++)
7914               {
7915                 cpu.Yblock32[j * 2] = 0;
7916                 putbits36_24 (& cpu.Yblock32[j * 2],  0,
7917                            cpu.SDWAM[toffset + j].ADDR);
7918                 putbits36_3  (& cpu.Yblock32[j * 2], 24,
7919                            cpu.SDWAM[toffset + j].R1);
7920                 putbits36_3  (& cpu.Yblock32[j * 2], 27,
7921                            cpu.SDWAM[toffset + j].R2);
7922                 putbits36_3  (& cpu.Yblock32[j * 2], 30,
7923                            cpu.SDWAM[toffset + j].R3);
7924                 cpu.Yblock32[j * 2 + 1] = 0;
7925 
7926                 putbits36_14 (& cpu.Yblock32[j * 2 + 1], 37 - 36,
7927                            cpu.SDWAM[toffset + j].BOUND);
7928                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 51 - 36,
7929                            cpu.SDWAM[toffset + j].R);
7930                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 52 - 36,
7931                            cpu.SDWAM[toffset + j].E);
7932                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 53 - 36,
7933                            cpu.SDWAM[toffset + j].W);
7934                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 54 - 36,
7935                            cpu.SDWAM[toffset + j].P);
7936                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 55 - 36,
7937                            cpu.SDWAM[toffset + j].U);
7938                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 56 - 36,
7939                            cpu.SDWAM[toffset + j].G);
7940                 putbits36_1  (& cpu.Yblock32[j * 2 + 1], 57 - 36,
7941                            cpu.SDWAM[toffset + j].C);
7942                 putbits36_14 (& cpu.Yblock32[j * 2 + 1], 58 - 36,
7943                            cpu.SDWAM[toffset + j].EB);
7944               }
7945           }
7946           break;
7947 
7948         /// Privileged - Clear Associative Memory
7949 
7950         case x1 (0532):  // camp
7951           {
7952             // C(TPR.CA) 16,17 control disabling or enabling the associative
7953             // memory.
7954             // This may be done to either or both halves.
7955             // The full/empty bit of cache PTWAM register is set to zero and
7956             // the LRU counters are initialized.
7957             if (cpu.tweaks.enable_wam)
7958               { // disabled, do nothing
7959                 if (cpu.tweaks.l68_mode || cpu.cu.PT_ON) // only clear when enabled
7960                     for (uint i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
7961                       {
7962                         cpu.PTWAM[i].FE = 0;
7963                         L68_ (cpu.PTWAM[i].USE = (word4) i;)
7964                         DPS8M_ (cpu.PTWAM[i].USE = 0;)
7965                       }
7966 
7967 // 58009997-040 A level of the associative memory is disabled if
7968 // C(TPR.CA) 16,17 = 01
7969 // 58009997-040 A level of the associative memory is enabled if
7970 // C(TPR.CA) 16,17 = 10
7971 // Level j is selected to be enabled/disable if
7972 // C(TPR.CA) 10+j = 1; j=1,2,3,4
7973 // All levels are selected to be enabled/disabled if
7974 // C(TPR.CA) 11,14 = 0
7975 // This is contrary to what AL39 says, so I'm not going to implement it.
7976 // In fact, I'm not even going to implement the halves.
7977 
7978                 DPS8M_ (if (cpu.TPR.CA != 0000002 && (cpu.TPR.CA & 3) != 0)
7979                   sim_warn ("CAMP ignores enable/disable %06o\n", cpu.TPR.CA);)
7980                 if ((cpu.TPR.CA & 3) == 02)
7981                   cpu.cu.PT_ON = 1;
7982                 else if ((cpu.TPR.CA & 3) == 01)
7983                   cpu.cu.PT_ON = 0;
7984               }
7985             else
7986               {
7987                 cpu.PTW0.FE  = 0;
7988                 cpu.PTW0.USE = 0;
7989               }
7990           }
7991           ucInvalidate (cpup);
7992           break;
7993 
7994         case x0 (0532):  // cams
7995           {
7996             // The full/empty bit of each SDWAM register is set to zero and the
7997             // LRU counters are initialized. The remainder of the contents of
7998             // the registers are unchanged. If the associative memory is
7999             // disabled, F and LRU are unchanged.
8000             // C(TPR.CA) 16,17 control disabling or enabling the associative
8001             // memory.
8002             // This may be done to either or both halves.
8003             if (cpu.tweaks.enable_wam)
8004               {
8005                 if (cpu.tweaks.l68_mode || cpu.cu.SD_ON) // only clear when enabled
8006                     for (uint i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
8007                       {
8008                         cpu.SDWAM[i].FE = 0;
8009                         L68_ (cpu.SDWAM[i].USE = (word4) i;)
8010                         DPS8M_ (cpu.SDWAM[i].USE = 0;)
8011                       }
8012 // 58009997-040 A level of the associative memory is disabled if
8013 // C(TPR.CA) 16,17 = 01
8014 // 58009997-040 A level of the associative memory is enabled if
8015 // C(TPR.CA) 16,17 = 10
8016 // Level j is selected to be enabled/disable if
8017 // C(TPR.CA) 10+j = 1; j=1,2,3,4
8018 // All levels are selected to be enabled/disabled if
8019 // C(TPR.CA) 11,14 = 0
8020 // This is contrary to what AL39 says, so I'm not going to implement it. In
8021 // fact, I'm not even going to implement the halves.
8022 
8023                 DPS8M_ (if (cpu.TPR.CA != 0000006 && (cpu.TPR.CA & 3) != 0)
8024                   sim_warn ("CAMS ignores enable/disable %06o\n", cpu.TPR.CA);)
8025                 if ((cpu.TPR.CA & 3) == 02)
8026                   cpu.cu.SD_ON = 1;
8027                 else if ((cpu.TPR.CA & 3) == 01)
8028                   cpu.cu.SD_ON = 0;
8029               }
8030             else
8031               {
8032                 cpu.SDW0.FE  = 0;
8033                 cpu.SDW0.USE = 0;
8034               }
8035           }
8036           ucInvalidate (cpup);
8037           break;
8038 
8039         /// Privileged - Configuration and Status
8040 
8041         case x0 (0233):  // rmcm
8042           {
8043             // C(TPR.CA)0,2 (C(TPR.CA)1,2 for the DPS 8M processor)
8044             // specify which processor port (i.e., which system
8045             // controller) is used.
8046             uint cpu_port_num;
8047             DPS8M_ (cpu_port_num = (cpu.TPR.CA >> 15) & 03;)
8048             L68_ (cpu_port_num = (cpu.TPR.CA >> 15) & 07;)
8049             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
8050               {
8051                 sim_warn ("rmcm to non-existent controller on "
8052                           "cpu %d port %d\n",
8053                           current_running_cpu_idx, cpu_port_num);
8054                 break;
8055               }
8056             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
8057             t_stat rc = scu_rmcm ((uint) scuUnitIdx,
8058                                   current_running_cpu_idx,
8059                                   & cpu.rA, & cpu.rQ);
8060 #if defined(TESTING)
8061             HDBGRegAW ("rmcm");
8062             HDBGRegQW ("rmcm");
8063 #endif
8064             if (rc)
8065               return rc;
8066             SC_I_ZERO (cpu.rA == 0);
8067             SC_I_NEG (cpu.rA & SIGN36);
8068           }
8069           break;
8070 
8071         case x0 (0413):  // rscr
8072           {
8073             // For the rscr instruction, the first 2 (DPS8M) or 3 (L68) bits of
8074             // the addr field of the instruction are used to specify which SCU.
8075             // (2 bits for the DPS8M. (Expect for x6x and x7x below, where
8076             // the selected SCU is the one holding the addressed memory).
8077 
8078             // According to DH02:
8079             //   XXXXXX0X  SCU Mode Register (Level 66 only)
8080             //   XXXXXX1X  Configuration switches
8081             //   XXXXXn2X  Interrupt mask port n
8082             //   XXXXXX3X  Interrupt cells
8083             //   XXXXXX4X  Elapsed time clock
8084             //   XXXXXX5X  Elapsed time clock
8085             //   XXXXXX6X  Mode register
8086             //   XXXXXX7X  Mode register
8087 
8088             // According to privileged_mode_ut,
8089             //   port*1024 + scr_input*8
8090 
8091             // privileged_mode_ut makes no reference to the special case
8092             // of x6x and x7x.
8093 
8094             // According to DH02, RSCR in Slave Mode does the CAF
8095             // without BAR correction, and then forces the CA to 040,
8096             // resulting in a Clock Read from the SCU on port 0.
8097 
8098             // According to AL93, RSCR in BAR mode is IPR.
8099 
8100 //
8101 // Implementing privileged_mode_ut.alm algorithm
8102 //
8103 
8104             // Extract port number
8105             uint cpu_port_num;
8106             DPS8M_ (cpu_port_num = (cpu.TPR.CA >> 10) & 03;)
8107             L68_ (cpu_port_num = (cpu.TPR.CA >> 10) & 07;)
8108 
8109             // Trace the cable from the port to find the SCU number
8110             // connected to that port
8111             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
8112               {
8113                 // CPTUR (cptUseFR) -- will be set by doFault
8114 
8115                 // Set IAn in Fault register
8116                 if (cpu_port_num == 0)
8117                   putbits36 (& cpu.faultRegister[0], 16, 4, 010);
8118                 else if (cpu_port_num == 1)
8119                   putbits36 (& cpu.faultRegister[0], 20, 4, 010);
8120                 else if (cpu_port_num == 2)
8121                   putbits36 (& cpu.faultRegister[0], 24, 4, 010);
8122                 else
8123                   putbits36 (& cpu.faultRegister[0], 28, 4, 010);
8124 
8125                 doFault (FAULT_CMD, fst_cmd_ctl, "(rscr)");
8126               }
8127             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
8128 #if defined(PANEL68)
8129             {
8130                uint function = (cpu.iefpFinalAddress >> 3) & 07;
8131                CPT (cpt13L, function);
8132             }
8133 #endif
8134             t_stat rc = scu_rscr (cpup, (uint) scuUnitIdx, current_running_cpu_idx,
8135                                   cpu.iefpFinalAddress & MASK15,
8136                                   & cpu.rA, & cpu.rQ);
8137 #if defined(TESTING)
8138             HDBGRegAW ("rscr");
8139             HDBGRegQW ("rscr");
8140 #endif
8141             if (rc)
8142               return rc;
8143           }
8144           break;
8145 
8146         case x0 (0231):  // rsw
8147           {
8148             if (! cpu.tweaks.l68_mode) {
8149               word6 rTAG = GET_TAG (IWB_IRODD);
8150               word6 Td = GET_TD (rTAG);
8151               word6 Tm = GET_TM (rTAG);
8152               if (Tm == TM_R && Td == TD_DL)
8153                 {
8154                   unsigned char PROM[1024];
8155                   setupPROM (current_running_cpu_idx, PROM);
8156                   cpu.rA = PROM[cpu.TPR.CA & 1023];
8157                   break;
8158                 }
8159             }  // DPS8M
8160             uint select = cpu.TPR.CA & 0x7;
8161             switch (select)
8162               {
8163                 case 0: // data switches
8164                   cpu.rA = cpu.switches.data_switches;
8165                   break;
8166 
8167                 case 1: // configuration switches for ports A, B, C, D
8168 // y = 1:
8169 //
8170 //   0               0 0               1 1               2 2               3
8171 //   0               8 9               7 8               6 7               5
8172 //  -------------------------------------------------------------------------
8173 //  |      PORT A     |     PORT B      |     PORT C      |     PORT D      |
8174 //  -------------------------------------------------------------------------
8175 //  | ADR |j|k|l| MEM | ADR |j|k|l| MEM | ADR |j|k|l| MEM | ADR |j|k|l| MEM |
8176 //  -------------------------------------------------------------------------
8177 //
8178 //
8179 //   ADR: Address assignment switch setting for port
8180 //         This defines the base address for the SCU
8181 //   j: port enabled flag
8182 //   k: system initialize enabled flag
8183 //   l: interface enabled flag
8184 //   MEM coded memory size
8185 //     000 32K     2^15
8186 //     001 64K     2^16
8187 //     010 128K    2^17
8188 //     011 256K    2^18
8189 //     100 512K    2^19
8190 //     101 1024K   2^20
8191 //     110 2048K   2^21
8192 //     111 4096K   2^22
8193 
8194                   cpu.rA  = 0;
8195                   cpu.rA |= (word36) (cpu.switches.assignment  [0] & 07LL)
8196                             << (35 -  (2 +  0));
8197                   cpu.rA |= (word36) (cpu.switches.enable      [0] & 01LL)
8198                             << (35 -  (3 +  0));
8199                   cpu.rA |= (word36) (cpu.switches.init_enable [0] & 01LL)
8200                             << (35 -  (4 +  0));
8201                   cpu.rA |= (word36) (cpu.switches.interlace   [0] ? 1LL:0LL)
8202                             << (35 -  (5 +  0));
8203                   cpu.rA |= (word36) (cpu.switches.store_size  [0] & 07LL)
8204                             << (35 -  (8 +  0));
8205 
8206                   cpu.rA |= (word36) (cpu.switches.assignment  [1] & 07LL)
8207                             << (35 -  (2 +  9));
8208                   cpu.rA |= (word36) (cpu.switches.enable      [1] & 01LL)
8209                             << (35 -  (3 +  9));
8210                   cpu.rA |= (word36) (cpu.switches.init_enable [1] & 01LL)
8211                             << (35 -  (4 +  9));
8212                   cpu.rA |= (word36) (cpu.switches.interlace   [1] ? 1LL:0LL)
8213                             << (35 -  (5 +  9));
8214                   cpu.rA |= (word36) (cpu.switches.store_size  [1] & 07LL)
8215                             << (35 -  (8 +  9));
8216 
8217                   cpu.rA |= (word36) (cpu.switches.assignment  [2] & 07LL)
8218                             << (35 -  (2 + 18));
8219                   cpu.rA |= (word36) (cpu.switches.enable      [2] & 01LL)
8220                             << (35 -  (3 + 18));
8221                   cpu.rA |= (word36) (cpu.switches.init_enable [2] & 01LL)
8222                             << (35 -  (4 + 18));
8223                   cpu.rA |= (word36) (cpu.switches.interlace   [2] ? 1LL:0LL)
8224                             << (35 -  (5 + 18));
8225                   cpu.rA |= (word36) (cpu.switches.store_size  [2] & 07LL)
8226                             << (35 -  (8 + 18));
8227 
8228                   cpu.rA |= (word36) (cpu.switches.assignment  [3] & 07LL)
8229                             << (35 -  (2 + 27));
8230                   cpu.rA |= (word36) (cpu.switches.enable      [3] & 01LL)
8231                             << (35 -  (3 + 27));
8232                   cpu.rA |= (word36) (cpu.switches.init_enable [3] & 01LL)
8233                             << (35 -  (4 + 27));
8234                   cpu.rA |= (word36) (cpu.switches.interlace   [3] ? 1LL:0LL)
8235                             << (35 -  (5 + 27));
8236                   cpu.rA |= (word36) (cpu.switches.store_size  [3] & 07LL)
8237                             << (35 -  (8 + 27));
8238                   break;
8239 
8240                 case 2: // fault base and processor number  switches
8241 // y = 2:
8242 //
8243 //   0     0 0 0 0            1 1 1     1 1 1 2 2 2 2 2 2 2   2 2     3 3   3
8244 //   0     3 4 5 6            2 3 4     7 8 9 0 1 2 3 4 5 6   8 9     2 3   5
8245 //  --------------------------------------------------------------------------
8246 //  |A|B|C|D|   |              | |       | | | |   | | | |     |       |     |
8247 //  --------- b |   FLT BASE   |c|0 0 0 0|d|e|f|0 0|g|h|i|0 0 0| SPEED | CPU |
8248 //  |a|a|a|a|   |              | |       | | | |   | | | |     |       |     |
8249 //  --------------------------------------------------------------------------
8250 //
8251 
8252 //   a: port A-D is 0: 4 word or 1: 2 word
8253 //   b: processor type 0:L68 or DPS, 1: DPS8M, 2,3: reserved for future use
8254 //   c: id prom 0: not installed, 1: installed
8255 //   d: 1: bcd option installed (marketing designation)
8256 //   e: 1: dps option installed (marketing designation)
8257 //   f: 1: 8k cache installed
8258 //   g: processor type designation: 0: dps8/xx, 1: dps8m/xx
8259 //   h: gcos/vms switch position: 0:GCOS mode 1: virtual mode
8260 //   i: current or new product line peripheral type: 0:CPL, 1:NPL
8261 //   SPEED: 0000 = 8/70, 0100 = 8/52
8262 //   CPU: Processor number
8263 // DPS 8M processors:
8264 // C(Port interlace, Ports A-D) -> C(A) 0,3
8265 // 01 -> C(A) 4,5
8266 // C(Fault base switches) -> C(A) 6,12
8267 // 1 -> C(A) 13
8268 // 0000 -> C(A) 14,17
8269 // 111 -> C(A) 18,20
8270 // 00 -> C(A) 21,22
8271 // 1 -> C(A) 23
8272 // C(Processor mode sw) -> C(A) 24
8273 // 1 -> C(A) 25
8274 // 000 -> C(A) 26,28
8275 // C(Processor speed) -> C (A) 29,32
8276 
8277 // C(Processor number switches) -> C(A) 33,35
8278 
8279 // According to bound_gcos_.1.s.archive/gcos_fault_processor_.pl1 (L68/DPS):
8280 //
8281 // /* Set the A register to reflect switch info. */
8282 //                          mc.regs.a =
8283 //
8284 // /* (A-reg bits) */
8285 // /* (0-3) Port address expansion option:           */ (4)"0"b
8286 // /* (4-5) Reserved for future use:                 */ || (2)"0"b
8287 // /* (6-12) Processor fault base address switches:  */ || (7)"0"b
8288 // /* (13-16) L66 peripheral connectability:         */ || (4)"0"b
8289 // /* (17) Future use (must be zero):                */ || (1)"1"b
8290 // /* (18) BCD option installed:                     */ || (1)"1"b
8291 // /* (19) DPS type processor:                       */ || (1)"0"b
8292 // /* (20) 8K cache option installed:                */ || (1)"0"b
8293 // /* (21) Gear shift model processor:               */ || (1)"0"b
8294 // /* (22) Power patch option installed:             */ || (1)"0"b
8295 // /* (23) VMS-CU option installed - 66B' proc:      */ || (1)"0"b
8296 // /* (24) VMS-VU option installed - 66B proc:       */ || (1)"0"b
8297 // /* (25) Type processor (0) CPL, (1) DPSE-NPL:     */ || (1)"0"b
8298 // /* (26) 6025, 6605 or 6610 type processor:        */ || (1)"0"b
8299 // /* (27) 2K cache option installed:                */ || (1)"0"b
8300 // /* (28) Extended memory option installed:         */ || (1)"0"b
8301 // /* (29-30) cabinet (00) 8/70, (01) 8/52, (10) 862, (11) 846:          */ || (2)"0"b
8302 // /* (31) EIS option installed:                     */ || (1)"1"b
8303 // /* (32) (1) slow memory access, (0) fast memory:  */ || (1)"0"b
8304 // /* (33) (1) no instruction overlap, (0) overlap:  */ || (1)"0"b
8305 // /* (34-35) Processor number:                      */ ||unspec (mc.cpu_type);
8306 
8307                   cpu.rA = 0;
8308                   DPS8M_ (
8309                     cpu.rA |= (word36) ((cpu.switches.interlace[0] == 2 ?
8310                             1LL : 0LL) << (35- 0));
8311                     cpu.rA |= (word36) ((cpu.switches.interlace[1] == 2 ?
8312                             1LL : 0LL) << (35- 1));
8313                     cpu.rA |= (word36) ((cpu.switches.interlace[2] == 2 ?
8314                             1LL : 0LL) << (35- 2));
8315                     cpu.rA |= (word36) ((cpu.switches.interlace[3] == 2 ?
8316                             1LL : 0LL) << (35- 3));
8317                   )
8318 
8319                   if (cpu.tweaks.l68_mode)
8320                     // NO-OP
8321                     // cpu.rA |= (word36) ((00L)  /* 0b00 L68/DPS */
8322                     //          << (35- 5));
8323                     ;
8324                   else
8325                     cpu.rA |= (word36) ((01L)  /* 0b01 DPS8M */
8326                              << (35- 5));
8327                   cpu.rA |= (word36) ((cpu.switches.FLT_BASE & 0177LL)
8328                              << (35-12));
8329                   DPS8M_ (cpu.rA |= (word36) ((01L) /* 0b1 ID_PROM installed */
8330                              << (35-13));)
8331                   // NO-OP
8332                   // cpu.rA |= (word36) ((00L) // 0b0000
8333                   //           << (35-17));
8334                   //cpu.rA |= (word36) ((0b111L)
8335                               //<< (35-20));
8336                   // According to rsw.incl.pl1, Multics ignores this bit.
8337                   // NO-OP
8338                   // cpu.rA |= (word36) ((00L)  // 0b0 BCD option off
8339                   //           << (35-18));
8340                   if (cpu.tweaks.l68_mode)
8341                     // NO-OP
8342                     // cpu.rA |= (word36) ((00L)  // 0b0 L68/DPS option: L68
8343                     //        << (35-19));
8344                     ;
8345                   else
8346                     cpu.rA |= (word36) ((01L)  // 0b1 L68/DPS option: DPS
8347                             << (35-19));
8348                   DPS8M_ (
8349                                              // 8K cache
8350                                              // 0b0: not installed
8351                                              // 0b1: installed
8352                     cpu.rA |= (word36) ((cpu.switches.enable_cache ? 1 : 0)
8353                             << (35-20));
8354                     // NO-OP
8355                     // cpu.rA |= (word36) ((00L) // 0b00
8356                     //         << (35-22));
8357                     cpu.rA |= (word36) ((cpu.switches.procMode)  /* 0b1 DPS8M */
8358                             << (35-23));
8359                     cpu.rA |= (word36) ((cpu.switches.procMode & 1U)
8360                             << (35-24));
8361                     // NO-OP
8362                     // cpu.rA |= (word36) ((00L) // 0b0 new product line (CPL/NPL)
8363                     //         << (35-25));
8364                     // NO-OP
8365                     // cpu.rA |= (word36) ((00L) // 0b000
8366                     //         << (35-28));
8367                     cpu.rA |= (word36) ((cpu.options.proc_speed & 017LL)
8368                             << (35-32));
8369                   )
8370 
8371                   L68_ (
8372                     // NO-OP
8373                     // cpu.rA |= (word36) ((00L) // 0b0 2K cache disabled
8374                     //         << (35-27));
8375                     // NO-OP
8376                     // cpu.rA |= (word36) ((00L) // 0b0 GCOS mode extended memory disabled
8377                     //         << (35-28));
8378                     cpu.rA |= (word36) ((016L) // 0b1110 CPU ID
8379                             << (35-32));
8380                   )
8381                   cpu.rA |= (word36) ((cpu.switches.cpu_num & 07LL)
8382                             << (35-35));
8383                   break;
8384 
8385                 case 3: // configuration switches for ports E, F, G, H
8386                   if (!cpu.tweaks.l68_mode) { // DPS8M
8387                     cpu.rA = 0;
8388                     break;
8389                   }
8390                   // L68
8391 // y = 3:
8392 //
8393 //   0               0 0               1 1               2 2               3
8394 //   0               8 9               7 8               6 7               5
8395 //  -------------------------------------------------------------------------
8396 //  |      PORT E     |     PORT F      |     PORT G      |     PORT H      |
8397 //  -------------------------------------------------------------------------
8398 //  | ADR |j|k|l| MEM | ADR |j|k|l| MEM | ADR |j|k|l| MEM | ADR |j|k|l| MEM |
8399 //  -------------------------------------------------------------------------
8400 //
8401 //
8402 //   ADR: Address assignment switch setting for port
8403 //         This defines the base address for the SCU
8404 //   j: port enabled flag
8405 //   k: system initialize enabled flag
8406 //   l: interface enabled flag
8407 //   MEM coded memory size
8408 //     000 32K     2^15
8409 //     001 64K     2^16
8410 //     010 128K    2^17
8411 //     011 256K    2^18
8412 //     100 512K    2^19
8413 //     101 1024K   2^20
8414 //     110 2048K   2^21
8415 //     111 4096K   2^22
8416 
8417                   cpu.rA  = 0;
8418                   cpu.rA |= (word36) (cpu.switches.assignment  [4] & 07LL)
8419                             << (35 -  (2 +  0));
8420                   cpu.rA |= (word36) (cpu.switches.enable      [4] & 01LL)
8421                             << (35 -  (3 +  0));
8422                   cpu.rA |= (word36) (cpu.switches.init_enable [4] & 01LL)
8423                             << (35 -  (4 +  0));
8424                   cpu.rA |= (word36) (cpu.switches.interlace   [4] ? 1LL:0LL)
8425                             << (35 -  (5 +  0));
8426                   cpu.rA |= (word36) (cpu.switches.store_size  [4] & 07LL)
8427                             << (35 -  (8 +  0));
8428 
8429                   cpu.rA |= (word36) (cpu.switches.assignment  [5] & 07LL)
8430                             << (35 -  (2 +  9));
8431                   cpu.rA |= (word36) (cpu.switches.enable      [5] & 01LL)
8432                             << (35 -  (3 +  9));
8433                   cpu.rA |= (word36) (cpu.switches.init_enable [5] & 01LL)
8434                             << (35 -  (4 +  9));
8435                   cpu.rA |= (word36) (cpu.switches.interlace   [5] ? 1LL:0LL)
8436                             << (35 -  (5 +  9));
8437                   cpu.rA |= (word36) (cpu.switches.store_size  [5] & 07LL)
8438                             << (35 -  (8 +  9));
8439 
8440                   cpu.rA |= (word36) (cpu.switches.assignment  [6] & 07LL)
8441                             << (35 -  (2 + 18));
8442                   cpu.rA |= (word36) (cpu.switches.enable      [6] & 01LL)
8443                             << (35 -  (3 + 18));
8444                   cpu.rA |= (word36) (cpu.switches.init_enable [6] & 01LL)
8445                             << (35 -  (4 + 18));
8446                   cpu.rA |= (word36) (cpu.switches.interlace   [6] ? 1LL:0LL)
8447                             << (35 -  (5 + 18));
8448                   cpu.rA |= (word36) (cpu.switches.store_size  [6] & 07LL)
8449                             << (35 -  (8 + 18));
8450 
8451                   cpu.rA |= (word36) (cpu.switches.assignment  [7] & 07LL)
8452                             << (35 -  (2 + 27));
8453                   cpu.rA |= (word36) (cpu.switches.enable      [7] & 01LL)
8454                             << (35 -  (3 + 27));
8455                   cpu.rA |= (word36) (cpu.switches.init_enable [7] & 01LL)
8456                             << (35 -  (4 + 27));
8457                   cpu.rA |= (word36) (cpu.switches.interlace   [7] ? 1LL:0LL)
8458                             << (35 -  (5 + 27));
8459                   cpu.rA |= (word36) (cpu.switches.store_size  [7] & 07LL)
8460                             << (35 -  (8 + 27));
8461                   break;
8462 
8463                 case 4:
8464                   // I suspect the this is a L68 only, but AL39 says both
8465                   // port interlace and half/full size
8466                   // The DPS doesn't seem to have the half/full size switches
8467                   // so we'll always report full, and the interlace bits were
8468                   // squeezed into RSW 2
8469 
8470 //  0                       1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2           3
8471 //  0                       2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9           5
8472 // -------------------------------------------------------------------------
8473 // |                         | A | B | C | D | E | F | G | H |             |
8474 // |0 0 0 0 0 0 0 0 0 0 0 0 0---------------------------------0 0 0 0 0 0 0|
8475 // |                         |f|g|f|g|f|g|f|g|f|g|f|g|f|g|f|g|             |
8476 // -------------------------------------------------------------------------
8477 //                         13 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1             7
8478 
8479                   cpu.rA  = 0;
8480                   cpu.rA |= (word36) (cpu.switches.interlace [0] == 2 ?
8481                             1LL : 0LL) << (35-13);
8482                   cpu.rA |= (word36) (cpu.switches.interlace [1] == 2 ?
8483                             1LL : 0LL) << (35-15);
8484                   cpu.rA |= (word36) (cpu.switches.interlace [2] == 2 ?
8485                             1LL : 0LL) << (35-17);
8486                   cpu.rA |= (word36) (cpu.switches.interlace [3] == 2 ?
8487                             1LL : 0LL) << (35-19);
8488                   L68_ (
8489                     cpu.rA |= (word36) (cpu.switches.interlace [4] == 2 ?
8490                             1LL : 0LL) << (35-21);
8491                     cpu.rA |= (word36) (cpu.switches.interlace [5] == 2 ?
8492                             1LL : 0LL) << (35-23);
8493                     cpu.rA |= (word36) (cpu.switches.interlace [6] == 2 ?
8494                             1LL : 0LL) << (35-25);
8495                     cpu.rA |= (word36) (cpu.switches.interlace [7] == 2 ?
8496                             1LL : 0LL) << (35-27);
8497                   )
8498                   break;
8499 
8500                 default:
8501                   // XXX Guessing values; also we don't know if this is actually a fault
8502                   doFault (FAULT_IPR,
8503                            fst_ill_mod,
8504                            "Illegal register select value");
8505               }
8506 #if defined(TESTING)
8507             HDBGRegAW ("rsw");
8508 #endif
8509             SC_I_ZERO (cpu.rA == 0);
8510             SC_I_NEG (cpu.rA & SIGN36);
8511           }
8512           break;
8513 
8514         /// Privileged - System Control
8515 
8516         case x0 (0015):  // cioc
8517           {
8518             // cioc The system controller addressed by Y (i.e., contains
8519             // the word at Y) sends a connect signal to the port specified
8520             // by C(Y) 33,35.
8521             int cpu_port_num = lookup_cpu_mem_map (cpup, cpu.iefpFinalAddress);
8522             // If there is no port to that memory location, fault
8523             if (cpu_port_num < 0)
8524               {
8525                 doFault (FAULT_ONC, fst_onc_nem, "(cioc)");
8526               }
8527             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
8528               {
8529                 doFault (FAULT_ONC, fst_onc_nem, "(cioc)");
8530               }
8531             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
8532 
8533 // expander word
8534 // dcl  1 scs$reconfig_general_cow aligned external, /* Used during reconfig
8535 //                                                      ops. */
8536 //   2 pad bit (36) aligned,
8537 //   2 cow,                        /* Connect operand word, in odd location. */
8538 //   3 sub_mask bit (8) unaligned, /* Expander sub-port mask */
8539 //   3 mbz1 bit (13) unaligned,
8540 //   3 expander_command bit (3) unaligned,   /* Expander command. */
8541 //   3 mbz2 bit (9) unaligned,
8542 //   3 controller_port fixed bin (3) unaligned unsigned;/* controller port for
8543 //                                                          this CPU */
8544 
8545             word8 sub_mask = getbits36_8 (cpu.CY, 0);
8546             word3 expander_command = getbits36_3 (cpu.CY, 21);
8547             uint scu_port_num = (uint) getbits36_3 (cpu.CY, 33);
8548             scu_cioc (current_running_cpu_idx, (uint) scuUnitIdx, scu_port_num,
8549                       expander_command, sub_mask);
8550           }
8551           break;
8552 
8553         case x0 (0553):  // smcm
8554           {
8555             // C(TPR.CA)0,2 (C(TPR.CA)1,2 for the DPS 8M processor)
8556             // specify which processor port (i.e., which system
8557             // controller) is used.
8558             uint cpu_port_num;
8559             DPS8M_ (cpu_port_num = (cpu.TPR.CA >> 15) & 03;)
8560             L68_ (cpu_port_num = (cpu.TPR.CA >> 15) & 07;)
8561             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
8562               {
8563                 sim_warn ("smcm to non-existent controller on "
8564                           "cpu %d port %d\n",
8565                           current_running_cpu_idx, cpu_port_num);
8566                 break;
8567               }
8568             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
8569             t_stat rc = scu_smcm ((uint) scuUnitIdx,
8570                                   current_running_cpu_idx, cpu.rA, cpu.rQ);
8571             if (rc)
8572               return rc;
8573           }
8574           break;
8575 
8576         case x0 (0451):  // smic
8577           {
8578             // For the smic instruction, the first 2 or 3 bits of the addr
8579             // field of the instruction are used to specify which SCU.
8580             // 2 bits for the DPS8M.
8581             //int scuUnitIdx = getbits36_2 (TPR.CA, 0);
8582 
8583             // C(TPR.CA)0,2 (C(TPR.CA)1,2 for the DPS 8M processor)
8584             // specify which processor port (i.e., which system
8585             // controller) is used.
8586             uint cpu_port_num;
8587             DPS8M_ (cpu_port_num = (cpu.TPR.CA >> 15) & 03;)
8588             L68_ (cpu_port_num = (cpu.TPR.CA >> 15) & 07;)
8589             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
8590               {
8591                 DPS8M_ (return SCPE_OK;)
8592                 // L68
8593                 // CPTUR (cptUseFR) -- will be set by doFault
8594                 if (cpu_port_num == 0)
8595                   putbits36_4 (& cpu.faultRegister[0], 16, 010);
8596                 else if (cpu_port_num == 1)
8597                   putbits36_4 (& cpu.faultRegister[0], 20, 010);
8598                 else if (cpu_port_num == 2)
8599                   putbits36_4 (& cpu.faultRegister[0], 24, 010);
8600                 else if (cpu_port_num == 3)
8601                   putbits36 (& cpu.faultRegister[0], 28, 4, 010);
8602 // XXX What if the port is > 3?
8603                 doFault (FAULT_CMD, fst_cmd_ctl, "(smic)");
8604               }
8605             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
8606             t_stat rc = scu_smic ((uint) scuUnitIdx, current_running_cpu_idx,
8607                                   cpu_port_num, cpu.rA);
8608             if (rc)
8609               return rc;
8610           }
8611           break;
8612 
8613         case x0 (0057):  // sscr
8614           {
8615             //uint cpu_port_num = (cpu.TPR.CA >> 15) & 03;
8616             // Looking at privileged_mode_ut.alm, shift 10 bits...
8617             uint cpu_port_num;
8618             DPS8M_ (cpu_port_num = (cpu.TPR.CA >> 10) & 03;)
8619             L68_ (cpu_port_num = (cpu.TPR.CA >> 10) & 07;)
8620             if (! get_scu_in_use (current_running_cpu_idx, cpu_port_num))
8621               {
8622                 // CPTUR (cptUseFR) -- will be set by doFault
8623                 if (cpu_port_num == 0)
8624                   putbits36_4 (& cpu.faultRegister[0], 16, 010);
8625                 else if (cpu_port_num == 1)
8626                   putbits36_4 (& cpu.faultRegister[0], 20, 010);
8627                 else if (cpu_port_num == 2)
8628                   putbits36_4 (& cpu.faultRegister[0], 24, 010);
8629                 else
8630                   putbits36 (& cpu.faultRegister[0], 28, 4, 010);
8631                 doFault (FAULT_CMD, fst_cmd_ctl, "(sscr)");
8632               }
8633             uint scuUnitIdx = get_scu_idx (current_running_cpu_idx, cpu_port_num);
8634             t_stat rc = scu_sscr (cpup, (uint) scuUnitIdx, current_running_cpu_idx,
8635                                   cpu_port_num, cpu.iefpFinalAddress & MASK15,
8636                                   cpu.rA, cpu.rQ);
8637 
8638             if (rc)
8639               return rc;
8640           }
8641           break;
8642 
8643         // Privileged - Miscellaneous
8644 
8645         case x0 (0212):  // absa
8646           {
8647             word36 result;
8648             int rc = doABSA (cpup, & result);
8649             if (rc)
8650               return rc;
8651             cpu.rA = result;
8652 #if defined(TESTING)
8653             HDBGRegAW ("absa");
8654 #endif
8655             SC_I_ZERO (cpu.rA == 0);
8656             SC_I_NEG (cpu.rA & SIGN36);
8657           }
8658           break;
8659 
8660         case x0 (0616):  // dis
8661 
8662           if (! cpu.tweaks.dis_enable)
8663             {
8664               return STOP_STOP;
8665             }
8666 
8667           // XXX This is subtle; g7Pending below won't see the queued
8668           // g7Fault. I don't understand how the real hardware dealt
8669           // with this, but this seems to work. (I would hazard a guess
8670           // that DIS was doing a continuous FETCH/EXECUTE cycle
8671           // ('if !interrupt goto .'))
8672           advanceG7Faults (cpup);
8673 
8674           if ((! cpu.tweaks.tro_enable) &&
8675               (! sample_interrupts (cpup)) &&
8676               (sim_qcount () == 0))  // XXX If clk_svc is implemented it will
8677                                      // break this logic
8678             {
8679               sim_printf ("DIS@0%06o with no interrupts pending and"
8680                           " no events in queue\n", cpu.PPR.IC);
8681 #if defined(WIN_STDIO)
8682               sim_printf ("\nCycles = %llu\n",
8683 #else
8684               sim_printf ("\nCycles = %'llu\n",
8685 #endif /* if defined(WIN_STDIO) */
8686                           (unsigned long long)cpu.cycleCnt);
8687 #if defined(WIN_STDIO)
8688               sim_printf ("\nInstructions = %llu\n",
8689 #else
8690               sim_printf ("\nInstructions = %'llu\n",
8691 #endif /* if defined(WIN_STDIO) */
8692                           (unsigned long long)cpu.cycleCnt);
8693               longjmp (cpu.jmpMain, JMP_STOP);
8694             }
8695 
8696 // Multics/BCE halt
8697           if (cpu.PPR.PSR == 0430 && cpu.PPR.IC == 012)
8698               {
8699                 sim_printf ("BCE DIS causes CPU halt\n");
8700                 sim_debug (DBG_MSG, & cpu_dev, "BCE DIS causes CPU halt\n");
8701 #if defined(LOCKLESS)
8702                 bce_dis_called = true;
8703 #endif // LOCKLESS
8704                 longjmp (cpu.jmpMain, JMP_STOP);
8705               }
8706 
8707 
8708 
8709 
8710 
8711 
8712 
8713 
8714 
8715 
8716 
8717 
8718 
8719 
8720 
8721 
8722 
8723 
8724 
8725 
8726 #if defined(ROUND_ROBIN)
8727           if (cpu.PPR.PSR == 034 && cpu.PPR.IC == 03535)
8728               {
8729                 sim_printf ("[%lld] sys_trouble$die DIS causes CPU halt\n", cpu.cycleCnt);
8730                 sim_debug (DBG_MSG, & cpu_dev, "sys_trouble$die DIS causes CPU halt\n");
8731                 //longjmp (cpu.jmpMain, JMP_STOP);
8732                 cpu.isRunning = false;
8733               }
8734 #endif
8735           sim_debug (DBG_TRACEEXT, & cpu_dev, "entered DIS_cycle\n");
8736 
8737           // No operation takes place, and the processor does not
8738           // continue with the next instruction; it waits for a
8739           // external interrupt signal.
8740           // AND, according to pxss.alm, TRO
8741 
8742 // Bless NovaScale...
8743 //  DIS
8744 //
8745 //    NOTES:
8746 //
8747 //      1. The inhibit bit in this instruction only affects the recognition
8748 //         of a Timer Runout (TROF) fault.
8749 //
8750 //         Inhibit ON delays the recognition of a TROF until the processor
8751 //         enters Slave mode.
8752 //
8753 //         Inhibit OFF allows the TROF to interrupt the DIS state.
8754 //
8755 //      2. For all other faults and interrupts, the inhibit bit is ignored.
8756 //
8757 //      3. The use of this instruction in the Slave or Master mode causes a
8758 //         Command fault.
8759 
8760           if (sample_interrupts (cpup))
8761             {
8762               sim_debug (DBG_TRACEEXT, & cpu_dev, "DIS sees an interrupt\n");
8763               cpu.interrupt_flag = true;
8764               break;
8765             }
8766 // Implementing TRO according to AL39 for the DIS cause the idle systems to
8767 // hang in the DIS instruction. Revert back to the old behavior.
8768 
8769           if (GET_I (cpu.cu.IWB) ? bG7PendingNoTRO (cpup) : bG7Pending (cpup))
8770 
8771 
8772 
8773 
8774 
8775 
8776 
8777 
8778             {
8779               sim_debug (DBG_TRACEEXT, & cpu_dev, "DIS sees a TRO\n");
8780               cpu.g7_flag = true;
8781               break;
8782             }
8783           else
8784             {
8785               sim_debug (DBG_TRACEEXT, & cpu_dev, "DIS refetches\n");
8786 #if defined(ROUND_ROBIN)
8787               if (cpu.tweaks.isolts_mode)
8788                 {
8789                   //sim_printf ("stopping CPU %c\n", current_running_cpu_idx + 'A');
8790                   cpu.isRunning = false;
8791                 }
8792 #endif
8793               return CONT_DIS;
8794             }
8795 
8796         /// POINTER REGISTER INSTRUCTIONS
8797 
8798         /// PRIVILEGED INSTRUCTIONS
8799 
8800         /// Privileged - Register Load
8801 
8802         /// Privileged - Clear Associative Memory
8803 
8804         /// EIS - Address Register Load
8805 
8806                          // aarn
8807         case x1 (0560):  // aar0
8808         case x1 (0561):  // aar1
8809         case x1 (0562):  // aar2
8810         case x1 (0563):  // aar3
8811         case x1 (0564):  // aar4
8812         case x1 (0565):  // aar5
8813         case x1 (0566):  // aar6
8814         case x1 (0567):  // aar7
8815           {
8816             // For n = 0, 1, ..., or 7 as determined by operation code
8817             PNL (L68_ (DU_CYCLE_DDU_LDEA;))
8818 
8819             if (getbits36_1 (cpu.CY, 23) != 0)
8820               doFault (FAULT_IPR,
8821                        fst_ill_proc,
8822                        "aarn C(Y)23 != 0");
8823 
8824             uint32 n = opcode10 & 07;  // get
8825             CPTUR (cptUsePRn + n);
8826 
8827             // C(Y)0,17 -> C(ARn.WORDNO)
8828             cpu.AR[n].WORDNO = GETHI (cpu.CY);
8829 
8830             uint TA = getbits36_2 (cpu.CY, 21);
8831             uint CN = getbits36_3 (cpu.CY, 18);
8832 
8833             switch (TA)
8834               {
8835                 case CTA4:  // 2
8836                   // If C(Y)21,22 = 10 (TA code = 2), then
8837                   //   C(Y)18,20 / 2 -> C(ARn.CHAR)
8838                   //   4 * (C(Y)18,20)mod2 + 1 -> C(ARn.BITNO)
8839 
8840                   // According to AL39, CN is translated:
8841                   //  CN   CHAR  BIT
8842                   //   0      0    1
8843                   //   1      0    5
8844                   //   2      1    1
8845                   //   3      1    5
8846                   //   4      2    1
8847                   //   5      2    5
8848                   //   6      3    1
8849                   //   7      3    5
8850                   //SET_AR_CHAR_BITNO (n, CN/2, 4 * (CN % 2) + 1);
8851 
8852                   // According to ISOLTS ps805
8853                   //  CN   CHAR  BIT
8854                   //   0      0    0
8855                   //   1      0    5
8856                   //   2      1    0
8857                   //   3      1    5
8858                   //   4      2    0
8859                   //   5      2    5
8860                   //   6      3    0
8861                   //   7      3    5
8862                   SET_AR_CHAR_BITNO (n, (word2) (CN/2), (CN % 2) ? 5 : 0);
8863 
8864                   break;
8865 
8866                 case CTA6:  // 1
8867                   // If C(Y)21,22 = 01 (TA code = 1) and C(Y)18,20 = 110
8868                   // or 111 an illegal procedure fault occurs.
8869                   if (CN > 5)
8870                     {
8871                       cpu.AR[n].WORDNO = 0;
8872                       SET_AR_CHAR_BITNO (n, 0, 0);
8873                       doFault (FAULT_IPR, fst_ill_proc, "aarn TN > 5");
8874                     }
8875 
8876                   // If C(Y)21,22 = 01 (TA code = 1), then
8877                   //   (6 * C(Y)18,20) / 9 -> C(ARn.CHAR)
8878                   //   (6 * C(Y)18,20)mod9 -> C(ARn.BITNO)
8879                   SET_AR_CHAR_BITNO (n, (word2) ((6 * CN) / 9),
8880                                      (6 * CN) % 9);
8881                   break;
8882 
8883                 case CTA9:  // 0
8884                   // If C(Y)21,22 = 00 (TA code = 0), then
8885                   //   C(Y)18,19 -> C(ARn.CHAR)
8886                   //   0000 -> C(ARn.BITNO)
8887                   // remember, 9-bit CN's are funky
8888                   SET_AR_CHAR_BITNO (n, (word2) (CN >> 1), 0);
8889                   break;
8890 
8891                 case CTAILL: // 3
8892                   // If C(Y)21,22 = 11 (TA code = 3) an illegal procedure
8893                   // fault occurs.
8894                   cpu.AR[n].WORDNO = 0;
8895                   SET_AR_CHAR_BITNO (n, 0, 0);
8896 #if defined(TESTING)
8897                   HDBGRegARW (n, "aarn");
8898 #endif
8899                   doFault (FAULT_IPR, fst_ill_proc, "aarn TA = 3");
8900               }
8901 #if defined(TESTING)
8902             HDBGRegARW (n, "aarn");
8903 #endif
8904           }
8905           break;
8906 
8907         // Load Address Register n
8908                         // larn
8909         case x1 (0760): // lar0
8910         case x1 (0761): // lar1
8911         case x1 (0762): // lar2
8912         case x1 (0763): // lar3
8913         case x1 (0764): // lar4
8914         case x1 (0765): // lar5
8915         case x1 (0766): // lar6
8916         case x1 (0767): // lar7
8917           {
8918             // For n = 0, 1, ..., or 7 as determined by operation code
8919             //    C(Y)0,23 -> C(ARn)
8920             PNL (L68_ (DU_CYCLE_DDU_LDEA;))
8921 
8922             uint32 n = opcode10 & 07;  // get n
8923             CPTUR (cptUsePRn + n);
8924             cpu.AR[n].WORDNO = GETHI (cpu.CY);
8925 // AL-38 implies CHAR/BITNO, but ISOLTS requires PR.BITNO.
8926             SET_AR_CHAR_BITNO (n,  getbits36_2 (cpu.CY, 18),
8927                                getbits36_4 (cpu.CY, 20));
8928 #if defined(TESTING)
8929             HDBGRegARW (n, "larn");
8930 #endif
8931           }
8932           break;
8933 
8934         // lareg - Load Address Registers
8935 
8936         case x1 (0463):  // lareg
8937           PNL (L68_ (DU_CYCLE_DDU_LDEA;))
8938 
8939           for (uint32 n = 0 ; n < 8 ; n += 1)
8940             {
8941               CPTUR (cptUsePRn + n);
8942               word36 tmp36 = cpu.Yblock8[n];
8943               cpu.AR[n].WORDNO = getbits36_18 (tmp36, 0);
8944               SET_AR_CHAR_BITNO (n,  getbits36_2 (tmp36, 18),
8945                                  getbits36_4 (tmp36, 20));
8946 #if defined(TESTING)
8947               HDBGRegARW (n, "lareg");
8948 #endif
8949             }
8950           break;
8951 
8952         // lpl - Load Pointers and Lengths
8953 
8954         case x1 (0467):  // lpl
8955           PNL (L68_ (DU_CYCLE_DDU_LDEA;))
8956           words2du (cpup, cpu.Yblock8);
8957           break;
8958 
8959         // narn -  (G'Kar?) Numeric Descriptor to Address Register n
8960                         // narn
8961         case x1 (0660): // nar0
8962         case x1 (0661): // nar1
8963         case x1 (0662): // nar2
8964         case x1 (0663): // nar3
8965         case x1 (0664): // nar4
8966         case x1 (0665): // nar5
8967         case x1 (0666): // nar6 beware!!!! :-)
8968         case x1 (0667): // nar7
8969           {
8970             // For n = 0, 1, ..., or 7 as determined by operation code
8971             PNL (L68_ (DU_CYCLE_DDU_LDEA;))
8972 
8973             uint32 n = opcode10 & 07;  // get
8974             CPTUR (cptUsePRn + n);
8975 
8976             // C(Y)0,17 -> C(ARn.WORDNO)
8977             cpu.AR[n].WORDNO = GETHI (cpu.CY);
8978 
8979             uint TN = getbits36_1 (cpu.CY, 21); // C(Y) 21
8980             uint CN = getbits36_3 (cpu.CY, 18); // C(Y) 18-20
8981 
8982             switch(TN)
8983               {
8984                 case CTN4:   // 1
8985                     // If C(Y)21 = 1 (TN code = 1), then
8986                     //   (C(Y)18,20) / 2 -> C(ARn.CHAR)
8987                     //   4 * (C(Y)18,20)mod2 + 1 -> C(ARn.BITNO)
8988 
8989                     // According to AL39, CN is translated:
8990                     //  CN   CHAR  BIT
8991                     //   0      0    1
8992                     //   1      0    5
8993                     //   2      1    1
8994                     //   3      1    5
8995                     //   4      2    1
8996                     //   5      2    5
8997                     //   6      3    1
8998                     //   7      3    5
8999                     //SET_AR_CHAR_BITNO (n, CN/2, 4 * (CN % 2) + 1);
9000 
9001                     // According to ISOLTS ps805
9002                     //  CN   CHAR  BIT
9003                     //   0      0    0
9004                     //   1      0    5
9005                     //   2      1    0
9006                     //   3      1    5
9007                     //   4      2    0
9008                     //   5      2    5
9009                     //   6      3    0
9010                     //   7      3    5
9011                     SET_AR_CHAR_BITNO (n, (word2) (CN/2), (CN % 2) ? 5 : 0);
9012 
9013                     break;
9014 
9015                 case CTN9:  // 0
9016                   // If C(Y)21 = 0 (TN code = 0) and C(Y)20 = 1 an
9017                   // illegal procedure fault occurs.
9018                   if ((CN & 1) != 0)
9019                     doFault (FAULT_IPR, fst_ill_proc, "narn N9 and CN odd");
9020                   // The character number is in bits 18-19; recover it
9021                   CN >>= 1;
9022                   // If C(Y)21 = 0 (TN code = 0), then
9023                   //   C(Y)18,20 -> C(ARn.CHAR)
9024                   //   0000 -> C(ARn.BITNO)
9025                   SET_AR_CHAR_BITNO (n, (word2) CN, 0);
9026                   break;
9027               }
9028 #if defined(TESTING)
9029             HDBGRegARW (n, "narn");
9030 #endif
9031           }
9032           break;
9033 
9034         /// EIS - Address Register Store
9035 
9036         // aran Address Register n to Alphanumeric Descriptor
9037 
9038                         // aran
9039         case x1 (0540): // ara0
9040         case x1 (0541): // ara1
9041         case x1 (0542): // ara2
9042         case x1 (0543): // ara3
9043         case x1 (0544): // ara4
9044         case x1 (0545): // ara5
9045         case x1 (0546): // ara6
9046         case x1 (0547): // ara7
9047             {
9048                 // The alphanumeric descriptor is fetched from Y and C(Y)21,22
9049                 // (TA field) is examined to determine the data type described.
9050                 PNL (L68_ (DU_CYCLE_DDU_STEA;))
9051 
9052                 uint TA = getbits36_2 (cpu.CY, 21);
9053 
9054                 // If C(Y)21,22 = 11 (TA code = 3) or C(Y)23 = 1 (unused bit),
9055                 // an illegal procedure fault occurs.
9056                 if (TA == 03) {
9057                   dlyDoFault (FAULT_IPR, fst_ill_proc, "ARAn tag == 3");
9058                   break;
9059                 }
9060                 if (getbits36_1 (cpu.CY, 23) != 0) {
9061                   dlyDoFault (FAULT_IPR, fst_ill_proc, "ARAn b23 == 1");
9062                   break;
9063                 }
9064 
9065                 uint32 n = opcode10 & 07;  // get
9066                 CPTUR (cptUsePRn + n);
9067                 // For n = 0, 1, ..., or 7 as determined by operation code
9068 
9069                 // C(ARn.WORDNO) -> C(Y)0,17
9070                 putbits36_18 (& cpu.CY, 0, cpu.AR[n].WORDNO & MASK18);
9071 
9072                 // If TA = 1 (6-bit data) or TA = 2 (4-bit data), C(ARn.CHAR)
9073                 // and C(ARn.BITNO) are translated to an equivalent character
9074                 // position that goes to C(Y)18,20.
9075 
9076                 int CN = 0;
9077 
9078                 switch (TA)
9079                 {
9080                     case CTA4:  // 2
9081                         // If C(Y)21,22 = 10 (TA code = 2), then
9082                         // (9 * C(ARn.CHAR) + C(ARn.BITNO) - 1) / 4 -> C(Y)18,20
9083                         CN = (9 * GET_AR_CHAR (n) + GET_AR_BITNO (n) - 1) / 4;
9084                         putbits36_3 (& cpu.CY, 18, (word3) CN & MASK3);
9085                         break;
9086 
9087                     case CTA6:  // 1
9088                         // If C(Y)21,22 = 01 (TA code = 1), then
9089                         // (9 * C(ARn.CHAR) + C(ARn.BITNO)) / 6 -> C(Y)18,20
9090                         CN = (9 * GET_AR_CHAR (n) + GET_AR_BITNO (n)) / 6;
9091                         putbits36_3 (& cpu.CY, 18, (word3) CN & MASK3);
9092                         break;
9093 
9094                     case CTA9:  // 0
9095                         // If C(Y)21,22 = 00 (TA code = 0), then
9096                         //   C(ARn.CHAR) -> C(Y)18,19
9097                         //   0 -> C(Y)20
9098                         putbits36_3 (& cpu.CY, 18,
9099                                      (word3) ((GET_AR_CHAR (n) & MASK2) << 1));
9100                         break;
9101                 }
9102               cpu.zone = 0777777700000;
9103               cpu.useZone = true;
9104             }
9105             break;
9106 
9107         // arnn Address Register n to Numeric Descriptor
9108 
9109                         // aarn
9110         case x1 (0640): // aar0
9111         case x1 (0641): // aar1
9112         case x1 (0642): // aar2
9113         case x1 (0643): // aar3
9114         case x1 (0644): // aar4
9115         case x1 (0645): // aar5
9116         case x1 (0646): // aar6
9117         case x1 (0647): // aar7
9118             {
9119                 PNL (L68_ (DU_CYCLE_DDU_STEA;))
9120                 uint32 n = opcode10 & 07;  // get register #
9121                 CPTUR (cptUsePRn + n);
9122 
9123                 // The Numeric descriptor is fetched from Y and C(Y)21,22 (TA
9124                 // field) is examined to determine the data type described.
9125 
9126                 uint TN = getbits36_1 (cpu.CY, 21); // C(Y) 21
9127 
9128                 // For n = 0, 1, ..., or 7 as determined by operation code
9129                 // C(ARn.WORDNO) -> C(Y)0,17
9130                 putbits36_18 (& cpu.CY, 0, cpu.AR[n].WORDNO & MASK18);
9131 
9132                 switch (TN)
9133                 {
9134                     case CTN4:  // 1
9135                       {
9136                         // If C(Y)21 = 1 (TN code = 1) then
9137                         //   (9 * C(ARn.CHAR) + C(ARn.BITNO) - 1) / 4 ->
9138                         //     C(Y)18,20
9139                         word3 CN = (9 * GET_AR_CHAR (n) +
9140                                     GET_AR_BITNO (n) - 1) / 4;
9141                         putbits36_3 (& cpu.CY, 18, CN & MASK3);
9142                         break;
9143                       }
9144                     case CTN9:  // 0
9145                         // If C(Y)21 = 0 (TN code = 0), then
9146                         //   C(ARn.CHAR) -> C(Y)18,19
9147                         //   0 -> C(Y)20
9148                         putbits36_3 (& cpu.CY, 18,
9149                                      (word3) ((GET_AR_CHAR (n) & MASK2) << 1));
9150                         break;
9151                 }
9152               cpu.zone = 0777777700000;
9153               cpu.useZone = true;
9154             }
9155             break;
9156 
9157         // sarn Store Address Register n
9158 
9159                         // sarn
9160         case x1 (0740): // sar0
9161         case x1 (0741): // sar1
9162         case x1 (0742): // sar2
9163         case x1 (0743): // sar3
9164         case x1 (0744): // sar4
9165         case x1 (0745): // sar5
9166         case x1 (0746): // sar6
9167         case x1 (0747): // sar7
9168             //For n = 0, 1, ..., or 7 as determined by operation code
9169             //  C(ARn) -> C(Y)0,23
9170             //  C(Y)24,35 -> unchanged
9171             {
9172                 PNL (L68_ (DU_CYCLE_DDU_STEA;))
9173                 uint32 n = opcode10 & 07;  // get n
9174                 CPTUR (cptUsePRn + n);
9175                 putbits36 (& cpu.CY,  0, 18, cpu.PR[n].WORDNO);
9176 // AL-39 implies CHAR/BITNO, but ISOLTS test 805 requires BITNO
9177                 putbits36 (& cpu.CY, 18, 2, GET_AR_CHAR (n));
9178                 putbits36 (& cpu.CY, 20, 4, GET_AR_BITNO (n));
9179                 //putbits36 (& cpu.CY, 18, 6, GET_PR_BITNO (n));
9180                 cpu.zone = 0777777770000;
9181                 cpu.useZone = true;
9182             }
9183           break;
9184 
9185         // sareg Store Address Registers
9186 
9187         case x1 (0443):  // sareg
9188             // a:AL39/ar1 According to ISOLTS ps805, the BITNO data is stored
9189             // in BITNO format, not CHAR/BITNO.
9190             PNL (L68_ (DU_CYCLE_DDU_STEA;))
9191             (void)memset (cpu.Yblock8, 0, sizeof (cpu.Yblock8));
9192             for (uint32 n = 0 ; n < 8 ; n += 1)
9193             {
9194                 CPTUR (cptUsePRn + n);
9195                 word36 arx = 0;
9196                 putbits36 (& arx,  0, 18, cpu.PR[n].WORDNO);
9197                 putbits36 (& arx, 18,  2, GET_AR_CHAR (n));
9198                 putbits36 (& arx, 20,  4, GET_AR_BITNO (n));
9199                 cpu.Yblock8[n] = arx;
9200             }
9201             break;
9202 
9203         // spl Store Pointers and Lengths
9204 
9205         case x1 (0447):  // spl
9206             PNL (L68_ (DU_CYCLE_DDU_STEA;))
9207             du2words (cpup, cpu.Yblock8);
9208           break;
9209 
9210         /// EIS - Address Register Special Arithmetic
9211 
9212         // a4bd Add 4-bit Displacement to Address Register 5
9213 
9214         case x1 (0502):  // a4bd
9215           asxbd (cpup, 4, false);
9216           break;
9217 
9218         // a6bd Add 6-bit Displacement to Address Register
9219 
9220         case x1 (0501):  // a6bd
9221           asxbd (cpup, 6, false);
9222           break;
9223 
9224         // a9bd Add 9-bit Displacement to Address Register
9225 
9226         case x1 (0500):  // a9bd
9227           asxbd (cpup, 9, false);
9228           break;
9229 
9230         // abd Add Bit Displacement to Address Register
9231 
9232         case x1 (0503):  // abd
9233           asxbd (cpup, 1, false);
9234           break;
9235 
9236         // awd Add Word Displacement to Address Register
9237 
9238         case x1 (0507):  // awd
9239           asxbd (cpup, 36, false);
9240           break;
9241 
9242         // s4bd Subtract 4-bit Displacement from Address Register
9243 
9244         case x1 (0522):  // s4bd
9245           asxbd (cpup, 4, true);
9246           break;
9247 
9248         // s6bd Subtract 6-bit Displacement from Address Register
9249 
9250         case x1 (0521):  // s6bd
9251           asxbd (cpup, 6, true);
9252           break;
9253 
9254         // s9bd Subtract 9-bit Displacement from Address Register
9255 
9256         case x1 (0520):  // s9bd
9257           asxbd (cpup, 9, true);
9258           break;
9259 
9260         // sbd Subtract Bit Displacement from Address Register
9261 
9262         case x1 (0523):  // sbd
9263           asxbd (cpup, 1, true);
9264           break;
9265 
9266         // swd Subtract Word Displacement from Address Register
9267 
9268         case x1 (0527):  // swd
9269           asxbd (cpup, 36, true);
9270           break;
9271 
9272         /// EIS = Alphanumeric Compare
9273 
9274         case x1 (0106):  // cmpc
9275           cmpc (cpup);
9276           break;
9277 
9278         case x1 (0120):  // scd
9279           scd (cpup);
9280           break;
9281 
9282         case x1 (0121):  // scdr
9283           scdr (cpup);
9284           break;
9285 
9286         case x1 (0124):  // scm
9287           scm (cpup);
9288           break;
9289 
9290         case x1 (0125):  // scmr
9291           scmr (cpup);
9292           break;
9293 
9294         case x1 (0164):  // tct
9295           tct (cpup);
9296           break;
9297 
9298         case x1 (0165):  // tctr
9299           tctr (cpup);
9300           break;
9301 
9302         /// EIS - Alphanumeric Move
9303 
9304         case x1 (0100):  // mlr
9305           mlr (cpup);
9306           break;
9307 
9308         case x1 (0101):  // mrl
9309           mrl (cpup);
9310           break;
9311 
9312         case x1 (0020):  // mve
9313           mve (cpup);
9314           break;
9315 
9316         case x1 (0160):  // mvt
9317           mvt (cpup);
9318           break;
9319 
9320         /// EIS - Numeric Compare
9321 
9322         case x1 (0303):  // cmpn
9323           cmpn (cpup);
9324           break;
9325 
9326         /// EIS - Numeric Move
9327 
9328         case x1 (0300):  // mvn
9329           mvn (cpup);
9330           break;
9331 
9332         case x1 (0024):   // mvne
9333           mvne (cpup);
9334           break;
9335 
9336         /// EIS - Bit String Combine
9337 
9338         case x1 (0060):   // csl
9339           csl (cpup);
9340           break;
9341 
9342         case x1 (0061):   // csr
9343           csr (cpup);
9344           break;
9345 
9346         /// EIS - Bit String Compare
9347 
9348         case x1 (0066):   // cmpb
9349           cmpb (cpup);
9350           break;
9351 
9352         /// EIS - Bit String Set Indicators
9353 
9354         case x1 (0064):   // sztl
9355           // The execution of this instruction is identical to the Combine
9356           // Bit Strings Left (csl) instruction except that C(BOLR)m is
9357           // not placed into C(Y-bit2)i-1.
9358           sztl (cpup);
9359           break;
9360 
9361         case x1 (0065):   // sztr
9362           // The execution of this instruction is identical to the Combine
9363           // Bit Strings Left (csr) instruction except that C(BOLR)m is
9364           // not placed into C(Y-bit2)i-1.
9365           sztr (cpup);
9366           break;
9367 
9368         /// EIS -- Data Conversion
9369 
9370         case x1 (0301):  // btd
9371           btd (cpup);
9372           break;
9373 
9374         case x1 (0305):  // dtb
9375           dtb (cpup);
9376           break;
9377 
9378         /// EIS - Decimal Addition
9379 
9380         case x1 (0202):  // ad2d
9381             ad2d (cpup);
9382             break;
9383 
9384         case x1 (0222):  // ad3d
9385             ad3d (cpup);
9386             break;
9387 
9388         /// EIS - Decimal Subtraction
9389 
9390         case x1 (0203):  // sb2d
9391             sb2d (cpup);
9392             break;
9393 
9394         case x1 (0223):  // sb3d
9395             sb3d (cpup);
9396             break;
9397 
9398         /// EIS - Decimal Multiplication
9399 
9400         case x1 (0206):  // mp2d
9401             mp2d (cpup);
9402             break;
9403 
9404         case x1 (0226):  // mp3d
9405             mp3d (cpup);
9406             break;
9407 
9408         /// EIS - Decimal Division
9409 
9410         case x1 (0207):  // dv2d
9411             dv2d (cpup);
9412             break;
9413 
9414         case x1 (0227):  // dv3d
9415             dv3d (cpup);
9416             break;
9417 
9418         case x1 (0420):  // emcall instruction Custom, for an emulator call for scp
9419         {
9420             if (cpu.tweaks.enable_emcall) {
9421               int ret = emCall (cpup);
9422               if (ret)
9423                 return ret;
9424               break;
9425             }
9426             goto unimp;
9427         }
9428 
9429         default:
9430         unimp:
9431           if (cpu.tweaks.halt_on_unimp)
9432             return STOP_STOP;
9433           doFault (FAULT_IPR,
9434                    fst_ill_op,
9435                    "Illegal instruction");
9436       }
9437     L68_ (
9438       cpu.ou.STR_OP = (is_ou && (i->info->flags & (STORE_OPERAND | STORE_YPAIR))) ? 1 : 0;
9439       cpu.ou.cycle |= ou_GOF;
9440       if (cpu.MR_cache.emr && cpu.MR_cache.ihr && is_ou)
9441         add_l68_OU_history (cpup);
9442       if (cpu.MR_cache.emr && cpu.MR_cache.ihr && is_du)
9443         add_l68_DU_history (cpup);
9444     )
9445     return SCPE_OK;
9446 }
9447 
9448 #include <ctype.h>
9449 #include <time.h>
9450 
9451 /*
9452  * emulator call instruction. Do whatever address field sez' ....
9453  */
9454 
9455 //static clockid_t clockID;
9456 //static struct timespec startTime;
9457 static uv_rusage_t startTime;
9458 static unsigned long long startInstrCnt;
9459 
9460 static int emCall (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
9461 {
9462     DCDstruct * i = & cpu.currentInstruction;
9463 
9464 // The address is absolute address of a structure consisting of a
9465 // operation code word and optional following words containing
9466 // data for the operation.
9467 
9468    word36 op = M[i->address];
9469    switch (op)
9470      {
9471        // OP 1: Print the unsigned decimal representation of the first data
9472        //       word.
9473        case 1:
9474          sim_printf ("%lld\n", (long long int) M[i->address+1]);
9475          break;
9476 
9477        // OP 2: Halt the simulation
9478        case 2:
9479 #if defined(LOCKLESS)
9480          bce_dis_called = true;
9481 #endif
9482          return STOP_STOP;
9483 
9484        // OP 3: Start CPU clock
9485        case 3:
9486          startInstrCnt = cpu.instrCnt;
9487          uv_getrusage (& startTime);
9488          break;
9489 
9490        // OP 4: Report CPU clock
9491        case 4:
9492          {
9493 #define ns_sec  (1000000000L)
9494 #define ns_msec (1000000000L / 1000L)
9495 #define ns_usec (1000000000L / 1000L / 1000L)
9496            uv_rusage_t now;
9497            uv_getrusage (& now);
9498            uint64_t start            = (uint64_t)(startTime.ru_utime.tv_usec * 1000 +
9499                                                   startTime.ru_utime.tv_sec * ns_sec);
9500            uint64_t stop             = (uint64_t)(now.ru_utime.tv_usec * 1000 +
9501                                                   now.ru_utime.tv_sec * ns_sec);
9502            uint64_t delta            = stop - start;
9503            uint64_t seconds          = delta / ns_sec;
9504            uint64_t milliseconds     = (delta / ns_msec) % 1000;
9505            uint64_t microseconds     = (delta / ns_usec) % 1000;
9506            uint64_t nanoseconds      = delta  % 1000;
9507            unsigned long long nInsts = cpu.instrCnt - startInstrCnt;
9508            double secs               = (double)(((long double) delta) / ((long double) ns_sec));
9509            long double ips           = (long double)(((long double) nInsts) / ((long double) secs));
9510            long double mips          = ips / 1000000.0L;
9511 
9512 #if defined(WIN_STDIO)
9513            sim_printf ("CPU time %llu.%03llu,%03llu,%03llu\n",
9514 #else
9515            sim_printf ("CPU time %'llu.%03llu,%03llu,%03llu\n",
9516 #endif /* if defined(WIN_STDIO) */
9517                        (unsigned long long) seconds,
9518                        (unsigned long long) milliseconds,
9519                        (unsigned long long) microseconds,
9520                        (unsigned long long) nanoseconds);
9521 #if defined(WIN_STDIO)
9522            sim_printf ("%llu instructions\n", (unsigned long long) nInsts);
9523            sim_printf ("%f MIPS\n", (double) mips);
9524 #else
9525            sim_printf ("%'llu instructions\n", (unsigned long long) nInsts);
9526            sim_printf ("%'f MIPS\n", (double) mips);
9527 #endif /* if defined(WIN_STDIO) */
9528            break;
9529          }
9530        default:
9531          sim_printf ("emcall unknown op %llo\n", (unsigned long long)op);
9532       }
9533     return 0;
9534 
9535 
9536 
9537 
9538 
9539 
9540 
9541 
9542 
9543 
9544 
9545 
9546 
9547 
9548 
9549 
9550 
9551 
9552 
9553 
9554 
9555 
9556 
9557 
9558 
9559 
9560 
9561 
9562 
9563 
9564 
9565 
9566 
9567 
9568 
9569 
9570 
9571 
9572 
9573 
9574 
9575 
9576 
9577 
9578 
9579 
9580 
9581 
9582 
9583 
9584 
9585 
9586 
9587 
9588 
9589 
9590 
9591 
9592 
9593 
9594 
9595 
9596 
9597 
9598 
9599 
9600 
9601 
9602 
9603 
9604 
9605 
9606 
9607 
9608 
9609 
9610 
9611 
9612 
9613 
9614 
9615 
9616 
9617 
9618 
9619 
9620 
9621 
9622 
9623 
9624 
9625 
9626 
9627 
9628 
9629 
9630 
9631 
9632 
9633 
9634 
9635 
9636 
9637 
9638 
9639 
9640 
9641 
9642 
9643 
9644 
9645 
9646 
9647 
9648 
9649 
9650 
9651 
9652 
9653 
9654 
9655 
9656 
9657 
9658 
9659 
9660 
9661 
9662 
9663 
9664 
9665 
9666 
9667 
9668 
9669 
9670 
9671 
9672 
9673 
9674 
9675 
9676 
9677 
9678 
9679 
9680 
9681 
9682 
9683 
9684 
9685 
9686 
9687 
9688 
9689 
9690 
9691 
9692 
9693 
9694 
9695 
9696 
9697 
9698 
9699 
9700 
9701 
9702 
9703 
9704 
9705 
9706 
9707 
9708 
9709 
9710 
9711 
9712 
9713 
9714 
9715 
9716 
9717 
9718 
9719 
9720 
9721 
9722 
9723 
9724 
9725   }
9726 
9727 // CANFAULT
9728 static int doABSA (cpu_state_t * cpup, word36 * result)
     /* [previous][next][first][last][top][bottom][index][help] */
9729   {
9730     word36 res;
9731     sim_debug (DBG_APPENDING, & cpu_dev, "absa CA:%08o\n", cpu.TPR.CA);
9732 
9733     //if (get_addr_mode (cpup) == ABSOLUTE_mode && ! cpu.isb29)
9734     //if (get_addr_mode (cpup) == ABSOLUTE_mode && ! cpu.went_appending) // ISOLTS-860
9735     if (get_addr_mode (cpup) == ABSOLUTE_mode && ! (cpu.cu.XSF || cpu.currentInstruction.b29)) // ISOLTS-860
9736       {
9737         * result = ((word36) (cpu.TPR.CA & MASK18)) << 12; // 24:12 format
9738         return SCPE_OK;
9739       }
9740 
9741     // ABSA handles directed faults differently, so a special append cycle is
9742     // needed.
9743     // do_append_cycle also provides WAM support, which is required by
9744     // ISOLTS-860 02
9745     //   res = (word36) do_append_cycle (cpu.TPR.CA & MASK18, ABSA_CYCLE, NULL,
9746     //                                   0) << 12;
9747     //res = (word36) do_append_cycle (ABSA_CYCLE, NULL, 0) << 12;
9748     res = (word36) doAppendCycleABSA (cpup, NULL, 0) << 12;
9749 
9750     * result = res;
9751 
9752     return SCPE_OK;
9753   }
9754 
9755 void doRCU (cpu_state_t * cpup)
     /* [previous][next][first][last][top][bottom][index][help] */
9756   {
9757 #if defined(LOOPTRC)
9758 elapsedtime ();
9759  sim_printf (" rcu to %05o:%06o  PSR:IC %05o:%06o\r\n",
9760              (cpu.Yblock8[0]>>18)&MASK15, (cpu.Yblock8[4]>>18)&MASK18, cpu.PPR.PSR, cpu.PPR.IC);
9761 #endif
9762 
9763     if_sim_debug (DBG_FAULT, & cpu_dev)
9764       {
9765         dump_words(cpup, cpu.Yblock8);
9766         //for (int i = 0; i < 8; i ++)
9767         //  {
9768         //    sim_debug (DBG_FAULT, & cpu_dev, "RCU %d %012"PRIo64"\n", i,
9769         //               cpu.Yblock8[i]);
9770         //  }
9771       }
9772 
9773     words2scu (cpup, cpu.Yblock8);
9774     decode_instruction (cpup, IWB_IRODD, & cpu.currentInstruction);
9775 
9776 // Restore addressing mode
9777 
9778     word1 saveP = cpu.PPR.P; // ISOLTS-870 02m
9779     if (TST_I_ABS == 0)
9780       set_addr_mode (cpup, APPEND_mode);
9781     else
9782       set_addr_mode (cpup, ABSOLUTE_mode);
9783     cpu.PPR.P = saveP;
9784 
9785     if (getbits36_1  (cpu.Yblock8[1], 35) == 0) // cpu.cu.FLT_INT is interrupt, not fault
9786       {
9787         sim_debug (DBG_FAULT, & cpu_dev, "RCU interrupt return\n");
9788         longjmp (cpu.jmpMain, JMP_REFETCH);
9789       }
9790 
9791     // Resync the append unit
9792     fauxDoAppendCycle (cpup, INSTRUCTION_FETCH);
9793 
9794 // All of the faults list as having handlers have actually
9795 // been encountered in Multics operation and are believed
9796 // to be being handled correctly. The handlers in
9797 // parenthesis are speculative and untested.
9798 //
9799 // Unhandled:
9800 //
9801 //    SDF Shutdown: Why would you RCU from a shutdown fault?
9802 //    STR Store:
9803 //      AL39 is contradictory or vague about store fault subfaults and store
9804 //      faults in general. They are mentioned:
9805 //        SPRPn: store fault (illegal pointer) (assuming STR:ISN)
9806 //        SMCM: store fault (not control)  -
9807 //        SMIC: store fault (not control)   > I believe that these should be
9808 //        SSCR: store fault (not control)  -  command fault
9809 //        TSS:  STR:OOB
9810 //        Bar mode out-of-bounds: STR:OOB
9811 //     The SCU register doesn't define which bit is "store fault (not control)"
9812 // STR:ISN - illegal segment number
9813 // STR:NEA - nonexistent address
9814 // STR:OOB - bar mode out-of-bounds
9815 //
9816 // decimal   octal
9817 // fault     fault  mnemonic   name             priority group  handler
9818 // number   address
9819 //   0         0      sdf      Shutdown               27 7
9820 //   1         2      str      Store                  10 4                                 get_BAR_address, instruction execution
9821 //   2         4      mme      Master mode entry 1    11 5      JMP_SYNC_FAULT_RETURN      instruction execution
9822 //   3         6      f1       Fault tag 1            17 5      (JMP_REFETCH/JMP_RESTART)  do_caf
9823 //   4        10      tro      Timer runout           26 7      JMP_REFETCH                FETCH_cycle
9824 //   5        12      cmd      Command                 9 4      JMP_REFETCH/JMP_RESTART    instruction execution
9825 //   6        14      drl      Derail                 15 5      JMP_REFETCH/JMP_RESTART    instruction execution
9826 //   7        16      luf      Lockup                  5 4      JMP_REFETCH                do_caf, FETCH_cycle
9827 //   8        20      con      Connect                25 7      JMP_REFETCH                FETCH_cycle
9828 //   9        22      par      Parity                  8 4
9829 //  10        24      ipr      Illegal procedure      16 5                                 doITSITP, do_caf, instruction execution
9830 //  11        26      onc      Operation not complete  4 2                                 nem_check, instruction execution
9831 //  12        30      suf      Startup                 1 1
9832 //  13        32      ofl      Overflow                7 3      JMP_REFETCH/JMP_RESTART    instruction execution
9833 //  14        34      div      Divide check            6 3                                 instruction execution
9834 //  15        36      exf      Execute                 2 1      JMP_REFETCH/JMP_RESTART    FETCH_cycle
9835 //  16        40      df0      Directed fault 0       20 6      JMP_REFETCH/JMP_RESTART    getSDW, do_append_cycle
9836 //  17        42      df1      Directed fault 1       21 6      JMP_REFETCH/JMP_RESTART    getSDW, do_append_cycle
9837 //  18        44      df2      Directed fault 2       22 6      (JMP_REFETCH/JMP_RESTART)  getSDW, do_append_cycle
9838 //  19        46      df3      Directed fault 3       23 6      JMP_REFETCH/JMP_RESTART    getSDW, do_append_cycle
9839 //  20        50      acv      Access violation       24 6      JMP_REFETCH/JMP_RESTART    fetchDSPTW, modifyDSPTW, fetchNSDW,
9840 //                                                                                          do_append_cycle, EXEC_cycle (ring alarm)
9841 //  21        52      mme2     Master mode entry 2    12 5      JMP_SYNC_FAULT_RETURN      instruction execution
9842 //  22        54      mme3     Master mode entry 3    13 5      (JMP_SYNC_FAULT_RETURN)    instruction execution
9843 //  23        56      mme4     Master mode entry 4    14 5      (JMP_SYNC_FAULT_RETURN)    instruction execution
9844 //  24        60      f2       Fault tag 2            18 5      JMP_REFETCH/JMP_RESTART    do_caf
9845 //  25        62      f3       Fault tag 3            19 5      JMP_REFETCH/JMP_RESTART    do_caf
9846 //  26        64               Unassigned
9847 //  27        66               Unassigned
9848 //  28        70               Unassigned
9849 //  29        72               Unassigned
9850 //  30        74               Unassigned
9851 //  31        76      trb      Trouble                 3 2                                  FETCH_cycle, doRCU
9852 
9853 // Reworking logic
9854 
9855 #define rework
9856 #if defined(rework)
9857     if (cpu.cu.FIF) // fault occurred during instruction fetch
9858       {
9859 //if (cpu.cu.rfi) sim_printf ( "RCU FIF refetch return caught rfi\n");
9860         // I am misusing this bit; on restart I want a way to tell the
9861         // CPU state machine to restart the instruction, which is not
9862         // how Multics uses it. I need to pick a different way to
9863         // communicate; for now, turn it off on refetch so the state
9864         // machine doesn't become confused.
9865         cpu.cu.rfi = 0;
9866         sim_debug (DBG_FAULT, & cpu_dev, "RCU FIF REFETCH return\n");
9867         longjmp (cpu.jmpMain, JMP_REFETCH);
9868       }
9869 
9870 // RFI means 'refetch this instruction'
9871     if (cpu.cu.rfi)
9872       {
9873 //sim_printf ( "RCU rfi refetch return\n");
9874         sim_debug (DBG_FAULT, & cpu_dev, "RCU rfi refetch return\n");
9875 // Setting the to RESTART causes ISOLTS 776 to report unexpected
9876 // trouble faults.
9877 // Without clearing rfi, ISOLTS pm776-08i LUFs.
9878         cpu.cu.rfi = 0;
9879         longjmp (cpu.jmpMain, JMP_REFETCH);
9880       }
9881 
9882 // The debug command uses MME2 to implement breakpoints, but it is not
9883 // clear what it does to the MC data to signal RFI behavior.
9884 
9885     word5 fi_addr = getbits36_5  (cpu.Yblock8[1], 30);
9886     if (fi_addr == FAULT_MME  ||
9887         fi_addr == FAULT_MME2 ||
9888         fi_addr == FAULT_MME3 ||
9889         fi_addr == FAULT_MME4 ||
9890         fi_addr == FAULT_DRL)
9891     //if (fi_addr == FAULT_MME2)
9892       {
9893 //sim_printf ("MME2 restart\n");
9894         sim_debug (DBG_FAULT, & cpu_dev, "RCU MME2 restart return\n");
9895         cpu.cu.rfi = 0;
9896         longjmp (cpu.jmpMain, JMP_RESTART);
9897       }
9898 #else
9899     if (cpu.cu.rfi || // S/W asked for the instruction to be started
9900         cpu.cu.FIF)   // fault occurred during instruction fetch
9901       {
9902         // I am misusing this bit; on restart I want a way to tell the
9903         // CPU state machine to restart the instruction, which is not
9904         // how Multics uses it. I need to pick a different way to
9905         // communicate; for now, turn it off on refetch so the state
9906         // machine doesn't become confused.
9907 
9908         cpu.cu.rfi = 0;
9909         sim_debug (DBG_FAULT, & cpu_dev, "RCU rfi/FIF REFETCH return\n");
9910         longjmp (cpu.jmpMain, JMP_REFETCH);
9911       }
9912 
9913 // It seems obvious that MMEx should do a JMP_SYNC_FAULT_RETURN, but doing
9914 // a JMP_RESTART makes 'debug' work. (The same change to DRL does not make
9915 // 'gtss' work, tho.
9916 
9917     if (fi_addr == FAULT_MME2)
9918       {
9919 //sim_printf ("MME2 restart\n");
9920         sim_debug (DBG_FAULT, & cpu_dev, "RCU MME2 restart return\n");
9921         cpu.cu.rfi = 1;
9922         longjmp (cpu.jmpMain, JMP_RESTART);
9923       }
9924 #endif
9925 
9926 
9927 
9928 
9929 
9930 
9931 
9932 
9933 
9934 
9935 
9936 
9937 
9938 
9939 
9940 
9941 
9942 
9943 
9944     // MME faults resume with the next instruction
9945 
9946 #if defined(rework)
9947     if (fi_addr == FAULT_DIV ||
9948         fi_addr == FAULT_OFL ||
9949         fi_addr == FAULT_IPR)
9950       {
9951         sim_debug (DBG_FAULT, & cpu_dev, "RCU sync fault return\n");
9952         cpu.cu.rfi = 0;
9953         longjmp (cpu.jmpMain, JMP_SYNC_FAULT_RETURN);
9954       }
9955 #else
9956     if (fi_addr == FAULT_MME  ||
9957      /* fi_addr == FAULT_MME2 || */
9958         fi_addr == FAULT_MME3 ||
9959         fi_addr == FAULT_MME4 ||
9960         fi_addr == FAULT_DRL  ||
9961         fi_addr == FAULT_DIV  ||
9962         fi_addr == FAULT_OFL  ||
9963         fi_addr == FAULT_IPR)
9964       {
9965         sim_debug (DBG_FAULT, & cpu_dev, "RCU MMEx sync fault return\n");
9966         cpu.cu.rfi = 0;
9967         longjmp (cpu.jmpMain, JMP_SYNC_FAULT_RETURN);
9968       }
9969 #endif
9970 
9971     // LUF can happen during fetch or CAF. If fetch, handled above
9972     if (fi_addr == FAULT_LUF)
9973       {
9974         cpu.cu.rfi = 1;
9975         sim_debug (DBG_FAULT, & cpu_dev, "RCU LUF RESTART return\n");
9976         longjmp (cpu.jmpMain, JMP_RESTART);
9977       }
9978 
9979     if (fi_addr == FAULT_DF0 ||
9980         fi_addr == FAULT_DF1 ||
9981         fi_addr == FAULT_DF2 ||
9982         fi_addr == FAULT_DF3 ||
9983         fi_addr == FAULT_ACV ||
9984         fi_addr == FAULT_F1  ||
9985         fi_addr == FAULT_F2  ||
9986         fi_addr == FAULT_F3  ||
9987         fi_addr == FAULT_CMD ||
9988         fi_addr == FAULT_EXF)
9989       {
9990         // If the fault occurred during fetch, handled above.
9991         cpu.cu.rfi = 1;
9992         sim_debug (DBG_FAULT, & cpu_dev, "RCU ACV RESTART return\n");
9993         longjmp (cpu.jmpMain, JMP_RESTART);
9994       }
9995     sim_printf ("doRCU dies with unhandled fault number %d\n", fi_addr);
9996     doFault (FAULT_TRB,
9997              (_fault_subtype) {.bits=fi_addr},
9998              "doRCU dies with unhandled fault number");
9999   }

/* [previous][next][first][last][top][bottom][index][help] */