root/src/dps8/dps8_cpu.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. SET_PR_BITNO
  2. SET_AR_CHAR_BITNO
  3. trackport
  4. doFault
  5. core_write
  6. core_write_zone
  7. core_read2
  8. core_write2
  9. core_readN
  10. core_writeN

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * scspell-id: 72d91a53-f62d-11ec-a98f-80ee73e9b8e7
   5  *
   6  * ---------------------------------------------------------------------------
   7  *
   8  * Copyright (c) 2007-2013 Michael Mondy
   9  * Copyright (c) 2012-2016 Harry Reed
  10  * Copyright (c) 2013-2022 Charles Anthony
  11  * Copyright (c) 2015-2021 Eric Swenson
  12  * Copyright (c) 2021-2024 The DPS8M Development Team
  13  *
  14  * This software is made available under the terms of the ICU License.
  15  * See the LICENSE.md file at the top-level directory of this distribution.
  16  *
  17  * ---------------------------------------------------------------------------
  18  */
  19 
  20 #if !defined(__STDC_WANT_IEC_60559_BFP_EXT__)
  21 # define __STDC_WANT_IEC_60559_BFP_EXT__ 1
  22 #endif /* if !defined(__STDC_WANT_IEC_60559_BFP_EXT__) */
  23 
  24 #include <sys/types.h>
  25 
  26 #if defined(__APPLE__)
  27 # undef SCHED_NEVER_YIELD
  28 # define SCHED_NEVER_YIELD 1
  29 # include <mach/thread_policy.h>
  30 # include <mach/task_info.h>
  31 # include <sys/types.h>
  32 # include <sys/sysctl.h>
  33 # include <mach/thread_policy.h>
  34 # include <mach/thread_act.h>
  35 #endif /* if defined(__APPLE__) */
  36 
  37 #include "../simh/sim_timer.h"
  38 #include "hdbg.h"
  39 
  40 #define N_CPU_UNITS 1 // Default
  41 
  42 // JMP_ENTRY must be 0, which is the return value of the setjmp initial entry
  43 #define JMP_ENTRY             0
  44 #define JMP_REENTRY           1
  45 #define JMP_STOP              2
  46 #define JMP_SYNC_FAULT_RETURN 3
  47 #define JMP_REFETCH           4
  48 #define JMP_RESTART           5
  49 
  50 // The CPU supports 3 addressing modes
  51 // [CAC] I tell a lie: 4 modes...
  52 // [CAC] I tell another lie: 5 modes...
  53 
  54 typedef enum
  55   {
  56     ABSOLUTE_mode,
  57     APPEND_mode,
  58   } addr_modes_e;
  59 
  60 // The control unit of the CPU is always in one of several states. We
  61 // don't currently use all of the states used in the physical CPU.
  62 // The FAULT_EXEC cycle did not exist in the physical hardware.
  63 
  64 typedef enum
  65   {
  66     FAULT_cycle,
  67     EXEC_cycle,
  68     FAULT_EXEC_cycle,
  69     INTERRUPT_cycle,
  70     INTERRUPT_EXEC_cycle,
  71     FETCH_cycle,
  72     PSEUDO_FETCH_cycle,
  73     SYNC_FAULT_RTN_cycle,
  74   } cycles_e;
  75 
  76 struct tpr_s
  77   {
  78     word3   TRR; // The current effective ring number
  79     word15  TSR; // The current effective segment number
  80     word6   TBR; // The current bit offset as calculated from ITS and ITP
  81                  // pointer pairs.
  82     word18  CA;  // The current computed address relative to the origin of the
  83                  // segment whose segment number is in TPR.TSR
  84   };
  85 
  86 struct ppr_s
  87   {
  88     word3   PRR; // The number of the ring in which the process is executing.
  89                  // It is set to the effective ring number of the procedure
  90                  // segment when control is transferred to the procedure.
  91     word15  PSR; // The segment number of the procedure being executed.
  92     word1   P;   // A flag controlling execution of privileged instructions.
  93                  // Its value is 1 (permitting execution of privileged
  94                  // instructions) if PPR.PRR is 0 and the privileged bit in
  95                  // the segment descriptor word (SDW.P) for the procedure is
  96                  // 1; otherwise, its value is 0.
  97     word18  IC;  // The word offset from the origin of the procedure segment
  98                  //  to the current instruction. (same as PPR.IC)
  99   };
 100 
 101 /////
 102 // The terms "pointer register" and "address register" both apply to the same
 103 // physical hardware. The distinction arises from the manner in which the
 104 // register is used and in the interpretation of the register contents.
 105 // "Pointer register" refers to the register as used by the appending unit and
 106 // "address register" refers to the register as used by the decimal unit.
 107 //
 108 // The three forms are compatible and may be freely intermixed. For example,
 109 // PRn may be loaded in pointer register form with the Effective Pointer to
 110 // Pointer Register n (eppn) instruction, then modified in pointer register
 111 // form with the Effective Address to Word/Bit Number of Pointer Register n
 112 // (eawpn) instruction, then further modified in address register form
 113 // (assuming character size k) with the Add k-Bit Displacement to Address
 114 // Register (akbd) instruction, and finally invoked in operand descriptor form
 115 // by the use of MF.AR in an EIS multiword instruction .
 116 //
 117 // The reader's attention is directed to the presence of two bit number
 118 // registers, PRn.BITNO and ARn.BITNO. Because the Multics processor was
 119 // implemented as an enhancement to an existing design, certain apparent
 120 // anomalies appear. One of these is the difference in the handling of
 121 // unaligned data items by the appending unit and decimal unit. The decimal
 122 // unit handles all unaligned data items with a 9-bit byte number and bit
 123 // offset within the byte. Conversion from the description given in the EIS
 124 // operand descriptor is done automatically by the hardware. The appending unit
 125 // maintains compatibility with the earlier generation Multics processor by
 126 // handling all unaligned data items with a bit offset from the prior word
 127 // boundary; again with any necessary conversion done automatically by the
 128 // hardware. Thus, a pointer register, PRn, may be loaded from an ITS pointer
 129 // pair having a pure bit offset and modified by one of the EIS address
 130 // register instructions (a4bd, s9bd, etc.) using character displacement
 131 // counts. The automatic conversion performed ensures that the pointer
 132 // register, PRi, and its matching address register, ARi, both describe the
 133 // same physical bit in main memory.
 134 //
 135 // N.B. Subtle differences between the interpretation of PR/AR. Need to take
 136 // this into account.
 137 //
 138 //     * For Pointer Registers:
 139 //       - PRn.WORDNO The offset in words from the base or origin of the
 140 //                    segment to the data item.
 141 //       - PRn.BITNO  The number of the bit within PRn.WORDNO that is the
 142 //                    first bit of the data item. Data items aligned on word
 143 //                    boundaries always have the value 0. Unaligned data items
 144 //                    may have any value in the range [1,35].
 145 //
 146 //     * For Address Registers:
 147 //       - ARn.WORDNO The offset in words relative to the current addressing
 148 //                    base referent (segment origin, BAR.BASE, or absolute 0
 149 //                    depending on addressing mode) to the word containing the
 150 //                    next data item element.
 151 //       - ARn.CHAR   The number of the 9-bit byte within ARn.WORDNO
 152 //                    containing the first bit of the next data item element.
 153 //       - ARn.BITNO  The number of the bit within ARn.CHAR that is the
 154 //                    first bit of the next data item element.
 155 /////
 156 
 157 struct par_s
 158   {
 159     word15  SNR;      // The segment number of the segment containing the data
 160                       // item described by the pointer register.
 161     word3   RNR;      // The final effective ring number value calculated during
 162                       // execution of the instruction that last loaded the PR.
 163 
 164     word6  PR_BITNO;  // The number of the bit within PRn.WORDNO that is the
 165                       // first bit of the data item. Data items aligned on word
 166                       // boundaries always have the value 0. Unaligned data
 167                       //  items may have any value in the range [1,35].
 168     word2   AR_CHAR;
 169     word4   AR_BITNO;
 170 
 171     word18  WORDNO;   // The offset in words from the base or origin of the
 172                       // segment to the data item.
 173   };
 174 
 175 // N.B. remember there are subtle differences between AR/PR.BITNO
 176 
 177 #define AR    PAR
 178 #define PR    PAR
 179 
 180 struct bar_s
 181   {
 182     word9 BASE;     // Contains the 9 high-order bits of an 18-bit address
 183                     // relocation constant. The low-order bits are generated
 184                     // as zeros.
 185     word9 BOUND;    // Contains the 9 high-order bits of the unrelocated
 186                     // address limit. The low- order bits are generated as
 187                     // zeros. An attempt to access main memory beyond this
 188                     // limit causes a store fault, out of bounds. A value of
 189                     // 0 is truly 0, indicating a null memory range.
 190   };
 191 
 192 struct dsbr_s
 193   {
 194     word24  ADDR;   // If DSBR.U = 1, the 24-bit absolute main memory address
 195                     //  of the origin of the current descriptor segment;
 196                     //  otherwise, the 24-bit absolute main memory address of
 197                     //  the page table for the current descriptor segment.
 198     word14  BND;    // The 14 most significant bits of the highest Y-block16
 199                     //  address of the descriptor segment that can be
 200                     //  addressed without causing an access violation, out of
 201                     //  segment bounds, fault.
 202     word1   U;      // A flag specifying whether the descriptor segment is
 203                     // unpaged (U = 1) or paged (U = 0).
 204     word12  STACK;  // The upper 12 bits of the 15-bit stack base segment
 205                     // number. It is used only during the execution of the
 206                     // call6 instruction. (See Section 8 for a discussion
 207                     //  of generation of the stack segment number.)
 208   };
 209 
 210 // The segment descriptor word (SDW) pair contains information that controls
 211 // the access to a segment. The SDW for segment n is located at offset 2n in
 212 // the descriptor segment whose description is currently loaded into the
 213 // descriptor segment base register (DSBR).
 214 
 215 struct sdw_s
 216   {
 217     word24  ADDR;    // The 24-bit absolute main memory address of the page
 218                      //  table for the target segment if SDWAM.U = 0;
 219                      //  otherwise, the 24-bit absolute main memory address
 220                      //  of the origin of the target segment.
 221     word3   R1;      // Upper limit of read/write ring bracket
 222     word3   R2;      // Upper limit of read/execute ring bracket
 223     word3   R3;      // Upper limit of call ring bracket
 224     word14  BOUND;   // The 14 high-order bits of the last Y-block16 address
 225                      //  within the segment that can be referenced without an
 226                      //  access violation, out of segment bound, fault.
 227     word1   R;       // Read permission bit. If this bit is set ON, read
 228                      //  access requests are allowed.
 229     word1   E;       // Execute permission bit. If this bit is set ON, the SDW
 230                      //  may be loaded into the procedure pointer register
 231                      //  (PPR) and instructions fetched from the segment for
 232                      //  execution.
 233     word1   W;       // Write permission bit. If this bit is set ON, write
 234                      //  access requests are allowed.
 235     word1   P;       // Privileged flag bit. If this bit is set ON, privileged
 236                      //  instructions from the segment may be executed if
 237                      //  PPR.PRR is 0.
 238     word1   U;       // Unpaged flag bit. If this bit is set ON, the segment
 239                      //  is unpaged and SDWAM.ADDR is the 24-bit absolute
 240                      //  main memory address of the origin of the segment. If
 241                      //  this bit is set OFF, the segment is paged andis
 242                      //  SDWAM.ADDR the 24-bit absolute main memory address of
 243                      //  the page table for the segment.
 244     word1   G;       // Gate control bit. If this bit is set OFF, calls and
 245                      //  transfers into the segment must be to an offset no
 246                      //  greater than the value of SDWAM.CL as described
 247                      //  below.
 248     word1   C;       // Cache control bit. If this bit is set ON, data and/or
 249                      //  instructions from the segment may be placed in the
 250                      //  cache memory.
 251     word14  EB;      // Call limiter (entry bound) value. If SDWAM.G is set
 252                      //  OFF, transfers of control into the segment must be to
 253                      //  segment addresses no greater than this value.
 254     word15  POINTER; // The effective segment number used to fetch this SDW
 255                      //  from main memory.
 256     word1   DF;      // Directed fault flag (called F in AL39).
 257                      //  * 0 = page not in main memory; execute directed fault
 258                      //        FC
 259                      //  * 1 = page is in main memory
 260     word2   FC;      // Directed fault number for page fault.
 261     word1   FE;      // Full/empty bit. If this bit is set ON, the SDW in the
 262                      //  register is valid. If this bit is set OFF, a hit is
 263                      //  not possible. All SDWAM.F bits are set OFF by the
 264                      //  instructions that clear the SDWAM.
 265     // L68: word4
 266     // DPS8M: word6
 267     word6   USE;
 268                      // Usage count for the register. The SDWAM.USE field is
 269                      //  used to maintain a strict FIFO queue order among the
 270                      //  SDWs. When an SDW is matched, its USE value is set to
 271                      //  15 (newest) on the DPS/L68 and to 63 on the DPS 8M,
 272                      //  and the queue is reordered. SDWs newly fetched from
 273                      //  main memory replace the SDW with USE value 0 (oldest)
 274                      //  and the queue is reordered.
 275   };
 276 
 277 typedef struct sdw_s sdw_s;
 278 typedef struct sdw_s sdw0_s;
 279 
 280 
 281 
 282 
 283 
 284 
 285 
 286 
 287 
 288 
 289 
 290 
 291 
 292 
 293 
 294 
 295 
 296 
 297 
 298 
 299 
 300 
 301 
 302 
 303 
 304 
 305 
 306 
 307 
 308 
 309 
 310 
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 
 319 
 320 
 321 
 322 
 323 
 324 
 325 
 326 
 327 
 328 
 329 
 330 
 331 
 332 
 333 
 334 // PTW as used by APU
 335 
 336 struct ptw_s
 337  {
 338     word18  ADDR;    // The 18 high-order bits of the 24-bit absolute
 339                      //  main memory address of the page.
 340     word1   U;       // * 1 = page has been used (referenced)
 341     word1   M;       // Page modified flag bit. This bit is set ON whenever
 342                      //  the PTW is used for a store type instruction. When
 343                      //  the bit changes value from 0 to 1, a special
 344                      //  extra cycle is generated to write it back into the
 345                      //  PTW in the page table in main memory.
 346     word1   DF;      // Directed fault flag
 347                      // * 0 = page not in main memory; execute directed fault FC
 348                      // * 1 = page is in main memory
 349     word2   FC;      // Directed fault number for page fault.
 350     word15  POINTER; // The effective segment number used to fetch this PTW
 351                      //  from main memory.
 352     word12  PAGENO;  // The 12 high-order bits of the 18-bit computed
 353                      //  address (TPR.CA) used to fetch this PTW from main
 354                      //  memory.
 355     word1   FE;      // Full/empty bit. If this bit is set ON, the PTW in
 356                      //  the register is valid. If this bit is set OFF, a
 357                      //  hit is not possible. All PTWAM.F bits are set OFF
 358                      //  by the instructions that clear the PTWAM.
 359     // DPS8M: word6
 360     // L68: word4
 361     word6   USE;
 362                      // Usage count for the register. The PTWAM.USE field
 363                      //  is used to maintain a strict FIFO queue order
 364                      //  among the PTWs. When an PTW is matched its USE
 365                      // value is set to 15 (newest) on the DPS/L68 and to
 366                      //  63 on the DPS 8M, and the queue is reordered.
 367                      //  PTWs newly fetched from main memory replace the
 368                      //  PTW with USE value 0 (oldest) and the queue is
 369                      //  reordered.
 370   };
 371 
 372 typedef struct ptw_s ptw_s;
 373 typedef struct ptw_s ptw0_s;
 374 
 375 
 376 
 377 
 378 
 379 
 380 
 381 
 382 
 383 
 384 
 385 
 386 
 387 
 388 
 389 
 390 
 391 
 392 
 393 
 394 //
 395 // Cache Mode Register
 396 //
 397 
 398 struct cache_mode_register_s
 399   {
 400     word15   cache_dir_address;
 401     word1    par_bit;
 402     word1    lev_ful;
 403     word1    csh1_on; // 1: The lower half of the cache memory is active and
 404                       // enabled as per the state of inst_on
 405     word1    csh2_on; // 1: The upper half of the cache memory is active and
 406                       // enabled as per the state of inst_on
 407     // L68 only
 408     word1    opnd_on; // 1: The cache memory (if active) is used for operands.
 409 
 410     word1    inst_on; // 1: The cache memory (if active) is used for
 411                       //  instructions.
 412     // When the cache-to-register mode flag (bit 59 of the cache mode register)
 413     // is set ON, the processor is forced to fetch the operands of all
 414     // double-precision operations unit load operations from the cache memory.
 415     // Y0,12 are ignored, Y15,21 select a column, and Y13,14 select a level.
 416     // All other operations (e.g., instruction fetches, single-precision
 417     // operands, etc.) are treated normally.
 418     word1    csh_reg;
 419     word1    str_asd;
 420     word1    col_ful;
 421     word2    rro_AB;
 422     word1    bypass_cache; // DPS8M only
 423     word2    luf;          // LUF value
 424                            // 0   1   2   3
 425                            // Lockup time
 426                            // 2ms 4ms 8ms 16ms
 427                            // The lockup timer is set to 16ms when the
 428                            // processor is initialized.
 429   };
 430 
 431 typedef struct cache_mode_register_s cache_mode_register_s;
 432 
 433 typedef struct mode_register_s
 434   {
 435     word36 r;
 436     // L68 only
 437                     //  8M      L68
 438     word15 FFV;     //  0       FFV     0 - 14
 439     word1 OC_TRAP;  //  0       a           16
 440     word1 ADR_TRAP; //  0       b           17
 441     word9 OPCODE;   //  0       OPCODE 18 - 26
 442     word1 OPCODEX;  //  0       OPCODE      27
 443 
 444  // word1 cuolin;   //  a       c           18 control unit overlap inhibit
 445  // word1 solin;    //  b       d           19 store overlap inhibit
 446     word1 sdpap;    //  c       e           20 store incorrect data parity
 447     word1 separ;    //  d       f           21 store incorrect ZAC
 448  // word2 tm;       //  e       g      22 - 23 timing margins
 449  // word2 vm;       //  f       h      24 - 25 voltage margins
 450                     //  0       0           26 history register overflow trap
 451                     //  0       0           27 strobe HR on opcode match
 452     word1 hrhlt;    //  g       i           28 history register overflow trap
 453 
 454     // DPS8M only
 455     word1 hrxfr;    //  h       j           29 strobe HR on transfer made
 456     // L68 only
 457                     //  h       j           29 strobe HR on opcode match
 458     word1 ihr;      //  i       k           30 Enable HR
 459     word1 ihrrs;    //  j                   31 HR reset options
 460                     //          l           31 HR lock control
 461                     //  k                   32 margin control
 462                     //          m           32 test mode indicator
 463     // DPS8M only
 464     word1 hexfp;    //  l       0           33 hex mode
 465                     //  0       0           34
 466      word1 emr;     //  m       n           35 enable MR
 467   } mode_register_s;
 468 
 469 extern DEVICE cpu_dev;
 470 
 471 // address of an EIS operand
 472 typedef struct EISaddr_s
 473   {
 474 #if !defined(EIS_PTR)
 475     word18  address;    // 18-bit virtual address
 476 #endif /* if !defined(EIS_PTR) */
 477 
 478     word36  data;
 479     word1    bit;
 480     eRW     mode;
 481 
 482     int     last_bit_posn;  // track for caching tests
 483 
 484     // for type of data being address by this object
 485 
 486     // eisDataType _type;   // type of data - alphanumeric/numeric
 487 
 488 #if !defined(EIS_PTR3)
 489     int     TA;    // type of Alphanumeric chars in src
 490 #endif /* if !defined(EIS_PTR3) */
 491     int     TN;    // type of Numeric chars in src
 492     int     cPos;
 493     int     bPos;
 494 
 495 #if !defined(EIS_PTR4)
 496     // for when using AR/PR register addressing
 497     word15  SNR;                // The segment number of the segment containing the
 498                                 //  data item described by the pointer register.
 499     word3   RNR;                // The effective ring number value calculated during
 500                                 //  execution of the instruction that last loaded.
 501     MemoryAccessType    mat;    // Memory access type for operation.
 502 #endif /* if !defined(EIS_PTR4) */
 503 
 504     // Cache
 505 
 506     // There is a cache for each operand, but they do not cross check;
 507     // this means that if one of them has a cached dirty word, the
 508     // others will not check for a hit, and will use the old value.
 509     // AL39 warns that overlapping operands can cause unexpected behavior
 510     // due to caching issues, so the this behavior is closer to the actual
 511     // h/w then to the theoretical need for cache consistency.
 512 
 513     // We don't need to cache mat or TPR because they will be constant
 514     // across an instruction.
 515 
 516     bool cacheValid;
 517     bool cacheDirty;
 518 #define paragraphSz 8
 519 #define paragraphMask 077777770
 520 #define paragraphOffsetMask 07
 521     word36 cachedParagraph [paragraphSz];
 522     bool wordDirty [paragraphSz];
 523     word18 cachedAddr;
 524 
 525   } EISaddr;
 526 
 527 typedef struct EISstruct_s
 528   {
 529     word36  op [3];         // raw operand descriptors
 530 #define OP1 op [0]          // 1st descriptor (2nd ins word)
 531 #define OP2 op [1]          // 2nd descriptor (3rd ins word)
 532 #define OP3 op [2]          // 3rd descriptor (4th ins word)
 533 
 534     bool     P;             // 4-bit data sign character control
 535 
 536     uint    MF [3];
 537 #define MF1 MF [0]          // Modification field for operand descriptor 1
 538 #define MF2 MF [1]          // Modification field for operand descriptor 2
 539 #define MF3 MF [2]          // Modification field for operand descriptor 3
 540 
 541     uint    CN [3];
 542 #define CN1 CN [0]
 543 #define CN2 CN [1]
 544 #define CN3 CN [2]
 545 
 546     uint    WN [3];
 547 #define WN1 WN [0]
 548 #define WN2 WN [1]
 549 #define WN3 CN [2]
 550 
 551    uint     C [3];
 552 #define C1  C [0]
 553 #define C2  C [1]
 554 #define C3  C [2]
 555 
 556    uint     B [3];
 557 #define B1  B [0]
 558 #define B2  B [1]
 559 #define B3  B [2]
 560 
 561    uint     N [3];
 562 #define N1  N [0]
 563 #define N2  N [1]
 564 #define N3  N [2]
 565 
 566     uint    TN [3];         // type numeric
 567 #define TN1 TN [0]
 568 #define TN2 TN [1]
 569 #define TN3 TN [2]
 570 
 571 #if defined(EIS_PTR3)
 572 # define TA1 cpu.du.TAk[0]
 573 # define TA2 cpu.du.TAk[1]
 574 # define TA3 cpu.du.TAk[2]
 575 #else
 576 
 577     uint     TA [3];        // type alphanumeric
 578 # define TA1 TA [0]
 579 # define TA2 TA [1]
 580 # define TA3 TA [2]
 581 #endif /* if defined(EIS_PTR3) */
 582 
 583    uint     S [3];          // Sign and decimal type of number
 584 #define S1  S [0]
 585 #define S2  S [1]
 586 #define S3  S [2]
 587 
 588     int     SF [3];         // scale factor
 589 #define SF1 SF [0]
 590 #define SF2 SF [1]
 591 #define SF3 SF [2]
 592 
 593     word18 _flags;          // flags set during operation
 594     word18 _faults;         // faults generated by instruction
 595 
 596     word72s x;              // a signed, 128-bit integers for playing with ...
 597 
 598     // Stuff for Micro-operations and Edit instructions...
 599 
 600     word9   editInsertionTable [8];     // 8 9-bit chars
 601 
 602     int     mopIF;          // current micro-operation IF field
 603     struct MOP_struct_s *m;          // pointer to current MOP struct
 604 
 605     word9   inBuffer [64];  // decimal unit input buffer
 606     word9   *in;            // pointer to current read position in inBuffer
 607     uint    inBufferCnt;    // number of characters in inBuffer
 608     word9   outBuffer [64]; // output buffer
 609     word9   *out;           // pointer to current write position in outBuffer;
 610 
 611     int     exponent;       // For decimal floating-point (evil)
 612     int     sign;           // For signed decimal (1, -1)
 613 
 614 #if defined(EIS_PTR2)
 615 # define KMOP 1
 616 #else
 617     EISaddr *mopAddress;    // mopAddress, pointer to addr [0], [1], or [2]
 618 #endif /* if defined(EIS_PTR2) */
 619 
 620     int     mopTally;       // number of micro-ops
 621     int     mopPos;         // current mop char posn
 622 
 623     // Edit Flags
 624     // The processor provides the following four edit flags for use by the
 625     // micro operations.
 626 
 627     bool    mopES;          // End Suppression flag; initially OFF, set ON by
 628                             //  a micro operation when zero-suppression ends.
 629     bool    mopSN;          // Sign flag; initially set OFF if the sending
 630                             //  string has an alphanumeric descriptor or an
 631                             //  unsigned numeric descriptor. If the sending
 632                             //  string has a signed numeric descriptor, the
 633                             //  sign is initially read from the sending string
 634                             //  from the digit position defined by the sign
 635                             //  and the decimal type field (S); SN is set
 636                             //  OFF if positive, ON if negative. If all
 637                             //  digits are zero, the data is assumed positive
 638                             //  and the SN flag is set OFF, even when the
 639                             //  sign is negative.
 640     bool    mopZ;           // Zero flag; initially set ON. It is set OFF
 641                             //  whenever a sending string character that is not
 642                             //  decimal zero is moved into the receiving string.
 643     bool    mopBZ;          // Blank-when-zero flag; initially set OFF and
 644                             //  set ON by either the ENF or SES micro
 645                             //  operation. If, at the completion of a move
 646                             //  (L1 exhausted), both the Z and BZ flags are
 647                             //  ON, the receiving string is filled with
 648                             //  character 1 of the edit insertion table.
 649 
 650     EISaddr addr [3];
 651 
 652 #define ADDR1       addr [0]
 653     int     srcTally;       // number of chars in src (max 63)
 654     int     srcTA;          // type of Alphanumeric chars in src
 655     int     srcSZ;          // size of chars in src (4-, 6-, or 9-bits)
 656 
 657 #define ADDR2       addr [1]
 658 
 659 #define ADDR3       addr [2]
 660     int     dstTally;       // number of chars in dst (max 63)
 661     int     dstSZ;          // size of chars in dst (4-, 6-, or 9-bits)
 662 
 663     bool    mvne;           // for MSES micro-op. True when mvne, false when mve
 664   } EISstruct;
 665 
 666 // Instruction decode structure. Used to represent instruction information
 667 
 668 typedef struct DCDstruct_s
 669   {
 670     struct opcode_s * info; // opcode_s *
 671     uint32 opcode;          // opcode
 672     bool   opcodeX;         // opcode extension
 673     uint32 opcode10;        // opcode | (opcodeX ? 01000 : 0)
 674     word18 address;         // bits 0-17 of instruction
 675     word1  b29;             // bit-29 - address via pointer register. Usually.
 676     bool   i;               // interrupt inhibit bit.
 677     word6  tag;             // instruction tag
 678 
 679     bool stiTally;          // for sti instruction
 680     bool restart;           // instruction is to be restarted
 681   } DCDstruct;
 682 
 683 // Emulator-only interrupt and fault info
 684 
 685 typedef struct
 686   {
 687     vol int fault [N_FAULT_GROUPS];
 688                             // only one fault in groups 1..6 can be pending
 689     vol bool XIP [N_SCU_UNITS_MAX];
 690   } events_t;
 691 
 692 // Physical Switches
 693 
 694 enum procModeSettings { procModeGCOS = 1, procModeMultics = 0 };
 695 
 696 // Switches on the Processor's maintenance and configuration panels
 697 typedef struct
 698   {
 699     uint FLT_BASE; // normally 7 MSB of 12bit fault base addr
 700     uint cpu_num;  // zero for CPU 'A', one for 'B' etc.
 701     word36 data_switches;
 702     word18 addr_switches;
 703     uint assignment [N_CPU_PORTS];
 704     uint interlace [N_CPU_PORTS];    // 0/2/4
 705     uint enable [N_CPU_PORTS];
 706     uint init_enable [N_CPU_PORTS];
 707     uint store_size [N_CPU_PORTS];   // 0-7 encoding 32K-4M
 708     enum procModeSettings procMode;  // 1 bit  Read by rsw instruction; format unknown
 709 
 710     bool enable_cache;   // Enable 8K cache
 711     bool sdwam_enable;   // Enable Segment Descriptor WAM
 712     bool ptwam_enable;   // Enable Page Table WAM
 713 
 714     // CPU serial number; not strictly a switch; on DPS8/M, burned into the CPU PROM
 715     uint serno;
 716   } switches_t;
 717 
 718 // Optional H/W
 719 typedef struct {
 720   uint proc_speed; // 4 bits Read by rsw instruction; format unknown
 721   bool hex_mode_installed;
 722   bool prom_installed;
 723   bool cache_installed;
 724   bool clock_slave_installed;
 725 } optionsType;
 726 
 727 // Hardware tweaks
 728 typedef struct {
 729     uint report_faults;   // If set, faults are reported and ignored
 730     uint tro_enable;      // If set, Timer runout faults are generated.
 731     uint drl_fatal;       // If set, DRL instructions halt the CPU
 732     bool useMap;          // If set, consult memory configuration switches to translate memory
 733                           //          addresses to SCU memory banks
 734     uint dis_enable;      // If non-zero, DIS instruction works
 735     uint halt_on_unimp;   // If non-zero, halt CPU on unimplemented instruction instead of faulting
 736     bool isolts_mode;     // If true, CPU is configured to run ISOLTS.
 737     uint enable_wam;      // If zero, the simulated cache is ignored and always returns "miss";
 738                           //           turning it on incurs a large performance hit.
 739     bool enable_emcall;   // If set, the instruction set is extended with simulator debugging instructions
 740     bool nodis;           // If true, start CPU in FETCH cycle; else start in DIS instruction
 741     bool l68_mode;        // False: DPS8/M; True: 6180
 742 } tweaksType;
 743 
 744 enum ou_cycle_e
 745   {
 746     ou_GIN = 0400,
 747     ou_GOS = 0200,
 748     ou_GD1 = 0100,
 749     ou_GD2 = 0040,
 750     ou_GOE = 0020,
 751     ou_GOA = 0010,
 752     ou_GOM = 0004,
 753     ou_GON = 0002,
 754     ou_GOF = 0001
 755   };
 756 
 757 typedef struct
 758   {
 759     // Operations Unit/Address Modification
 760     bool   directOperandFlag;
 761     word36 directOperand;
 762     word6  characterOperandSize; // just the left most bit
 763     word3  characterOperandOffset;
 764     word18 character_address;
 765     word36 character_data;
 766     bool crflag;
 767 
 768     // L68 only
 769     word2 eac;
 770     word1 RB1_FULL;
 771     word1 RP_FULL;
 772     word1 RS_FULL;
 773     word9 cycle;
 774     word1 STR_OP;
 775     // End L68 only
 776 
 777 #if defined(PANEL68)
 778     word9 RS;
 779     word4 opsz;
 780     word10 reguse;
 781 #endif /* if defined(PANEL68) */
 782   } ou_unit_data_t;
 783 
 784 // APU history operation parameter
 785 
 786 enum APUH_e
 787   {
 788     APUH_FDSPTW = 1llu << (35 - 17),
 789     APUH_MDSPTW = 1llu << (35 - 18),
 790     APUH_FSDWP  = 1llu << (35 - 19),
 791     APUH_FPTW   = 1llu << (35 - 20),
 792     APUH_FPTW2  = 1llu << (35 - 21),
 793     APUH_MPTW   = 1llu << (35 - 22),
 794     APUH_FANP   = 1llu << (35 - 23),
 795     APUH_FAP    = 1llu << (35 - 24)
 796   };
 797 
 798 enum {
 799 //   AL39 pg 64 APU hist.
 800         apu_FLT = 1ll << (33 -  0), //  0   l FLT Access violation or directed
 801                                     //            fault on this cycle
 802                                     //  1-2 a BSY    Data source for ESN
 803     apu_ESN_PSR = 0,                //                  00 PPR.PSR
 804     apu_ESN_SNR = 1ll << (33 -  1), //                  01 PRn.SNR
 805     apu_ESN_TSR = 1ll << (33 -  2), //                  10 TPR.TSR
 806                                     //                  11 not used
 807                                     //  3     PRAP
 808        apu_HOLD = 1ll << (33 -  4), //  4     HOLD  An access violation or
 809                                     //              directed fault is waiting
 810                                     //  5     FRIW
 811                                     //  6     XSF
 812                                     //  7     STF
 813        apu_TP_P = 1ll << (33 -  8), //  8     TP P    Guessing PPR.p set from
 814                                     //                SDW.P
 815        apu_PP_P = 1ll << (33 -  9), //  9     PP P    PPR.P?
 816                                     // 10     ?
 817                                     // 11     S-ON   Segment on?
 818                                     // 12     ZMAS
 819                                     // 13     SDMF   Seg. Descr. Modify?
 820                                     // 14     SFND
 821                                     // 15     ?
 822                                     // 16     P-ON   Page on?
 823                                     // 17     ZMAP
 824                                     // 18     PTMF
 825                                     // 19     PFND
 826       apu_FDPT  = 1ll << (33 - 20), // 20   b FDPT   Fetch descriptor segment PTW
 827       apu_MDPT  = 1ll << (33 - 21), // 21   c MDPT   Modify descriptor segment PTW
 828       apu_FSDP  = 1ll << (33 - 22), // 22   d FSDP   Fetch SDW paged descr. seg.
 829       apu_FSDN  = 1ll << (33 - 23), // 23     FSDN   Fetch SDW non-paged
 830       apu_FPTW  = 1ll << (33 - 24), // 24   e FPTW   Fetch PTW
 831       apu_MPTW  = 1ll << (33 - 25), // 25   g MPTW   Modify PTW
 832       apu_FPTW2 = 1ll << (33 - 26), // 26   f FPT2   // Fetch prepage
 833       apu_FAP   = 1ll << (33 - 27), // 27   i FAP    Final address fetch from
 834                                     //               paged seg.
 835       apu_FANP  = 1ll << (33 - 28), // 28   h FANP   Final address fetch from
 836                                     //               non-paged segment
 837                                     // 29     FAAB   Final address absolute?
 838       apu_FA    = 1ll << (33 - 30), // 30     FA     Final address?
 839                                     // 31     EAAU
 840       apu_PIAU  = 1ll << (33 - 32)  // 32     PIAU   Instruction fetch?
 841                                     // 33     TGAU
 842   };
 843 
 844 typedef struct
 845   {
 846     processor_cycle_type lastCycle;
 847 #if defined(PANEL68)
 848     word34 state;
 849 #endif /* if defined(PANEL68) */
 850   } apu_unit_data_t;
 851 
 852 typedef struct
 853   {
 854     // NB: Some of the data normally stored here is represented
 855     // elsewhere -- e.g.,the PPR is a variable outside of this
 856     // struct.   Other data is live and only stored here.
 857 
 858     // This is a collection of flags and registers from the
 859     // appending unit and the control unit.  The scu and rcu
 860     // instructions store and load these values to an 8 word
 861     // memory block.
 862     //
 863     // The CU data may only be valid for use with the scu and
 864     // rcu instructions.
 865     //
 866     // Comments indicate format as stored in 8 words by the scu
 867     // instruction.
 868 
 869     // NOTE: PPR (procedure pointer register) is a combination of registers:
 870     //   From the Appending Unit
 871     //     PRR bits [0..2] of word 0
 872     //     PSR bits [3..17] of word 0
 873     //     P   bit 18 of word 0
 874     //   From the Control Unit
 875     //     IC  bits [0..17] of word 4
 876 
 877     /* word 0 */
 878                    // 0-2   PRR is stored in PPR
 879                    // 3-17  PSR is stored in PPR
 880                    // 18    P   is stored in PPR
 881     word1 XSF;     // 19    XSF External segment flag
 882     word1 SDWAMM;  // 20    SDWAMM Match on SDWAM
 883     word1 SD_ON;   // 21    SDWAM enabled
 884     word1 PTWAMM;  // 22    PTWAMM Match on PTWAM
 885     word1 PT_ON;   // 23    PTWAM enabled
 886 
 887 
 888 
 889 
 890 
 891 
 892 
 893 
 894 
 895 
 896 
 897 
 898 
 899     word12 APUCycleBits;
 900 
 901 
 902     /* word 1 */
 903                    //                 AVF Access Violation Fault
 904                    //                 SF  Store Fault
 905                    //                 IPF Illegal Procedure Fault
 906                    //
 907     word1 IRO_ISN; //  0    IRO       AVF Illegal Ring Order
 908                    //       ISN       SF  Illegal segment number
 909     word1 OEB_IOC; //  1    ORB       AVF Out of execute bracket [sic] should
 910                    //                     be OEB?
 911                    //       IOC       IPF Illegal op code
 912     word1 EOFF_IAIM;
 913                    //  2    E-OFF     AVF Execute bit is off
 914                    //       IA+IM     IPF Illegal address of modifier
 915     word1 ORB_ISP; //  3    ORB       AVF Out of read bracket
 916                    //       ISP       IPF Illegal slave procedure
 917     word1 ROFF_IPR;//  4    R-OFF     AVF Read bit is off
 918                    //       IPR       IPF Illegal EIS digit
 919     word1 OWB_NEA; //  5    OWB       AVF Out of write bracket
 920                    //       NEA       SF  Nonexistent address
 921     word1 WOFF_OOB;//  6    W-OFF     AVF Write bit is off
 922                    //       OOB       SF  Out of bounds (BAR mode)
 923     word1 NO_GA;   //  7    NO GA     AVF Not a gate
 924     word1 OCB;     //  8    OCB       AVF Out of call bracket
 925     word1 OCALL;   //  9    OCALL     AVF Outward call
 926     word1 BOC;     // 10    BOC       AVF Bad outward call
 927 // PTWAM error is DPS8M only
 928     word1 PTWAM_ER;// 11    PTWAM_ER  AVF PTWAM error // inward return
 929     word1 CRT;     // 12    CRT       AVF Cross ring transfer
 930     word1 RALR;    // 13    RALR      AVF Ring alarm
 931 // On DPS8M a SDWAM error, on DP8/L68 a WAM error
 932     word1 SDWAM_ER;// 14    SWWAM_ER  AVF SDWAM error
 933     word1 OOSB;    // 15    OOSB      AVF Out of segment bounds
 934     word1 PARU;    // 16    PARU      Parity fault - processor parity upper
 935     word1 PARL;    // 17    PARL      Parity fault - processor parity lower
 936     word1 ONC1;    // 18    ONC1      Operation not complete fault error #1
 937     word1 ONC2;    // 19    ONC2      Operation not complete fault error #2
 938     word4 IA;      // 20-23 IA        System control illegal action lines
 939     word3 IACHN;   // 24-26 IACHN     Illegal action processor port
 940     word3 CNCHN;   // 27-29 CNCHN     Connect fault - connect processor port
 941     word5 FI_ADDR; // 30-34 F/I ADDR  Modulo 2 fault/interrupt vector address
 942     word1 FLT_INT; // 35    F/I       0 = interrupt; 1 = fault
 943 
 944     /* word 2 */
 945                    //  0- 2 TRR
 946                    //  3-17 TSR
 947                    // 18-21 PTW
 948                    //                  18  PTWAM levels A, B enabled
 949                    //                  19  PTWAM levels C, D enabled
 950                    //                  20  PTWAM levels A, B match
 951                    //                  21  PTWAM levels C, D match
 952                    // 22-25 SDW
 953                    //                  22  SDWAM levels A, B enabled
 954                    //                  23  SDWAM levels C, D enabled
 955                    //                  24  SDWAM levels A, B match
 956                    //                  25  SDWAM levels C, D match
 957                    // 26             0
 958                    // 27-29 CPU      CPU Number
 959     word6 delta;   // 30-35 DELTA    addr increment for repeats
 960 
 961     /* word 3 */
 962                    //  0-17          0
 963                    // 18-21 TSNA     Pointer register number for non-EIS
 964                    //                operands or EIS Operand #1
 965                    //                  18-20 PRNO Pointer register number
 966                    //                  21       PRNO is valid
 967                    // 22-25 TSNB     Pointer register number for EIS operand #2
 968                    //                  22-24 PRNO Pointer register number
 969                    //                  25       PRNO is valid
 970                    // 26-29 TSNC     Pointer register number for EIS operand #2
 971                    //                  26-28 PRNO Pointer register number
 972                    //                  29       PRNO is valid
 973     word3 TSN_PRNO [3];
 974     word1 TSN_VALID [3];
 975 
 976                    // 30-35 TEMP BIT Current bit offset (TPR.TBR)
 977 
 978     /* word 4 */
 979                    //  0-17 PPR.IC
 980     word18 IR;     // 18-35 Indicator register
 981                    //    18 ZER0
 982                    //    19 NEG
 983                    //    20 CARY
 984                    //    21 OVFL
 985                    //    22 EOVF
 986                    //    23 EUFL
 987                    //    24 OFLM
 988                    //    25 TRO
 989                    //    26 PAR
 990                    //    27 PARM
 991                    //    28 -BM
 992                    //    29 TRU
 993                    //    30 MIF
 994                    //    31 ABS
 995                    //    32 HEX [sic] Figure 3-32 is wrong.
 996                    // 33-35 0
 997 
 998     /* word 5 */
 999 
1000                    //  0-17 COMPUTED ADDRESS (TPR.CA)
1001     word1 repeat_first;
1002                    // 18    RF  First cycle of all repeat instructions
1003     word1 rpt;     // 19    RPT Execute an Repeat (rpt) instruction
1004     word1 rd;      // 20    RD  Execute an Repeat Double (rpd) instruction
1005     word1 rl;      // 21    RL  Execute a Repeat Link (rpl) instruction
1006     word1 pot;     // 22    POT Prepare operand tally
1007                    // 23    PON Prepare operand no tally
1008     //xde xdo
1009     // 0   0   no execute           -> 0 0
1010     // 1   0   execute XEC          -> 0 0
1011     // 1   1   execute even of XED  -> 0 1
1012     // 0   1   execute odd of XED   -> 0 0
1013     word1 xde;     // 24    XDE Execute instruction from Execute Double even
1014                    //       pair
1015     word1 xdo;     // 25    XDO Execute instruction from Execute Double odd pair
1016     word1 itp;     // 26    ITP Execute ITP indirect cycle
1017     word1 rfi;     // 27    RFI Restart this instruction
1018     word1 its;     // 28    ITS Execute ITS indirect cycle
1019     word1 FIF;     // 29    FIF Fault occurred during instruction fetch
1020     word6 CT_HOLD; // 30-35 CT HOLD contents of the "remember modifier" register
1021 
1022     /* word 6 */
1023     word36 IWB;
1024 
1025     /* word 7 */
1026     word36 IRODD; /* Instr holding register; odd word of last pair fetched */
1027  } ctl_unit_data_t;
1028 
1029 #define USE_IRODD (cpu.cu.rd && ((cpu. PPR.IC & 1) != 0))
1030 #define IWB_IRODD (USE_IRODD ? cpu.cu.IRODD : cpu.cu.IWB)
1031 
1032 // L68 only
1033 enum du_cycle1_e
1034   {
1035     //  0 -FPOL Prepare operand length
1036     du1_nFPOL        = 0400000000000ull,
1037     //  1 -FPOP Prepare operand pointer
1038     du1_nFPOP        = 0200000000000ull,
1039     //  2 -NEED-DESC Need descriptor
1040     du1_nNEED_DESC   = 0100000000000ull,
1041     //  3 -SEL-ADR Select address register
1042     du1_nSEL_DIR     = 0040000000000ull,
1043     //  4 -DLEN=DIRECT Length equals direct
1044     du1_nDLEN_DIRECT = 0020000000000ull,
1045     //  5 -DFRST Descriptor processed for first time
1046     du1_nDFRST       = 0010000000000ull,
1047     //  6 -FEXR Extended register modification
1048     du1_nFEXR        = 0004000000000ull,
1049     //  7 -DLAST-FRST Last cycle of DFRST
1050     du1_nLAST_DFRST  = 0002000000000ull,
1051     //  8 -DDU-LDEA Decimal unit load  (lpl?)
1052     du1_nDDU_LDEA    = 0001000000000ull,
1053     //  9 -DDU-STAE Decimal unit store (spl?)
1054     du1_nDDU_STEA    = 0000400000000ull,
1055     // 10 -DREDO Redo operation without pointer and length update
1056     du1_nDREDO       = 0000200000000ull,
1057     // 11 -DLVL<WD-SZ Load with count less than word size
1058     du1_nDLVL_WD_SZ  = 0000100000000ull,
1059     // 12 -EXH Exhaust
1060     du1_nEXH         = 0000040000000ull,
1061     // 13 DEND-SEQ End of sequence
1062     du1_DEND_SEQ     = 0000020000000ull,
1063     // 14 -DEND End of instruction
1064     du1_nEND         = 0000010000000ull,
1065     // 15 -DU=RD+WRT Decimal unit write-back
1066     du1_nDU_RD_WRT   = 0000004000000ull,
1067     // 16 -PTRA00 PR address bit 0
1068     du1_nPTRA00      = 0000002000000ull,
1069     // 17 -PTRA01 PR address bit 1
1070     du1_nPTRA01      = 0000001000000ull,
1071     // 18 FA/Il Descriptor l active
1072     du1_FA_I1        = 0000000400000ull,
1073     // 19 FA/I2 Descriptor 2 active
1074     du1_FA_I2        = 0000000200000ull,
1075     // 20 FA/I3 Descriptor 3 active
1076     du1_FA_I3        = 0000000100000ull,
1077     // 21 -WRD Word operation
1078     du1_nWRD         = 0000000040000ull,
1079     // 22 -NINE 9-bit character operation
1080     du1_nNINE        = 0000000020000ull,
1081     // 23 -SIX 6-bit character operation
1082     du1_nSIX         = 0000000010000ull,
1083     // 24 -FOUR 4-bit character operation
1084     du1_nFOUR        = 0000000004000ull,
1085     // 25 -BIT Bit operation
1086     du1_nBIT         = 0000000002000ull,
1087     // 26 Unused
1088     //               = 0000000001000ull,
1089     // 27 Unused
1090     //               = 0000000000400ull,
1091     // 28 Unused
1092     //               = 0000000000200ull,
1093     // 29 Unused
1094     //               = 0000000000100ull,
1095     // 30 FSAMPL Sample for mid-instruction interrupt
1096     du1_FSAMPL       = 0000000000040ull,
1097     // 31 -DFRST-CT Specified first count of a sequence
1098     du1_nDFRST_CT    = 0000000000020ull,
1099     // 32 -ADJ-LENGTH Adjust length
1100     du1_nADJ_LENTGH  = 0000000000010ull,
1101     // 33 -INTRPTD Mid-instruction interrupt
1102     du1_nINTRPTD     = 0000000000004ull,
1103     // 34 -INHIB Inhibit STC1 (force "STC0")
1104     du1_nINHIB       = 0000000000002ull,
1105     // 35 Unused
1106     //               = 0000000000001ull,
1107   };
1108 
1109 // L68 only
1110 enum du_cycle2_e
1111   {
1112     // 36 DUD Decimal unit idle
1113     du2_DUD          = 0400000000000ull,
1114     // 37 -GDLDA Descriptor load gate A
1115     du2_nGDLDA       = 0200000000000ull,
1116     // 38 -GDLDB Descriptor load gate B
1117     du2_nGDLDB       = 0100000000000ull,
1118     // 39 -GDLDC Descriptor load gate C
1119     du2_nGDLDC       = 0040000000000ull,
1120     // 40 NLD1 Prepare alignment count for first numeric operand load
1121     du2_NLD1         = 0020000000000ull,
1122     // 41 GLDP1 Numeric operand one load gate
1123     du2_GLDP1        = 0010000000000ull,
1124     // 42 NLD2 Prepare alignment count for second numeric operand load
1125     du2_NLD2         = 0004000000000ull,
1126     // 43 GLDP2 Numeric operand two load gate
1127     du2_GLDP2        = 0002000000000ull,
1128     // 44 ANLD1 Alphanumeric operand one load gate
1129     du2_ANLD1        = 0001000000000ull,
1130     // 45 ANLD2 Alphanumeric operand two load gate
1131     du2_ANLD2        = 0000400000000ull,
1132     // 46 LDWRT1 Load rewrite register one gate (XXX Guess indirect desc. MFkID)
1133     du2_LDWRT1       = 0000200000000ull,
1134     // 47 LDWRT2 Load rewrite register two gate (XXX Guess indirect desc. MFkID)
1135     du2_LDWRT2       = 0000100000000ull,
1136     // 50 -DATA-AVLDU Decimal unit data available
1137     du2_nDATA_AVLDU  = 0000040000000ull,
1138     // 49 WRT1 Rewrite register one loaded
1139     du2_WRT1         = 0000020000000ull,
1140     // 50 GSTR Numeric store gate
1141     du2_GSTR         = 0000010000000ull,
1142     // 51 ANSTR Alphanumeric store gate
1143     du2_ANSTR        = 0000004000000ull,
1144     // 52 FSTR-OP-AV Operand available to be stored
1145     du2_FSTR_OP_AV   = 0000002000000ull,
1146     // 53 -FEND-SEQ End sequence flag
1147     du2_nFEND_SEQ    = 0000001000000ull,
1148     // 54 -FLEN<128 Length less than 128
1149     du2_nFLEN_128    = 0000000400000ull,
1150     // 55 FGCH Character operation gate
1151     du2_FGCH         = 0000000200000ull,
1152     // 56 FANPK Alphanumeric packing cycle gate
1153     du2_FANPK        = 0000000100000ull,
1154     // 57 FEXMOP Execute MOP gate
1155     du2_FEXOP        = 0000000040000ull,
1156     // 58 FBLNK Blanking gate
1157     du2_FBLNK        = 0000000020000ull,
1158     // 59 Unused
1159     //               = 0000000010000ull,
1160     // 60 DGBD Binary to decimal execution gate
1161     du2_DGBD         = 0000000004000ull,
1162     // 61 DGDB Decimal to binary execution gate
1163     du2_DGDB         = 0000000002000ull,
1164     // 62 DGSP Shift procedure gate
1165     du2_DGSP         = 0000000001000ull,
1166     // 63 FFLTG Floating result flag
1167     du2_FFLTG        = 0000000000400ull,
1168     // 64 FRND Rounding flag
1169     du2_FRND         = 0000000000200ull,
1170     // 65 DADD-GATE Add/subtract execute gate
1171     du2_DADD_GATE    = 0000000000100ull,
1172     // 66 DMP+DV-GATE Multiply/divide execution gate
1173     du2_DMP_DV_GATE  = 0000000000040ull,
1174     // 67 DXPN-GATE Exponent network execution gate
1175     du2_DXPN_GATE    = 0000000000020ull,
1176     // 68 Unused
1177     //               = 0000000000010ull,
1178     // 69 Unused
1179     //               = 0000000000004ull,
1180     // 70 Unused
1181     //               = 0000000000002ull,
1182     // 71 Unused
1183     //               = 0000000000001ull,
1184   };
1185 
1186 // L68 only
1187 #define DU_CYCLE_GDLDA {   clrmask (& cpu.du.cycle2, du2_nGDLDA);              \
1188                            setmask (& cpu.du.cycle2, du2_nGDLDB | du2_nGDLDC); }
1189 #define DU_CYCLE_GDLDB {   clrmask (& cpu.du.cycle2, du2_nGDLDB);              \
1190                            setmask (& cpu.du.cycle2, du2_nGDLDA | du2_nGDLDC); }
1191 #define DU_CYCLE_GDLDC {   clrmask (& cpu.du.cycle2, du2_nGDLDC);              \
1192                            setmask (& cpu.du.cycle2, du2_nGDLDA | du2_nGDLDB); }
1193 #define DU_CYCLE_FA_I1     setmask (& cpu.du.cycle1, du1_FA_I1)
1194 #define DU_CYCLE_FA_I2     setmask (& cpu.du.cycle1, du1_FA_I2)
1195 #define DU_CYCLE_FA_I3     setmask (& cpu.du.cycle1, du1_FA_I3)
1196 #define DU_CYCLE_ANLD1     setmask (& cpu.du.cycle2, du2_ANLD1)
1197 #define DU_CYCLE_ANLD2     setmask (& cpu.du.cycle2, du2_ANLD2)
1198 #define DU_CYCLE_NLD1      setmask (& cpu.du.cycle2, du2_NLD1)
1199 #define DU_CYCLE_NLD2      setmask (& cpu.du.cycle2, du2_NLD2)
1200 #define DU_CYCLE_FRND      setmask (& cpu.du.cycle2, du2_FRND)
1201 #define DU_CYCLE_DGBD      setmask (& cpu.du.cycle2, du2_DGBD)
1202 #define DU_CYCLE_DGDB      setmask (& cpu.du.cycle2, du2_DGDB)
1203 #define DU_CYCLE_DDU_LDEA  clrmask (& cpu.du.cycle1, du1_nDDU_LDEA)
1204 #define DU_CYCLE_DDU_STEA  clrmask (& cpu.du.cycle1, du1_nDDU_STEA)
1205 #define DU_CYCLE_END       clrmask (& cpu.du.cycle1, du1_nEND)
1206 #define DU_CYCLE_LDWRT1    setmask (& cpu.du.cycle2, du2_LDWRT1)
1207 #define DU_CYCLE_LDWRT2    setmask (& cpu.du.cycle2, du2_LDWRT2)
1208 #define DU_CYCLE_FEXOP     setmask (& cpu.du.cycle2, du2_FEXOP)
1209 #define DU_CYCLE_ANSTR     setmask (& cpu.du.cycle2, du2_ANSTR)
1210 #define DU_CYCLE_GSTR      setmask (& cpu.du.cycle2, du2_GSTR)
1211 #define DU_CYCLE_FLEN_128  clrmask (& cpu.du.cycle2, du2_nFLEN_128)
1212 #define DU_CYCLE_FDUD  { cpu.du.cycle1 = \
1213                       du1_nFPOL        | \
1214                       du1_nFPOP        | \
1215                       du1_nNEED_DESC   | \
1216                       du1_nSEL_DIR     | \
1217                       du1_nDLEN_DIRECT | \
1218                       du1_nDFRST       | \
1219                       du1_nFEXR        | \
1220                       du1_nLAST_DFRST  | \
1221                       du1_nDDU_LDEA    | \
1222                       du1_nDDU_STEA    | \
1223                       du1_nDREDO       | \
1224                       du1_nDLVL_WD_SZ  | \
1225                       du1_nEXH         | \
1226                       du1_nEND         | \
1227                       du1_nDU_RD_WRT   | \
1228                       du1_nWRD         | \
1229                       du1_nNINE        | \
1230                       du1_nSIX         | \
1231                       du1_nFOUR        | \
1232                       du1_nBIT         | \
1233                       du1_nINTRPTD     | \
1234                       du1_nINHIB;        \
1235                     cpu.du.cycle2 =      \
1236                       du2_DUD          | \
1237                       du2_nGDLDA       | \
1238                       du2_nGDLDB       | \
1239                       du2_nGDLDC       | \
1240                       du2_nDATA_AVLDU  | \
1241                       du2_nFEND_SEQ    | \
1242                       du2_nFLEN_128;     \
1243                   }
1244 #define DU_CYCLE_nDUD clrmask (& cpu.du.cycle2, du2_DUD)
1245 
1246 #if defined(PANEL68)
1247 // Control points
1248 # define CPT(R,C) cpu.cpt[R][C]=1
1249 # define CPTUR(C) cpu.cpt[cpt5L][C]=1
1250 #else
1251 # define CPT(R,C)
1252 # define CPTUR(C)
1253 #endif /* if defined(PANEL68) */
1254 
1255 
1256 
1257 
1258 
1259 
1260 
1261 
1262 
1263 
1264 
1265 
1266 
1267 
1268 
1269 
1270 
1271 
1272 
1273 
1274 
1275 
1276 
1277 
1278 
1279 
1280 
1281 
1282 
1283 
1284 
1285 
1286 
1287 
1288 
1289 
1290 
1291 
1292 
1293 
1294 
1295 
1296 
1297 
1298 
1299 
1300 
1301 
1302 
1303 
1304 
1305 
1306 
1307 
1308 
1309 
1310 
1311 
1312 
1313 
1314 
1315 
1316 
1317 
1318 
1319 
1320 
1321 
1322 
1323 
1324 
1325 
1326 
1327 
1328 
1329 
1330 
1331 
1332 
1333 
1334 
1335 
1336 
1337 
1338 
1339 
1340 
1341 
1342 
1343 
1344 
1345 
1346 typedef struct du_unit_data_t
1347   {
1348     // Word 0
1349 
1350                       //  0- 8  9   Zeros
1351     word1 Z;          //     9  1   Z       All bit-string instruction results
1352                       //                      are zero
1353     word1 NOP;        //    10  1   0       Negative overpunch found in 6-4
1354                       //                      expanded move
1355     word24 CHTALLY;   // 12-35 24   CHTALLY The number of characters examined
1356                       //                      by the scm, scmr, scd,
1357                       //                      scdr, tct, or tctr instructions
1358                       //                      (up to the interrupt or match)
1359 
1360     // Word 1
1361 
1362                       //  0-35 26   Zeros
1363 
1364     // Word 2
1365 
1366     // word24 D1_PTR; //  0-23 24   D1 PTR  Address of the last double-word
1367                       //                      accessed by operand descriptor 1;
1368                       //                      bits 17-23 (bit-address) valid
1369                       //                      only for initial access
1370                       //    24  1   Zero
1371     // word2 TA1;     // 25-26  2   TA1     Alphanumeric type of operand
1372                       //                      descriptor 1
1373                       // 27-29  3   Zeroes
1374                       //    30  1   I       Decimal unit interrupted flag; a
1375                       //                      copy of the mid-instruction
1376                       //                      interrupt fault indicator
1377     // word1 F1;      //    31  1   F1      First time; data in operand
1378                       //                      descriptor 1 is valid
1379     // word1 A1;      //    32  1   A1      Operand descriptor 1 is active
1380                       // 33-35  3   Zeroes
1381 
1382     // Word 3
1383 
1384     word10 LEVEL1;    //  0- 9 10   LEVEL 1 Difference in the count of
1385                       //                      characters loaded into the and
1386                       //                      processor characters not acted
1387                       //                      upon
1388     // word24 D1_RES; // 12-35 24   D1 RES  Count of characters remaining in
1389                       //                      operand descriptor 1
1390 
1391     // Word 4
1392 
1393     // word24 D2_PTR; //  0-23 24   D2 PTR  Address of the last double-word
1394                       //                      accessed by operand descriptor 2;
1395                       //                      bits 17-23 (bit-address) valid
1396                       //                      only for initial access
1397                       //    24  1   Zero
1398     // word2 TA2;     // 25-26  2   TA2     Alphanumeric type of operand
1399                       //                      descriptor 2
1400                       // 27-29  3   Zeroes
1401     word1 R;          //    30  1   R       Last cycle performed must be
1402                       //                    repeated
1403     // word1 F2;      //    31  1   F2      First time; data in operand
1404                       //                      descriptor 2 is valid
1405     // word1 A2;      //    32  1   A2      Operand descriptor 2 is active
1406                       // 33-35  3   Zeroes
1407 
1408     // Word 5
1409 
1410     word10 LEVEL2;    //  0- 9 10   LEVEL 2 Same as LEVEL 1, but used mainly
1411                       //                      for OP 2 information
1412     // word24 D2_RES; // 12-35 24   D2 RES  Count of characters remaining in
1413                       //                      operand descriptor 2
1414 
1415     // Word 6
1416 
1417     // word24 D3_PTR; //  0-23 24   D3 PTR  Address of the last double-word
1418                       //                      accessed by operand descriptor 3;
1419                       //                      bits 17-23 (bit-address) valid
1420                       //                      only for initial access
1421                       //    24  1   Zero
1422     // word2 TA3;     // 25-26  2   TA3     Alphanumeric type of operand
1423                       //                      descriptor 3
1424                       // 27-29  3   Zeroes
1425                       //    30  1   R       Last cycle performed must be
1426                       //                      repeated
1427                       //                    [XXX: what is the difference between
1428                       //                      this and word4.R]
1429     // word1 F3;      //    31  1   F3      First time; data in operand
1430                       //                      descriptor 3 is valid
1431     // word1 A3;      //    32  1   A3      Operand descriptor 3 is active
1432     word3 JMP;        // 33-35  3   JMP     Descriptor count; number of words
1433                       //                      to skip to find the next
1434                       //                      instruction following this
1435                       //                      multiword instruction
1436 
1437     // Word 7
1438 
1439                       //  0-12 12   Zeroes
1440     // word24 D3_RES; // 12-35 24   D3 RES  Count of characters remaining in
1441                       //                      operand descriptor 3
1442 
1443     // Fields from above reorganized for generality
1444     word2 TAk [3];
1445 
1446 // D_PTR is a word24 divided into a 18 bit address, and a 6-bit bitno/char
1447 // field
1448 
1449     word18 Dk_PTR_W [3];
1450 #define D1_PTR_W Dk_PTR_W [0]
1451 #define D2_PTR_W Dk_PTR_W [1]
1452 #define D3_PTR_W Dk_PTR_W [2]
1453 
1454     word6 Dk_PTR_B [3];
1455 #define D1_PTR_B Dk_PTR_B [0]
1456 #define D2_PTR_B Dk_PTR_B [1]
1457 #define D3_PTR_B Dk_PTR_B [2]
1458 
1459     word24 Dk_RES [3];
1460 #define D_RES Dk_RES
1461 #define D1_RES Dk_RES [0]
1462 #define D2_RES Dk_RES [1]
1463 #define D3_RES Dk_RES [2]
1464 
1465     word1 Fk [3];
1466 //#define F Fk
1467 #define F1 Fk [0]
1468 #define F2 Fk [0]
1469 #define F3 Fk [0]
1470 
1471     word1 Ak [3];
1472 
1473     // Working storage for EIS instruction processing.
1474 
1475     // These values must be restored on instruction restart
1476     word7 MF [3]; // Modifier fields for each instruction.
1477 
1478     // Image of LPL/SPL for ISOLTS compliance
1479     word36 image [8];
1480 
1481 #if defined(PANEL68)
1482     word37 cycle1;
1483     word37 cycle2;
1484     word1 POL; // Prepare operand length
1485     word1 POP; // Prepare operand pointer
1486 #endif /* if defined(PANEL68) */
1487   } du_unit_data_t;
1488 
1489 #if defined(PANEL68)
1490 // prepare_state bits
1491 enum
1492   {
1493     ps_PIA = 0200,
1494     ps_POA = 0100,
1495     ps_RIW = 0040,
1496     ps_SIW = 0020,
1497     ps_POT = 0010,
1498     ps_PON = 0004,
1499     ps_RAW = 0002,
1500     ps_SAW = 0001
1501   };
1502 #endif /* if defined(PANEL68) */
1503 
1504 // History registers
1505 
1506 // CU History register flag2 field bit
1507 
1508 enum
1509   {
1510     CUH_XINT = 0100,
1511     CUH_IFT  =  040,
1512     CUH_CRD  =  020,
1513     CUH_MRD  =  010,
1514     CUH_MSTO =   04,
1515     CUH_PIB  =   02
1516 };
1517 
1518 #define N_DPS8M_WAM_ENTRIES 64
1519 #define N_DPS8M_WAM_MASK   077
1520 #define N_L68_WAM_ENTRIES   16
1521 #define N_L68_WAM_MASK     017
1522 #define N_NAX_WAM_ENTRIES   64
1523 #define N_MODEL_WAM_ENTRIES (cpu.tweaks.l68_mode ? N_L68_WAM_ENTRIES : N_DPS8M_WAM_ENTRIES)
1524 
1525 #include "ucache.h"
1526 
1527 typedef struct cpu_state_s
1528   {
1529     EISstruct currentEISinstruction;
1530 
1531     uCache_t uCache;
1532 
1533     unsigned long long cycleCnt;
1534     unsigned long long instrCnt;
1535     unsigned long long instrCntT0;
1536     unsigned long long instrCntT1;
1537     unsigned long long lockCnt;
1538     unsigned long long lockImmediate;
1539     unsigned long long lockWait;
1540     unsigned long long lockWaitMax;
1541 #if !defined(SCHED_NEVER_YIELD)
1542     unsigned long long lockYield;
1543 #endif /* if !defined(SCHED_NEVER_YIELD) */
1544 
1545     // From the control unit history register:
1546     _fault_subtype subFault; // saved by doFault
1547 
1548     word36   rA;     // accumulator
1549     word36   rQ;     // quotient
1550 
1551     fault_acv_subtype_  acvFaults;   // pending ACV faults
1552 
1553     sdw_s * SDW; // working SDW
1554 
1555     // Zone mask
1556     word36 zone;
1557 
1558     ptw_s * PTW;
1559 
1560     word36 CY;              // C(Y) operand data from memory
1561 
1562     uint64 lufCounter;
1563 
1564     _fault_subtype dlySubFltNum;
1565 
1566     const char * dlyCtx;
1567 
1568     word36 faultRegister [2];
1569 
1570     word36 itxPair [2];
1571 
1572 //#if defined(THREADZ) || defined(LOCKLESS)
1573 //    struct timespec rTRTime; // time when rTR was set
1574 //#endif
1575 
1576     mode_register_s MR;
1577     // Changes to the mode register history bits do not take affect until
1578     // the next instruction (ISOLTS 700 2a). Cache the values here so
1579     // that post register updates can see the old values.
1580     mode_register_s MR_cache;
1581 
1582     DCDstruct currentInstruction;
1583 
1584     ou_unit_data_t ou;
1585 
1586     word36 Ypair[2];        //  2-words
1587     word36 Yblock8[8];      //  8-words
1588     word36 Yblock16[16];    // 16-words
1589     word36 Yblock32[32];    // 32-words
1590 
1591     word36 scu_data[8];     // For SCU instruction
1592 
1593     ctl_unit_data_t cu;
1594     du_unit_data_t du;
1595 
1596     switches_t switches;
1597     optionsType options;
1598     tweaksType tweaks;
1599     switches_t isolts_switches_save;
1600 
1601     jmp_buf jmpMain; // This is the entry to the CPU state machine
1602 
1603     unsigned long      faultCnt [N_FAULTS];
1604 
1605     _fault_subtype  g7SubFaults [N_FAULTS];
1606 
1607     word36 history [N_HIST_SETS] [N_MAX_HIST_SIZE] [2];
1608 
1609     cycles_e cycle;
1610 
1611     _fault faultNumber;      // fault number saved by doFault
1612 
1613     apu_unit_data_t apu;
1614 
1615     word27   rTR;    // timer [map: TR, 9 0's]
1616 #if defined(THREADZ) || defined(LOCKLESS)
1617     uint     rTRsample;
1618 #endif
1619     word24   rY;     // address operand
1620 
1621     word18  lnk;     // rpl link value
1622 
1623     uint g7FaultsPreset;
1624     uint g7Faults;
1625 
1626     word24 iefpFinalAddress;
1627 
1628     // ISOLTS fine grain TR estimation
1629     uint rTRlsb;
1630     uint shadowTR;
1631     uint TR0; // The value that the TR was set to.
1632 
1633     // Arguments for delayed overflow fault
1634     _fault dlyFltNum;
1635 
1636     word18 last_write;
1637 
1638 #if defined(LOCKLESS)
1639     word24 locked_addr;
1640     word24 char_word_address;
1641 #endif /* if defined(LOCKLESS) */
1642 
1643     word24 rmw_address;
1644 
1645     uint restart_address;
1646 
1647     struct
1648       {
1649         word15 PSR;
1650         word3  PRR;
1651         word18 IC;
1652       } cu_data;            // For STCD instruction
1653     uint rTRticks;
1654 
1655     struct tpr_s TPR;     // Temporary Pointer Register
1656     struct ppr_s PPR;     // Procedure Pointer Register
1657     struct dsbr_s DSBR;   // Descriptor Segment Base Register
1658     ptw0_s PTW0; // a PTW not in PTWAM (PTWx1)
1659 
1660     uint history_cyclic [N_HIST_SETS]; // 0..63
1661 
1662     sdw_s SDW0;  // a SDW not in SDWAM
1663     sdw_s _s;
1664 
1665     word18   rX [8]; // index
1666 
1667     // Number of banks in each SCU
1668     uint sc_num_banks [N_SCU_UNITS_MAX];
1669 
1670     // Caching some cabling data for interrupt handling.
1671     // When a CPU calls get_highest_intr(), it needs to know
1672     // what port on the SCU it is attached to. Because of port
1673     // expanders several CPUs can be attached to an SCU port,
1674     // mapping from the CPU to the SCU is easier to query
1675     uint scu_port[N_SCU_UNITS_MAX];
1676 
1677     // L68 FFV faults
1678 
1679      uint FFV_faults_preset;
1680      uint FFV_faults;
1681      uint FFV_fault_number;
1682 
1683 #if defined(AFFINITY)
1684     uint affinity;
1685 #endif /* if defined(AFFINITY) */
1686 
1687     events_t events;
1688 
1689     word24 pad[16];
1690 
1691     struct par_s PAR [8]; // pointer/address registers
1692 
1693     ptw_s PTWAM [N_NAX_WAM_ENTRIES];
1694 
1695     // Map memory address through memory configuration switches
1696     // Minimum allocation chunk is 64K (SCBANK_SZ)
1697     // addr / SCBANK_SZ => bank_number
1698     // scbank_map[bank_number] is address of the bank in M. -1 is unmapped.
1699     int sc_addr_map [N_SCBANKS];
1700     // The SCU number holding each bank
1701     int sc_scu_map [N_SCBANKS];
1702 
1703     sdw_s SDWAM [N_NAX_WAM_ENTRIES]; // Segment Descriptor Word Associative Memory
1704 
1705     // Address Modification tally
1706     word12 AM_tally;
1707 
1708     struct bar_s BAR;     // Base Address Register
1709 
1710     cache_mode_register_s CMR;
1711 
1712     // The following are all from the control unit history register:
1713 
1714     bool interrupt_flag;     // an interrupt is pending in this cycle
1715     bool g7_flag;            // a g7 fault is pending in this cycle;
1716 
1717     bool wasXfer;      // The previous instruction was a transfer
1718 
1719     bool wasInhibited; // One or both of the previous instruction
1720                        // pair was interrupt inhibited.
1721 
1722     bool isExec;  // The instruction being executed is the target of
1723                   // an XEC or XED instruction
1724     bool isXED;   // The instruction being executed is the target of an
1725                   // XEC instruction
1726 
1727     bool  isolts_switches_saved;
1728 
1729     word8    rE;       // exponent [map: rE, 28 0's]
1730 
1731     word6    rTAG;     // instruction tag
1732     word3    rRALR;    // ring alarm [3b] [map: 33 0's, RALR]
1733     word3    RSDWH_R1; // Track the ring number of the last SDW
1734 
1735     // L68: word4
1736     // DPS8M: word6
1737     word6 SDWAMR;
1738 
1739     // Zone mask
1740     bool useZone;
1741 
1742     // L68: word4
1743     // DPS8M: word6
1744     word6 PTWAMR;
1745 
1746     // G7 faults
1747     bool bTroubleFaultCycle;
1748 
1749     bool lufOccurred;
1750     bool secret_addressing_mode;
1751     // Used by LCPR to prevent the LCPR instruction from being recorded
1752     // in the CU.
1753     bool skip_cu_hist;
1754 
1755     // If the instruction wants overflow thrown after operand write
1756     bool dlyFlt;
1757 
1758     bool restart;
1759 
1760     // L68 FFV faults
1761     bool is_FFV;
1762 
1763 #if defined(ROUND_ROBIN)
1764     bool isRunning;
1765 #endif /* if defined(ROUND_ROBIN) */
1766 
1767 #if defined(AFFINITY)
1768     bool set_affinity;
1769 #endif /* if defined(AFFINITY) */
1770 
1771 #if defined(SPEED)
1772 # define SC_MAP_ADDR(addr,real_addr)                           \
1773    if (cpu.tweaks.useMap)                                      \
1774       {                                                        \
1775         uint pgnum = addr / SCBANK_SZ;                         \
1776         uint os = addr % SCBANK_SZ;                            \
1777         int base = cpu.sc_addr_map[pgnum];                     \
1778         if (base < 0)                                          \
1779           {                                                    \
1780             doFault (FAULT_STR, fst_str_nea,  __func__);       \
1781           }                                                    \
1782         real_addr = (uint) base + os;                          \
1783       }                                                        \
1784     else                                                       \
1785       real_addr = addr;
1786 #else
1787 # define SC_MAP_ADDR(addr,real_addr)                           \
1788    if (cpu.tweaks.useMap)                                      \
1789       {                                                        \
1790         uint pgnum = addr / SCBANK_SZ;                         \
1791         uint os = addr % SCBANK_SZ;                            \
1792         int base = cpu.sc_addr_map[pgnum];                     \
1793         if (base < 0)                                          \
1794           {                                                    \
1795             doFault (FAULT_STR, fst_str_nea,  __func__);       \
1796           }                                                    \
1797         real_addr = (uint) base + os;                          \
1798       }                                                        \
1799     else                                                       \
1800       {                                                        \
1801         nem_check (addr, __func__);                            \
1802         real_addr = addr;                                      \
1803       }
1804 #endif /* if defined(SPEED) */
1805 
1806 #if defined(PANEL68)
1807     // Intermediate data collection for APU SCROLL
1808     word18 lastPTWOffset;
1809 // The L68 APU SCROLL 4U has an entry "ACSD"; I am interpreting it as
1810 //   on: lastPTRAddr was a DSPTW
1811 //  off: lastPTRAddr was a PTW
1812     bool lastPTWIsDS;
1813     word18 APUDataBusOffset;
1814     word24 APUDataBusAddr;
1815     word24 APUMemAddr;
1816     word1 panel4_red_ready_light_state;
1817     word1 panel7_enabled_light_state;
1818 // The state of the panel switches
1819     volatile word15 APU_panel_segno_sw;
1820     volatile word1  APU_panel_enable_match_ptw_sw;  // lock
1821     volatile word1  APU_panel_enable_match_sdw_sw;  // lock
1822     volatile word1  APU_panel_scroll_select_ul_sw;
1823     volatile word4  APU_panel_scroll_select_n_sw;
1824     volatile word4  APU_panel_scroll_wheel_sw;
1825     //volatile word18 APU_panel_addr_sw;
1826     volatile word18 APU_panel_enter_sw;
1827     volatile word18 APU_panel_display_sw;
1828     volatile word4  CP_panel_wheel_sw;
1829     volatile word4  DATA_panel_ds_sw;
1830     volatile word4  DATA_panel_d1_sw;
1831     volatile word4  DATA_panel_d2_sw;
1832     volatile word4  DATA_panel_d3_sw;
1833     volatile word4  DATA_panel_d4_sw;
1834     volatile word4  DATA_panel_d5_sw;
1835     volatile word4  DATA_panel_d6_sw;
1836     volatile word4  DATA_panel_d7_sw;
1837     volatile word4  DATA_panel_wheel_sw;
1838     volatile word4  DATA_panel_addr_stop_sw;
1839     volatile word1  DATA_panel_enable_sw;
1840     volatile word1  DATA_panel_validate_sw;
1841     volatile word1  DATA_panel_auto_fast_sw;  // lock
1842     volatile word1  DATA_panel_auto_slow_sw;  // lock
1843     volatile word4  DATA_panel_cycle_sw;      // lock
1844     volatile word1  DATA_panel_step_sw;       // lock
1845     volatile word1  DATA_panel_s_trig_sw;
1846     volatile word1  DATA_panel_execute_sw;    // lock
1847     volatile word1  DATA_panel_scope_sw;
1848     volatile word1  DATA_panel_init_sw;       // lock
1849     volatile word1  DATA_panel_exec_sw;       // lock
1850     volatile word4  DATA_panel_hr_sel_sw;
1851     volatile word4  DATA_panel_trackers_sw;
1852     volatile bool panelInitialize;
1853 
1854     // Intermediate data collection for DATA SCROLL
1855     bool portBusy;
1856     word2 portSelect;
1857     word36 portAddr [N_CPU_PORTS];
1858     word36 portData [N_CPU_PORTS];
1859     // Intermediate data collection for CU
1860     word36 IWRAddr;
1861     word7 dataMode; // 0100  9 bit
1862                     // 0040  6 bit
1863                     // 0020  4 bit
1864                     // 0010  1 bit
1865                     // 0004  36 bit
1866                     // 0002  alphanumeric
1867                     // 0001  numeric
1868     word8 prepare_state;
1869     bool DACVpDF;
1870     bool AR_F_E;
1871     bool INS_FETCH;
1872     // Control Points data acquisition
1873     word1 cpt [28] [36];
1874 #endif /* if defined(PANEL68) */
1875 #define cpt1U   0  // Instruction processing tracking
1876 #define cpt1L   1  // Instruction processing tracking
1877 #define cpt2U   2  // Instruction execution tracking
1878 #define cpt2L   3  // Instruction execution tracking
1879 #define cpt3U   4  // Register usage
1880 #define cpt3L   5  // Register usage
1881 #define cpt4U   6
1882 #define cpt4L   7
1883 #define cpt5U   8
1884 #define cpt5L   9
1885 #define cpt6U  10
1886 #define cpt6L  11
1887 #define cpt7U  12
1888 #define cpt7L  13
1889 #define cpt8U  14
1890 #define cpt8L  15
1891 #define cpt9U  16
1892 #define cpt9L  17
1893 #define cpt10U 18
1894 #define cpt10L 19
1895 #define cpt11U 20
1896 #define cpt11L 21
1897 #define cpt12U 22
1898 #define cpt12L 23
1899 #define cpt13U 24
1900 #define cpt13L 25
1901 #define cpt14U 26
1902 #define cpt14L 27
1903 
1904 #define cptUseE     0
1905 #define cptUseBAR   1
1906 #define cptUseTR    2
1907 #define cptUseRALR  3
1908 #define cptUsePRn   4  // 4 - 11
1909 #define cptUseDSBR 12
1910 #define cptUseFR   13
1911 #define cptUseMR   14
1912 #define cptUseCMR  15
1913 #define cptUseIR   16
1914   } cpu_state_t;
1915 
1916 typedef struct MOP_struct_s
1917   {
1918     char * mopName;     // name of microoperation
1919     int (* f) (cpu_state_t *);   // pointer to mop() [returns character to be stored]
1920   } MOP_struct;
1921 
1922 #if defined(M_SHARED)
1923 extern cpu_state_t * cpus;
1924 #else
1925 extern cpu_state_t cpus [N_CPU_UNITS_MAX];
1926 #endif /* if defined(M_SHARED) */
1927 
1928 #if defined(THREADZ) || defined(LOCKLESS)
1929 extern __thread cpu_state_t * restrict _cpup;
1930 #else
1931 extern cpu_state_t * restrict _cpup;
1932 #endif /* if defined(THREADZ) || defined(LOCKLESS) */
1933 
1934 #define cpu (* cpup)
1935 
1936 #define N_STALL_POINTS 16
1937 struct stall_point_s
1938   {
1939     word15 segno;
1940     word18 offset;
1941     useconds_t time;
1942   };
1943 extern struct stall_point_s stall_points [N_STALL_POINTS];
1944 extern bool stall_point_active;
1945 
1946 uint set_cpu_idx (uint cpuNum);
1947 #if defined(THREADZ) || defined(LOCKLESS)
1948 extern __thread uint current_running_cpu_idx;
1949 extern bool bce_dis_called;
1950 #else
1951 # if defined(ROUND_ROBIN)
1952 extern uint current_running_cpu_idx;
1953 # else
1954 #  define current_running_cpu_idx 0
1955 # endif /* if defined(ROUND_ROBIN) */
1956 #endif /* if defined(THREADZ) || defined(LOCKLESS) */
1957 
1958 // Support code to access ARn.BITNO, ARn.CHAR, PRn.BITNO
1959 
1960 #define GET_PR_BITNO(n) (cpu.PAR[n].PR_BITNO)
1961 #define GET_AR_BITNO(n) (cpu.PAR[n].AR_BITNO)
1962 #define GET_AR_CHAR(n)  (cpu.PAR[n].AR_CHAR)
1963 static inline void SET_PR_BITNO (cpu_state_t * restrict cpup, uint n, word6 b)
     /* [previous][next][first][last][top][bottom][index][help] */
1964   {
1965      cpu.PAR[n].PR_BITNO = b;
1966      cpu.PAR[n].AR_BITNO = (b % 9) & MASK4;
1967      cpu.PAR[n].AR_CHAR = (b / 9) & MASK2;
1968   }
1969 #define SET_PR_BITNO(n, b) SET_PR_BITNO(cpup, n, b)
1970 static inline void SET_AR_CHAR_BITNO (cpu_state_t * restrict cpup, uint n, word2 c, word4 b)
     /* [previous][next][first][last][top][bottom][index][help] */
1971   {
1972      cpu.PAR[n].PR_BITNO = c * 9 + b;
1973      cpu.PAR[n].AR_BITNO = b & MASK4;
1974      cpu.PAR[n].AR_CHAR = c & MASK2;
1975   }
1976 #define SET_AR_CHAR_BITNO(n, c, b) SET_AR_CHAR_BITNO(cpup, n, c, b)
1977 
1978 bool sample_interrupts (cpu_state_t * cpup);
1979 t_stat simh_hooks (cpu_state_t * cpup);
1980 int operand_size (cpu_state_t * cpup);
1981 //void read_operand (word18 addr, processor_cycle_type cyctyp);
1982 void readOperandRead (cpu_state_t * cpup, word18 addr);
1983 void readOperandRMW (cpu_state_t * cpup, word18 addr);
1984 t_stat write_operand (cpu_state_t * cpup, word18 addr, processor_cycle_type acctyp);
1985 
1986 #if defined(PANEL68)
1987 static inline void trackport (word24 a, word36 d)
     /* [previous][next][first][last][top][bottom][index][help] */
1988   {
1989     cpu_state_t * cpup = _cpup;
1990     // Simplifying assumption: 4 * 4MW SCUs
1991     word2 port = (a >> 22) & MASK2;
1992     cpu.portSelect = port;
1993     cpu.portAddr [port] = a;
1994     cpu.portData [port] = d;
1995     cpu.portBusy = false;
1996   }
1997 #endif /* if defined(PANEL68) */
1998 
1999 #if defined(SPEED) && defined(INLINE_CORE)
2000 # error INLINE_CORE has known issues.
2001 // Ugh. Circular dependencies XXX
2002 void doFault (_fault faultNumber, _fault_subtype faultSubtype,
     /* [previous][next][first][last][top][bottom][index][help] */
2003               const char * faultMsg) NO_RETURN;
2004 extern const _fault_subtype fst_str_nea;
2005 
2006 static inline int core_read (word24 addr, word36 *data, \
2007   UNUSED const char * ctx)
2008   {
2009     PNL (cpu.portBusy = true;)
2010     SC_MAP_ADDR (addr, addr);
2011     * data = M[addr] & DMASK;
2012 # if defined(TR_WORK_MEM)
2013     cpu.rTRticks ++;
2014 # endif /* if defined(TR_WORK_MEM) */
2015     PNL (trackport (addr, * data);)
2016     return 0;
2017   }
2018 
2019 static inline int core_write (word24 addr, word36 data, \
     /* [previous][next][first][last][top][bottom][index][help] */
2020   UNUSED const char * ctx)
2021   {
2022     PNL (cpu.portBusy = true;)
2023     SC_MAP_ADDR (addr, addr);
2024     if (cpu.tweaks.isolts_mode)
2025       {
2026         if (cpu.MR.sdpap)
2027           {
2028             sim_warn ("failing to implement sdpap\n");
2029             cpu.MR.sdpap = 0;
2030           }
2031         if (cpu.MR.separ)
2032           {
2033             sim_warn ("failing to implement separ\n");
2034             cpu.MR.separ = 0;
2035           }
2036      }
2037     M[addr] = data & DMASK;
2038 # if defined(TR_WORK_MEM)
2039     cpu.rTRticks ++;
2040 # endif /* if defined(TR_WORK_MEM) */
2041     PNL (trackport (addr, data);)
2042     return 0;
2043   }
2044 
2045 static inline int core_write_zone (word24 addr, word36 data, \
     /* [previous][next][first][last][top][bottom][index][help] */
2046   UNUSED const char * ctx)
2047   {
2048     PNL (cpu.portBusy = true;)
2049     SC_MAP_ADDR (addr, addr);
2050     if (cpu.tweaks.isolts_mode)
2051       {
2052         if (cpu.MR.sdpap)
2053           {
2054             sim_warn ("failing to implement sdpap\n");
2055             cpu.MR.sdpap = 0;
2056           }
2057         if (cpu.MR.separ)
2058           {
2059             sim_warn ("failing to implement separ\n");
2060             cpu.MR.separ = 0;
2061           }
2062       }
2063     M[addr] = (M[addr] & ~cpu.zone) | (data & cpu.zone);
2064     cpu.useZone = false; // Safety
2065 # if defined(TR_WORK_MEM)
2066     cpu.rTRticks ++;
2067 # endif /* if defined(TR_WORK_MEM) */
2068     PNL (trackport (addr, data);)
2069     return 0;
2070   }
2071 
2072 static inline int core_read2 (word24 addr, word36 *even, word36 *odd,
     /* [previous][next][first][last][top][bottom][index][help] */
2073                               UNUSED const char * ctx)
2074   {
2075     PNL (cpu.portBusy = true;)
2076     SC_MAP_ADDR (addr, addr);
2077     *even = M[addr++] & DMASK;
2078     *odd = M[addr] & DMASK;
2079 # if defined(TR_WORK_MEM)
2080     cpu.rTRticks ++;
2081 # endif /* if defined(TR_WORK_MEM) */
2082     PNL (trackport (addr - 1, * even);)
2083     return 0;
2084   }
2085 
2086 static inline int core_write2 (word24 addr, word36 even, word36 odd,
     /* [previous][next][first][last][top][bottom][index][help] */
2087                                UNUSED const char * ctx)
2088   {
2089     PNL (cpu.portBusy = true;)
2090     SC_MAP_ADDR (addr, addr);
2091     if (cpu.tweaks.isolts_mode)
2092       {
2093         if (cpu.MR.sdpap)
2094           {
2095             sim_warn ("failing to implement sdpap\n");
2096             cpu.MR.sdpap = 0;
2097           }
2098         if (cpu.MR.separ)
2099           {
2100             sim_warn ("failing to implement separ\n");
2101             cpu.MR.separ = 0;
2102           }
2103       }
2104     M[addr++] = even;
2105     M[addr] = odd;
2106     PNL (trackport (addr - 1, even);)
2107 # if defined(TR_WORK_MEM)
2108     cpu.rTRticks ++;
2109 # endif /* if defined(TR_WORK_MEM) */
2110     return 0;
2111   }
2112 #else
2113 int core_read (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx);
2114 int core_write (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2115 int core_write_zone (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2116 int core_read2 (cpu_state_t * cpup, word24 addr, word36 *even, word36 *odd, const char * ctx);
2117 int core_write2 (cpu_state_t * cpup, word24 addr, word36 even, word36 odd, const char * ctx);
2118 #endif /* if defined(SPEED) && defined(INLINE_CORE) */
2119 
2120 #if defined(LOCKLESS)
2121 
2122 /*
2123  * Atomic operations to use defined as follows:
2124  *
2125  *  AIX_ATOMICS  -  IBM AIX atomics
2126  *  BSD_ATOMICS  -  FreeBSD atomics
2127  *  GNU_ATOMICS  -  GNU atomics
2128  * SYNC_ATOMICS  -  GNU sync-style atomics
2129  *
2130  * The following are reserved and not yet implemented:
2131  *
2132  *  ISO_ATOMICS  -  ISO/IEC 9899:2011 (C11) atomics
2133  *   NT_ATOMICS  -  Microsoft Windows NT atomics
2134  *
2135  * For further details, see:
2136  *
2137  * AIX_ATOMICS:
2138  *  https://www.ibm.com/docs/en/aix/7.3?topic=services-atomic-operations
2139  *
2140  * BSD_ATOMICS:
2141  *  https://www.freebsd.org/cgi/man.cgi?query=atomic&sektion=9&format=html
2142  *  https://man.dragonflybsd.org/?command=atomic&section=9
2143  *
2144  * GNU_ATOMICS:
2145  *  https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
2146  *
2147  * SYNC_ATOMICS:
2148  *  https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
2149  *
2150  * ISO_ATOMICS:
2151  *  https://en.cppreference.com/w/c/atomic
2152  *
2153  * NT_ATOMICS:
2154  *  https://docs.microsoft.com/en-us/windows/win32/sync/synchronization-functions
2155  *  https://docs.microsoft.com/en-us/windows/win32/sync/interlocked-variable-access
2156  */
2157 
2158 // AIX_ATOMICS are SYNC_ATOMICS (for now)
2159 # if ( defined (AIX_ATOMICS) && \
2160    (! (defined (SYNC_ATOMICS))))
2161 #  define SYNC_ATOMICS 1
2162 # endif
2163 
2164 // FreeBSD atomics (default on for FreeBSD)
2165 # if (! defined (GNU_ATOMICS)) && (! defined (SYNC_ATOMICS)) && \
2166      (! defined (BSD_ATOMICS)) && (! defined (AIX_ATOMICS))
2167 #  if defined(__FreeBSD__) \
2168    || defined(__DragonFly__)
2169 #   undef BSD_ATOMICS
2170 #   define BSD_ATOMICS 1
2171 #  endif
2172 # endif
2173 
2174 // Otherwise, default to GNU_ATOMICS
2175 # if (! defined (GNU_ATOMICS)) && (! defined (BSD_ATOMICS)) && \
2176      (! defined (SYNC_ATOMICS)) && (! defined (AIX_ATOMICS))
2177 #  undef GNU_ATOMICS
2178 #  define GNU_ATOMICS 1
2179 # endif
2180 
2181 int core_read_lock (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx);
2182 int core_write_unlock (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2183 int core_unlock_all(cpu_state_t * cpup);
2184 
2185 # define DEADLOCK_DETECT   0x40000000U
2186 # define MEM_LOCKED_BIT    61
2187 # define MEM_LOCKED        (1LLU<<MEM_LOCKED_BIT)
2188 
2189 # if !defined(SCHED_NEVER_YIELD)
2190 #  undef SCHED_YIELD
2191 #  define SCHED_YIELD                                                    \
2192   do                                                                     \
2193     {                                                                    \
2194       if ((i & 0xff) == 0)                                               \
2195         {                                                                \
2196           sched_yield();                                                 \
2197           cpu.lockYield++;                                               \
2198         }                                                                \
2199     }                                                                    \
2200   while(0)
2201 # else
2202 #  undef SCHED_YIELD
2203 #  define SCHED_YIELD                                                    \
2204   do                                                                     \
2205     {                                                                    \
2206     }                                                                    \
2207   while(0)
2208 # endif /* if !defined(SCHED_NEVER_YIELD) */
2209 
2210 # if defined (BSD_ATOMICS)
2211 #  include <machine/atomic.h>
2212 
2213 #  define LOCK_CORE_WORD(addr)                                           \
2214   do                                                                     \
2215     {                                                                    \
2216       unsigned int i = DEADLOCK_DETECT;                                  \
2217       while ( atomic_testandset_64((volatile uint64_t *)&M[addr],        \
2218             MEM_LOCKED_BIT) == 1 && i > 0)                               \
2219         {                                                                \
2220           i--;                                                           \
2221           SCHED_YIELD;                                                   \
2222         }                                                                \
2223       if (i == 0)                                                        \
2224         {                                                                \
2225           sim_warn ("%s: locked %x addr %x deadlock\n", __func__,        \
2226               cpu.locked_addr, addr);                                    \
2227         }                                                                \
2228       cpu.lockCnt++;                                                     \
2229       if (i == DEADLOCK_DETECT)                                          \
2230         cpu.lockImmediate++;                                             \
2231       cpu.lockWait += (DEADLOCK_DETECT-i);                               \
2232       cpu.lockWaitMax = ((DEADLOCK_DETECT-i) > cpu.lockWaitMax) ?        \
2233           (DEADLOCK_DETECT-i) : cpu.lockWaitMax;                         \
2234     }                                                                    \
2235   while (0)
2236 
2237 #  define LOAD_ACQ_CORE_WORD(res, addr)                                  \
2238   do                                                                     \
2239     {                                                                    \
2240       res = atomic_load_acq_64((volatile uint64_t *)&M[addr]);           \
2241     }                                                                    \
2242   while (0)
2243 
2244 #  define STORE_REL_CORE_WORD(addr, data)                                \
2245   do                                                                     \
2246     {                                                                    \
2247       atomic_store_rel_64((volatile uint64_t *)&M[addr], data & DMASK);  \
2248     }                                                                    \
2249   while (0)
2250 
2251 # endif // BSD_ATOMICS
2252 
2253 # if defined(GNU_ATOMICS)
2254 
2255 #  define LOCK_CORE_WORD(addr)                                           \
2256   do                                                                     \
2257     {                                                                    \
2258       unsigned int i = DEADLOCK_DETECT;                                  \
2259       while ((__atomic_fetch_or((volatile uint64_t *)&M[addr],           \
2260         MEM_LOCKED, __ATOMIC_ACQ_REL) & MEM_LOCKED)                      \
2261                 && i > 0)                                                \
2262     {                                                                    \
2263       i--;                                                               \
2264       SCHED_YIELD;                                                       \
2265     }                                                                    \
2266       if (i == 0)                                                        \
2267         {                                                                \
2268           sim_warn ("%s: locked %x addr %x deadlock\n",                  \
2269             __func__, cpu.locked_addr, addr);                            \
2270         }                                                                \
2271       cpu.lockCnt++;                                                     \
2272       if (i == DEADLOCK_DETECT)                                          \
2273           cpu.lockImmediate++;                                           \
2274       cpu.lockWait += (DEADLOCK_DETECT-i);                               \
2275       cpu.lockWaitMax = ((DEADLOCK_DETECT-i) >                           \
2276           cpu.lockWaitMax) ? (DEADLOCK_DETECT-i) :                       \
2277               cpu.lockWaitMax;                                           \
2278     }                                                                    \
2279   while (0)
2280 
2281 #  define LOAD_ACQ_CORE_WORD(res, addr)                                  \
2282   do                                                                     \
2283     {                                                                    \
2284       res = __atomic_load_n((volatile uint64_t *)&M[addr],               \
2285           __ATOMIC_ACQUIRE);                                             \
2286     }                                                                    \
2287   while (0)
2288 
2289 #  define STORE_REL_CORE_WORD(addr, data)                                \
2290   do                                                                     \
2291     {                                                                    \
2292       __atomic_store_n((volatile uint64_t *)&M[addr], data &             \
2293           DMASK, __ATOMIC_RELEASE);                                      \
2294     }                                                                    \
2295   while (0)
2296 
2297 # endif // GNU_ATOMICS
2298 
2299 # if defined(SYNC_ATOMICS)
2300 #  if defined(MEMORY_ACCESS_NOT_STRONGLY_ORDERED)
2301 #   define MEM_BARRIER()   do { __sync_synchronize(); } while (0)
2302 #  else
2303 #   define MEM_BARRIER()   do {} while (0)
2304 #  endif
2305 
2306 #  define LOCK_CORE_WORD(addr)                                           \
2307      do                                                                  \
2308        {                                                                 \
2309          unsigned int i = DEADLOCK_DETECT;                               \
2310          while ((__sync_fetch_and_or((volatile uint64_t *)&M[addr],      \
2311              MEM_LOCKED) & MEM_LOCKED) && i > 0)                         \
2312            {                                                             \
2313             i--;                                                         \
2314             SCHED_YIELD;                                                 \
2315            }                                                             \
2316          if (i == 0)                                                     \
2317            {                                                             \
2318             sim_warn ("%s: locked %x addr %x deadlock\n", __func__,      \
2319                 cpu.locked_addr, addr);                                  \
2320             }                                                            \
2321          cpu.lockCnt++;                                                  \
2322          if (i == DEADLOCK_DETECT)                                       \
2323            cpu.lockImmediate++;                                          \
2324          cpu.lockWait += (DEADLOCK_DETECT-i);                            \
2325          cpu.lockWaitMax = ((DEADLOCK_DETECT-i) > cpu.lockWaitMax) ?     \
2326              (DEADLOCK_DETECT-i) : cpu.lockWaitMax;                      \
2327        }                                                                 \
2328      while (0)
2329 
2330 #  define LOAD_ACQ_CORE_WORD(res, addr)                                  \
2331      do                                                                  \
2332        {                                                                 \
2333          res = M[addr];                                                  \
2334          MEM_BARRIER();                                                  \
2335        }                                                                 \
2336      while (0)
2337 
2338 #  define STORE_REL_CORE_WORD(addr, data)                                \
2339   do                                                                     \
2340     {                                                                    \
2341       MEM_BARRIER();                                                     \
2342       M[addr] = data & DMASK;                                            \
2343     }                                                                    \
2344   while (0)
2345 
2346 # endif  // SYNC_ATOMICS
2347 #endif  // LOCKLESS
2348 
2349 static inline void core_readN (cpu_state_t * cpup, word24 addr, word36 * data, uint n,
     /* [previous][next][first][last][top][bottom][index][help] */
2350                                UNUSED const char * ctx)
2351   {
2352     for (uint i = 0; i < n; i ++)
2353       {
2354         core_read (cpup, addr + i, data + i, ctx);
2355         //HDBGMRead (addr + i, * (data + i), __func__);
2356       }
2357   }
2358 
2359 static inline void core_writeN (cpu_state_t * cpup, word24 addr, word36 * data, uint n,
     /* [previous][next][first][last][top][bottom][index][help] */
2360                                 UNUSED const char * ctx)
2361   {
2362     for (uint i = 0; i < n; i ++)
2363       {
2364         core_write (cpup, addr + i, data [i], ctx);
2365         //HDBGMWrite (addr + i, * (data + i), __func__);
2366       }
2367   }
2368 
2369 int is_priv_mode (cpu_state_t * cpup);
2370 //void set_went_appending (void);
2371 //void clr_went_appending (void);
2372 //bool get_went_appending (void);
2373 bool get_bar_mode (cpu_state_t * cpup);
2374 addr_modes_e get_addr_mode (cpu_state_t * cpup);
2375 void set_addr_mode (cpu_state_t * cpup, addr_modes_e mode);
2376 void decode_instruction (cpu_state_t * cpup, word36 inst, DCDstruct * p);
2377 #if !defined(SPEED)
2378 t_stat set_mem_watch (int32 arg, const char * buf);
2379 #endif /* if !defined(SPEED) */
2380 char *str_SDW0 (char * buf, sdw_s *SDW);
2381 int lookup_cpu_mem_map (cpu_state_t * cpup, word24 addr);
2382 void cpu_init (void);
2383 void setup_scbank_map (cpu_state_t * cpup);
2384 void add_dps8m_CU_history (cpu_state_t * cpup);
2385 void add_dps8m_DUOU_history (word36 flags, word18 ICT, word9 RS_REG, word9 flags2);
2386 void add_dps8m_APU_history (word15 ESN, word21 flags, word24 RMA, word3 RTRR, word9 flags2);
2387 void add_dps8m_EAPU_history (word18 ZCA, word18 opcode);
2388 void add_l68_CU_history (cpu_state_t * cpup);
2389 void add_l68_OU_history (cpu_state_t * cpup);
2390 void add_l68_DU_history (cpu_state_t * cpup);
2391 void add_l68_APU_history (cpu_state_t * cpup, enum APUH_e op);
2392 void add_history_force (cpu_state_t * cpup, uint hset, word36 w0, word36 w1);
2393 void printPtid(pthread_t pt);
2394 word18 get_BAR_address(cpu_state_t * cpup, word18 addr);
2395 #if defined(THREADZ) || defined(LOCKLESS)
2396 t_stat threadz_sim_instr (void);
2397 void * cpu_thread_main (void * arg);
2398 #endif
2399 void cpu_reset_unit_idx (UNUSED uint cpun, bool clear_mem);
2400 void setupPROM (uint cpuNo, unsigned char * PROM);
2401 void cpuStats (uint cpuNo);

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