root/src/dps8/dps8_faults.c

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

DEFINITIONS

This source file includes following definitions.
  1. emCallReportFault
  2. clearFaultCycle
  3. doFault
  4. do_FFV_fault
  5. dlyDoFault
  6. bG7Pending
  7. bG7PendingNoTRO
  8. setG7fault
  9. set_FFV_fault
  10. clearTROFault
  11. doG7Fault
  12. advanceG7Faults

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * SPDX-License-Identifier: Multics
   5  * scspell-id: 4182f303-f62e-11ec-9475-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) 2017 Michal Tomek
  13  * Copyright (c) 2021-2022 The DPS8M Development Team
  14  *
  15  * All rights reserved.
  16  *
  17  * This software is made available under the terms of the ICU
  18  * License, version 1.8.1 or later.  For more details, see the
  19  * LICENSE.md file at the top-level directory of this distribution.
  20  *
  21  * ---------------------------------------------------------------------------
  22  *
  23  * This source file may contain code comments that adapt, include, and/or
  24  * incorporate Multics program code and/or documentation distributed under
  25  * the Multics License.  In the event of any discrepancy between code
  26  * comments herein and the original Multics materials, the original Multics
  27  * materials should be considered authoritative unless otherwise noted.
  28  * For more details and historical background, see the LICENSE.md file at
  29  * the top-level directory of this distribution.
  30  *
  31  * ---------------------------------------------------------------------------
  32  */
  33 
  34 #include <stdio.h>
  35 
  36 #include "dps8.h"
  37 #include "dps8_sys.h"
  38 #include "dps8_faults.h"
  39 #include "dps8_scu.h"
  40 #include "dps8_iom.h"
  41 #include "dps8_cable.h"
  42 #include "dps8_cpu.h"
  43 #include "dps8_append.h"
  44 #include "dps8_ins.h"
  45 #include "dps8_utils.h"
  46 #if defined(THREADZ) || defined(LOCKLESS)
  47 # include "threadz.h"
  48 #endif
  49 
  50 #define DBG_CTR cpu.cycleCnt
  51 
  52 /*
  53  * FAULT RECOGNITION
  54  * For the discussion following, the term "function" is defined as a major processor functional
  55  * cycle. Examples are: APPEND CYCLE, CA CYCLE, INSTRUCTION FETCH CYCLE, OPERAND STORE CYCLE,
  56  * DIVIDE EXECUTION CYCLE. Some of these cycles are discussed in various sections of this manual.
  57  * Faults in groups 1 and 2 cause the processor to abort all functions immediately by entering a
  58  * FAULT CYCLE. Faults in group 3 cause the processor to "close out" current functions without
  59  * taking any irrevocable action (such as setting PTW.U in an APPEND CYCLE or modifying an
  60  * indirect word in a CA CYCLE), then to discard any pending functions (such as an APPEND CYCLE
  61  * needed during a CA CYCLE), and to enter a FAULT CYCLE. Faults in group 4 cause the processor
  62  * to suspend overlapped operation, to complete current and pending functions for the current
  63  * instruction, and then to enter a FAULT CYCLE. Faults in groups 5 or 6 are normally detected
  64  * during virtual address formation and instruction decode. These faults cause the processor to
  65  * suspend overlapped operation, to complete the current and pending instructions, and to enter
  66  * a FAULT CYCLE. If a fault in a higher priority group is generated by the execution of the
  67  * current or pending instructions, that higher priority fault will take precedence and the
  68  * group 5 or 6 fault will be lost. If a group 5 or 6 fault is detected during execution of the
  69  * current instruction (e.g., an access violation, out of segment bounds, fault during certain
  70  * interruptible EIS instructions), the instruction is considered "complete" upon detection of
  71  * the fault. Faults in group 7 are held and processed (with interrupts) at the completion of
  72  * the current instruction pair. Group 7 faults are inhibitable by setting bit 28 of the
  73  * instruction word. Faults in groups 3 through 6 must wait for the system controller to
  74  * acknowledge the last access request before entering the FAULT CYCLE.
  75  */
  76 
  77 /*
  78  *                                Table 7-1. List of Faults
  79  *
  80  * Decimal fault     Octal (1)      Fault   Fault name            Priority    Group
  81  *    number      fault address   mnemonic
  82  *       0      ;         0     ;      sdf  ;   Shutdown             ;   27     ;     7
  83  *       1      ;         2     ;      str  ;   Store                ;   10     ;     4
  84  *       2      ;         4     ;      mme  ;   Master mode entry 1  ;   11     ;     5
  85  *       3      ;         6     ;      f1   ;   Fault tag 1          ;   17     ;     5
  86  *       4      ;        10     ;      tro  ;   Timer runout         ;   26     ;     7
  87  *       5      ;        12     ;      cmd  ;   Command              ;   9      ;     4
  88  *       6      ;        14     ;      drl  ;   Derail               ;   15     ;     5
  89  *       7      ;        16     ;      luf  ;   Lockup               ;   5      ;     4
  90  *       8      ;        20     ;      con  ;   Connect              ;   25     ;     7
  91  *       9      ;        22     ;      par  ;   Parity               ;   8      ;     4
  92  *       10     ;        24     ;      ipr  ;   Illegal procedure    ;   16     ;     5
  93  *       11     ;        26     ;      onc  ;   Operation not complete ; 4      ;     2
  94  *       12     ;        30     ;      suf  ;   Startup              ;   1      ;     1
  95  *       13     ;        32     ;      ofl  ;   Overflow             ;   7      ;     3
  96  *       14     ;        34     ;      div  ;   Divide check         ;   6      ;     3
  97  *       15     ;        36     ;      exf  ;   Execute              ;   2      ;     1
  98  *       16     ;        40     ;      df0  ;   Directed fault 0     ;   20     ;     6
  99  *       17     ;        42     ;      df1  ;   Directed fault 1     ;   21     ;     6
 100  *       18     ;        44     ;      df2  ;   Directed fault 2     ;   22     ;     6
 101  *       19     ;        46     ;      df3  ;   Directed fault 3     ;   23     ;     6
 102  *       20     ;        50     ;      acv  ;   Access violation     ;   24     ;     6
 103  *       21     ;        52     ;      mme2 ;   Master mode entry 2  ;   12     ;     5
 104  *       22     ;        54     ;      mme3 ;   Master mode entry 3  ;   13     ;     5
 105  *       23     ;        56     ;      mme4 ;   Master mode entry 4  ;   14     ;     5
 106  *       24     ;        60     ;      f2   ;   Fault tag 2          ;   18     ;     5
 107  *       25     ;        62     ;      f3   ;   Fault tag 3          ;   19     ;     5
 108  *       26     ;        64     ;           ;   Unassigned           ;          ;
 109  *       27     ;        66     ;           ;   Unassigned           ;          ;
 110  */
 111 
 112 #ifndef QUIET_UNUSED
 113 static dps8faults _faultsP[] = { // sorted by priority
 114 //      number  address  mnemonic  name                   Priority   Group
 115     {   12,     030,     "suf",    "Startup",                   1,      1,     false },
 116     {   15,     036,     "exf",    "Execute",                   2,      1,     false },
 117     {   31,     076,     "trb",    "Trouble",                   3,      2,     false },
 118     {   11,     026,     "onc",    "Operation not complete",    4,      2,     false },
 119     {    7,     016,     "luf",    "Lockup",                    5,      4,     false },
 120     {   14,     034,     "div",    "Divide check",              6,      3,     false },
 121     {   13,     032,     "ofl",    "Overflow",                  7,      3,     false },
 122     {    9,     022,     "par",    "Parity",                    8,      4,     false },
 123     {    5,     012,     "cmd",    "Command",                   9,      4,     false },
 124     {    1,       2,     "str",    "Store",                    10,      4,     false },
 125     {    2,       4,     "mme",    "Master mode entry 1",      11,      5,     false },
 126     {   21,     052,    "mme2",    "Master mode entry 2",      12,      5,     false },
 127     {   22,     054,    "mme3",    "Master mode entry 3",      13,      5,     false },
 128     {   23,     056,    "mme4",    "Master mode entry 4",      14,      5,     false },
 129     {    6,     014,     "drl",    "Derail",                   15,      5,     false },
 130     {   10,     024,     "ipr",    "Illegal procedure",        16,      5,     false },
 131     {    3,      06,      "f1",    "Fault tag 1",              17,      5,     false },
 132     {   24,     060,      "f2",    "Fault tag 2",              18,      5,     false },
 133     {   25,     062,      "f3",    "Fault tag 3",              19,      5,     false },
 134     {   16,     040,     "df0",    "Directed fault 0",         20,      6,     false },
 135     {   17,     042,     "df1",    "Directed fault 1",         21,      6,     false },
 136     {   18,     044,     "df2",    "Directed fault 2",         22,      6,     false },
 137     {   19,     046,     "df3",    "Directed fault 3",         23,      6,     false },
 138     {   20,     050,     "acv",    "Access violation",         24,      6,     false },
 139     {    8,     020,     "con",    "Connect",                  25,      7,     false },
 140     {    4,     010,     "tro",    "Timer runout",             26,      7,     false },
 141     {    0,       0,     "sdf",    "Shutdown",                 27,      7,     false },
 142     {   26,     064,     "???",    "Unassigned",               -1,     -1,     false },
 143     {   27,     066,     "???",    "Unassigned",               -1,     -1,     false },
 144     {   -1,      -1,      NULL,     NULL,                      -1,     -1,     false }
 145 };
 146 #endif
 147 #ifndef QUIET_UNUSED
 148 static dps8faults _faults[] = {    // sorted by number
 149 //      number  address  mnemonic  name                   Priority   Group
 150     {   0,        0,     "sdf",    "Shutdown",                 27,      7,     false },
 151     {   1,        2,     "str",    "Store",                    10,      4,     false },
 152     {   2,        4,     "mme",    "Master mode entry 1",      11,      5,     false },
 153     {   3,       06,      "f1",    "Fault tag 1",              17,      5,     false },
 154     {   4,      010,     "tro",    "Timer runout",             26,      7,     false },
 155     {   5,      012,     "cmd",    "Command",                  9,       4,     false },
 156     {   6,      014,     "drl",    "Derail",                   15,      5,     false },
 157     {   7,      016,     "luf",    "Lockup",                   5,       4,     false },
 158     {   8,      020,     "con",    "Connect",                  25,      7,     false },
 159     {   9,      022,     "par",    "Parity",                   8,       4,     false },
 160     {   10,     024,     "ipr",    "Illegal procedure",        16,      5,     false },
 161     {   11,     026,     "onc",    "Operation not complete",   4,       2,     false },
 162     {   12,     030,     "suf",    "Startup",                  1,       1,     false },
 163     {   13,     032,     "ofl",    "Overflow",                 7,       3,     false },
 164     {   14,     034,     "div",    "Divide check",             6,       3,     false },
 165     {   15,     036,     "exf",    "Execute",                  2,       1,     false },
 166     {   16,     040,     "df0",    "Directed fault 0",         20,      6,     false },
 167     {   17,     042,     "df1",    "Directed fault 1",         21,      6,     false },
 168     {   18,     044,     "df2",    "Directed fault 2",         22,      6,     false },
 169     {   19,     046,     "df3",    "Directed fault 3",         23,      6,     false },
 170     {   20,     050,     "acv",    "Access violation",         24,      6,     false },
 171     {   21,     052,    "mme2",    "Master mode entry 2",      12,      5,     false },
 172     {   22,     054,    "mme3",    "Master mode entry 3",      13,      5,     false },
 173     {   23,     056,    "mme4",    "Master mode entry 4",      14,      5,     false },
 174     {   24,     060,      "f2",    "Fault tag 2",              18,      5,     false },
 175     {   25,     062,      "f3",    "Fault tag 3",              19,      5,     false },
 176     {   26,     064,     "???",    "Unassigned",               -1,     -1,     false },
 177     {   27,     066,     "???",    "Unassigned",               -1,     -1,     false },
 178     {   28,     070,     "???",    "Unassigned",               -1,     -1,     false },
 179     {   29,     072,     "???",    "Unassigned",               -1,     -1,     false },
 180     {   30,     074,     "???",    "Unassigned",               -1,     -1,     false },
 181     {   31,     076,     "trb",    "Trouble",                   3,      2,     false },
 182     {   -1,     -1,       NULL,     NULL,                      -1,     -1,     false }
 183 };
 184 #endif
 185 
 186 char * faultNames [N_FAULTS] =
 187   {
 188     "Shutdown",
 189     "Store",
 190     "Master mode entry 1",
 191     "Fault tag 1",
 192     "Timer runout",
 193     "Command",
 194     "Derail",
 195     "Lockup",
 196     "Connect",
 197     "Parity",
 198     "Illegal procedure",
 199     "Operation not complete",
 200     "Startup",
 201     "Overflow",
 202     "Divide check",
 203     "Execute",
 204     "Directed fault 0",
 205     "Directed fault 1",
 206     "Directed fault 2",
 207     "Directed fault 3",
 208     "Access violation",
 209     "Master mode entry 2",
 210     "Master mode entry 3",
 211     "Master mode entry 4",
 212     "Fault tag 2",
 213     "Fault tag 3",
 214     "Unassigned 26",
 215     "Unassigned 27",
 216     "Unassigned 28",
 217     "Unassigned 29",
 218     "Unassigned 30",
 219     "Trouble"
 220   };
 221 //bool pending_fault = false;     // true when a fault has been signalled, but not processed
 222 
 223 #ifndef QUIET_UNUSED
 224 static bool port_interrupts[8] = { false, false, false, false, false, false, false, false };
 225 #endif
 226 
 227 //-----------------------------------------------------------------------------
 228 // ***  Constants, unchanging lookup tables, etc
 229 
 230 #ifndef QUIET_UNUSED
 231 static int fault2group[32] = {
 232     // from AL39, page 7-3
 233     7, 4, 5, 5, 7, 4, 5, 4,
 234     7, 4, 5, 2, 1, 3, 3, 1,
 235     6, 6, 6, 6, 6, 5, 5, 5,
 236     5, 5, 0, 0, 0, 0, 0, 2
 237 };
 238 
 239 static int fault2prio[32] = {
 240     // from AL39, page 7-3
 241     27, 10, 11, 17, 26,  9, 15,  5,
 242     25,  8, 16,  4,  1,  7,  6,  2,
 243     20, 21, 22, 23, 24, 12, 13, 14,
 244     18, 19,  0,  0,  0,  0,  0,  3
 245 };
 246 #endif
 247 
 248 /*
 249  * fault handler(s).
 250  */
 251 
 252 #ifdef TESTING
 253 // We stash a few things for debugging; they are accessed by emCall.
 254 static word18 fault_ic;
 255 static word15 fault_psr;
 256 static char fault_msg [1024];
 257 
 258 void emCallReportFault (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 259   {
 260            sim_printf ("fault report:\n");
 261            sim_printf ("  fault number %d (%o)\n", cpu . faultNumber, cpu . faultNumber);
 262            sim_printf ("  subfault number %llu (%llo)\n", (unsigned long long) cpu.subFault.bits,
 263                    (unsigned long long)cpu.subFault.bits);
 264            sim_printf ("  faulting address %05o:%06o\n", fault_psr, fault_ic);
 265            sim_printf ("  msg %s\n", fault_msg);
 266   }
 267 #endif
 268 
 269 void clearFaultCycle (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 270   {
 271     cpu . bTroubleFaultCycle = false;
 272   }
 273 
 274 /*
 275 
 276 Faults in groups 1 and 2 cause the processor to abort all functions immediately
 277 by entering a FAULT CYCLE.
 278 
 279 Faults in group 3 cause the processor to "close out" current functions without
 280 taking any irrevocable action (such as setting PTW.U in an APPEND CYCLE or
 281 modifying an indirect word in a CA CYCLE), then to discard any pending
 282 functions (such as an APPEND CYCLE needed during a CA CYCLE), and to enter a
 283 FAULT CYCLE.
 284 
 285 Faults in group 4 cause the processor to suspend overlapped operation, to
 286 complete current and pending functions for the current instruction, and then to
 287 enter a FAULT CYCLE.
 288 
 289 Faults in groups 5 or 6 are normally detected during virtual address formation
 290 and instruction decode. These faults cause the processor to suspend overlapped
 291 operation, to complete the current and pending instructions, and to enter a
 292 FAULT CYCLE. If a fault in a higher priority group is generated by the
 293 execution of the current or pending instructions, that higher priority fault
 294 will take precedence and the group 5 or 6 fault will be lost. If a group 5 or 6
 295 fault is detected during execution of the current instruction (e.g., an access
 296 violation, out of segment bounds, fault during certain interruptible EIS
 297 instructions), the instruction is considered "complete" upon detection of the
 298 fault.
 299 
 300 Faults in group 7 are held and processed (with interrupts) at the completion
 301 of the current instruction pair.
 302 
 303 Group 7 faults are inhibitable by setting bit 28 of the instruction word.
 304 
 305 Faults in groups 3 through 6 must wait for the system controller to acknowledge
 306 the last access request before entering the FAULT CYCLE.
 307 
 308 After much rumination here are my thoughts for fault processing .....
 309 
 310 For now, at least, we must remember a few things:
 311 
 312 1) We only have 1 cpu so we have few & limited async faults - shutdown, TRO,
 313 etc.
 314 2) We have no overlapping instruction execution
 315 3) Because of 2) we have no pending instructions
 316 4) We have no system controller to wait for
 317 
 318 Group 1 & 2 faults can be processed immediately and then proceed to next
 319 instruction as long as no transfer prevents us from returning from the XED pair.
 320 
 321 Group 3 faults will probably also execute immediately since a G3 fault causes
 322 "the processor to "close out" current functions without taking any irrevocable
 323 action (such as setting PTW.U in an APPEND CYCLE or modifying an indirect word
 324 in a CA CYCLE), then to discard any pending functions (such as an APPEND CYCLE
 325 needed during a CA CYCLE), and to enter a FAULT CYCLE."
 326 
 327 Group 4 faults will probably also execute immediately since a G4 fault causes
 328 "the processor to suspend overlapped operation, to complete current and pending
 329 functions for the current instruction, and then to enter a FAULT CYCLE."
 330 
 331 Group 5 & 6 faults will probably also execute immediately because "if a group 5
 332 or 6 fault is detected during execution of the current instruction (e.g., an
 333 access violation, out of segment bounds, fault during certain interruptible EIS
 334 instructions), the instruction is considered "complete" upon detection of the
 335 fault." However, remember "If a fault in a higher priority group is generated
 336 by the execution of the current or pending instructions, that higher priority
 337 fault will take precedence and the group 5 or 6 fault will be lost. If a group
 338 5 or 6 fault is detected during execution of the current instruction (e.g., an
 339 access violation, out of segment bounds, fault during certain interruptible EIS
 340 instructions), the instruction is considered "complete" upon detection of the
 341 fault."
 342 
 343 For further justification of immediate execution since "Faults in groups 3
 344 through 6 must wait for the system controller to acknowledge the last access
 345 request before entering the FAULT CYCLE."
 346 
 347 Group 7 faults will be processed after next even instruction decode instruction
 348 decode, but before instruction execution. In this way we can actually use
 349 bit-28 tp inhibit interrupts
 350 
 351 */
 352 
 353 #ifdef LOOPTRC
 354 # include <time.h>
 355 void elapsedtime (void);
 356 #endif
 357 
 358 #ifndef NEED_128
 359 const _fault_subtype fst_zero      = (_fault_subtype) {.bits=0};
 360 const _fault_subtype fst_acv9      = (_fault_subtype) {.fault_acv_subtype=ACV9};
 361 const _fault_subtype fst_acv15     = (_fault_subtype) {.fault_acv_subtype=ACV15};
 362 const _fault_subtype fst_ill_mod   = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_MOD};
 363 const _fault_subtype fst_ill_proc  = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC};
 364 const _fault_subtype fst_ill_dig   = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_DIG};
 365 const _fault_subtype fst_ill_op    = (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP};
 366 const _fault_subtype fst_str_oob   = (_fault_subtype) {.fault_str_subtype=flt_str_oob};
 367 const _fault_subtype fst_str_nea   = (_fault_subtype) {.fault_str_subtype=flt_str_nea};
 368 const _fault_subtype fst_str_ptr   = (_fault_subtype) {.fault_str_subtype=flt_str_ill_ptr};
 369 const _fault_subtype fst_cmd_lprpn = (_fault_subtype) {.fault_cmd_subtype=flt_cmd_lprpn_bits};
 370 const _fault_subtype fst_cmd_ctl   = (_fault_subtype) {.fault_cmd_subtype=flt_cmd_not_control};
 371 const _fault_subtype fst_onc_nem   = (_fault_subtype) {.fault_onc_subtype=flt_onc_nem};
 372 #endif
 373 // CANFAULT
 374 void doFault (_fault faultNumber, _fault_subtype subFault,
     /* [previous][next][first][last][top][bottom][index][help] */
 375               const char * faultMsg)
 376   {
 377 #ifdef LOOPTRC
 378 if (faultNumber == FAULT_TRO)
 379 {
 380  elapsedtime ();
 381  sim_printf (" TRO PSR:IC %05o:%06o\r\n", cpu.PPR.PSR, cpu.PPR.IC);
 382 }
 383 else if (faultNumber == FAULT_ACV)
 384 {
 385  elapsedtime ();
 386  sim_printf (" ACV %012llo PSR:IC %05o:%06o\r\n", subFault.bits, cpu.PPR.PSR, cpu.PPR.IC);
 387 }
 388 #endif
 389 //if (current_running_cpu_idx)
 390     //sim_printf ("Fault %d(0%0o), sub %ld(0%lo), dfc %c, '%s'\n",
 391                //faultNumber, faultNumber, subFault, subFault,
 392                //cpu . bTroubleFaultCycle ? 'Y' : 'N', faultMsg);
 393 //if (current_running_cpu_idx)
 394     //sim_printf ("xde %d xdo %d\n", cpu.cu.xde, cpu.cu.xdo);
 395     sim_debug (DBG_FAULT, & cpu_dev,
 396                "Fault %d(0%0o), sub %"PRIu64"(0%"PRIo64"), dfc %c, '%s'\n",
 397                faultNumber, faultNumber, subFault.bits, subFault.bits,
 398                cpu . bTroubleFaultCycle ? 'Y' : 'N', faultMsg);
 399 #ifdef PROFILER
 400 # ifndef GNU_ATOMICS
 401 #  error PROFILER requires GNU_ATOMICS
 402 # endif
 403     __atomic_add_fetch (& cpu.faults[faultNumber], 1u, __ATOMIC_ACQUIRE);
 404 #endif
 405 #ifdef TESTING
 406     HDBGFault (faultNumber, subFault, faultMsg, "");
 407 #endif
 408 #ifndef SPEED
 409     if_sim_debug (DBG_FAULT, & cpu_dev)
 410       traceInstruction (DBG_FAULT);
 411 #endif
 412 
 413     PNL (cpu.DACVpDF = faultNumber >=  FAULT_DF0 && faultNumber <= FAULT_ACV;)
 414 
 415 #ifdef TESTING
 416     // some debugging support stuff
 417     fault_psr = cpu . PPR.PSR;
 418     fault_ic  = cpu . PPR.IC;
 419     strcpy (fault_msg, faultMsg);
 420 #endif
 421 
 422     //if (faultNumber < 0 || faultNumber > 31)
 423     if (faultNumber & ~037U)  // quicker?
 424     {
 425         sim_printf ("fault(out-of-range): %d %llo '%s'\n",
 426                     faultNumber, (unsigned long long)subFault.bits,
 427                     faultMsg ? faultMsg : "?");
 428         sim_warn ("fault out-of-range\n");
 429         faultNumber = FAULT_TRB;
 430     }
 431 
 432     cpu.faultNumber = faultNumber;
 433     cpu.subFault    = subFault;
 434     cpu.faultCnt [faultNumber] ++;
 435 
 436     // "The occurrence of a fault or interrupt sets the cache-to-register mode bit to OFF." a:AL39/cmr1
 437     CPTUR (cptUseCMR);
 438     cpu.CMR.csh_reg = 0;
 439 
 440     // Increment FCT
 441 
 442     word3 FCT = cpu.cu.APUCycleBits & MASK3;
 443     FCT = (FCT + 1u) & MASK3;
 444     cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | FCT);
 445 
 446     // Set fault register bits
 447 
 448     CPTUR (cptUseFR);
 449     if (faultNumber == FAULT_IPR)
 450       {
 451 
 452 
 453 
 454 
 455 
 456 
 457 
 458 
 459 
 460 
 461         cpu . faultRegister [0] |= subFault.bits;
 462 
 463       }
 464     else if (faultNumber == FAULT_ONC && subFault.fault_onc_subtype == flt_onc_nem)
 465       {
 466         cpu . faultRegister [0] |= FR_NEM;
 467       }
 468     else if (faultNumber == FAULT_STR)
 469       {
 470         if (subFault.fault_str_subtype == flt_str_oob)
 471           cpu . faultRegister [0] |= FR_OOB;
 472         //else if (subFault.fault_str_subtype == flt_str_ill_ptr)
 473           //cpu . faultRegister [0] |= ?;    // XXX
 474         //else if (subFault.fault_str_subtype == flt_str_nea)
 475           //cpu . faultRegister [0] |= ?;    // XXX
 476       }
 477     else if (faultNumber == FAULT_CON)
 478       {
 479         switch (subFault.fault_con_subtype)
 480           {
 481             case con_a:
 482               cpu . faultRegister [0] |= FR_CON_A;
 483               break;
 484             case con_b:
 485               cpu . faultRegister [0] |= FR_CON_B;
 486               break;
 487             case con_c:
 488               cpu . faultRegister [0] |= FR_CON_C;
 489               break;
 490             case con_d:
 491               cpu . faultRegister [0] |= FR_CON_D;
 492               break;
 493             default:
 494               sim_warn ("FAULT_CON can't map port %lo\n", (long unsigned) subFault.fault_con_subtype);
 495               break;
 496           }
 497       }
 498 
 499     // Set cu word1 fault bits
 500 
 501     cpu . cu . IRO_ISN          = 0;
 502     cpu . cu . OEB_IOC          = 0;
 503     cpu . cu . EOFF_IAIM        = 0;
 504     cpu . cu . ORB_ISP          = 0;
 505     cpu . cu . ROFF_IPR         = 0;
 506     cpu . cu . OWB_NEA          = 0;
 507     cpu . cu . WOFF_OOB         = 0;
 508     cpu . cu . NO_GA            = 0;
 509     cpu . cu . OCB              = 0;
 510     cpu . cu . OCALL            = 0;
 511     cpu . cu . BOC              = 0;
 512     DPS8M_ (cpu . cu . PTWAM_ER = 0;)
 513     cpu . cu . CRT              = 0;
 514     cpu . cu . RALR             = 0;
 515     cpu . cu . SDWAM_ER         = 0;
 516     cpu . cu . OOSB             = 0;
 517     cpu . cu . PARU             = 0;
 518     cpu . cu . PARL             = 0;
 519     cpu . cu . ONC1             = 0;
 520     cpu . cu . ONC2             = 0;
 521     cpu . cu . IA               = 0;
 522     cpu . cu . IACHN            = 0;
 523     cpu . cu . CNCHN            = (faultNumber == FAULT_CON) ? subFault.fault_con_subtype & MASK3 : 0;
 524 
 525     // Set control unit 'fault occurred during instruction fetch' flag
 526     cpu . cu . FIF       = cpu . cycle == FETCH_cycle ? 1 : 0;
 527     cpu . cu . FI_ADDR   = (word5) faultNumber;
 528 
 529     // XXX Under what conditions should this be set?
 530     // Assume no
 531     // Reading Multics source, it seems like Multics is setting this bit; I'm going
 532     // to assume that the h/w also sets it to 0, and the s/w has to explicitly set it on.
 533     cpu . cu . rfi = 0;
 534 
 535 // Try to decide if this a MIF fault (fault during EIS instruction)
 536 // EIS instructions are not used in fault/interrupt pairs, so the
 537 // only time an EIS instruction could be executing is during EXEC_cycle.
 538 // I am also assuming that only multi-word EIS instructions are of interest.
 539 // Testing faultNumber fixes ISOLTS 890-04a
 540     // fixes 890-04a and 791 / 792
 541     SC_I_MIF (cpu.cycle == EXEC_cycle &&
 542               (cpu.currentInstruction.info->ndes > 0 ||
 543                (faultNumber == FAULT_IPR && (subFault.fault_ipr_subtype & FR_ILL_OP_CONST) &&
 544                 cpu.currentInstruction.opcodeX &&
 545                 (cpu.currentInstruction.opcode & 0410) == 0)));
 546     sim_debug (DBG_TRACEEXT, & cpu_dev, "MIF %o\n", TST_I_MIF);
 547 
 548 
 549 
 550 
 551 
 552 
 553 
 554 
 555 
 556 
 557 
 558 
 559     if (faultNumber == FAULT_ACV)
 560       {
 561         // This is annoyingly inefficient since the subFault value
 562         // is bitwise the same as the upper half of CU word1;
 563         // if the upper half were not broken out, then this would be
 564         // cpu . cu . word1_upper_half = subFault.
 565 
 566         if (subFault.fault_acv_subtype & ACV0)
 567           cpu . cu . IRO_ISN   = 1;
 568         if (subFault.fault_acv_subtype & ACV1)
 569           cpu . cu . OEB_IOC   = 1;
 570         if (subFault.fault_acv_subtype & ACV2)
 571           cpu . cu . EOFF_IAIM = 1;
 572         if (subFault.fault_acv_subtype & ACV3)
 573           cpu . cu . ORB_ISP   = 1;
 574         if (subFault.fault_acv_subtype & ACV4)
 575           cpu . cu . ROFF_IPR  = 1;
 576         if (subFault.fault_acv_subtype & ACV5)
 577           cpu . cu . OWB_NEA   = 1;
 578         if (subFault.fault_acv_subtype & ACV6)
 579           cpu . cu . WOFF_OOB  = 1;
 580         if (subFault.fault_acv_subtype & ACV7)
 581           cpu . cu . NO_GA     = 1;
 582         if (subFault.fault_acv_subtype & ACV8)
 583           cpu . cu . OCB       = 1;
 584         if (subFault.fault_acv_subtype & ACV9)
 585           cpu . cu . OCALL     = 1;
 586         if (subFault.fault_acv_subtype & ACV10)
 587           cpu . cu . BOC       = 1;
 588         if (subFault.fault_acv_subtype & ACV11)
 589           cpu . cu . PTWAM_ER  = 1;
 590         if (subFault.fault_acv_subtype & ACV12)
 591           cpu . cu . CRT       = 1;
 592         if (subFault.fault_acv_subtype & ACV13)
 593           cpu . cu . RALR      = 1;
 594         if (subFault.fault_acv_subtype & ACV14)
 595           cpu . cu . SDWAM_ER  = 1;
 596         if (subFault.fault_acv_subtype & ACV15)
 597           cpu . cu . OOSB      = 1;
 598       }
 599     else if (faultNumber == FAULT_STR)
 600       {
 601         if (subFault.fault_str_subtype == flt_str_oob)
 602           cpu . cu . WOFF_OOB  = 1;
 603         //else if (subFault.fault_str_subtype == flt_str_ill_ptr)
 604           //cpu . cu . ??? = 1; // XXX
 605         else if (subFault.fault_str_subtype == flt_str_nea)
 606           cpu . cu . OWB_NEA   = 1;
 607       }
 608     else if (faultNumber == FAULT_IPR)
 609       {
 610         if (subFault.fault_ipr_subtype & FR_ILL_OP_CONST)
 611           cpu . cu . OEB_IOC   = 1;
 612         if (subFault.fault_ipr_subtype & FR_ILL_MOD_CONST)
 613           cpu . cu . EOFF_IAIM = 1;
 614         if (subFault.fault_ipr_subtype & FR_ILL_SLV_CONST)
 615           cpu . cu . ORB_ISP   = 1;
 616         if (subFault.fault_ipr_subtype & FR_ILL_DIG)
 617           cpu . cu . ROFF_IPR  = 1;
 618       }
 619     else if (faultNumber == FAULT_CMD)
 620       {
 621         if (subFault.fault_cmd_subtype == flt_cmd_lprpn_bits)
 622           cpu . cu . IA        = 0;
 623         else if (subFault.fault_cmd_subtype == flt_cmd_not_control)
 624           cpu . cu . IA        = 010;
 625       }
 626 
 627     L68_ (
 628       // History registers
 629       // IHRRS; AL39 pg 47
 630       // History register lock control. If this bit is set ON, set STROBE ยข
 631       // (bit 30, key k) OFF, locking the history registers for all faults
 632       // including the floating faults.
 633       CPTUR (cptUseMR);
 634       if (cpu.MR.emr && cpu.MR.ihrrs)
 635         {
 636           cpu.MR.ihr = 0;
 637         }
 638     )
 639     DPS8M_ (
 640       // History registers
 641       // IHRRS; AL39 pg 49
 642       // Additional resetting of bit 30. If bit 31 = 1, the following faults also
 643       // reset bit 30:
 644       //   Lock Up
 645       //   Parity
 646       //   Command
 647       //   Store
 648       //   Illegal Procedure
 649       //   Shutdown
 650       if (cpu.MR.emr && cpu.MR.ihrrs)
 651         {
 652           if (faultNumber == FAULT_LUF ||
 653               faultNumber == FAULT_PAR ||
 654               faultNumber == FAULT_CMD ||
 655               faultNumber == FAULT_STR ||
 656               faultNumber == FAULT_IPR ||
 657               faultNumber == FAULT_SDF)
 658             {
 659               cpu.MR.ihr = 0;
 660             }
 661         }
 662       // Enable History Registers.  This bit will be reset by ... an Op Not
 663       // Complete fault. It may be reset by other faults (see bit 31).
 664       if (faultNumber == FAULT_ONC)
 665         {
 666           cpu.MR.ihr = 0;
 667         }
 668     )
 669 
 670     // If already in a FAULT CYCLE then signal trouble fault
 671 
 672     if (cpu.cycle == FAULT_EXEC_cycle)
 673       {
 674         sim_debug (DBG_CYCLE, & cpu_dev, "Changing fault number to Trouble fault\n");
 675 
 676         cpu.faultNumber = FAULT_TRB;
 677         cpu.cu.FI_ADDR  = FAULT_TRB;
 678         cpu.subFault.bits = 0; // XXX ???
 679         // XXX Does the CU or FR need fixing? ticket #36
 680         if (cpu . bTroubleFaultCycle)
 681           {
 682 #if !defined(THREADZ) && !defined(LOCKLESS)
 683 # ifndef PANEL68
 684 #  ifndef ROUND_ROBIN
 685             if ((! sample_interrupts ()) &&
 686                 (sim_qcount () == 0))  // XXX If clk_svc is implemented it will
 687                                      // break this logic
 688               {
 689                 sim_printf \
 690                     ("Fault cascade @0%06o with no interrupts pending and no events in queue\n",
 691                      cpu . PPR.IC);
 692                 sim_printf("\nCycles = %"PRId64"\n", cpu.cycleCnt);
 693                 sim_printf("\nInstructions = %"PRId64"\n", cpu.instrCnt);
 694                 //stop_reason = STOP_FLT_CASCADE;
 695                 longjmp (cpu.jmpMain, JMP_STOP);
 696               }
 697 #  endif
 698 # endif
 699 #endif
 700           }
 701         else
 702           {
 703 //--            f = &_faults[FAULT_TRB];
 704             cpu . bTroubleFaultCycle = true;
 705           }
 706       }
 707     else
 708       {
 709         cpu . bTroubleFaultCycle = false;
 710       }
 711 
 712     // If doInstruction faults, the instruction cycle counter doesn't get
 713     // bumped.
 714     if (cpu . cycle == EXEC_cycle)
 715       cpu.instrCnt ++;
 716 
 717     cpu . cycle = FAULT_cycle;
 718     sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to FAULT_cycle\n");
 719     longjmp (cpu.jmpMain, JMP_REENTRY);
 720 }
 721 
 722 void do_FFV_fault (uint fault_number, const char * fault_msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 723   {
 724     sim_debug (DBG_FAULT, & cpu_dev,
 725                "Floating fault %d '%s'\n",
 726                fault_number, fault_msg);
 727 #ifndef SPEED
 728     if_sim_debug (DBG_FAULT, & cpu_dev)
 729       traceInstruction (DBG_FAULT);
 730 #endif
 731 
 732     if (fault_number < 1 || fault_number > 3)
 733       {
 734         sim_printf ("floating fault(out-of-range): %d '%s'\n",
 735                     fault_number, fault_msg ? fault_msg : "?");
 736         sim_warn ("fault out-of-range\n");
 737       }
 738 
 739     cpu.FFV_fault_number = fault_number;
 740     cpu.faultNumber      = fault_number;
 741 
 742     // "The occurrence of a fault or interrupt sets the
 743     // cache-to-register mode bit to OFF." a:AL39/cmr1
 744     CPTUR (cptUseCMR);
 745     cpu.CMR.csh_reg = 0;
 746 
 747     // Increment FCT
 748 
 749     word3 FCT = cpu.cu.APUCycleBits & MASK3;
 750     FCT = (FCT + 1) & MASK3;
 751     cpu.cu.APUCycleBits = (word12) ((cpu.cu.APUCycleBits & 07770) | FCT);
 752 
 753     // Set fault register bits
 754     CPTUR (cptUseFR);
 755     cpu.faultRegister [0] = 0;
 756 
 757     // Set cu word1 fault bits
 758 
 759     cpu.cu.IRO_ISN   = 0;
 760     cpu.cu.OEB_IOC   = 0;
 761     cpu.cu.EOFF_IAIM = 0;
 762     cpu.cu.ORB_ISP   = 0;
 763     cpu.cu.ROFF_IPR  = 0;
 764     cpu.cu.OWB_NEA   = 0;
 765     cpu.cu.WOFF_OOB  = 0;
 766     cpu.cu.NO_GA     = 0;
 767     cpu.cu.OCB       = 0;
 768     cpu.cu.OCALL     = 0;
 769     cpu.cu.BOC       = 0;
 770 // FFVs are L68 only, so don't need this:
 771 //# ifdef DPS8M
 772     //cpu.cu.PTWAM_ER = 0;
 773 //# endif
 774     cpu.cu.CRT      = 0;
 775     cpu.cu.RALR     = 0;
 776     cpu.cu.SDWAM_ER = 0;
 777     cpu.cu.OOSB     = 0;
 778     cpu.cu.PARU     = 0;
 779     cpu.cu.PARL     = 0;
 780     cpu.cu.ONC1     = 0;
 781     cpu.cu.ONC2     = 0;
 782     cpu.cu.IA       = 0;
 783     cpu.cu.IACHN    = 0;
 784     cpu.cu.CNCHN    = 0;
 785 
 786     // Set control unit 'fault occurred during instruction fetch' flag
 787     cpu.cu.FIF       = 0;
 788     cpu.cu.FI_ADDR   = (word5) fault_number & MASK5;
 789 
 790     // XXX Under what conditions should this be set?
 791     // Assume no
 792     // Reading Multics source, it seems like Multics is setting this bit; I'm going
 793     // to assume that the h/w also sets it to 0, and the s/w has to explicitly set it on.
 794     cpu.cu.rfi = 0;
 795 
 796 // Try to decide if this a MIF fault (fault during EIS instruction)
 797 // EIS instructions are not used in fault/interrupt pairs, so the
 798 // only time an EIS instruction could be executing is during EXEC_cycle.
 799 // I am also assuming that only multi-word EIS instructions are of interest.
 800 
 801     SC_I_MIF (cpu.cycle == EXEC_cycle &&
 802         cpu.currentInstruction.info->ndes > 0);
 803     sim_debug (DBG_TRACEEXT, & cpu_dev, "MIF %o\n", TST_I_MIF);
 804 
 805 
 806     // History registers
 807     // IHRRS; AL39 pg 47
 808     // History register lock control. If this bit is set ON, set STROBE ยข
 809     // (bit 30, key k) OFF, locking the history registers for all faults
 810     // including the floating faults.
 811     CPTUR (cptUseMR);
 812     if (cpu.MR.emr && cpu.MR.ihrrs)
 813       {
 814         cpu.MR.ihr = 0;
 815       }
 816 
 817     if (cpu.cycle == FAULT_EXEC_cycle)
 818       {
 819         cpu.faultNumber   = FAULT_TRB;
 820         cpu.cu.FI_ADDR    = FAULT_TRB;
 821         cpu.subFault.bits = 0; // XXX ???
 822         // XXX Does the CU or FR need fixing? ticket #36
 823         if (cpu.bTroubleFaultCycle)
 824           {
 825 #if !defined(THREADZ) && !defined(LOCKLESS)
 826 # ifndef PANEL68
 827 #  ifndef ROUND_ROBIN
 828             if ((! sample_interrupts ()) &&
 829                 (sim_qcount () == 0))  // XXX If clk_svc is implemented it will
 830                                        // break this logic
 831               {
 832                 sim_printf \
 833                     ("Fault cascade @0%06o with no interrupts pending and no events in queue\n",
 834                      cpu.PPR.IC);
 835                 sim_printf("\nCycles = %"PRId64"\n", cpu.cycleCnt);
 836                 sim_printf("\nInstructions = %"PRId64"\n", cpu.instrCnt);
 837                 longjmp (cpu.jmpMain, JMP_STOP);
 838               }
 839 #  endif
 840 # endif
 841 #endif
 842           }
 843         else
 844           {
 845             cpu.bTroubleFaultCycle = true;
 846           }
 847         cpu.cycle = FAULT_cycle;
 848         sim_debug (DBG_CYCLE, & cpu_dev, "Setting cycle to FAULT_cycle\n");
 849         longjmp (cpu.jmpMain, JMP_REENTRY);
 850       }
 851     cpu.bTroubleFaultCycle = false;
 852 
 853     // If doInstruction faults, the instruction cycle counter doesn't get
 854     // bumped.
 855     if (cpu . cycle == EXEC_cycle)
 856       cpu.instrCnt ++;
 857 
 858     cpu.is_FFV = true;
 859     cpu.cycle  = FAULT_cycle;
 860     longjmp (cpu.jmpMain, JMP_REENTRY);
 861 }
 862 
 863 void dlyDoFault (_fault faultNumber, _fault_subtype subFault,
     /* [previous][next][first][last][top][bottom][index][help] */
 864                 const char * faultMsg)
 865   {
 866     cpu.dlyFlt       = true;
 867     cpu.dlyFltNum    = faultNumber;
 868     cpu.dlySubFltNum = subFault;
 869     cpu.dlyCtx       = faultMsg;
 870   }
 871 
 872 //
 873 // return true if group 7 faults are pending ...
 874 //
 875 
 876 // Note: The DIS code assumes that the only G7 fault is TRO. Adding any
 877 // other G7 faults will potentially require changing the DIS code.
 878 
 879 bool bG7Pending (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 880   {
 881     if (cpu.tweaks.l68_mode)
 882      return cpu.g7Faults != 0 || cpu.FFV_faults != 0; // L68
 883     return cpu.g7Faults != 0; // DPS8M
 884   }
 885 
 886 bool bG7PendingNoTRO (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 887   {
 888     if (cpu.tweaks.l68_mode)
 889       return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0 || cpu.FFV_faults != 0; // L68
 890     return (cpu.g7Faults & (~ (1u << FAULT_TRO))) != 0; // DPS8M
 891   }
 892 
 893 void setG7fault (uint cpuNo, _fault faultNo, _fault_subtype subFault)
     /* [previous][next][first][last][top][bottom][index][help] */
 894   {
 895     sim_debug (DBG_FAULT, & cpu_dev, "setG7fault CPU %d fault %d (%o) sub %"PRId64" %"PRIo64"\n",
 896                cpuNo, faultNo, faultNo, subFault.bits, subFault.bits);
 897     cpus[cpuNo].g7FaultsPreset |= (1u << faultNo);
 898     //cpu.g7SubFaultsPreset [faultNo] = subFault;
 899     cpus[cpuNo].g7SubFaults [faultNo] = subFault;
 900 #if defined(THREADZ) || defined(LOCKLESS)
 901     wakeCPU(cpuNo);
 902 #endif
 903   }
 904 
 905 void set_FFV_fault (uint f_fault_no)
     /* [previous][next][first][last][top][bottom][index][help] */
 906   {
 907     sim_debug (DBG_FAULT, & cpu_dev, "set_FFV_fault CPU f_fault_no %u\n",
 908                f_fault_no);
 909     // Map fault number (2/4/6) to bit mask  01/02/04
 910     cpu.FFV_faults_preset |= 1u << ((f_fault_no / 2) - 1);
 911   }
 912 
 913 void clearTROFault (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 914   {
 915     cpu . g7Faults &= ~(1u << FAULT_TRO);
 916   }
 917 
 918 void doG7Fault (bool allowTR)
     /* [previous][next][first][last][top][bottom][index][help] */
 919   {
 920     // sim_printf ("doG7fault %08o [%"PRId64"]\n", cpu . g7Faults, cpu.cycleCnt);
 921     // if (cpu . g7Faults)
 922       // {
 923         // sim_debug (DBG_FAULT, & cpu_dev, "doG7Fault %08o\n", cpu . g7Faults);
 924       // }
 925     // According AL39,  Table 7-1. List of Faults, priority of connect is 25
 926     // and priority of Timer runout is 26, lower number means higher priority
 927 #if defined(THREADZ) || defined(LOCKLESS)
 928     lock_scu ();
 929 #endif
 930      if (cpu.g7Faults & (1u << FAULT_CON))
 931        {
 932          cpu.g7Faults &= ~(1u << FAULT_CON);
 933 
 934 #if defined(THREADZ) || defined(LOCKLESS)
 935          unlock_scu ();
 936 #endif
 937          doFault (FAULT_CON, cpu.g7SubFaults [FAULT_CON], "Connect");
 938        }
 939 
 940      if (allowTR && (cpu.g7Faults & (1u << FAULT_TRO)))
 941        {
 942          cpu . g7Faults &= ~(1u << FAULT_TRO);
 943 
 944          //sim_printf("timer runout %12o\n",cpu.PPR.IC);
 945 #if defined(THREADZ) || defined(LOCKLESS)
 946          unlock_scu ();
 947 #endif
 948          doFault (FAULT_TRO, fst_zero, "Timer runout");
 949        }
 950 
 951      // Strictly speaking EXF isn't a G7 fault, but if we treat is as one,
 952      // we are allowing the current instruction to complete, simplifying
 953      // implementation
 954      if (cpu . g7Faults & (1u << FAULT_EXF))
 955        {
 956          cpu . g7Faults &= ~(1u << FAULT_EXF);
 957 
 958 #if defined(THREADZ) || defined(LOCKLESS)
 959          unlock_scu ();
 960 #endif
 961          doFault (FAULT_EXF, fst_zero, "Execute fault");
 962        }
 963 
 964      if (cpu.tweaks.l68_mode) { // L68
 965        if (cpu.FFV_faults & 1u)  // FFV + 2 OC TRAP
 966          {
 967            cpu.FFV_faults &= ~1u;
 968 #if defined(THREADZ) || defined(LOCKLESS)
 969            unlock_scu ();
 970 #endif
 971            do_FFV_fault (1, "OC TRAP");
 972          }
 973        if (cpu.FFV_faults & 2u)  // FFV + 4 CU HISTORY OVERFLOW TRAP
 974          {
 975            cpu.FFV_faults &= ~2u;
 976 #if defined(THREADZ) || defined(LOCKLESS)
 977            unlock_scu ();
 978 #endif
 979            do_FFV_fault (2, "CU HIST OVF TRAP");
 980          }
 981        if (cpu.FFV_faults & 4u)  // FFV + 6 ADR TRAP
 982          {
 983            cpu.FFV_faults &= ~4u;
 984 #if defined(THREADZ) || defined(LOCKLESS)
 985            unlock_scu ();
 986 #endif
 987            do_FFV_fault (3, "ADR TRAP");
 988          }
 989      }
 990 #if defined(THREADZ) || defined(LOCKLESS)
 991      unlock_scu ();
 992 #endif
 993      doFault (FAULT_TRB, (_fault_subtype) {.bits=cpu.g7Faults}, "Dazed and confused in doG7Fault");
 994   }
 995 
 996 void advanceG7Faults (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 997   {
 998 #if defined(THREADZ) || defined(LOCKLESS)
 999     lock_scu ();
1000 #endif
1001     cpu.g7Faults       |= cpu.g7FaultsPreset;
1002     cpu.g7FaultsPreset  = 0;
1003     //memcpy (cpu.g7SubFaults, cpu.g7SubFaultsPreset, sizeof (cpu.g7SubFaults));
1004     L68_ (
1005       cpu.FFV_faults |= cpu.FFV_faults_preset;
1006       cpu.FFV_faults_preset = 0;
1007     )
1008 #if defined(THREADZ) || defined(LOCKLESS)
1009     unlock_scu ();
1010 #endif
1011   }

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