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. core_read
  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 coreLockState_s {
1528     uint64_t lockCnt;
1529     uint64_t lockImmediate;
1530     uint64_t lockWait;
1531     uint64_t lockWaitMax;
1532 #if !defined(SCHED_NEVER_YIELD)
1533     uint64_t lockYield;
1534 #endif /* if !defined(SCHED_NEVER_YIELD) */
1535     word24 locked_addr;
1536 } coreLockState_t;
1537 
1538 typedef struct cpu_state_s
1539   {
1540     EISstruct currentEISinstruction;
1541 
1542     uCache_t uCache;
1543 
1544     unsigned long long cycleCnt;
1545     unsigned long long instrCnt;
1546     unsigned long long instrCntT0;
1547     unsigned long long instrCntT1;
1548 
1549     coreLockState_t coreLockState;
1550 
1551     // From the control unit history register:
1552     _fault_subtype subFault; // saved by doFault
1553 
1554     word36   rA;     // accumulator
1555     word36   rQ;     // quotient
1556 
1557     fault_acv_subtype_  acvFaults;   // pending ACV faults
1558 
1559     sdw_s * SDW; // working SDW
1560 
1561     // Zone mask
1562     word36 zone;
1563 
1564     ptw_s * PTW;
1565 
1566     word36 CY;              // C(Y) operand data from memory
1567 
1568     uint64 lufCounter;
1569 
1570     _fault_subtype dlySubFltNum;
1571 
1572     const char * dlyCtx;
1573 
1574     word36 faultRegister [2];
1575 
1576     word36 itxPair [2];
1577 
1578 //#if defined(THREADZ) || defined(LOCKLESS)
1579 //    struct timespec rTRTime; // time when rTR was set
1580 //#endif
1581 
1582     mode_register_s MR;
1583     // Changes to the mode register history bits do not take affect until
1584     // the next instruction (ISOLTS 700 2a). Cache the values here so
1585     // that post register updates can see the old values.
1586     mode_register_s MR_cache;
1587 
1588     DCDstruct currentInstruction;
1589 
1590     ou_unit_data_t ou;
1591 
1592     word36 Ypair[2];        //  2-words
1593     word36 Yblock8[8];      //  8-words
1594     word36 Yblock16[16];    // 16-words
1595     word36 Yblock32[32];    // 32-words
1596 
1597     word36 scu_data[8];     // For SCU instruction
1598 
1599     ctl_unit_data_t cu;
1600     du_unit_data_t du;
1601 
1602     switches_t switches;
1603     optionsType options;
1604     tweaksType tweaks;
1605     switches_t isolts_switches_save;
1606 
1607     jmp_buf jmpMain; // This is the entry to the CPU state machine
1608 
1609     unsigned long      faultCnt [N_FAULTS];
1610 
1611     _fault_subtype  g7SubFaults [N_FAULTS];
1612 
1613     word36 history [N_HIST_SETS] [N_MAX_HIST_SIZE] [2];
1614 
1615     cycles_e cycle;
1616 
1617     _fault faultNumber;      // fault number saved by doFault
1618 
1619     apu_unit_data_t apu;
1620 
1621     word27   rTR;    // timer [map: TR, 9 0's]
1622 #if defined(THREADZ) || defined(LOCKLESS)
1623     uint     rTRsample;
1624 #endif
1625     word24   rY;     // address operand
1626 
1627     word18  lnk;     // rpl link value
1628 
1629     uint g7FaultsPreset;
1630     uint g7Faults;
1631 
1632     word24 iefpFinalAddress;
1633 
1634     // ISOLTS fine grain TR estimation
1635     uint rTRlsb;
1636     uint shadowTR;
1637     uint TR0; // The value that the TR was set to.
1638 
1639     // Arguments for delayed overflow fault
1640     _fault dlyFltNum;
1641 
1642     word18 last_write;
1643 
1644 #if defined(LOCKLESS)
1645     word24 char_word_address;
1646 #endif /* if defined(LOCKLESS) */
1647 
1648     word24 rmw_address;
1649 
1650     uint restart_address;
1651 
1652     struct
1653       {
1654         word15 PSR;
1655         word3  PRR;
1656         word18 IC;
1657       } cu_data;            // For STCD instruction
1658     uint rTRticks;
1659 
1660     struct tpr_s TPR;     // Temporary Pointer Register
1661     struct ppr_s PPR;     // Procedure Pointer Register
1662     struct dsbr_s DSBR;   // Descriptor Segment Base Register
1663     ptw0_s PTW0; // a PTW not in PTWAM (PTWx1)
1664 
1665     uint history_cyclic [N_HIST_SETS]; // 0..63
1666 
1667     sdw_s SDW0;  // a SDW not in SDWAM
1668     sdw_s _s;
1669 
1670     word18   rX [8]; // index
1671 
1672     // Number of banks in each SCU
1673     uint sc_num_banks [N_SCU_UNITS_MAX];
1674 
1675     // Caching some cabling data for interrupt handling.
1676     // When a CPU calls get_highest_intr(), it needs to know
1677     // what port on the SCU it is attached to. Because of port
1678     // expanders several CPUs can be attached to an SCU port,
1679     // mapping from the CPU to the SCU is easier to query
1680     uint scu_port[N_SCU_UNITS_MAX];
1681 
1682     // L68 FFV faults
1683 
1684      uint FFV_faults_preset;
1685      uint FFV_faults;
1686      uint FFV_fault_number;
1687 
1688 #if defined(AFFINITY)
1689     uint affinity;
1690 #endif /* if defined(AFFINITY) */
1691 
1692     events_t events;
1693 
1694     word24 pad[16];
1695 
1696     struct par_s PAR [8]; // pointer/address registers
1697 
1698     ptw_s PTWAM [N_NAX_WAM_ENTRIES];
1699 
1700     // Map memory address through memory configuration switches
1701     // Minimum allocation chunk is 64K (SCBANK_SZ)
1702     // addr / SCBANK_SZ => bank_number
1703     // scbank_map[bank_number] is address of the bank in M. -1 is unmapped.
1704     int sc_addr_map [N_SCBANKS];
1705     // The SCU number holding each bank
1706     int sc_scu_map [N_SCBANKS];
1707 
1708     sdw_s SDWAM [N_NAX_WAM_ENTRIES]; // Segment Descriptor Word Associative Memory
1709 
1710     // Address Modification tally
1711     word12 AM_tally;
1712 
1713     struct bar_s BAR;     // Base Address Register
1714 
1715     cache_mode_register_s CMR;
1716 
1717     // The following are all from the control unit history register:
1718 
1719     bool interrupt_flag;     // an interrupt is pending in this cycle
1720     bool g7_flag;            // a g7 fault is pending in this cycle;
1721 
1722     bool wasXfer;      // The previous instruction was a transfer
1723 
1724     bool wasInhibited; // One or both of the previous instruction
1725                        // pair was interrupt inhibited.
1726 
1727     bool isExec;  // The instruction being executed is the target of
1728                   // an XEC or XED instruction
1729     bool isXED;   // The instruction being executed is the target of an
1730                   // XEC instruction
1731 
1732     bool  isolts_switches_saved;
1733 
1734     word8    rE;       // exponent [map: rE, 28 0's]
1735 
1736     word6    rTAG;     // instruction tag
1737     word3    rRALR;    // ring alarm [3b] [map: 33 0's, RALR]
1738     word3    RSDWH_R1; // Track the ring number of the last SDW
1739 
1740     // L68: word4
1741     // DPS8M: word6
1742     word6 SDWAMR;
1743 
1744     // Zone mask
1745     bool useZone;
1746 
1747     // L68: word4
1748     // DPS8M: word6
1749     word6 PTWAMR;
1750 
1751     // G7 faults
1752     bool bTroubleFaultCycle;
1753 
1754     bool lufOccurred;
1755     bool secret_addressing_mode;
1756     // Used by LCPR to prevent the LCPR instruction from being recorded
1757     // in the CU.
1758     bool skip_cu_hist;
1759 
1760     // If the instruction wants overflow thrown after operand write
1761     bool dlyFlt;
1762 
1763     bool restart;
1764 
1765     // L68 FFV faults
1766     bool is_FFV;
1767 
1768 #if defined(ROUND_ROBIN)
1769     bool isRunning;
1770 #endif /* if defined(ROUND_ROBIN) */
1771 
1772 #if defined(AFFINITY)
1773     bool set_affinity;
1774 #endif /* if defined(AFFINITY) */
1775 
1776 #if defined(SPEED)
1777 # define SC_MAP_ADDR(addr,real_addr)                           \
1778    if (cpu.tweaks.useMap)                                      \
1779       {                                                        \
1780         uint pgnum = addr / SCBANK_SZ;                         \
1781         uint os = addr % SCBANK_SZ;                            \
1782         int base = cpu.sc_addr_map[pgnum];                     \
1783         if (base < 0)                                          \
1784           {                                                    \
1785             doFault (FAULT_STR, fst_str_nea,  __func__);       \
1786           }                                                    \
1787         real_addr = (uint) base + os;                          \
1788       }                                                        \
1789     else                                                       \
1790       real_addr = addr;
1791 #else
1792 # define SC_MAP_ADDR(addr,real_addr)                           \
1793    if (cpu.tweaks.useMap)                                      \
1794       {                                                        \
1795         uint pgnum = addr / SCBANK_SZ;                         \
1796         uint os = addr % SCBANK_SZ;                            \
1797         int base = cpu.sc_addr_map[pgnum];                     \
1798         if (base < 0)                                          \
1799           {                                                    \
1800             doFault (FAULT_STR, fst_str_nea,  __func__);       \
1801           }                                                    \
1802         real_addr = (uint) base + os;                          \
1803       }                                                        \
1804     else                                                       \
1805       {                                                        \
1806         nem_check (addr, __func__);                            \
1807         real_addr = addr;                                      \
1808       }
1809 #endif /* if defined(SPEED) */
1810 
1811 #if defined(PANEL68)
1812     // Intermediate data collection for APU SCROLL
1813     word18 lastPTWOffset;
1814 // The L68 APU SCROLL 4U has an entry "ACSD"; I am interpreting it as
1815 //   on: lastPTRAddr was a DSPTW
1816 //  off: lastPTRAddr was a PTW
1817     bool lastPTWIsDS;
1818     word18 APUDataBusOffset;
1819     word24 APUDataBusAddr;
1820     word24 APUMemAddr;
1821     word1 panel4_red_ready_light_state;
1822     word1 panel7_enabled_light_state;
1823 // The state of the panel switches
1824     volatile word15 APU_panel_segno_sw;
1825     volatile word1  APU_panel_enable_match_ptw_sw;  // lock
1826     volatile word1  APU_panel_enable_match_sdw_sw;  // lock
1827     volatile word1  APU_panel_scroll_select_ul_sw;
1828     volatile word4  APU_panel_scroll_select_n_sw;
1829     volatile word4  APU_panel_scroll_wheel_sw;
1830     //volatile word18 APU_panel_addr_sw;
1831     volatile word18 APU_panel_enter_sw;
1832     volatile word18 APU_panel_display_sw;
1833     volatile word4  CP_panel_wheel_sw;
1834     volatile word4  DATA_panel_ds_sw;
1835     volatile word4  DATA_panel_d1_sw;
1836     volatile word4  DATA_panel_d2_sw;
1837     volatile word4  DATA_panel_d3_sw;
1838     volatile word4  DATA_panel_d4_sw;
1839     volatile word4  DATA_panel_d5_sw;
1840     volatile word4  DATA_panel_d6_sw;
1841     volatile word4  DATA_panel_d7_sw;
1842     volatile word4  DATA_panel_wheel_sw;
1843     volatile word4  DATA_panel_addr_stop_sw;
1844     volatile word1  DATA_panel_enable_sw;
1845     volatile word1  DATA_panel_validate_sw;
1846     volatile word1  DATA_panel_auto_fast_sw;  // lock
1847     volatile word1  DATA_panel_auto_slow_sw;  // lock
1848     volatile word4  DATA_panel_cycle_sw;      // lock
1849     volatile word1  DATA_panel_step_sw;       // lock
1850     volatile word1  DATA_panel_s_trig_sw;
1851     volatile word1  DATA_panel_execute_sw;    // lock
1852     volatile word1  DATA_panel_scope_sw;
1853     volatile word1  DATA_panel_init_sw;       // lock
1854     volatile word1  DATA_panel_exec_sw;       // lock
1855     volatile word4  DATA_panel_hr_sel_sw;
1856     volatile word4  DATA_panel_trackers_sw;
1857     volatile bool panelInitialize;
1858 
1859     // Intermediate data collection for DATA SCROLL
1860     bool portBusy;
1861     word2 portSelect;
1862     word36 portAddr [N_CPU_PORTS];
1863     word36 portData [N_CPU_PORTS];
1864     // Intermediate data collection for CU
1865     word36 IWRAddr;
1866     word7 dataMode; // 0100  9 bit
1867                     // 0040  6 bit
1868                     // 0020  4 bit
1869                     // 0010  1 bit
1870                     // 0004  36 bit
1871                     // 0002  alphanumeric
1872                     // 0001  numeric
1873     word8 prepare_state;
1874     bool DACVpDF;
1875     bool AR_F_E;
1876     bool INS_FETCH;
1877     // Control Points data acquisition
1878     word1 cpt [28] [36];
1879 #endif /* if defined(PANEL68) */
1880 #define cpt1U   0  // Instruction processing tracking
1881 #define cpt1L   1  // Instruction processing tracking
1882 #define cpt2U   2  // Instruction execution tracking
1883 #define cpt2L   3  // Instruction execution tracking
1884 #define cpt3U   4  // Register usage
1885 #define cpt3L   5  // Register usage
1886 #define cpt4U   6
1887 #define cpt4L   7
1888 #define cpt5U   8
1889 #define cpt5L   9
1890 #define cpt6U  10
1891 #define cpt6L  11
1892 #define cpt7U  12
1893 #define cpt7L  13
1894 #define cpt8U  14
1895 #define cpt8L  15
1896 #define cpt9U  16
1897 #define cpt9L  17
1898 #define cpt10U 18
1899 #define cpt10L 19
1900 #define cpt11U 20
1901 #define cpt11L 21
1902 #define cpt12U 22
1903 #define cpt12L 23
1904 #define cpt13U 24
1905 #define cpt13L 25
1906 #define cpt14U 26
1907 #define cpt14L 27
1908 
1909 #define cptUseE     0
1910 #define cptUseBAR   1
1911 #define cptUseTR    2
1912 #define cptUseRALR  3
1913 #define cptUsePRn   4  // 4 - 11
1914 #define cptUseDSBR 12
1915 #define cptUseFR   13
1916 #define cptUseMR   14
1917 #define cptUseCMR  15
1918 #define cptUseIR   16
1919   } cpu_state_t;
1920 
1921 typedef struct MOP_struct_s
1922   {
1923     char * mopName;     // name of microoperation
1924     int (* f) (cpu_state_t *);   // pointer to mop() [returns character to be stored]
1925   } MOP_struct;
1926 
1927 #if defined(M_SHARED)
1928 extern cpu_state_t * cpus;
1929 #else
1930 extern cpu_state_t cpus [N_CPU_UNITS_MAX];
1931 #endif /* if defined(M_SHARED) */
1932 
1933 #if defined(THREADZ) || defined(LOCKLESS)
1934 extern __thread cpu_state_t * restrict _cpup;
1935 #else
1936 extern cpu_state_t * restrict _cpup;
1937 #endif /* if defined(THREADZ) || defined(LOCKLESS) */
1938 
1939 #define cpu (* cpup)
1940 
1941 #define N_STALL_POINTS 16
1942 struct stall_point_s
1943   {
1944     word15 segno;
1945     word18 offset;
1946     useconds_t time;
1947   };
1948 extern struct stall_point_s stall_points [N_STALL_POINTS];
1949 extern bool stall_point_active;
1950 
1951 uint set_cpu_idx (uint cpuNum);
1952 #if defined(THREADZ) || defined(LOCKLESS)
1953 extern __thread uint current_running_cpu_idx;
1954 extern bool bce_dis_called;
1955 #else
1956 # if defined(ROUND_ROBIN)
1957 extern uint current_running_cpu_idx;
1958 # else
1959 #  define current_running_cpu_idx 0
1960 # endif /* if defined(ROUND_ROBIN) */
1961 #endif /* if defined(THREADZ) || defined(LOCKLESS) */
1962 
1963 // Support code to access ARn.BITNO, ARn.CHAR, PRn.BITNO
1964 
1965 #define GET_PR_BITNO(n) (cpu.PAR[n].PR_BITNO)
1966 #define GET_AR_BITNO(n) (cpu.PAR[n].AR_BITNO)
1967 #define GET_AR_CHAR(n)  (cpu.PAR[n].AR_CHAR)
1968 static inline void SET_PR_BITNO (cpu_state_t * restrict cpup, uint n, word6 b)
     /* [previous][next][first][last][top][bottom][index][help] */
1969   {
1970      cpu.PAR[n].PR_BITNO = b;
1971      cpu.PAR[n].AR_BITNO = (b % 9) & MASK4;
1972      cpu.PAR[n].AR_CHAR = (b / 9) & MASK2;
1973   }
1974 #define SET_PR_BITNO(n, b) SET_PR_BITNO(cpup, n, b)
1975 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] */
1976   {
1977      cpu.PAR[n].PR_BITNO = c * 9 + b;
1978      cpu.PAR[n].AR_BITNO = b & MASK4;
1979      cpu.PAR[n].AR_CHAR = c & MASK2;
1980   }
1981 #define SET_AR_CHAR_BITNO(n, c, b) SET_AR_CHAR_BITNO(cpup, n, c, b)
1982 
1983 bool sample_interrupts (cpu_state_t * cpup);
1984 t_stat simh_hooks (cpu_state_t * cpup);
1985 int operand_size (cpu_state_t * cpup);
1986 //void read_operand (word18 addr, processor_cycle_type cyctyp);
1987 void readOperandRead (cpu_state_t * cpup, word18 addr);
1988 void readOperandRMW (cpu_state_t * cpup, word18 addr);
1989 t_stat write_operand (cpu_state_t * cpup, word18 addr, processor_cycle_type acctyp);
1990 
1991 #if defined(PANEL68)
1992 static inline void trackport (word24 a, word36 d)
     /* [previous][next][first][last][top][bottom][index][help] */
1993   {
1994     cpu_state_t * cpup = _cpup;
1995     // Simplifying assumption: 4 * 4MW SCUs
1996     word2 port = (a >> 22) & MASK2;
1997     cpu.portSelect = port;
1998     cpu.portAddr [port] = a;
1999     cpu.portData [port] = d;
2000     cpu.portBusy = false;
2001   }
2002 #endif /* if defined(PANEL68) */
2003 
2004 #if defined(SPEED) && defined(INLINE_CORE)
2005 # error INLINE_CORE has known issues.
2006 // Ugh. Circular dependencies XXX
2007 NO_RETURN void doFault (_fault faultNumber, _fault_subtype faultSubtype,
2008               const char * faultMsg);
2009 extern const _fault_subtype fst_str_nea;
2010 
2011 static inline int core_read (word24 addr, word36 *data, \
     /* [previous][next][first][last][top][bottom][index][help] */
2012   UNUSED const char * ctx)
2013   {
2014     PNL (cpu.portBusy = true;)
2015     SC_MAP_ADDR (addr, addr);
2016     * data = M[addr] & DMASK;
2017 # if defined(TR_WORK_MEM)
2018     cpu.rTRticks ++;
2019 # endif /* if defined(TR_WORK_MEM) */
2020     PNL (trackport (addr, * data);)
2021     return 0;
2022   }
2023 
2024 static inline int core_write (word24 addr, word36 data, \
     /* [previous][next][first][last][top][bottom][index][help] */
2025   UNUSED const char * ctx)
2026   {
2027     PNL (cpu.portBusy = true;)
2028     SC_MAP_ADDR (addr, addr);
2029     if (cpu.tweaks.isolts_mode)
2030       {
2031         if (cpu.MR.sdpap)
2032           {
2033             sim_warn ("failing to implement sdpap\n");
2034             cpu.MR.sdpap = 0;
2035           }
2036         if (cpu.MR.separ)
2037           {
2038             sim_warn ("failing to implement separ\n");
2039             cpu.MR.separ = 0;
2040           }
2041      }
2042     M[addr] = data & DMASK;
2043 # if defined(TR_WORK_MEM)
2044     cpu.rTRticks ++;
2045 # endif /* if defined(TR_WORK_MEM) */
2046     PNL (trackport (addr, data);)
2047     return 0;
2048   }
2049 
2050 static inline int core_write_zone (word24 addr, word36 data, \
     /* [previous][next][first][last][top][bottom][index][help] */
2051   UNUSED const char * ctx)
2052   {
2053     PNL (cpu.portBusy = true;)
2054     SC_MAP_ADDR (addr, addr);
2055     if (cpu.tweaks.isolts_mode)
2056       {
2057         if (cpu.MR.sdpap)
2058           {
2059             sim_warn ("failing to implement sdpap\n");
2060             cpu.MR.sdpap = 0;
2061           }
2062         if (cpu.MR.separ)
2063           {
2064             sim_warn ("failing to implement separ\n");
2065             cpu.MR.separ = 0;
2066           }
2067       }
2068     M[addr] = (M[addr] & ~cpu.zone) | (data & cpu.zone);
2069     cpu.useZone = false; // Safety
2070 # if defined(TR_WORK_MEM)
2071     cpu.rTRticks ++;
2072 # endif /* if defined(TR_WORK_MEM) */
2073     PNL (trackport (addr, data);)
2074     return 0;
2075   }
2076 
2077 static inline int core_read2 (word24 addr, word36 *even, word36 *odd,
     /* [previous][next][first][last][top][bottom][index][help] */
2078                               UNUSED const char * ctx)
2079   {
2080     PNL (cpu.portBusy = true;)
2081     SC_MAP_ADDR (addr, addr);
2082     *even = M[addr++] & DMASK;
2083     *odd = M[addr] & DMASK;
2084 # if defined(TR_WORK_MEM)
2085     cpu.rTRticks ++;
2086 # endif /* if defined(TR_WORK_MEM) */
2087     PNL (trackport (addr - 1, * even);)
2088     return 0;
2089   }
2090 
2091 static inline int core_write2 (word24 addr, word36 even, word36 odd,
     /* [previous][next][first][last][top][bottom][index][help] */
2092                                UNUSED const char * ctx)
2093   {
2094     PNL (cpu.portBusy = true;)
2095     SC_MAP_ADDR (addr, addr);
2096     if (cpu.tweaks.isolts_mode)
2097       {
2098         if (cpu.MR.sdpap)
2099           {
2100             sim_warn ("failing to implement sdpap\n");
2101             cpu.MR.sdpap = 0;
2102           }
2103         if (cpu.MR.separ)
2104           {
2105             sim_warn ("failing to implement separ\n");
2106             cpu.MR.separ = 0;
2107           }
2108       }
2109     M[addr++] = even;
2110     M[addr] = odd;
2111     PNL (trackport (addr - 1, even);)
2112 # if defined(TR_WORK_MEM)
2113     cpu.rTRticks ++;
2114 # endif /* if defined(TR_WORK_MEM) */
2115     return 0;
2116   }
2117 #else
2118 int core_read (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx);
2119 int core_write (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2120 int core_write_zone (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2121 int core_read2 (cpu_state_t * cpup, word24 addr, word36 *even, word36 *odd, const char * ctx);
2122 int core_write2 (cpu_state_t * cpup, word24 addr, word36 even, word36 odd, const char * ctx);
2123 #endif /* if defined(SPEED) && defined(INLINE_CORE) */
2124 
2125 #if defined(LOCKLESS)
2126 
2127 /*
2128  * Atomic operations to use defined as follows:
2129  *
2130  *  AIX_ATOMICS  -  IBM AIX atomics
2131  *  BSD_ATOMICS  -  FreeBSD atomics
2132  *  GNU_ATOMICS  -  GNU atomics
2133  * SYNC_ATOMICS  -  GNU sync-style atomics
2134  *
2135  * The following are reserved and not yet implemented:
2136  *
2137  *  ISO_ATOMICS  -  ISO/IEC 9899:2011 (C11) atomics
2138  *   NT_ATOMICS  -  Microsoft Windows NT atomics
2139  *
2140  * For further details, see:
2141  *
2142  * AIX_ATOMICS:
2143  *  https://www.ibm.com/docs/en/aix/7.3?topic=services-atomic-operations
2144  *
2145  * BSD_ATOMICS:
2146  *  https://www.freebsd.org/cgi/man.cgi?query=atomic&sektion=9&format=html
2147  *  https://man.dragonflybsd.org/?command=atomic&section=9
2148  *
2149  * GNU_ATOMICS:
2150  *  https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
2151  *
2152  * SYNC_ATOMICS:
2153  *  https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
2154  *
2155  * ISO_ATOMICS:
2156  *  https://en.cppreference.com/w/c/atomic
2157  *
2158  * NT_ATOMICS:
2159  *  https://docs.microsoft.com/en-us/windows/win32/sync/synchronization-functions
2160  *  https://docs.microsoft.com/en-us/windows/win32/sync/interlocked-variable-access
2161  */
2162 
2163 // AIX_ATOMICS are SYNC_ATOMICS (for now)
2164 # if ( defined (AIX_ATOMICS) && \
2165    (! (defined (SYNC_ATOMICS))))
2166 #  define SYNC_ATOMICS 1
2167 # endif
2168 
2169 // FreeBSD atomics (default on for FreeBSD)
2170 # if (! defined (GNU_ATOMICS)) && (! defined (SYNC_ATOMICS)) && \
2171      (! defined (BSD_ATOMICS)) && (! defined (AIX_ATOMICS))
2172 #  if defined(__FreeBSD__) \
2173    || defined(__DragonFly__)
2174 #   undef BSD_ATOMICS
2175 #   define BSD_ATOMICS 1
2176 #  endif
2177 # endif
2178 
2179 // Otherwise, default to GNU_ATOMICS
2180 # if (! defined (GNU_ATOMICS)) && (! defined (BSD_ATOMICS)) && \
2181      (! defined (SYNC_ATOMICS)) && (! defined (AIX_ATOMICS))
2182 #  undef GNU_ATOMICS
2183 #  define GNU_ATOMICS 1
2184 # endif
2185 
2186 int core_read_lock (cpu_state_t * cpup, word24 addr, word36 *data, const char * ctx);
2187 int core_write_unlock (cpu_state_t * cpup, word24 addr, word36 data, const char * ctx);
2188 int core_unlock_all(cpu_state_t * cpup);
2189 
2190 # define DEADLOCK_DETECT   0x40000000U
2191 # define MEM_LOCKED_BIT    61
2192 # define MEM_LOCKED        (1LLU<<MEM_LOCKED_BIT)
2193 
2194 # if !defined(SCHED_NEVER_YIELD)
2195 #  undef SCHED_YIELD
2196 #  define SCHED_YIELD(lockStatePtr)                                      \
2197   do                                                                     \
2198     {                                                                    \
2199       if ((i & 0xff) == 0)                                               \
2200         {                                                                \
2201           sched_yield();                                                 \
2202           (lockStatePtr)->lockYield++;                                   \
2203         }                                                                \
2204     }                                                                    \
2205   while(0)
2206 # else
2207 #  undef SCHED_YIELD
2208 #  define SCHED_YIELD(lockStatePtr)                                      \
2209   do                                                                     \
2210     {                                                                    \
2211     }                                                                    \
2212   while(0)
2213 # endif /* if !defined(SCHED_NEVER_YIELD) */
2214 
2215 # if defined (BSD_ATOMICS)
2216 #  include <machine/atomic.h>
2217 
2218 #  define LOCK_CORE_WORD(addr,lockStatePtr)                                           \
2219   do                                                                     \
2220     {                                                                    \
2221       unsigned int i = DEADLOCK_DETECT;                                  \
2222       while ( atomic_testandset_64((volatile uint64_t *)&M[addr],        \
2223             MEM_LOCKED_BIT) == 1 && i > 0)                               \
2224         {                                                                \
2225           i--;                                                           \
2226           SCHED_YIELD(lockStatePtr);                                     \
2227         }                                                                \
2228       if (i == 0)                                                        \
2229         {                                                                \
2230           sim_warn ("%s: locked %x addr %x deadlock\n", __func__,        \
2231               (lockStatePtr)->locked_addr, addr);                        \
2232         }                                                                \
2233       (lockStatePtr)->lockCnt++;                                         \
2234       if (i == DEADLOCK_DETECT)                                          \
2235         (lockStatePtr)->lockImmediate++;                                 \
2236       (lockStatePtr)->lockWait += (DEADLOCK_DETECT-i);                   \
2237       (lockStatePtr)->lockWaitMax = ((DEADLOCK_DETECT-i) >               \
2238           (lockStatePtr)->lockWaitMax) ?                                 \
2239               (DEADLOCK_DETECT-i) : (lockStatePtr)->lockWaitMax;         \
2240     }                                                                    \
2241   while (0)
2242 
2243 #  define LOAD_ACQ_CORE_WORD(res, addr)                                  \
2244   do                                                                     \
2245     {                                                                    \
2246       res = atomic_load_acq_64((volatile uint64_t *)&M[addr]);           \
2247     }                                                                    \
2248   while (0)
2249 
2250 #  define STORE_REL_CORE_WORD(addr, data)                                \
2251   do                                                                     \
2252     {                                                                    \
2253       atomic_store_rel_64((volatile uint64_t *)&M[addr], data & DMASK);  \
2254     }                                                                    \
2255   while (0)
2256 
2257 # endif // BSD_ATOMICS
2258 
2259 # if defined(GNU_ATOMICS)
2260 
2261 #  define LOCK_CORE_WORD(addr,lockStatePtr)                              \
2262   do                                                                     \
2263     {                                                                    \
2264       unsigned int i = DEADLOCK_DETECT;                                  \
2265       while ((__atomic_fetch_or((volatile uint64_t *)&M[addr],           \
2266         MEM_LOCKED, __ATOMIC_ACQ_REL) & MEM_LOCKED)                      \
2267                 && i > 0)                                                \
2268     {                                                                    \
2269       i--;                                                               \
2270       SCHED_YIELD(lockStatePtr);                                         \
2271     }                                                                    \
2272       if (i == 0)                                                        \
2273         {                                                                \
2274           sim_warn ("%s: locked %x addr %x deadlock\n",                  \
2275             __func__, (lockStatePtr)->locked_addr, addr);                \
2276         }                                                                \
2277       (lockStatePtr)->lockCnt++;                                         \
2278       if (i == DEADLOCK_DETECT)                                          \
2279           (lockStatePtr)->lockImmediate++;                               \
2280       (lockStatePtr)->lockWait += (DEADLOCK_DETECT-i);                   \
2281       (lockStatePtr)->lockWaitMax = ((DEADLOCK_DETECT-i) >               \
2282           (lockStatePtr)->lockWaitMax) ? (DEADLOCK_DETECT-i) :           \
2283               (lockStatePtr)->lockWaitMax;                               \
2284     }                                                                    \
2285   while (0)
2286 
2287 #  define LOAD_ACQ_CORE_WORD(res, addr)                                  \
2288   do                                                                     \
2289     {                                                                    \
2290       res = __atomic_load_n((volatile uint64_t *)&M[addr],               \
2291           __ATOMIC_ACQUIRE);                                             \
2292     }                                                                    \
2293   while (0)
2294 
2295 #  define STORE_REL_CORE_WORD(addr, data)                                \
2296   do                                                                     \
2297     {                                                                    \
2298       __atomic_store_n((volatile uint64_t *)&M[addr], data &             \
2299           DMASK, __ATOMIC_RELEASE);                                      \
2300     }                                                                    \
2301   while (0)
2302 
2303 # endif // GNU_ATOMICS
2304 
2305 # if defined(SYNC_ATOMICS)
2306 #  if defined(MEMORY_ACCESS_NOT_STRONGLY_ORDERED)
2307 #   define MEM_BARRIER()   do { __sync_synchronize(); } while (0)
2308 #  else
2309 #   define MEM_BARRIER()   do {} while (0)
2310 #  endif
2311 
2312 #  define LOCK_CORE_WORD(addr,lockStatePtr)                                           \
2313      do                                                                  \
2314        {                                                                 \
2315          unsigned int i = DEADLOCK_DETECT;                               \
2316          while ((__sync_fetch_and_or((volatile uint64_t *)&M[addr],      \
2317              MEM_LOCKED) & MEM_LOCKED) && i > 0)                         \
2318            {                                                             \
2319             i--;                                                         \
2320             SCHED_YIELD(lockStatePtr);                                   \
2321            }                                                             \
2322          if (i == 0)                                                     \
2323            {                                                             \
2324             sim_warn ("%s: locked %x addr %x deadlock\n", __func__,      \
2325                 (lockStatePtr)->locked_addr, addr);                      \
2326             }                                                            \
2327          (lockStatePtr)->lockCnt++;                                      \
2328          if (i == DEADLOCK_DETECT)                                       \
2329            (lockStatePtr)->lockImmediate++;                              \
2330          (lockStatePtr)->lockWait += (DEADLOCK_DETECT-i);                \
2331          (lockStatePtr)->lockWaitMax = ((DEADLOCK_DETECT-i) >            \
2332              (lockStatePtr)->lockWaitMax) ?                              \
2333                  (DEADLOCK_DETECT-i) : (lockStatePtr)->lockWaitMax;      \
2334        }                                                                 \
2335      while (0)
2336 
2337 #  define LOAD_ACQ_CORE_WORD(res, addr)                                  \
2338      do                                                                  \
2339        {                                                                 \
2340          res = M[addr];                                                  \
2341          MEM_BARRIER();                                                  \
2342        }                                                                 \
2343      while (0)
2344 
2345 #  define STORE_REL_CORE_WORD(addr, data)                                \
2346   do                                                                     \
2347     {                                                                    \
2348       MEM_BARRIER();                                                     \
2349       M[addr] = data & DMASK;                                            \
2350     }                                                                    \
2351   while (0)
2352 
2353 # endif  // SYNC_ATOMICS
2354 #endif  // LOCKLESS
2355 
2356 static inline void core_readN (cpu_state_t * cpup, word24 addr, word36 * data, uint n,
     /* [previous][next][first][last][top][bottom][index][help] */
2357                                UNUSED const char * ctx)
2358   {
2359     for (uint i = 0; i < n; i ++)
2360       {
2361         core_read (cpup, addr + i, data + i, ctx);
2362         //HDBGMRead (addr + i, * (data + i), __func__);
2363       }
2364   }
2365 
2366 static inline void core_writeN (cpu_state_t * cpup, word24 addr, word36 * data, uint n,
     /* [previous][next][first][last][top][bottom][index][help] */
2367                                 UNUSED const char * ctx)
2368   {
2369     for (uint i = 0; i < n; i ++)
2370       {
2371         core_write (cpup, addr + i, data [i], ctx);
2372         //HDBGMWrite (addr + i, * (data + i), __func__);
2373       }
2374   }
2375 
2376 int is_priv_mode (cpu_state_t * cpup);
2377 //void set_went_appending (void);
2378 //void clr_went_appending (void);
2379 //bool get_went_appending (void);
2380 bool get_bar_mode (cpu_state_t * cpup);
2381 addr_modes_e get_addr_mode (cpu_state_t * cpup);
2382 void set_addr_mode (cpu_state_t * cpup, addr_modes_e mode);
2383 void decode_instruction (cpu_state_t * cpup, word36 inst, DCDstruct * p);
2384 #if !defined(SPEED)
2385 t_stat set_mem_watch (int32 arg, const char * buf);
2386 #endif /* if !defined(SPEED) */
2387 char *str_SDW0 (char * buf, sdw_s *SDW);
2388 int lookup_cpu_mem_map (cpu_state_t * cpup, word24 addr);
2389 void cpu_init (void);
2390 void setup_scbank_map (cpu_state_t * cpup);
2391 void add_dps8m_CU_history (cpu_state_t * cpup);
2392 void add_dps8m_DUOU_history (word36 flags, word18 ICT, word9 RS_REG, word9 flags2);
2393 void add_dps8m_APU_history (word15 ESN, word21 flags, word24 RMA, word3 RTRR, word9 flags2);
2394 void add_dps8m_EAPU_history (word18 ZCA, word18 opcode);
2395 void add_l68_CU_history (cpu_state_t * cpup);
2396 void add_l68_OU_history (cpu_state_t * cpup);
2397 void add_l68_DU_history (cpu_state_t * cpup);
2398 void add_l68_APU_history (cpu_state_t * cpup, enum APUH_e op);
2399 void add_history_force (cpu_state_t * cpup, uint hset, word36 w0, word36 w1);
2400 void printPtid(pthread_t pt);
2401 word18 get_BAR_address(cpu_state_t * cpup, word18 addr);
2402 #if defined(THREADZ) || defined(LOCKLESS)
2403 t_stat threadz_sim_instr (void);
2404 void * cpu_thread_main (void * arg);
2405 void perfTest (char * testName);
2406 #endif
2407 void cpu_reset_unit_idx (UNUSED uint cpun, bool clear_mem);
2408 void setupPROM (uint cpuNo, unsigned char * PROM);
2409 void cpuStats (uint cpuNo);

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