root/src/dps8/dps8_sys.c

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

DEFINITIONS

This source file includes following definitions.
  1. print_default_base_system_script
  2. do_ini_line
  3. set_default_base_system
  4. boot_skip
  5. do_execute_fault
  6. do_restart
  7. set_sys_polling_interval
  8. set_sys_slow_polling_interval
  9. set_sys_poll_check_rate
  10. dps_debug_mme_cntdwn
  11. dps_debug_skip
  12. dps_debug_start
  13. dps_debug_stop
  14. dps_debug_break
  15. dps_debug_segno
  16. dps_debug_ringno
  17. dps_debug_bar
  18. abs_addr_n
  19. abs_addr
  20. lookup_book_segment
  21. add_book_segment
  22. add_book_component
  23. lookup_system_book_address
  24. lookup_address
  25. lookup_system_book_name
  26. list_source
  27. stack_trace
  28. list_source_at
  29. load_system_book
  30. add_system_book_entry
  31. lookup_system_book
  32. fetchSDW
  33. virtAddrN
  34. virt_address
  35. set_search_path
  36. brkbrk
  37. sbreak
  38. dfx1entry
  39. dfx1exit
  40. dv2scale
  41. dfx2entry
  42. mdfx3entry
  43. smfx1entry
  44. search_memory
  45. set_dbg_cpu_mask
  46. scraper
  47. clear_yield
  48. yield
  49. set_luf
  50. dbgevent_compar
  51. dbgevent_lookup
  52. set_dbgevent
  53. rewind_media
  54. load_media
  55. ready_media
  56. trkw
  57. trkr
  58. usr1_signal_handler
  59. systabInit
  60. dps8_init
  61. dps8_exit
  62. getAddress
  63. parse_addr
  64. fprint_addr
  65. fprint_sym
  66. parse_sym
  67. sys_show_config
  68. sys_set_break
  69. sys_show_break
  70. sys_set_config
  71. sys_reset
  72. dps8_init_strip

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * SPDX-License-Identifier: Multics
   5  * scspell-id: ff1a12fc-f62e-11ec-aea6-80ee73e9b8e7
   6  *
   7  * ---------------------------------------------------------------------------
   8  *
   9  * Copyright (c) 2007-2013 Michael Mondy
  10  * Copyright (c) 2012-2016 Harry Reed
  11  * Copyright (c) 2013-2021 Charles Anthony
  12  * Copyright (c) 2016 Michal Tomek
  13  * Copyright (c) 2021 Jeffrey H. Johnson <trnsz@pobox.com>
  14  * Copyright (c) 2021-2022 The DPS8M Development Team
  15  *
  16  * All rights reserved.
  17  *
  18  * This software is made available under the terms of the ICU
  19  * License, version 1.8.1 or later.  For more details, see the
  20  * LICENSE.md file at the top-level directory of this distribution.
  21  *
  22  * ---------------------------------------------------------------------------
  23  *
  24  * This source file may contain code comments that adapt, include, and/or
  25  * incorporate Multics program code and/or documentation distributed under
  26  * the Multics License.  In the event of any discrepancy between code
  27  * comments herein and the original Multics materials, the original Multics
  28  * materials should be considered authoritative unless otherwise noted.
  29  * For more details and historical background, see the LICENSE.md file at
  30  * the top-level directory of this distribution.
  31  *
  32  * ---------------------------------------------------------------------------
  33  */
  34 
  35 #include <stdio.h>
  36 #ifndef __MINGW64__
  37 # ifndef __MINGW32__
  38 #  ifndef CROSS_MINGW64
  39 #   ifndef CROSS_MINGW32
  40 #    ifndef __OpenBSD__
  41 #     ifndef __HAIKU__
  42 #      ifndef __ANDROID__
  43 #       ifndef __sh__
  44 #        ifndef __serenity__
  45 #         include <wordexp.h>
  46 #        endif /* ifndef __serenity__ */
  47 #       endif /* ifndef __sh__ */
  48 #      endif /* ifndef __ANDROID__ */
  49 #     endif /* ifndef __HAIKU__ */
  50 #    endif /* ifndef __OpenBSD__ */
  51 #    include <signal.h>
  52 #   endif /* ifndef CROSS_MINGW32 */
  53 #  endif /* ifndef CROSS_MINGW64 */
  54 # endif /* ifndef __MINGW32__ */
  55 #endif /* ifndef __MINGW64__ */
  56 #include <unistd.h>
  57 #include <ctype.h>
  58 
  59 #ifdef __APPLE__
  60 # include <pthread.h>
  61 #endif
  62 
  63 #include "dps8.h"
  64 #include "dps8_sys.h"
  65 #include "dps8_faults.h"
  66 #include "dps8_scu.h"
  67 #include "dps8_iom.h"
  68 #include "dps8_console.h"
  69 #include "dps8_cable.h"
  70 #include "dps8_cpu.h"
  71 #include "dps8_state.h"
  72 #include "dps8_ins.h"
  73 #include "dps8_math.h"
  74 #include "dps8_mt.h"
  75 #include "dps8_socket_dev.h"
  76 #include "dps8_disk.h"
  77 #include "dps8_append.h"
  78 #include "dps8_fnp2.h"
  79 #include "dps8_crdrdr.h"
  80 #include "dps8_crdpun.h"
  81 #include "dps8_prt.h"
  82 #include "dps8_urp.h"
  83 #include "dps8_absi.h"
  84 #include "dps8_utils.h"
  85 #include "shm.h"
  86 #include "utlist.h"
  87 #include "ver.h"
  88 #if defined(THREADZ) || defined(LOCKLESS)
  89 # include "threadz.h"
  90 #endif
  91 
  92 #ifdef PANEL68
  93 # include "panelScraper.h"
  94 #endif
  95 
  96 #include "segldr.h"
  97 
  98 #define DBG_CTR cpu.cycleCnt
  99 
 100 #define ASSUME0 0
 101 
 102 #ifdef TESTING
 103 # undef FREE
 104 # define FREE(p) free(p)
 105 #endif /* ifdef TESTING */
 106 
 107 // Strictly speaking, memory belongs in the SCU.
 108 // We will treat memory as viewed from the CPU and elide the
 109 // SCU configuration that maps memory across multiple SCUs.
 110 // I would guess that multiple SCUs helped relieve memory
 111 // contention across multiple CPUs, but that is a level of
 112 // emulation that will be ignored.
 113 
 114 struct system_state_s * system_state;
 115 
 116 vol word36 * M = NULL;  //-V707   // memory
 117 
 118 //
 119 // These are part of the scp interface
 120 //
 121 
 122 char sim_name[] = "DPS8/M";
 123 int32 sim_emax = 4;  // some EIS can take up to 4-words
 124 static void dps8_init(void);
 125 static void dps8_exit (void);
 126 void (*sim_vm_init) (void) = & dps8_init;  // CustomCmds;
 127 void (*sim_vm_exit) (void) = & dps8_exit;  // CustomCmds;
 128 
 129 #ifdef TESTING
 130 static t_addr parse_addr(DEVICE *dptr, const char *cptr, const char **optr);
 131 static void fprint_addr(FILE *stream, DEVICE *dptr, t_addr addr);
 132 #endif // TESTING
 133 
 134 int32 luf_flag = 1;
 135 
 136 ////////////////////////////////////////////////////////////////////////////////
 137 //
 138 // SCP Commands
 139 //
 140 
 141 //
 142 // System configuration commands
 143 //
 144 
 145 // Script to string cables and set switches
 146 
 147 #ifndef PERF_STRIP
 148 static char * default_base_system_script [] =
 149   {
 150     // ;
 151     // ; Configure test system
 152     // ;
 153     // ; CPU, IOM * 2, MPC, TAPE * 16, DISK * 16, SCU * 4, OPC * 2, FNP, URP * 3,
 154     // ; PRT, RDR, PUN
 155     // ;
 156     // ;
 157     // ; From AN70-1 System Initialization PLM May 84, pg 8-4:
 158     // ;
 159     // ; All CPUs and IOMs must share the same layout of port assignments to
 160     // ; SCUs. Thus, if memory port B of CPU C goes to SCU D, the memory port
 161     // ; B of all other CPUs and IOMs must go to SCU D. All CPUs and IOMs must
 162     // ; describe this SCU the same; all must agree in memory sizes. Also, all
 163     // ; SCUs must agree on port assignments of CPUs and IOMs. This, if port 3
 164     // ; of SCU C goes to CPU A, the port 3 of all other SCUs must also go to
 165     // ; CPU A.
 166     // ;
 167     // ; Pg. 8-6:
 168     // ;
 169     // ; The actual memory size of the memory attached to the SCU attached to
 170     // ; the processor port in questions is 32K * 2 ** (encoded memory size).
 171     // ; The port assignment couples with the memory size to determine the base
 172     // ; address of the SCU connected to the specified CPU port (absolute
 173     // ; address of the first location in the memory attached to that SCU). The
 174     // ; base address of the SCU is the (actual memory size) * (port assignment).
 175     // ;
 176     // ; Pg. 8-6
 177     // ;
 178     // ; [bits 09-11 lower store size]
 179     // ;
 180     // ; A DPS-8 SCU may have up to four store units attached to it. If this is
 181     // ; the case, two stores units form a pair of units. The size of a pair of
 182     // ; units (or a single unit) is 32K * 2 ** (lower store size) above.
 183     // ;
 184     // ;
 185     // ;
 186     // ; Looking at bootload_io, it would appear that Multics is happier with
 187     // ; IOM0 being the bootload IOM, despite suggestions elsewhere that was
 188     // ; not a requirement.
 189 
 190 //
 191 // IOM channel assignments
 192 //
 193 // IOM A
 194 //
 195 //  012 MTP0           tape drives
 196 //  013 IPC0 port 0    FIPS disk controller
 197 //  014 MSP0 port 0    disk controller
 198 //  015 URP0           card reader controller
 199 //  016 URP1           card punch controller
 200 //  017 URP2           printer controller
 201 //  020 FNPD           comm line controller
 202 //  021 FNPA           comm line controller
 203 //  022 FNPB           comm line controller
 204 //  023 FNPC           comm line controller
 205 //  024 FNPE           comm line controller
 206 //  025 FNPF           comm line controller
 207 //  026 FNPG           comm line controller
 208 //  027 FNPH           comm line controller
 209 //  032 ABSI0          IMP controller
 210 //  036 OPC0           operator console
 211 //  040 SKCA
 212 //  041 SKCB
 213 //  042 SKCC
 214 //  043 SKCD
 215 //  044 SKCE
 216 //  045 SKCF
 217 //  046 SKCG
 218 //  047 SKCH
 219 //
 220 // IOM B
 221 //
 222 //  013 IPC0 port 1    FIPS disk controller
 223 //  014 MSP0 port 1    disk controller
 224 
 225     // ; Disconnect everything...
 226     "CABLE_RIPOUT",
 227 
 228     "SET CPU NUNITS=6",
 229     "SET IOM NUNITS=2",
 230     // ; 16 drives plus a placeholder for the controller
 231     "SET TAPE NUNITS=17",
 232     "SET MTP NUNITS=1",
 233     // ; 4 3381 drives; 2 controllers
 234     // ; 4 d501 drives; 2 controller
 235     // ; 4 d451 drives; same controller has d501s
 236     // ; 2 d500 drives; same controller has d501s
 237     "SET IPC NUNITS=2",
 238     "SET MSP NUNITS=2",
 239     "SET DISK NUNITS=26",
 240     "SET SCU NUNITS=4",
 241     "SET OPC NUNITS=2",
 242     "SET FNP NUNITS=8",
 243     "SET URP NUNITS=10",
 244     "SET RDR NUNITS=3",
 245     "SET PUN NUNITS=3",
 246     "SET PRT NUNITS=4",
 247 # ifdef WITH_ABSI_DEV
 248 #  ifndef __MINGW64__
 249 #   ifndef __MINGW32__
 250 #    ifndef CROSS_MINGW64
 251 #     ifndef CROSS_MINGW32
 252     "SET ABSI NUNITS=1",
 253 #     endif /* ifndef CROSS_MINGW32 */
 254 #    endif /* ifndef CROSS_MINGW64 */
 255 #   endif /* ifndef __MINGW32__ */
 256 #  endif /* ifndef __MINGW64__ */
 257 # endif /* ifdef WITH_ABSI_DEV */
 258 # ifdef WITH_SOCKET_DEV
 259 #  ifndef __MINGW64__
 260 #   ifndef __MINGW32__
 261 #    ifndef CROSS_MINGW64
 262 #     ifndef CROSS_MINGW32
 263     "SET SKC NUNITS=64",
 264 #     endif /* ifndef CROSS_MINGW32 */
 265 #    endif /* ifndef CROSS_MINGW64 */
 266 #   endif /* ifndef __MINGW32__ */
 267 #  endif /* ifndef __MINGW64__ */
 268 # endif /* ifdef WITH_SOCKET_DEV */
 269 
 270 // CPU0
 271 
 272     "SET CPU0 CONFIG=FAULTBASE=Multics",
 273 
 274     "SET CPU0 CONFIG=NUM=0",
 275     // ; As per GB61-01 Operators Guide, App. A
 276     // ; switches: 4, 6, 18, 19, 20, 23, 24, 25, 26, 28
 277     "SET CPU0 CONFIG=DATA=024000717200",
 278     "SET CPU0 CONFIG=ADDRESS=000000000000",
 279 
 280     // ; enable ports 0 and 1 (scu connections)
 281     // ; portconfig: ABCD
 282     // ;   each is 3 bits addr assignment
 283     // ;           1 bit enabled
 284     // ;           1 bit sysinit enabled
 285     // ;           1 bit interlace enabled (interlace?)
 286     // ;           3 bit memory size
 287     // ;              0 - 32K
 288     // ;              1 - 64K
 289     // ;              2 - 128K
 290     // ;              3 - 256K
 291     // ;              4 - 512K
 292     // ;              5 - 1M
 293     // ;              6 - 2M
 294     // ;              7 - 4M
 295 
 296     "SET CPU0 CONFIG=PORT=A",
 297     "SET CPU0   CONFIG=ASSIGNMENT=0",
 298     "SET CPU0   CONFIG=INTERLACE=0",
 299     "SET CPU0   CONFIG=ENABLE=1",
 300     "SET CPU0   CONFIG=INIT_ENABLE=1",
 301     "SET CPU0   CONFIG=STORE_SIZE=4M",
 302 
 303     "SET CPU0 CONFIG=PORT=B",
 304     "SET CPU0   CONFIG=ASSIGNMENT=1",
 305     "SET CPU0   CONFIG=INTERLACE=0",
 306     "SET CPU0   CONFIG=ENABLE=1",
 307     "SET CPU0   CONFIG=INIT_ENABLE=1",
 308     "SET CPU0   CONFIG=STORE_SIZE=4M",
 309 
 310     "SET CPU0 CONFIG=PORT=C",
 311     "SET CPU0   CONFIG=ASSIGNMENT=2",
 312     "SET CPU0   CONFIG=INTERLACE=0",
 313     "SET CPU0   CONFIG=ENABLE=1",
 314     "SET CPU0   CONFIG=INIT_ENABLE=1",
 315     "SET CPU0   CONFIG=STORE_SIZE=4M",
 316 
 317     "SET CPU0 CONFIG=PORT=D",
 318     "SET CPU0   CONFIG=ASSIGNMENT=3",
 319     "SET CPU0   CONFIG=INTERLACE=0",
 320     "SET CPU0   CONFIG=ENABLE=1",
 321     "SET CPU0   CONFIG=INIT_ENABLE=1",
 322     "SET CPU0   CONFIG=STORE_SIZE=4M",
 323 
 324     // ; 0 = GCOS 1 = VMS
 325     "SET CPU0 CONFIG=MODE=Multics",
 326 
 327     "SET CPU0 CONFIG=ENABLE_CACHE=enable",
 328     "SET CPU0 CONFIG=SDWAM=enable",
 329     "SET CPU0 CONFIG=PTWAM=enable",
 330 
 331     // ; 0 = 8/70
 332     "SET CPU0 CONFIG=SPEED=0",
 333 
 334     "SET CPU0 CONFIG=DIS_ENABLE=enable",
 335     "SET CPU0 CONFIG=STEADY_CLOCK=disable",
 336     "SET CPU0 CONFIG=HALT_ON_UNIMPLEMENTED=disable",
 337     "SET CPU0 CONFIG=ENABLE_WAM=disable",
 338     "SET CPU0 CONFIG=REPORT_FAULTS=disable",
 339     "SET CPU0 CONFIG=TRO_ENABLE=enable",
 340     "SET CPU0 CONFIG=Y2K=disable",
 341     "SET CPU0 CONFIG=DRL_FATAL=disable",
 342     "SET CPU0 CONFIG=USEMAP=disable",
 343     "SET CPU0 CONFIG=PROM_INSTALLED=enable",
 344     "SET CPU0 CONFIG=HEX_MODE_INSTALLED=disable",
 345     "SET CPU0 CONFIG=CACHE_INSTALLED=enable",
 346     "SET CPU0 CONFIG=CLOCK_SLAVE_INSTALLED=enable",
 347 
 348 // CPU1
 349 
 350     "SET CPU1 CONFIG=FAULTBASE=Multics",
 351 
 352     "SET CPU1 CONFIG=NUM=1",
 353     // ; As per GB61-01 Operators Guide, App. A
 354     // ; switches: 4, 6, 18, 19, 20, 23, 24, 25, 26, 28
 355     "SET CPU1 CONFIG=DATA=024000717200",
 356     "SET CPU1 CONFIG=ADDRESS=000000000000",
 357 
 358     // ; enable ports 0 and 1 (scu connections)
 359     // ; portconfig: ABCD
 360     // ;   each is 3 bits addr assignment
 361     // ;           1 bit enabled
 362     // ;           1 bit sysinit enabled
 363     // ;           1 bit interlace enabled (interlace?)
 364     // ;           3 bit memory size
 365     // ;              0 - 32K
 366     // ;              1 - 64K
 367     // ;              2 - 128K
 368     // ;              3 - 256K
 369     // ;              4 - 512K
 370     // ;              5 - 1M
 371     // ;              6 - 2M
 372     // ;              7 - 4M
 373 
 374     "SET CPU1 CONFIG=PORT=A",
 375     "SET CPU1   CONFIG=ASSIGNMENT=0",
 376     "SET CPU1   CONFIG=INTERLACE=0",
 377     "SET CPU1   CONFIG=ENABLE=1",
 378     "SET CPU1   CONFIG=INIT_ENABLE=1",
 379     "SET CPU1   CONFIG=STORE_SIZE=4M",
 380 
 381     "SET CPU1 CONFIG=PORT=B",
 382     "SET CPU1   CONFIG=ASSIGNMENT=1",
 383     "SET CPU1   CONFIG=INTERLACE=0",
 384     "SET CPU1   CONFIG=ENABLE=1",
 385     "SET CPU1   CONFIG=INIT_ENABLE=1",
 386     "SET CPU1   CONFIG=STORE_SIZE=4M",
 387 
 388     "SET CPU1 CONFIG=PORT=C",
 389     "SET CPU1   CONFIG=ASSIGNMENT=2",
 390     "SET CPU1   CONFIG=INTERLACE=0",
 391     "SET CPU1   CONFIG=ENABLE=1",
 392     "SET CPU1   CONFIG=INIT_ENABLE=1",
 393     "SET CPU1   CONFIG=STORE_SIZE=4M",
 394 
 395     "SET CPU1 CONFIG=PORT=D",
 396     "SET CPU1   CONFIG=ASSIGNMENT=3",
 397     "SET CPU1   CONFIG=INTERLACE=0",
 398     "SET CPU1   CONFIG=ENABLE=1",
 399     "SET CPU1   CONFIG=INIT_ENABLE=1",
 400     "SET CPU1   CONFIG=STORE_SIZE=4M",
 401 
 402     // ; 0 = GCOS 1 = VMS
 403     "SET CPU1 CONFIG=MODE=Multics",
 404 
 405     "SET CPU1 CONFIG=ENABLE_CACHE=enable",
 406     "SET CPU1 CONFIG=SDWAM=enable",
 407     "SET CPU1 CONFIG=PTWAM=enable",
 408 
 409     // ; 0 = 8/70
 410     "SET CPU1 CONFIG=SPEED=0",
 411 
 412     "SET CPU1 CONFIG=DIS_ENABLE=enable",
 413     "SET CPU1 CONFIG=STEADY_CLOCK=disable",
 414     "SET CPU1 CONFIG=HALT_ON_UNIMPLEMENTED=disable",
 415     "SET CPU1 CONFIG=ENABLE_WAM=disable",
 416     "SET CPU1 CONFIG=REPORT_FAULTS=disable",
 417     "SET CPU1 CONFIG=TRO_ENABLE=enable",
 418     "SET CPU1 CONFIG=Y2K=disable",
 419     "SET CPU1 CONFIG=DRL_FATAL=disable",
 420     "SET CPU1 CONFIG=USEMAP=disable",
 421     "SET CPU1 CONFIG=PROM_INSTALLED=enable",
 422     "SET CPU1 CONFIG=HEX_MODE_INSTALLED=disable",
 423     "SET CPU1 CONFIG=CACHE_INSTALLED=enable",
 424     "SET CPU1 CONFIG=CLOCK_SLAVE_INSTALLED=enable",
 425 
 426 // CPU2
 427 
 428     "SET CPU2 CONFIG=FAULTBASE=Multics",
 429 
 430     "SET CPU2 CONFIG=NUM=2",
 431     // ; As per GB61-01 Operators Guide, App. A
 432     // ; switches: 4, 6, 18, 19, 20, 23, 24, 25, 26, 28
 433     "SET CPU2 CONFIG=DATA=024000717200",
 434     "SET CPU2 CONFIG=ADDRESS=000000000000",
 435 
 436     // ; enable ports 0 and 1 (scu connections)
 437     // ; portconfig: ABCD
 438     // ;   each is 3 bits addr assignment
 439     // ;           1 bit enabled
 440     // ;           1 bit sysinit enabled
 441     // ;           1 bit interlace enabled (interlace?)
 442     // ;           3 bit memory size
 443     // ;              0 - 32K
 444     // ;              1 - 64K
 445     // ;              2 - 128K
 446     // ;              3 - 256K
 447     // ;              4 - 512K
 448     // ;              5 - 1M
 449     // ;              6 - 2M
 450     // ;              7 - 4M
 451 
 452     "SET CPU2 CONFIG=PORT=A",
 453     "SET CPU2   CONFIG=ASSIGNMENT=0",
 454     "SET CPU2   CONFIG=INTERLACE=0",
 455     "SET CPU2   CONFIG=ENABLE=1",
 456     "SET CPU2   CONFIG=INIT_ENABLE=1",
 457     "SET CPU2   CONFIG=STORE_SIZE=4M",
 458 
 459     "SET CPU2 CONFIG=PORT=B",
 460     "SET CPU2   CONFIG=ASSIGNMENT=1",
 461     "SET CPU2   CONFIG=INTERLACE=0",
 462     "SET CPU2   CONFIG=ENABLE=1",
 463     "SET CPU2   CONFIG=INIT_ENABLE=1",
 464     "SET CPU2   CONFIG=STORE_SIZE=4M",
 465 
 466     "SET CPU2 CONFIG=PORT=C",
 467     "SET CPU2   CONFIG=ASSIGNMENT=2",
 468     "SET CPU2   CONFIG=INTERLACE=0",
 469     "SET CPU2   CONFIG=ENABLE=1",
 470     "SET CPU2   CONFIG=INIT_ENABLE=1",
 471     "SET CPU2   CONFIG=STORE_SIZE=4M",
 472 
 473     "SET CPU2 CONFIG=PORT=D",
 474     "SET CPU2   CONFIG=ASSIGNMENT=3",
 475     "SET CPU2   CONFIG=INTERLACE=0",
 476     "SET CPU2   CONFIG=ENABLE=1",
 477     "SET CPU2   CONFIG=INIT_ENABLE=1",
 478     "SET CPU2   CONFIG=STORE_SIZE=4M",
 479 
 480     // ; 0 = GCOS 1 = VMS
 481     "SET CPU2 CONFIG=MODE=Multics",
 482 
 483     "SET CPU2 CONFIG=ENABLE_CACHE=enable",
 484     "SET CPU2 CONFIG=SDWAM=enable",
 485     "SET CPU2 CONFIG=PTWAM=enable",
 486 
 487     // ; 0 = 8/70
 488     "SET CPU2 CONFIG=SPEED=0",
 489 
 490     "SET CPU2 CONFIG=DIS_ENABLE=enable",
 491     "SET CPU2 CONFIG=STEADY_CLOCK=disable",
 492     "SET CPU2 CONFIG=HALT_ON_UNIMPLEMENTED=disable",
 493     "SET CPU2 CONFIG=ENABLE_WAM=disable",
 494     "SET CPU2 CONFIG=REPORT_FAULTS=disable",
 495     "SET CPU2 CONFIG=TRO_ENABLE=enable",
 496     "SET CPU2 CONFIG=Y2K=disable",
 497     "SET CPU2 CONFIG=DRL_FATAL=disable",
 498     "SET CPU2 CONFIG=USEMAP=disAble",
 499     "SET CPU2 CONFIG=PROM_INSTALLED=enable",
 500     "SET CPU2 CONFIG=HEX_MODE_INSTALLED=disable",
 501     "SET CPU2 CONFIG=CACHE_INSTALLED=enable",
 502     "SET CPU2 CONFIG=CLOCK_SLAVE_INSTALLED=enable",
 503 
 504 // CPU3
 505 
 506     "SET CPU3 CONFIG=FAULTBASE=Multics",
 507 
 508     "SET CPU3 CONFIG=NUM=3",
 509     // ; As per GB61-01 Operators Guide, App. A
 510     // ; switches: 4, 6, 18, 19, 20, 23, 24, 25, 26, 28
 511     "SET CPU3 CONFIG=DATA=024000717200",
 512     "SET CPU3 CONFIG=ADDRESS=000000000000",
 513 
 514     // ; enable ports 0 and 1 (scu connections)
 515     // ; portconfig: ABCD
 516     // ;   each is 3 bits addr assignment
 517     // ;           1 bit enabled
 518     // ;           1 bit sysinit enabled
 519     // ;           1 bit interlace enabled (interlace?)
 520     // ;           3 bit memory size
 521     // ;              0 - 32K
 522     // ;              1 - 64K
 523     // ;              2 - 128K
 524     // ;              3 - 256K
 525     // ;              4 - 512K
 526     // ;              5 - 1M
 527     // ;              6 - 2M
 528     // ;              7 - 4M
 529 
 530     "SET CPU3 CONFIG=PORT=A",
 531     "SET CPU3   CONFIG=ASSIGNMENT=0",
 532     "SET CPU3   CONFIG=INTERLACE=0",
 533     "SET CPU3   CONFIG=ENABLE=1",
 534     "SET CPU3   CONFIG=INIT_ENABLE=1",
 535     "SET CPU3   CONFIG=STORE_SIZE=4M",
 536 
 537     "SET CPU3 CONFIG=PORT=B",
 538     "SET CPU3   CONFIG=ASSIGNMENT=1",
 539     "SET CPU3   CONFIG=INTERLACE=0",
 540     "SET CPU3   CONFIG=ENABLE=1",
 541     "SET CPU3   CONFIG=INIT_ENABLE=1",
 542     "SET CPU3   CONFIG=STORE_SIZE=4M",
 543 
 544     "SET CPU3 CONFIG=PORT=C",
 545     "SET CPU3   CONFIG=ASSIGNMENT=2",
 546     "SET CPU3   CONFIG=INTERLACE=0",
 547     "SET CPU3   CONFIG=ENABLE=1",
 548     "SET CPU3   CONFIG=INIT_ENABLE=1",
 549     "SET CPU3   CONFIG=STORE_SIZE=4M",
 550 
 551     "SET CPU3 CONFIG=PORT=D",
 552     "SET CPU3   CONFIG=ASSIGNMENT=3",
 553     "SET CPU3   CONFIG=INTERLACE=0",
 554     "SET CPU3   CONFIG=ENABLE=1",
 555     "SET CPU3   CONFIG=INIT_ENABLE=1",
 556     "SET CPU3   CONFIG=STORE_SIZE=4M",
 557 
 558     // ; 0 = GCOS 1 = VMS
 559     "SET CPU3 CONFIG=MODE=Multics",
 560 
 561     "SET CPU3 CONFIG=ENABLE_CACHE=enable",
 562     "SET CPU3 CONFIG=SDWAM=enable",
 563     "SET CPU3 CONFIG=PTWAM=enable",
 564 
 565     // ; 0 = 8/70
 566     "SET CPU3 CONFIG=SPEED=0",
 567 
 568     "SET CPU3 CONFIG=DIS_ENABLE=enable",
 569     "SET CPU3 CONFIG=STEADY_CLOCK=disable",
 570     "SET CPU3 CONFIG=HALT_ON_UNIMPLEMENTED=disable",
 571     "SET CPU3 CONFIG=ENABLE_WAM=disable",
 572     "SET CPU3 CONFIG=REPORT_FAULTS=disable",
 573     "SET CPU3 CONFIG=TRO_ENABLE=enable",
 574     "SET CPU3 CONFIG=Y2K=disable",
 575     "SET CPU3 CONFIG=DRL_FATAL=disable",
 576     "SET CPU3 CONFIG=USEMAP=disable",
 577     "SET CPU3 CONFIG=PROM_INSTALLED=enable",
 578     "SET CPU3 CONFIG=HEX_MODE_INSTALLED=disable",
 579     "SET CPU3 CONFIG=CACHE_INSTALLED=enable",
 580     "SET CPU3 CONFIG=CLOCK_SLAVE_INSTALLED=enable",
 581 
 582 // CPU4
 583 
 584     "SET CPU4 CONFIG=FAULTBASE=Multics",
 585 
 586     "SET CPU4 CONFIG=NUM=4",
 587     // ; As per GB61-01 Operators Guide, App. A
 588     // ; switches: 4, 6, 18, 19, 20, 23, 24, 25, 26, 28
 589     "SET CPU4 CONFIG=DATA=024000717200",
 590     "SET CPU4 CONFIG=ADDRESS=000000000000",
 591 
 592     // ; enable ports 0 and 1 (scu connections)
 593     // ; portconfig: ABCD
 594     // ;   each is 3 bits addr assignment
 595     // ;           1 bit enabled
 596     // ;           1 bit sysinit enabled
 597     // ;           1 bit interlace enabled (interlace?)
 598     // ;           3 bit memory size
 599     // ;              0 - 32K
 600     // ;              1 - 64K
 601     // ;              2 - 128K
 602     // ;              3 - 256K
 603     // ;              4 - 512K
 604     // ;              5 - 1M
 605     // ;              6 - 2M
 606     // ;              7 - 4M
 607 
 608     "SET CPU4 CONFIG=PORT=A",
 609     "SET CPU4   CONFIG=ASSIGNMENT=0",
 610     "SET CPU4   CONFIG=INTERLACE=0",
 611     "SET CPU4   CONFIG=ENABLE=1",
 612     "SET CPU4   CONFIG=INIT_ENABLE=1",
 613     "SET CPU4   CONFIG=STORE_SIZE=4M",
 614 
 615     "SET CPU4 CONFIG=PORT=B",
 616     "SET CPU4   CONFIG=ASSIGNMENT=1",
 617     "SET CPU4   CONFIG=INTERLACE=0",
 618     "SET CPU4   CONFIG=ENABLE=1",
 619     "SET CPU4   CONFIG=INIT_ENABLE=1",
 620     "SET CPU4   CONFIG=STORE_SIZE=4M",
 621 
 622     "SET CPU4 CONFIG=PORT=C",
 623     "SET CPU4   CONFIG=ASSIGNMENT=2",
 624     "SET CPU4   CONFIG=INTERLACE=0",
 625     "SET CPU4   CONFIG=ENABLE=1",
 626     "SET CPU4   CONFIG=INIT_ENABLE=1",
 627     "SET CPU4   CONFIG=STORE_SIZE=4M",
 628 
 629     "SET CPU4 CONFIG=PORT=D",
 630     "SET CPU4   CONFIG=ASSIGNMENT=3",
 631     "SET CPU4   CONFIG=INTERLACE=0",
 632     "SET CPU4   CONFIG=ENABLE=1",
 633     "SET CPU4   CONFIG=INIT_ENABLE=1",
 634     "SET CPU4   CONFIG=STORE_SIZE=4M",
 635 
 636     // ; 0 = GCOS 1 = VMS
 637     "SET CPU4 CONFIG=MODE=Multics",
 638 
 639     "SET CPU4 CONFIG=ENABLE_CACHE=enable",
 640     "SET CPU4 CONFIG=SDWAM=enable",
 641     "SET CPU4 CONFIG=PTWAM=enable",
 642 
 643     // ; 0 = 8/70
 644     "SET CPU4 CONFIG=SPEED=0",
 645 
 646     "SET CPU4 CONFIG=DIS_ENABLE=enable",
 647     "SET CPU4 CONFIG=STEADY_CLOCK=disable",
 648     "SET CPU4 CONFIG=HALT_ON_UNIMPLEMENTED=disable",
 649     "SET CPU4 CONFIG=ENABLE_WAM=disable",
 650     "SET CPU4 CONFIG=REPORT_FAULTS=disable",
 651     "SET CPU4 CONFIG=TRO_ENABLE=enable",
 652     "SET CPU4 CONFIG=Y2K=disable",
 653     "SET CPU4 CONFIG=DRL_FATAL=disable",
 654     "SET CPU4 CONFIG=USEMAP=disable",
 655     "SET CPU4 CONFIG=PROM_INSTALLED=enable",
 656     "SET CPU4 CONFIG=HEX_MODE_INSTALLED=disable",
 657     "SET CPU4 CONFIG=CACHE_INSTALLED=enable",
 658     "SET CPU4 CONFIG=CLOCK_SLAVE_INSTALLED=enable",
 659 
 660 // CPU5
 661 
 662     "SET CPU5 CONFIG=FAULTBASE=Multics",
 663 
 664     "SET CPU5 CONFIG=NUM=5",
 665     // ; As per GB61-01 Operators Guide, App. A
 666     // ; switches: 4, 6, 18, 19, 20, 23, 24, 25, 26, 28
 667     "SET CPU5 CONFIG=DATA=024000717200",
 668     "SET CPU5 CONFIG=ADDRESS=000000000000",
 669 
 670     // ; enable ports 0 and 1 (scu connections)
 671     // ; portconfig: ABCD
 672     // ;   each is 3 bits addr assignment
 673     // ;           1 bit enabled
 674     // ;           1 bit sysinit enabled
 675     // ;           1 bit interlace enabled (interlace?)
 676     // ;           3 bit memory size
 677     // ;              0 - 32K
 678     // ;              1 - 64K
 679     // ;              2 - 128K
 680     // ;              3 - 256K
 681     // ;              4 - 512K
 682     // ;              5 - 1M
 683     // ;              6 - 2M
 684     // ;              7 - 4M
 685 
 686     "SET CPU5 CONFIG=PORT=A",
 687     "SET CPU5   CONFIG=ASSIGNMENT=0",
 688     "SET CPU5   CONFIG=INTERLACE=0",
 689     "SET CPU5   CONFIG=ENABLE=1",
 690     "SET CPU5   CONFIG=INIT_ENABLE=1",
 691     "SET CPU5   CONFIG=STORE_SIZE=4M",
 692 
 693     "SET CPU5 CONFIG=PORT=B",
 694     "SET CPU5   CONFIG=ASSIGNMENT=1",
 695     "SET CPU5   CONFIG=INTERLACE=0",
 696     "SET CPU5   CONFIG=ENABLE=1",
 697     "SET CPU5   CONFIG=INIT_ENABLE=1",
 698     "SET CPU5   CONFIG=STORE_SIZE=4M",
 699 
 700     "SET CPU5 CONFIG=PORT=C",
 701     "SET CPU5   CONFIG=ASSIGNMENT=2",
 702     "SET CPU5   CONFIG=INTERLACE=0",
 703     "SET CPU5   CONFIG=ENABLE=1",
 704     "SET CPU5   CONFIG=INIT_ENABLE=1",
 705     "SET CPU5   CONFIG=STORE_SIZE=4M",
 706 
 707     "SET CPU5 CONFIG=PORT=D",
 708     "SET CPU5   CONFIG=ASSIGNMENT=3",
 709     "SET CPU5   CONFIG=INTERLACE=0",
 710     "SET CPU5   CONFIG=ENABLE=1",
 711     "SET CPU5   CONFIG=INIT_ENABLE=1",
 712     "SET CPU5   CONFIG=STORE_SIZE=4M",
 713 
 714     // ; 0 = GCOS 1 = VMS
 715     "SET CPU5 CONFIG=MODE=Multics",
 716 
 717     "SET CPU5 CONFIG=ENABLE_CACHE=enable",
 718     "SET CPU5 CONFIG=SDWAM=enable",
 719     "SET CPU5 CONFIG=PTWAM=enable",
 720 
 721     // ; 0 = 8/70
 722     "SET CPU5 CONFIG=SPEED=0",
 723 
 724     "SET CPU5 CONFIG=DIS_ENABLE=enable",
 725     "SET CPU5 CONFIG=STEADY_CLOCK=disable",
 726     "SET CPU5 CONFIG=HALT_ON_UNIMPLEMENTED=disable",
 727     "SET CPU5 CONFIG=ENABLE_WAM=disable",
 728     "SET CPU5 CONFIG=REPORT_FAULTS=disable",
 729     "SET CPU5 CONFIG=TRO_ENABLE=enable",
 730     "SET CPU5 CONFIG=Y2K=disable",
 731     "SET CPU5 CONFIG=DRL_FATAL=disable",
 732     "SET CPU5 CONFIG=USEMAP=disable",
 733     "SET CPU5 CONFIG=PROM_INSTALLED=enable",
 734     "SET CPU5 CONFIG=HEX_MODE_INSTALLED=disable",
 735     "SET CPU5 CONFIG=CACHE_INSTALLED=enable",
 736     "SET CPU5 CONFIG=CLOCK_SLAVE_INSTALLED=enable",
 737 
 738 
 739 
 740 
 741 
 742 
 743 
 744 
 745 
 746 
 747 
 748 
 749 
 750 
 751 
 752 
 753 
 754 
 755 
 756 
 757 
 758 
 759 
 760 
 761 
 762 
 763 
 764 
 765 
 766 
 767 
 768 
 769 
 770 
 771 
 772 
 773 
 774 
 775 
 776 
 777 
 778 
 779 
 780 
 781 
 782 
 783 
 784 
 785 
 786 
 787 
 788 
 789 
 790 
 791 
 792 
 793 
 794 
 795 
 796 
 797 
 798 
 799 
 800 
 801 
 802 
 803 
 804 
 805 
 806 
 807 
 808 
 809 
 810 
 811 
 812 
 813 
 814 
 815 
 816 
 817 
 818 
 819 
 820 
 821 
 822 
 823 
 824 
 825 
 826 
 827 
 828 
 829 
 830 
 831 
 832 
 833 
 834 
 835 
 836 
 837 
 838 
 839 
 840 
 841 
 842 
 843 
 844 
 845 
 846 
 847 
 848 
 849 
 850 
 851 
 852 
 853 
 854 
 855 
 856 
 857 
 858 
 859 
 860 
 861 
 862 
 863 
 864 
 865 
 866 
 867 
 868 
 869 
 870 
 871 
 872 
 873 
 874 
 875 
 876 
 877 
 878 
 879 
 880 
 881 
 882 
 883 
 884 
 885 
 886 
 887 
 888 
 889 
 890 
 891 
 892 
 893 
 894 
 895 
 896 
 897 
 898 
 899 
 900 
 901 // IOM0
 902 
 903     "SET IOM0 CONFIG=IOM_BASE=Multics",
 904     "SET IOM0 CONFIG=MULTIPLEX_BASE=0120",
 905     "SET IOM0 CONFIG=OS=Multics",
 906     "SET IOM0 CONFIG=BOOT=tape",
 907     "SET IOM0 CONFIG=TAPECHAN=012",
 908     "SET IOM0 CONFIG=CARDCHAN=011",
 909     "SET IOM0 CONFIG=SCUPORT=0",
 910 
 911     "SET IOM0 CONFIG=PORT=0",
 912     "SET IOM0   CONFIG=ADDR=0",
 913     "SET IOM0   CONFIG=INTERLACE=0",
 914     "SET IOM0   CONFIG=ENABLE=1",
 915     "SET IOM0   CONFIG=INITENABLE=0",
 916     "SET IOM0   CONFIG=HALFSIZE=0",
 917     "SET IOM0   CONFIG=STORE_SIZE=4M",
 918 
 919     "SET IOM0 CONFIG=PORT=1",
 920     "SET IOM0   CONFIG=ADDR=1",
 921     "SET IOM0   CONFIG=INTERLACE=0",
 922     "SET IOM0   CONFIG=ENABLE=1",
 923     "SET IOM0   CONFIG=INITENABLE=0",
 924     "SET IOM0   CONFIG=HALFSIZE=0",
 925     "SET IOM0   CONFIG=STORE_SIZE=4M",
 926 
 927     "SET IOM0 CONFIG=PORT=2",
 928     "SET IOM0   CONFIG=ADDR=2",
 929     "SET IOM0   CONFIG=INTERLACE=0",
 930     "SET IOM0   CONFIG=ENABLE=1",
 931     "SET IOM0   CONFIG=INITENABLE=0",
 932     "SET IOM0   CONFIG=HALFSIZE=0",
 933     "SET IOM0   CONFIG=STORE_SIZE=4M",
 934 
 935     "SET IOM0 CONFIG=PORT=3",
 936     "SET IOM0   CONFIG=ADDR=3",
 937     "SET IOM0   CONFIG=INTERLACE=0",
 938     "SET IOM0   CONFIG=ENABLE=1",
 939     "SET IOM0   CONFIG=INITENABLE=0",
 940     "SET IOM0   CONFIG=HALFSIZE=0",
 941     "SET IOM0   CONFIG=STORE_SIZE=4M",
 942 
 943     "SET IOM0 CONFIG=PORT=4",
 944     "SET IOM0   CONFIG=ENABLE=0",
 945 
 946     "SET IOM0 CONFIG=PORT=5",
 947     "SET IOM0   CONFIG=ENABLE=0",
 948 
 949     "SET IOM0 CONFIG=PORT=6",
 950     "SET IOM0   CONFIG=ENABLE=0",
 951 
 952     "SET IOM0 CONFIG=PORT=7",
 953     "SET IOM0   CONFIG=ENABLE=0",
 954 
 955 // IOM1
 956 
 957     "SET IOM1 CONFIG=IOM_BASE=Multics2",
 958     "SET IOM1 CONFIG=MULTIPLEX_BASE=0121",
 959     "SET IOM1 CONFIG=OS=Multics",
 960     "SET IOM1 CONFIG=BOOT=tape",
 961     "SET IOM1 CONFIG=TAPECHAN=012",
 962     "SET IOM1 CONFIG=CARDCHAN=011",
 963     "SET IOM1 CONFIG=SCUPORT=0",
 964 
 965     "SET IOM1 CONFIG=PORT=0",
 966     "SET IOM1   CONFIG=ADDR=0",
 967     "SET IOM1   CONFIG=INTERLACE=0",
 968     "SET IOM1   CONFIG=ENABLE=1",
 969     "SET IOM1   CONFIG=INITENABLE=0",
 970     "SET IOM1   CONFIG=HALFSIZE=0",
 971 
 972     "SET IOM1 CONFIG=PORT=1",
 973     "SET IOM1   CONFIG=ADDR=1",
 974     "SET IOM1   CONFIG=INTERLACE=0",
 975     "SET IOM1   CONFIG=ENABLE=1",
 976     "SET IOM1   CONFIG=INITENABLE=0",
 977     "SET IOM1   CONFIG=HALFSIZE=0",
 978 
 979     "SET IOM1 CONFIG=PORT=2",
 980     "SET IOM1   CONFIG=ENABLE=0",
 981     "SET IOM1 CONFIG=PORT=3",
 982     "SET IOM1   CONFIG=ENABLE=0",
 983     "SET IOM1 CONFIG=PORT=4",
 984     "SET IOM1   CONFIG=ENABLE=0",
 985     "SET IOM1 CONFIG=PORT=5",
 986     "SET IOM1   CONFIG=ENABLE=0",
 987     "SET IOM1 CONFIG=PORT=6",
 988     "SET IOM1   CONFIG=ENABLE=0",
 989     "SET IOM1 CONFIG=PORT=7",
 990     "SET IOM1   CONFIG=ENABLE=0",
 991 
 992 
 993 
 994 
 995 
 996 
 997 
 998 
 999 
1000 
1001 
1002 
1003 
1004 
1005 
1006 
1007 
1008 
1009 
1010 
1011 
1012 
1013 
1014 
1015 
1016 
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1025 
1026 
1027 
1028 
1029 
1030 
1031 
1032 
1033 
1034 
1035 
1036 
1037 
1038 
1039 
1040 
1041 
1042 
1043 
1044 
1045 
1046 
1047 
1048 
1049 
1050 
1051 
1052 
1053 
1054 
1055 
1056 
1057 
1058 
1059 
1060 
1061 
1062 
1063 
1064 
1065 
1066 
1067 
1068 
1069 // SCU0
1070 
1071     "SET SCU0 CONFIG=MODE=program",
1072     "SET SCU0 CONFIG=PORT0=enable",
1073     "SET SCU0 CONFIG=PORT1=enable",
1074     "SET SCU0 CONFIG=PORT2=enable",
1075     "SET SCU0 CONFIG=PORT3=enable",
1076     "SET SCU0 CONFIG=PORT4=enable",
1077     "SET SCU0 CONFIG=PORT5=enable",
1078     "SET SCU0 CONFIG=PORT6=enable",
1079     "SET SCU0 CONFIG=PORT7=enable",
1080     "SET SCU0 CONFIG=MASKA=7",
1081     "SET SCU0 CONFIG=MASKB=off",
1082     "SET SCU0 CONFIG=LWRSTORESIZE=7",
1083     "SET SCU0 CONFIG=CYCLIC=0040",
1084     "SET SCU0 CONFIG=NEA=0200",
1085     "SET SCU0 CONFIG=ONL=014",
1086     "SET SCU0 CONFIG=INT=0",
1087     "SET SCU0 CONFIG=LWR=0",
1088 
1089 // SCU1
1090 
1091     "SET SCU1 CONFIG=MODE=program",
1092     "SET SCU1 CONFIG=PORT0=enable",
1093     "SET SCU1 CONFIG=PORT1=enable",
1094     "SET SCU1 CONFIG=PORT2=enable",
1095     "SET SCU1 CONFIG=PORT3=enable",
1096     "SET SCU1 CONFIG=PORT4=enable",
1097     "SET SCU1 CONFIG=PORT5=enable",
1098     "SET SCU1 CONFIG=PORT6=enable",
1099     "SET SCU1 CONFIG=PORT7=enable",
1100     "SET SCU1 CONFIG=MASKA=off",
1101     "SET SCU1 CONFIG=MASKB=off",
1102     "SET SCU1 CONFIG=LWRSTORESIZE=7",
1103     "SET SCU1 CONFIG=CYCLIC=0040",
1104     "SET SCU1 CONFIG=NEA=0200",
1105     "SET SCU1 CONFIG=ONL=014",
1106     "SET SCU1 CONFIG=INT=0",
1107     "SET SCU1 CONFIG=LWR=0",
1108 
1109 // SCU2
1110 
1111     "SET SCU2 CONFIG=MODE=program",
1112     "SET SCU2 CONFIG=PORT0=enable",
1113     "SET SCU2 CONFIG=PORT1=enable",
1114     "SET SCU2 CONFIG=PORT2=enable",
1115     "SET SCU2 CONFIG=PORT3=enable",
1116     "SET SCU2 CONFIG=PORT4=enable",
1117     "SET SCU2 CONFIG=PORT5=enable",
1118     "SET SCU2 CONFIG=PORT6=enable",
1119     "SET SCU2 CONFIG=PORT7=enable",
1120     "SET SCU2 CONFIG=MASKA=off",
1121     "SET SCU2 CONFIG=MASKB=off",
1122     "SET SCU2 CONFIG=LWRSTORESIZE=7",
1123     "SET SCU2 CONFIG=CYCLIC=0040",
1124     "SET SCU2 CONFIG=NEA=0200",
1125     "SET SCU2 CONFIG=ONL=014",
1126     "SET SCU2 CONFIG=INT=0",
1127     "SET SCU2 CONFIG=LWR=0",
1128 
1129 // SCU3
1130 
1131     "SET SCU3 CONFIG=MODE=program",
1132     "SET SCU3 CONFIG=PORT0=enable",
1133     "SET SCU3 CONFIG=PORT1=enable",
1134     "SET SCU3 CONFIG=PORT2=enable",
1135     "SET SCU3 CONFIG=PORT3=enable",
1136     "SET SCU3 CONFIG=PORT4=enable",
1137     "SET SCU3 CONFIG=PORT5=enable",
1138     "SET SCU3 CONFIG=PORT6=enable",
1139     "SET SCU3 CONFIG=PORT7=enable",
1140     "SET SCU3 CONFIG=MASKA=off",
1141     "SET SCU3 CONFIG=MASKB=off",
1142     "SET SCU3 CONFIG=LWRSTORESIZE=7",
1143     "SET SCU3 CONFIG=CYCLIC=0040",
1144     "SET SCU3 CONFIG=NEA=0200",
1145     "SET SCU3 CONFIG=ONL=014",
1146     "SET SCU3 CONFIG=INT=0",
1147     "SET SCU3 CONFIG=LWR=0",
1148 
1149 
1150 
1151 
1152 
1153 
1154 
1155 
1156 
1157 
1158 
1159 
1160 
1161 
1162 
1163 
1164 
1165 
1166 
1167 
1168 
1169 
1170 
1171 
1172 
1173 
1174 
1175 
1176 
1177 
1178 
1179 
1180 
1181 
1182 
1183 
1184 
1185 
1186 
1187 
1188 
1189 
1190 
1191 
1192 
1193 
1194 
1195 
1196 
1197 
1198 
1199 
1200 
1201 
1202 
1203 
1204 
1205 
1206 
1207 
1208 
1209 
1210 
1211 
1212 
1213 
1214 
1215 
1216 
1217 
1218 
1219 
1220 
1221 
1222 
1223 
1224 
1225 
1226 
1227 
1228 
1229 
1230 
1231     // ; DO NOT CHANGE THE CONFIGURATION OF THE FNP UNITS.
1232     // ; Restrictions in the FNP code that REQUIRE the simulator
1233     // ; unit numbers to be the same as the Multics unit numbers!
1234     // ; i.e. fnp0 == fnpa, etc.
1235     // ;
1236     // ; FNP a 3400
1237     // ; FNP b 3700
1238     // ; FNP c 4200
1239     // ; FNP d 4500
1240     // ; FNP e 5000
1241     // ; FNP f 5300
1242     // ; FNP g 5600
1243     // ; FNP h 6100
1244 
1245     "SET FNP0 CONFIG=MAILBOX=03400",
1246     "SET FNP0 IPC_NAME=fnp-a",
1247     "SET FNP1 CONFIG=MAILBOX=03700",
1248     "SET FNP1 IPC_NAME=fnp-b",
1249     "SET FNP2 CONFIG=MAILBOX=04200",
1250     "SET FNP2 IPC_NAME=fnp-c",
1251     "SET FNP3 CONFIG=MAILBOX=04500",
1252     "SET FNP3 IPC_NAME=fnp-d",
1253     "SET FNP4 CONFIG=MAILBOX=05000",
1254     "SET FNP4 IPC_NAME=fnp-e",
1255     "SET FNP5 CONFIG=MAILBOX=05300",
1256     "SET FNP5 IPC_NAME=fnp-f",
1257     "SET FNP6 CONFIG=MAILBOX=05600",
1258     "SET FNP6 IPC_NAME=fnp-g",
1259     "SET FNP7 CONFIG=MAILBOX=06100",
1260     "SET FNP7 IPC_NAME=fnp-h",
1261 
1262     //XXX"set mtp0 boot_drive=1",
1263     // ; Attach tape MPC to IOM 0, chan 012, dev_code 0
1264     "SET MTP0 BOOT_DRIVE=0",
1265     "SET MTP0 NAME=MTP0",
1266     // ; Attach TAPE unit 0 to IOM 0, chan 012, dev_code 1
1267     "CABLE IOM0 012 MTP0 0",
1268     "CABLE IOM1 012 MTP0 1",
1269     "CABLE MTP0 1 TAPE1",
1270     "SET TAPE1 NAME=tapa_01",
1271     "CABLE MTP0 2 TAPE2",
1272     "SET TAPE2 NAME=tapa_02",
1273     "CABLE MTP0 3 TAPE3",
1274     "SET TAPE3 NAME=tapa_03",
1275     "CABLE MTP0 4 TAPE4",
1276     "SET TAPE4 NAME=tapa_04",
1277     "CABLE MTP0 5 TAPE5",
1278     "SET TAPE5 NAME=tapa_05",
1279     "CABLE MTP0 6 TAPE6",
1280     "SET TAPE6 NAME=tapa_06",
1281     "CABLE MTP0 7 TAPE7",
1282     "SET TAPE7 NAME=tapa_07",
1283     "CABLE MTP0 8 TAPE8",
1284     "SET TAPE8 NAME=tapa_08",
1285     "CABLE MTP0 9 TAPE9",
1286     "SET TAPE9 NAME=tapa_09",
1287     "CABLE MTP0 10 TAPE10",
1288     "SET TAPE10 NAME=tapa_10",
1289     "CABLE MTP0 11 TAPE11",
1290     "SET TAPE11 NAME=tapa_11",
1291     "CABLE MTP0 12 TAPE12",
1292     "SET TAPE12 NAME=tapa_12",
1293     "CABLE MTP0 13 TAPE13",
1294     "SET TAPE13 NAME=tapa_13",
1295     "CABLE MTP0 14 TAPE14",
1296     "SET TAPE14 NAME=tapa_14",
1297     "CABLE MTP0 15 TAPE15",
1298     "SET TAPE15 NAME=tapa_15",
1299     "CABLE MTP0 16 TAPE16",
1300     "SET TAPE16 NAME=tapa_16",
1301 
1302 // 4 3381 disks
1303 
1304     "SET IPC0 NAME=IPC0",
1305     "CABLE IOM0 013 IPC0 0",
1306     "CABLE IOM1 013 IPC0 1",
1307     // ; Attach DISK unit 0 to IPC0 dev_code 0",
1308     "CABLE IPC0 0 DISK0",
1309     "SET DISK0 TYPE=3381",
1310     "SET DISK0 NAME=dska_00",
1311     // ; Attach DISK unit 1 to IPC0 dev_code 1",
1312     "cable IPC0 1 DISK1",
1313     "set disk1 type=3381",
1314     "set disk1 name=dska_01",
1315     // ; Attach DISK unit 2 to IPC0 dev_code 2",
1316     "CABLE IPC0 2 DISK2",
1317     "SET DISK2 TYPE=3381",
1318     "SET DISK2 NAME=dska_02",
1319     // ; Attach DISK unit 3 to IPC0 dev_code 3",
1320     "CABLE IPC0 3 DISK3",
1321     "SET DISK3 TYPE=3381",
1322     "SET DISK3 NAME=dska_03",
1323 
1324 // 4 d501 disks + 4 d451 disks + 2 d500 disks
1325     "SET MSP0 NAME=MSP0",
1326     "CABLE IOM0 014 MSP0 0",
1327     "CABLE IOM1 014 MSP0 1",
1328 
1329     // ; Attach DISK unit 4 to MSP0 dev_code 1",
1330     "CABLE MSP0 1 DISK4",
1331     "SET disk4 TYPE=d501",
1332     "SET disk4 NAME=dskb_01",
1333     // ; Attach DISK unit 5 to MSP0 dev_code 2",
1334     "CABLE MSP0 2 DISK5",
1335     "SET DISK5 TYPE=d501",
1336     "SET DISK5 NAME=dskb_02",
1337     // ; Attach DISK unit 6 to MSP0 dev_code 3",
1338     "CABLE MSP0 3 DISK6",
1339     "SET DISK6 TYPE=d501",
1340     "SET DISK6 NAME=dskb_03",
1341     // ; Attach DISK unit 7 to MSP0 dev_code 4",
1342     "CABLE MSP0 4 DISK7",
1343     "SET DISK7 TYPE=d501",
1344     "SET DISK7 NAME=dskb_04",
1345 
1346     // ; Attach DISK unit 8 to MSP0 dev_code 5",
1347     "CABLE MSP0 5 DISK8",
1348     "SET DISK8 TYPE=d451",
1349     "SET DISK8 NAME=dskb_05",
1350     // ; Attach DISK unit 9 to MSP0 dev_code 6",
1351     "CABLE MSP0 6 DISK9",
1352     "SET DISK9 TYPE=d451",
1353     "SET DISK9 NAME=dskb_06",
1354     // ; Attach DISK unit 10 to MSP0 dev_code 7",
1355     "CABLE MSP0 7 DISK10",
1356     "SET DISK10 TYPE=d451",
1357     "SET DISK10 NAME=dskb_07",
1358     // ; Attach DISK unit 11 to MSP0 dev_code 8",
1359     "CABLE MSP0 8 DISK11",
1360     "SET DISK11 TYPE=d451",
1361     "SET DISK11 NAME=dskb_08",
1362     // ; Attach DISK unit 12 to MSP0 dev_code 9",
1363     "CABLE MSP0 9 DISK12",
1364     "SET DISK12 TYPE=d500",
1365     "SET DISK12 NAME=dskb_09",
1366     // ; Attach DISK unit 13 to MSP0 dev_code 10",
1367     "CABLE MSP0 10 DISK13",
1368     "SET DISK13 TYPE=d500",
1369     "SET DISK13 NAME=dskb_10",
1370 
1371     // since we define 16 (decimal) 3381s in the default config deck, we need to add another 12
1372     // ; Attach DISK unit 14 to IPC0 dev_code 4",
1373     "CABLE IPC0 4 DISK14",
1374     "SET DISK14 TYPE=3381",
1375     "SET DISK14 NAME=dska_04",
1376     // ; Attach DISK unit 15 to IPC0 dev_code 5",
1377     "CABLE IPC0 5 DISK15",
1378     "SET DISK15 TYPE=3381",
1379     "SET DISK15 NAME=dska_05",
1380     // ; Attach DISK unit 16 to IPC0 dev_code 6",
1381     "CABLE IPC0 6 DISK16",
1382     "SET DISK16 TYPE=3381",
1383     "SET DISK16 NAME=dska_06",
1384     // ; Attach DISK unit 17 to IPC0 dev_code 7",
1385     "CABLE IPC0 7 DISK17",
1386     "SET DISK17 TYPE=3381",
1387     "SET DISK17 NAME=dska_07",
1388     // ; Attach DISK unit 18 to IPC0 dev_code 8",
1389     "CABLE IPC0 8 DISK18",
1390     "SET DISK18 TYPE=3381",
1391     "SET DISK18 NAME=dska_08",
1392     // ; Attach DISK unit 19 to IPC0 dev_code 9",
1393     "CABLE IPC0 9 DISK19",
1394     "SET DISK19 TYPE=3381",
1395     "SET DISK19 NAME=dska_09",
1396     // ; Attach DISK unit 20 to IPC0 dev_code 10",
1397     "CABLE IPC0 10 DISK20",
1398     "SET DISK20 TYPE=3381",
1399     "SET DISK20 NAME=dska_10",
1400     // ; Attach DISK unit 21 to IPC0 dev_code 11",
1401     "CABLE IPC0 11 DISK21",
1402     "SET DISK21 TYPE=3381",
1403     "SET DISK21 NAME=dska_11",
1404     // ; Attach DISK unit 22 to IPC0 dev_code 12",
1405     "CABLE IPC0 12 DISK22",
1406     "SET DISK22 TYPE=3381",
1407     "SET DISK22 NAME=dska_12",
1408     // ; Attach DISK unit 23 to IPC0 dev_code 13",
1409     "CABLE IPC0 13 DISK23",
1410     "SET DISK23 TYPE=3381",
1411     "SET DISK23 NAME=dska_13",
1412     // ; Attach DISK unit 24 to IPC0 dev_code 14",
1413     "CABLE IPC0 14 DISK24",
1414     "SET DISK24 TYPE=3381",
1415     "SET DISK24 NAME=dska_14",
1416     // ; Attach DISK unit 25 to IPC0 dev_code 15",
1417     "CABLE IPC0 15 DISK25",
1418     "SET DISK25 TYPE=3381",
1419     "SET DISK25 NAME=dska_15",
1420 
1421     // ; Attach OPC unit 0 to IOM A, chan 036, dev_code 0
1422     "CABLE IOMA 036 OPC0",
1423     // ; Attach OPC unit 1 to IOM A, chan 053, dev_code 0
1424     "CABLE IOMA 053 OPC1",
1425     "SET OPC1 CONFIG=MODEL=m6601",
1426     // No "devices" for console, so no 'CABLE OPC0 # CONx', etc.
1427 
1428     // ;;;
1429     // ;;; FNP
1430     // ;;;
1431 
1432     // ; Attach FNP unit 3 (d) to IOM A, chan 020, dev_code 0
1433     "CABLE IOMA 020 FNPD",
1434     // ; Attach FNP unit 0 (a) to IOM A, chan 021, dev_code 0
1435     "CABLE IOMA 021 FNPA",
1436     // ; Attach FNP unit 1 (b) to IOM A, chan 022, dev_code 0
1437     "CABLE IOMA 022 FNPB",
1438     // ; Attach FNP unit 2 (c) to IOM A, chan 023, dev_code 0
1439     "CABLE IOMA 023 FNPC",
1440     // ; Attach FNP unit 4 (e) to IOM A, chan 024, dev_code 0
1441     "CABLE IOMA 024 FNPE",
1442     // ; Attach FNP unit 5 (f) to IOM A, chan 025, dev_code 0
1443     "CABLE IOMA 025 FNPF",
1444     // ; Attach FNP unit 6 (g) to IOM A, chan 026, dev_code 0
1445     "CABLE IOMA 026 FNPG",
1446     // ; Attach FNP unit 7 (h) to IOM A, chan 027, dev_code 0
1447     "CABLE IOMA 027 FNPH",
1448 
1449     // ;;;
1450     // ;;; MPC
1451     // ;;;
1452 
1453     // ; Attach MPC unit 0 to IOM 0, char 015, dev_code 0
1454     "CABLE IOM0 015 URP0",
1455     "SET URP0 NAME=urpa",
1456 
1457     // ; Attach RDR unit 0 to IOM 0, chan 015, dev_code 1
1458     "CABLE URP0 1 RDR0",
1459     "SET RDR0 NAME=rdra",
1460 
1461     // ; Attach MPC unit 1 to IOM 0, char 016, dev_code 0
1462     "CABLE IOM0 016 URP1",
1463     "SET URP1 NAME=urpb",
1464 
1465     // ; Attach PUN unit 0 to IOM 0, chan 016, dev_code 1
1466     "CABLE URP1 1 PUN0",
1467     "SET PUN0 NAME=puna",
1468 
1469     // ; Attach MPC unit 2 to IOM 0, char 017, dev_code 0
1470     "CABLE IOM0 017 URP2",
1471     "SET URP2 NAME=urpc",
1472 
1473     // ; Attach PRT unit 0 to IOM 0, chan 017, dev_code 1
1474     "CABLE URP2 1 PRT0",
1475     "SET PRT0 NAME=prta",
1476 //    "SET PRT0 MODEL=1600",    // Needs polts fixes
1477 
1478     // ; Attach MPC unit 3 to IOM 0, char 050, dev_code 0
1479     "CABLE IOMA 050 URP3",
1480     "SET URP3 NAME=urpd",
1481 
1482     // ; Attach PRT unit 1 to IOM 0, chan 050, dev_code 1
1483     "CABLE URP3 1 PRT1",
1484     "SET PRT1 NAME=prtb",
1485 //    "SET PRT1 MODEL=303",    // Needs polts fixes
1486 
1487     // ; Attach MPC unit 4 to IOM 0, char 051, dev_code 0
1488     "CABLE IOMA 051 URP4",
1489     "SET URP4 NAME=urpe",
1490 
1491     // ; Attach PRT unit 2 to IOM 0, chan 051, dev_code 1
1492     "CABLE URP4 1 PRT2",
1493     "SET PRT2 NAME=prtc",
1494 //    "SET PRT2 MODEL=300",    // Needs polts fixes
1495 
1496     // ; Attach MPC unit 5 to IOM 0, chan 052, dev_code 0
1497     "CABLE IOMA 052 URP5",
1498     "SET URP5 NAME=urpf",
1499 
1500     // ; Attach PRT unit 3 to IOM 0, chan 052, dev_code 1
1501     "CABLE URP5 1 PRT3",
1502     "SET PRT3 NAME=prtd",
1503 //    "SET PRT3 MODEL=202",    // Needs polts fixes
1504 
1505     // ; Attach MPC unit 6 to IOM 0, chan 055, dev_code 0
1506     "CABLE IOMA 055 URP6",
1507     "SET URP6 NAME=urpg",
1508 
1509     // ; Attach RDR unit 1 to IOM 0, chan 055, dev_code 1
1510     "CABLE URP6 1 RDRB",
1511     "SET RDR1 NAME=rdrb",
1512 
1513     // ; Attach MPC unit 7 to IOM 0, chan 056, dev_code 0
1514     "CABLE IOMA 056 URP7",
1515     "SET URP7 NAME=urph",
1516 
1517     // ; Attach RDR unit 2 to IOM 0, chan 056, dev_code 1
1518     "CABLE URP7 1 RDRC",
1519     "SET RDR2 NAME=rdrc",
1520 
1521     // ; Attach MPC unit 8 to IOM 0, chan 057, dev_code 0
1522     "CABLE IOMA 057 URP8",
1523     "SET URP8 NAME=urpi",
1524 
1525     // ; Attach PUN unit 1 to IOM 0, chan 057, dev_code 1
1526     "CABLE URP8 1 PUNB",
1527     "SET PUN1 NAME=punb",
1528 
1529     // ; Attach MPC unit 9 to IOM 0, chan 060, dev_code 0
1530     "CABLE IOMA 060 URP9",
1531     "SET URP9 NAME=urpj",
1532 
1533     // ; Attach PUN unit 2 to IOM 0, chan 060, dev_code 1
1534     "CABLE URP9 1 PUNC",
1535     "SET PUN2 NAME=punc",
1536 
1537 # ifdef WITH_SOCKET_DEV
1538 #  ifndef __MINGW64__
1539 #   ifndef __MINGW32__
1540 #    ifndef CROSS_MINGW32
1541 #     ifndef CROSS_MINGW64
1542     "CABLE IOMA 040 SKCA",
1543     "CABLE IOMA 041 SKCB",
1544     "CABLE IOMA 042 SKCC",
1545     "CABLE IOMA 043 SKCD",
1546     "CABLE IOMA 044 SKCE",
1547     "CABLE IOMA 045 SKCF",
1548     "CABLE IOMA 046 SKCG",
1549     "CABLE IOMA 047 SKCH",
1550 #     endif /* ifndef CROSS_MINGW64 */
1551 #    endif /* ifndef CROSS_MINGW32 */
1552 #   endif /* ifndef __MINGW32__ */
1553 #  endif /* ifndef __MINGW64__ */
1554 # endif /* ifdef WITH_SOCKET_DEV */
1555 
1556 
1557 
1558 
1559 
1560 
1561 
1562 
1563 
1564 
1565 
1566 
1567 
1568 
1569 
1570 
1571 
1572 
1573 
1574 
1575 
1576 
1577 
1578 
1579 
1580 
1581 
1582 
1583 
1584 
1585 
1586 
1587 
1588 
1589 
1590 
1591 
1592 
1593 
1594 
1595 
1596 
1597 
1598 
1599 
1600 
1601 
1602 
1603 
1604 
1605 
1606 
1607 
1608 
1609 
1610 
1611 
1612 
1613 
1614 
1615 
1616 
1617 
1618 
1619 
1620 # ifdef WITH_ABSI_DEV
1621 #  ifndef __MINGW64__
1622 #   ifndef __MINGW32__
1623 #    ifndef CROSS_MINGW64
1624 #     ifndef CROSS_MINGW32
1625     // ; Attach ABSI unit 0 to IOM 0, chan 032, dev_code 0
1626     "CABLE IOM0 032 ABSI0",
1627 #     endif /* CROSS_MINGW32 */
1628 #    endif /* CROSS_MINGW64 */
1629 #   endif /* __MINGW32__ */
1630 #  endif /* __MINGW64__ */
1631 # endif /* ifdef WITH_ABSI_DEV */
1632 
1633     // ; Attach IOM unit 0 port A (0) to SCU unit 0, port 0
1634     "CABLE SCU0 0 IOM0 0", // SCU0 port 0 IOM0 port 0
1635 
1636     // ; Attach IOM unit 0 port B (1) to SCU unit 1, port 0
1637     "CABLE SCU1 0 IOM0 1", // SCU1 port 0 IOM0 port 1
1638 
1639     // ; Attach IOM unit 0 port C (2) to SCU unit 2, port 0
1640     "CABLE SCU2 0 IOM0 2", // SCU2 port 0 IOM0 port 2
1641 
1642     // ; Attach IOM unit 0 port D (3) to SCU unit 3, port 0
1643     "CABLE SCU3 0 IOM0 3", // SCU3 port 0 IOM0 port 3
1644 
1645     // ; Attach IOM unit 1 port A (0) to SCU unit 0, port 1
1646     "CABLE SCU0 1 IOM1 0", // SCU0 port 0 IOM0 port 0
1647 
1648     // ; Attach IOM unit 1 port B (1) to SCU unit 1, port 1
1649     "CABLE SCU1 1 IOM1 1", // SCU1 port 0 IOM0 port 1
1650 
1651     // ; Attach IOM unit 1 port C (2) to SCU unit 2, port 1
1652     "CABLE SCU2 1 IOM1 2", // SCU2 port 0 IOM0 port 2
1653 
1654     // ; Attach IOM unit 1 port D (3) to SCU unit 3, port 1
1655     "CABLE SCU3 1 IOM1 3", // SCU3 port 0 IOM0 port 3
1656 
1657 // SCU0 --> CPU0-5
1658 
1659     // ; Attach SCU unit 0 port 7 to CPU unit A (1), port 0
1660     "CABLE SCU0 7 CPU0 0",
1661 
1662     // ; Attach SCU unit 0 port 6 to CPU unit B (1), port 0
1663     "CABLE SCU0 6 CPU1 0",
1664 
1665     // ; Attach SCU unit 0 port 5 to CPU unit C (2), port 0
1666     "CABLE SCU0 5 CPU2 0",
1667 
1668     // ; Attach SCU unit 0 port 4 to CPU unit D (3), port 0
1669     "CABLE SCU0 4 CPU3 0",
1670 
1671     // ; Attach SCU unit 0 port 3 to CPU unit E (4), port 0
1672     "CABLE SCU0 3 CPU4 0",
1673 
1674     // ; Attach SCU unit 0 port 2 to CPU unit F (5), port 0
1675     "CABLE SCU0 2 CPU5 0",
1676 
1677 // SCU1 --> CPU0-5
1678 
1679     // ; Attach SCU unit 1 port 7 to CPU unit A (1), port 1
1680     "CABLE SCU1 7 CPU0 1",
1681 
1682     // ; Attach SCU unit 1 port 6 to CPU unit B (1), port 1
1683     "CABLE SCU1 6 CPU1 1",
1684 
1685     // ; Attach SCU unit 1 port 5 to CPU unit C (2), port 1
1686     "CABLE SCU1 5 CPU2 1",
1687 
1688     // ; Attach SCU unit 1 port 4 to CPU unit D (3), port 1
1689     "CABLE SCU1 4 CPU3 1",
1690 
1691     // ; Attach SCU unit 1 port 3 to CPU unit E (4), port 0
1692     "CABLE SCU1 3 CPU4 1",
1693 
1694     // ; Attach SCU unit 1 port 2 to CPU unit F (5), port 0
1695     "CABLE SCU1 2 CPU5 1",
1696 
1697 // SCU2 --> CPU0-5
1698 
1699     // ; Attach SCU unit 2 port 7 to CPU unit A (1), port 2
1700     "CABLE SCU2 7 CPU0 2",
1701 
1702     // ; Attach SCU unit 2 port 6 to CPU unit B (1), port 2
1703     "CABLE SCU2 6 CPU1 2",
1704 
1705     // ; Attach SCU unit 2 port 5 to CPU unit C (2), port 2
1706     "CABLE SCU2 5 CPU2 2",
1707 
1708     // ; Attach SCU unit 2 port 4 to CPU unit D (3), port 2
1709     "CABLE SCU2 4 CPU3 2",
1710 
1711     // ; Attach SCU unit 2 port 3 to CPU unit E (4), port 0
1712     "CABLE SCU2 3 CPU4 2",
1713 
1714     // ; Attach SCU unit 2 port 2 to CPU unit F (5), port 0
1715     "CABLE SCU2 2 CPU5 2",
1716 
1717 // SCU3 --> CPU0-5
1718 
1719     // ; Attach SCU unit 3 port 7 to CPU unit A (1), port 3
1720     "CABLE SCU3 7 CPU0 3",
1721 
1722     // ; Attach SCU unit 3 port 6 to CPU unit B (1), port 3
1723     "CABLE SCU3 6 CPU1 3",
1724 
1725     // ; Attach SCU unit 3 port 5 to CPU unit C (2), port 3
1726     "CABLE SCU3 5 CPU2 3",
1727 
1728     // ; Attach SCU unit 3 port 4 to CPU unit D (3), port 3
1729     "CABLE SCU3 4 CPU3 3",
1730 
1731     // ; Attach SCU unit 3 port 3 to CPU unit E (4), port 0
1732     "CABLE SCU3 3 CPU4 3",
1733 
1734     // ; Attach SCU unit 3 port 2 to CPU unit F (5), port 0
1735     "CABLE SCU3 2 CPU5 3",
1736 
1737     "SET CPU0 RESET",
1738     "SET SCU0 RESET",
1739     "SET SCU1 RESET",
1740     "SET SCU2 RESET",
1741     "SET SCU3 RESET",
1742     "SET IOM0 RESET",
1743 
1744 # if defined(THREADZ) || defined(LOCKLESS)
1745     "SET CPU NUNITS=6",
1746 # else
1747 #  ifdef ROUND_ROBIN
1748     "SET CPU NUNITS=6",
1749 #  else
1750     "SET CPU NUNITS=1",
1751 #  endif
1752 # endif // THREADZ
1753     // "SET SYS CONFIG=ACTIVATE_TIME=8",
1754     // "SET SYS CONFIG=TERMINATE_TIME=8",
1755     "SET SYS CONFIG=CONNECT_TIME=-1",
1756   }; // default_base_system_script
1757 
1758 void print_default_base_system_script (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1759   {
1760     int n_lines = sizeof (default_base_system_script) / sizeof (char *);
1761     sim_printf ("; DEFAULT_BASE_SYSTEM_SCRIPT (%lu lines follow)\n",
1762             (unsigned long)n_lines);
1763     for (int line = 0; line < n_lines; line ++)
1764     sim_printf ("%s\n", default_base_system_script[line]);
1765   }
1766 
1767 // Execute a line of script
1768 
1769 static void do_ini_line (char * text)
     /* [previous][next][first][last][top][bottom][index][help] */
1770   {
1771     //sim_msg ("<%s?\n", text);
1772     char gbuf[257];
1773     const char * cptr = get_glyph (text, gbuf, 0); /* get command glyph */
1774     CTAB *cmdp;
1775     if ((cmdp = find_cmd (gbuf)))            /* lookup command */
1776       {
1777         t_stat stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */
1778         if (stat != SCPE_OK)
1779           sim_warn ("%s: %s\n", sim_error_text (SCPE_UNK), text);
1780       }
1781     else
1782       sim_warn ("%s: %s\n", sim_error_text (SCPE_UNK), text);
1783   }
1784 
1785 // Execute the base system script; this strings the cables
1786 // and sets the switches
1787 
1788 static t_stat set_default_base_system (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1789   {
1790 # ifdef PERF_STRIP
1791     cpu_dev.numunits = 1;
1792 # else
1793     int n_lines = sizeof (default_base_system_script) / sizeof (char *);
1794     for (int line = 0; line < n_lines; line ++)
1795       do_ini_line (default_base_system_script [line]);
1796 # endif
1797     return SCPE_OK;
1798   }
1799 
1800 // Skip records on the boot tape.
1801 // The T&D tape first record is for testing DPS8s, the
1802 // second record (1st record / tape mark / 2nd record)
1803 // is for testing DPS8/Ms.
1804 // XXX assumes the boot tape is on tape unit 0
1805 
1806 static t_stat boot_skip (int32 UNUSED arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1807   {
1808     uint32 skipped;
1809     t_stat rc = sim_tape_sprecsf (& mt_unit[0], 1, & skipped);
1810     if (rc == SCPE_OK)
1811       tape_states[0].rec_num ++;
1812     return rc;
1813   }
1814 
1815 // Simulate pressing the 'EXECUTE FAULT' button. Used as an
1816 // emergency interrupt of Multics if it hangs and becomes
1817 // unresponsive to the operators console.
1818 
1819 static t_stat do_execute_fault (UNUSED int32 arg,  UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1820   {
1821     // Assume bootload CPU
1822     setG7fault (0, FAULT_EXF, fst_zero);
1823     return SCPE_OK;
1824   }
1825 
1826 // Simulate pressing the 'XED 10000' sequence; this starts BCE
1827 //
1828 //  sim> restart
1829 //  sim> go
1830 
1831 static t_stat do_restart (UNUSED int32 arg,  UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1832   {
1833     if (sim_is_running)
1834       {
1835         sim_printf ("Don't restart a running system....\r\n");
1836         return SCPE_ARG;
1837       }
1838     int n = 010000; //-V536
1839     if (buf)
1840       {
1841         n = (int) strtol (buf, NULL, 0);
1842       }
1843     sim_printf ("Restart entry 0%o\n", n);
1844 
1845 
1846 
1847 
1848 
1849 
1850 
1851 
1852 
1853 
1854 
1855 
1856 
1857     cpu_reset_unit_idx (0, false);
1858     cpu.restart         = true;
1859     cpu.restart_address = (uint) n;
1860 
1861     t_stat rc = run_cmd (RU_CONT, "");
1862     return rc;
1863   }
1864 
1865 static t_stat set_sys_polling_interval (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1866   {
1867     if (! buf)
1868       return SCPE_ARG;
1869     int n = atoi (buf);
1870     if (n < 1 || n > 1000) // 1 millisecond to 1 second
1871       {
1872         sim_printf ("POLL %d: must be 1 (1 millisecond) to 1000 (1 second)\r\n", n);
1873         return SCPE_ARG;
1874       }
1875     sim_printf ("Polling set to %d milliseconds\r\n", n);
1876     sys_opts.sys_poll_interval = (uint) n;
1877     return SCPE_OK;
1878   }
1879 
1880 static t_stat set_sys_slow_polling_interval (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1881   {
1882     if (! buf)
1883       return SCPE_ARG;
1884     int n = atoi (buf);
1885     if (n < 1 || n > 1000) // 1 - slow poll every pool; 1000 - slow poll every 1000 polls
1886       {
1887         sim_printf ("SLOWPOLL %d: must be 1 (1 slow poll per pol) to 1000 (1 slow poll per 1000 polls)\r\n", n);
1888         return SCPE_ARG;
1889       }
1890     sim_printf ("Slow polling set to %d polls\r\n", n);
1891     sys_opts.sys_slow_poll_interval = (uint) n;
1892     return SCPE_OK;
1893   }
1894 
1895 static t_stat set_sys_poll_check_rate (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1896   {
1897     if (! buf)
1898       return SCPE_ARG;
1899     int n = atoi (buf);
1900     if (n < 1 || n > 1024*1024) // 1 - poll check rate in CPY cycles: 1 - check every cycle; 1024 check every 1024 cycles
1901       {
1902         sim_printf ("CHECKPOLL %d: must be 1 (check every cycle) to 1048576 (check every million cycles\r\n", n);
1903         return SCPE_ARG;
1904       }
1905     sim_printf ("Poll check rate set to %d CPU cycles\r\n", n);
1906     sys_opts.sys_poll_check_rate = (uint) n;
1907     return SCPE_OK;
1908   }
1909 #endif /* ifndef PERF_STRIP */
1910 
1911 //
1912 // Debugging commands
1913 //
1914 
1915 #ifdef TESTING
1916 
1917 // Filter settings for our customized sim_debug
1918 
1919 // Start debug output at CPU cycle N.
1920 uint64 sim_deb_start      = 0;
1921 // Stop debug output at CPU cycle N.
1922 uint64 sim_deb_stop       = 0;
1923 // Break to scp prompt at CPU cycle N.
1924 uint64 sim_deb_break      = 0;
1925 // Enable CPU sim_debug iff PPR.PSR == N
1926 bool sim_deb_segno_on     = false;
1927 # ifdef NO_C_ELLIPSIS
1928 bool sim_deb_segno[DEBUG_SEGNO_LIMIT];
1929 # else
1930 bool sim_deb_segno[DEBUG_SEGNO_LIMIT] = { [0 ... DEBUG_SEGNO_LIMIT - 1] = false };
1931 # endif
1932 // Enable CPU sim_debug iff PPR.PRR == N
1933 uint64 sim_deb_ringno     = NO_SUCH_RINGNO;
1934 // Suppress CPU sim_debug calls that pass all
1935 // of the filters after N times
1936 uint64 sim_deb_skip_limit = 0;
1937 // Suppress the first N CPU sim_debug calls
1938 // that pass all of the filters
1939 uint64 sim_deb_skip_cnt   = 0;
1940 // Suppress sim_debug until the MME instruction
1941 // has been executed N times
1942 uint64 sim_deb_mme_cntdwn = 0;
1943 // Suppress CPU sim_debug unless CPU number bit set
1944 uint dbgCPUMask           = 0377; // default all 8 on
1945 
1946 // Suppress CPU sim_debug unless BAR mode
1947 bool sim_deb_bar          = false;
1948 
1949 // Set the various filters
1950 
1951 static t_stat dps_debug_mme_cntdwn (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1952   {
1953     sim_deb_mme_cntdwn = strtoull (buf, NULL, 0);
1954     sim_msg ("Debug MME countdown set to %llu\n", (long long unsigned int)sim_deb_mme_cntdwn);
1955     return SCPE_OK;
1956   }
1957 
1958 static t_stat dps_debug_skip (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1959   {
1960     sim_deb_skip_cnt   = 0;
1961     sim_deb_skip_limit = strtoull (buf, NULL, 0);
1962     sim_msg ("Debug skip set to %llu\n", (long long unsigned int)sim_deb_skip_limit);
1963     return SCPE_OK;
1964   }
1965 
1966 static t_stat dps_debug_start (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1967   {
1968     sim_deb_start = strtoull (buf, NULL, 0);
1969     sim_msg ("Debug set to start at cycle: %llu\n", (long long unsigned int)sim_deb_start);
1970     return SCPE_OK;
1971   }
1972 
1973 static t_stat dps_debug_stop (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1974   {
1975     sim_deb_stop = strtoull (buf, NULL, 0);
1976     sim_msg ("Debug set to stop at cycle: %llu\n", (long long unsigned int)sim_deb_stop);
1977     return SCPE_OK;
1978   }
1979 
1980 static t_stat dps_debug_break (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1981   {
1982     sim_deb_break = strtoull (buf, NULL, 0);
1983     if (buf[0] == '+')
1984       sim_deb_break += sim_deb_start;
1985     sim_msg ("Debug set to break at cycle: %llu\n", (long long unsigned int)sim_deb_break);
1986     return SCPE_OK;
1987   }
1988 
1989 static t_stat dps_debug_segno (int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
1990   {
1991     if (arg)
1992       {
1993         unsigned long segno = strtoul (buf, NULL, 0);
1994         if (segno >= DEBUG_SEGNO_LIMIT)
1995           {
1996             sim_printf ("out of range; 0 to %u %d.\n", DEBUG_SEGNO_LIMIT, DEBUG_SEGNO_LIMIT);
1997             return SCPE_ARG;
1998           }
1999         sim_deb_segno[segno] = true;
2000         sim_deb_segno_on     = true;
2001         sim_msg ("Debug set for segno %llo %llu.\n",
2002                 (long long unsigned int)segno, (long long unsigned int) segno);
2003       }
2004     else
2005       {
2006         memset (sim_deb_segno, 0, sizeof (sim_deb_segno));
2007         sim_deb_segno_on = false;
2008         sim_msg ("Debug set for all segments\n");
2009       }
2010     return SCPE_OK;
2011   }
2012 
2013 static t_stat dps_debug_ringno (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
2014   {
2015     sim_deb_ringno = strtoull (buf, NULL, 0);
2016     sim_msg ("Debug set to ringno %llo\n", (long long unsigned int)sim_deb_ringno);
2017     return SCPE_OK;
2018   }
2019 
2020 static t_stat dps_debug_bar (int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
2021   {
2022     sim_deb_bar = arg;
2023     if (arg)
2024       sim_msg ("Debug set BAR %llo\n", (long long unsigned int)sim_deb_ringno);
2025     else
2026       sim_msg ("Debug unset BAR %llo\n", (long long unsigned int)sim_deb_ringno);
2027     return SCPE_OK;
2028   }
2029 
2030 
2031 
2032 
2033 
2034 
2035 
2036 
2037 
2038 
2039 
2040 
2041 
2042 
2043 
2044 
2045 
2046 
2047 
2048 
2049 
2050 
2051 
2052 
2053 
2054 
2055 
2056 
2057 
2058 
2059 
2060 
2061 
2062 
2063 
2064 
2065 
2066 
2067 
2068 
2069 
2070 
2071 
2072 
2073 
2074 
2075 
2076 
2077 
2078 
2079 
2080 
2081 
2082 
2083 
2084 
2085 
2086 
2087 
2088 
2089 
2090 
2091 
2092 
2093 
2094 
2095 
2096 
2097 
2098 
2099 
2100 
2101 
2102 
2103 
2104 
2105 
2106 
2107 
2108 
2109 
2110 
2111 
2112 
2113 
2114 
2115 
2116 
2117 
2118 
2119 
2120 
2121 
2122 
2123 
2124 
2125 
2126 
2127 
2128 
2129 
2130 
2131 
2132 
2133 
2134 
2135 
2136 
2137 
2138 
2139 
2140 
2141 
2142 
2143 
2144 
2145 
2146 
2147 
2148 
2149 
2150 
2151 
2152 
2153 
2154 
2155 
2156 
2157 
2158 
2159 
2160 
2161 
2162 
2163 
2164 
2165 
2166 
2167 
2168 
2169 
2170 
2171 
2172 
2173 
2174 
2175 
2176 
2177 
2178 
2179 
2180 
2181 
2182 
2183 
2184 
2185 
2186 
2187 
2188 
2189 
2190 
2191 
2192 
2193 
2194 
2195 
2196 
2197 
2198 
2199 
2200 
2201 
2202 
2203 
2204 
2205 
2206 
2207 
2208 
2209 
2210 
2211 
2212 
2213 
2214 
2215 
2216 
2217 
2218 
2219 
2220 
2221 
2222 
2223 
2224 
2225 
2226 
2227 
2228 
2229 
2230 
2231 
2232 
2233 
2234 
2235 
2236 
2237 
2238 
2239 
2240 // Translate seg:offset to absolute address
2241 
2242 static t_stat abs_addr_n (int segno, uint offset)
     /* [previous][next][first][last][top][bottom][index][help] */
2243   {
2244     word24 res;
2245 
2246     //t_stat rc = computeAbsAddrN (& res, segno, offset);
2247     if (dbgLookupAddress ((word18) segno, offset, & res, NULL))
2248       return SCPE_ARG;
2249 
2250     sim_msg ("Address is %08o\n", res);
2251     return SCPE_OK;
2252   }
2253 
2254 // ABS segno:offset
2255 // scp command to translate segno:offset to absolute address
2256 
2257 static t_stat abs_addr (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
2258   {
2259     uint segno;
2260     uint offset;
2261     if (sscanf (buf, "%o:%o", & segno, & offset) != 2)
2262       return SCPE_ARG;
2263     return abs_addr_n ((int) segno, offset);
2264   }
2265 
2266 // LOAD_SYSTEM_BOOK <filename>
2267 
2268 // Read a system_book segment, extracting segment names and numbers
2269 // and component names, offsets, and lengths
2270 
2271 # define BOOT_SEGMENTS_MAX 1024
2272 # define BOOT_COMPONENTS_MAX 4096
2273 # define BOOK_SEGMENT_NAME_LEN 33
2274 
2275 static struct book_segment
2276   {
2277     char * segname;
2278     int  segno;
2279   } book_segments[BOOT_SEGMENTS_MAX];
2280 
2281 static int n_book_segments = 0;
2282 
2283 static struct book_component
2284   {
2285     char * compname;
2286     int  book_segment_number;
2287     uint txt_start, txt_length;
2288     int  intstat_start, intstat_length, symbol_start, symbol_length;
2289   } book_components[BOOT_COMPONENTS_MAX];
2290 
2291 static int n_book_components = 0;
2292 
2293 static int lookup_book_segment (char * name)
     /* [previous][next][first][last][top][bottom][index][help] */
2294   {
2295     for (int i = 0; i < n_book_segments; i ++)
2296       if (strcmp (name, book_segments[i].segname) == 0)
2297         return i;
2298     return -1;
2299   }
2300 
2301 static int add_book_segment (char * name, int segno)
     /* [previous][next][first][last][top][bottom][index][help] */
2302   {
2303     int n = lookup_book_segment (name);
2304     if (n >= 0)
2305       return n;
2306     if (n_book_segments >= BOOT_SEGMENTS_MAX)
2307       return -1;
2308     book_segments[n_book_segments].segname = strdup (name);
2309     if (!book_segments[n_book_segments].segname)
2310       {
2311         fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
2312                  __func__, __FILE__, __LINE__);
2313 # if defined(USE_BACKTRACE)
2314 #  ifdef SIGUSR2
2315         (void)raise(SIGUSR2);
2316         /*NOTREACHED*/ /* unreachable */
2317 #  endif /* ifdef SIGUSR2 */
2318 # endif /* if defined(USE_BACKTRACE) */
2319         abort();
2320       }
2321     book_segments[n_book_segments].segno   = segno;
2322     n = n_book_segments;
2323     n_book_segments ++;
2324     return n;
2325   }
2326 
2327 static int add_book_component (int segnum, char * name, uint txt_start,
     /* [previous][next][first][last][top][bottom][index][help] */
2328                                uint txt_length, int intstat_start,
2329                                int intstat_length, int symbol_start,
2330                                int symbol_length)
2331   {
2332     if (n_book_components >= BOOT_COMPONENTS_MAX)
2333       return -1;
2334     book_components[n_book_components].compname            = strdup (name);
2335     if (!book_components[n_book_components].compname)
2336       {
2337         fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
2338                  __func__, __FILE__, __LINE__);
2339 # if defined(USE_BACKTRACE)
2340 #  ifdef SIGUSR2
2341         (void)raise(SIGUSR2);
2342         /*NOTREACHED*/ /* unreachable */
2343 #  endif /* ifdef SIGUSR2 */
2344 # endif /* if defined(USE_BACKTRACE) */
2345         abort();
2346       }
2347     book_components[n_book_components].book_segment_number = segnum;
2348     book_components[n_book_components].txt_start           = txt_start;
2349     book_components[n_book_components].txt_length          = txt_length;
2350     book_components[n_book_components].intstat_start       = intstat_start;
2351     book_components[n_book_components].intstat_length      = intstat_length;
2352     book_components[n_book_components].symbol_start        = symbol_start;
2353     book_components[n_book_components].symbol_length       = symbol_length;
2354     int n = n_book_components;
2355     n_book_components ++;
2356     return n;
2357   }
2358 
2359 // Given a segno:offset, try to translate to
2360 // component name and offset in the component
2361 
2362 // Warning: returns ptr to static buffer
2363 static char * lookup_system_book_address (word18 segno, word18 offset,
     /* [previous][next][first][last][top][bottom][index][help] */
2364                                          char * * compname, word18 * compoffset)
2365   {
2366     static char buf[129];
2367     int i;
2368 
2369     for (i = 0; i < n_book_segments; i ++)
2370       if (book_segments[i].segno == (int) segno)
2371         break;
2372 
2373     if (i >= n_book_segments)
2374       return NULL;
2375 
2376     int best = -1;
2377     uint bestoffset = 0;
2378 
2379     for (int j = 0; j < n_book_components; j ++)
2380       {
2381         if (book_components[j].book_segment_number != i)
2382           continue;
2383         if (book_components[j].txt_start <= offset &&
2384             book_components[j].txt_start + book_components[j].txt_length > offset)
2385           {
2386             sprintf (buf, "%s:%s+0%0o", book_segments[i].segname,
2387               book_components[j].compname,
2388               offset - book_components[j].txt_start);
2389             if (compname)
2390               * compname = book_components[j].compname;
2391             if (compoffset)
2392               * compoffset = offset - book_components[j].txt_start;
2393             return buf;
2394           }
2395         if (book_components[j].txt_start <= offset &&
2396             book_components[j].txt_start > bestoffset)
2397           {
2398             best = j;
2399             bestoffset = book_components[j].txt_start;
2400           }
2401       }
2402 
2403     if (best != -1)
2404       {
2405         // Didn't find a component track bracketed the offset; return the
2406         // component that was before the offset
2407         if (compname)
2408           * compname = book_components[best].compname;
2409         if (compoffset)
2410           * compoffset = offset - book_components[best].txt_start;
2411         sprintf (buf, "%s:%s+0%0o", book_segments[i].segname,
2412           book_components[best].compname,
2413           offset - book_components[best].txt_start);
2414         return buf;
2415       }
2416 
2417     // Found a segment, but it had no components. Return the segment name
2418     // as the component name
2419 
2420     if (compname)
2421       * compname = book_segments[i].segname;
2422     if (compoffset)
2423       * compoffset = offset;
2424     sprintf (buf, "%s:+0%0o", book_segments[i].segname,
2425              offset);
2426     return buf;
2427   }
2428 
2429 // Given a segno and offset, find the component name and its
2430 // offset in the segment
2431 
2432 char * lookup_address (word18 segno, word18 offset, char * * compname,
     /* [previous][next][first][last][top][bottom][index][help] */
2433                        word18 * compoffset)
2434   {
2435     if (compname)
2436       * compname = NULL;
2437     if (compoffset)
2438       * compoffset = 0;
2439 
2440     // Magic numbers!
2441     // Multics seems to have a copy of hpchs_ (segno 0162) in segment 0322;
2442     // This little tweak allows source code level tracing for segment 0322,
2443     // and has no operational significance to the emulator
2444     // Hmmm. What is happening is that these segments are being loaded into
2445     // ring 4, and assigned segment #'s; the assigned number will vary
2446     // depending on the exact sequence of events.
2447     if (segno == 0322)
2448       segno = 0162;
2449     if (segno == 0310)
2450       segno = 041;
2451     if (segno == 0314)
2452       segno = 041;
2453     if (segno == 0313)
2454       segno = 040;
2455     if (segno == 0317)
2456       segno = 0161;
2457 
2458 
2459 
2460 
2461 
2462 
2463 
2464 
2465 
2466 
2467 
2468 
2469 
2470 
2471 
2472 
2473 
2474 
2475 
2476 
2477 
2478 
2479 
2480 
2481 
2482 
2483 
2484 
2485 
2486 
2487 
2488 
2489     char * ret = lookup_system_book_address (segno, offset, compname, compoffset);
2490     return ret;
2491   }
2492 
2493 // Given a segment name and component name, return the
2494 // components segment number and offset
2495 
2496 // Warning: returns ptr to static buffer
2497 static int lookup_system_book_name (char * segname, char * compname, long * segno,
     /* [previous][next][first][last][top][bottom][index][help] */
2498                                     long * offset)
2499   {
2500     int i;
2501     for (i = 0; i < n_book_segments; i ++)
2502       if (strcmp (book_segments[i].segname, segname) == 0)
2503         break;
2504     if (i >= n_book_segments)
2505       return -1;
2506 
2507     for (int j = 0; j < n_book_components; j ++)
2508       {
2509         if (book_components[j].book_segment_number != i)
2510           continue;
2511         if (strcmp (book_components[j].compname, compname) == 0)
2512           {
2513             * segno = book_segments[i].segno;
2514             * offset = (long) book_components[j].txt_start;
2515             return 0;
2516           }
2517       }
2518 
2519    return -1;
2520  }
2521 
2522 static char * source_search_path = NULL;
2523 
2524 // Given a component name and an offset in the component,
2525 // find the listing file of the component and try to
2526 // print the source code line that generated the code at
2527 // component:offset
2528 
2529 void list_source (char * compname, word18 offset, uint dflag)
     /* [previous][next][first][last][top][bottom][index][help] */
2530   {
2531     const int offset_str_len = 10;
2532     //char offset_str[offset_str_len + 1];
2533     char offset_str[17];
2534     sprintf (offset_str, "    %06o", offset);
2535 
2536     char path[(source_search_path ? strlen (source_search_path) : 1) +
2537                1 + // "/"
2538                (compname ? strlen (compname) : 1) +
2539                 1 + strlen (".list") + 1];
2540     char * searchp = source_search_path ? source_search_path : ".";
2541     // find <search path>/<compname>.list
2542     while (* searchp)
2543       {
2544         size_t pathlen = strcspn (searchp, ":");
2545         strncpy (path, searchp, pathlen);
2546         path[pathlen] = '\0';
2547         if (searchp[pathlen] == ':')
2548           searchp += pathlen + 1;
2549         else
2550           searchp += pathlen;
2551 
2552         if (compname)
2553           {
2554             strcat (path, "/");
2555             strcat (path, compname);
2556           }
2557         strcat (path, ".list");
2558         //sim_msg ("<%s>\n", path);
2559         FILE * listing = fopen (path, "r");
2560         if (listing)
2561           {
2562             char line[1025];
2563             if (feof (listing))
2564               goto fileDone;
2565             fgets (line, 1024, listing);
2566             if (strncmp (line, "ASSEMBLY LISTING", 16) == 0)
2567               {
2568                 // Search ALM listing file
2569                 // sim_msg ("found <%s>\n", path);
2570 
2571                 // ALM listing files look like:
2572                 //     000226  4a  4 00010 7421 20  \tstx2]tbootload_0$entry_stack_ptr,id
2573                 while (! feof (listing))
2574                   {
2575                     fgets (line, 1024, listing);
2576                     if (strncmp (line, offset_str, (size_t) offset_str_len) == 0)
2577                       {
2578                         if (! dflag)
2579                           sim_msg ("%s", line);
2580                         else
2581                           sim_debug (dflag, & cpu_dev, "%s", line);
2582                         //break;
2583                       }
2584                     if (strcmp (line, "\fLITERALS\n") == 0)
2585                       break;
2586                   }
2587               } // if assembly listing
2588             else if (strncmp (line, "\tCOMPILATION LISTING", 20) == 0)
2589               {
2590                 // Search PL/I listing file
2591 
2592                 // PL/I files have a line location table
2593                 //     "   LINE    LOC      LINE    LOC ...."
2594 
2595                 bool foundTable = false;
2596                 while (! feof (listing))
2597                   {
2598                     fgets (line, 1024, listing);
2599                     if (strncmp (line, "   LINE    LOC", 14) != 0)
2600                       continue;
2601                     foundTable = true;
2602                     // Found the table
2603                     // Table lines look like
2604                     //     "     13 000705       275 000713  ...
2605                     // But some times
2606                     //     "     10 000156   21   84 000164
2607                     //     "      8 000214        65 000222    4   84 000225
2608                     //
2609                     //     "    349 001442       351 001445       353 001454    1    9 001456    1   11 001461    1   12 001463    1   13 001470
2610                     //     " 1   18 001477       357 001522       361 001525       363 001544       364 001546       365 001547       366 001553
2611 
2612                     //  I think the numbers refer to include files...
2613                     //   But of course the format is slightly off...
2614                     //    table    ".1...18
2615                     //    listing  ".1....18
2616                     int best = -1;
2617                     char bestLines[8] = {0, 0, 0, 0, 0, 0, 0};
2618                     while (! feof (listing))
2619                       {
2620                         int loc[7];
2621                         char linenos[7][8];
2622                         memset (linenos, 0, sizeof (linenos));
2623                         fgets (line, 1024, listing);
2624                         // sometimes the leading columns are blank...
2625                         while (strncmp (line,
2626                                         "                 ", 8 + 6 + 3) == 0)
2627                           memmove (line, line + 8 + 6 + 3,
2628                                    strlen (line + 8 + 6 + 3));
2629                         // deal with the extra numbers...
2630 
2631                         int cnt = sscanf (line,
2632                           // " %d %o %d %o %d %o %d %o %d %o %d %o %d %o",
2633                           "%8c%o%*3c"
2634                           "%8c%o%*3c"
2635                           "%8c%o%*3c"
2636                           "%8c%o%*3c"
2637                           "%8c%o%*3c"
2638                           "%8c%o%*3c"
2639                           "%8c%o",
2640                           (char *) & linenos[0], (uint *) & loc[0],
2641                           (char *) & linenos[1], (uint *) & loc[1],
2642                           (char *) & linenos[2], (uint *) & loc[2],
2643                           (char *) & linenos[3], (uint *) & loc[3],
2644                           (char *) & linenos[4], (uint *) & loc[4],
2645                           (char *) & linenos[5], (uint *) & loc[5],
2646                           (char *) & linenos[6], (uint *) & loc[6]);
2647                         if (! (cnt == 2 || cnt == 4 || cnt == 6 ||
2648                                cnt == 8 || cnt == 10 || cnt == 12 ||
2649                                cnt == 14))
2650                           break; // end of table
2651                         int n;
2652                         for (n = 0; n < cnt / 2; n ++)
2653                           {
2654                             if (loc[n] > best && loc[n] <= (int) offset)
2655                               {
2656                                 best = loc[n];
2657                                 memcpy (bestLines, linenos[n],
2658                                         sizeof (bestLines));
2659                               }
2660                           }
2661                         if (best == (int) offset)
2662                           break;
2663                       }
2664                     if (best == -1)
2665                       goto fileDone; // Not found in table
2666 
2667                     //   But of course the format is slightly off...
2668                     //    table    ".1...18
2669                     //    listing  ".1....18
2670                     // bestLines "21   84 "
2671                     // listing   " 21    84 "
2672                     char searchPrefix[10];
2673                     searchPrefix[0] = ' ';
2674                     searchPrefix[1] = bestLines[0];
2675                     searchPrefix[2] = bestLines[1];
2676                     searchPrefix[3] = ' ';
2677                     searchPrefix[4] = bestLines[2];
2678                     searchPrefix[5] = bestLines[3];
2679                     searchPrefix[6] = bestLines[4];
2680                     searchPrefix[7] = bestLines[5];
2681                     searchPrefix[8] = bestLines[6];
2682                     // ignore trailing space; some times it's a tab
2683                     // searchPrefix[ 9] = bestLines[ 7];
2684                     searchPrefix[9] = '\0';
2685 
2686                     // Look for the line in the listing
2687                     rewind (listing);
2688                     while (! feof (listing))
2689                       {
2690                         fgets (line, 1024, listing);
2691                         if (strncmp (line, "\f\tSOURCE", 8) == 0)
2692                           goto fileDone; // end of source code listing
2693                         char prefix[10];
2694                         strncpy (prefix, line, 9);
2695                         prefix[9] = '\0';
2696                         if (strcmp (prefix, searchPrefix) != 0)
2697                           continue;
2698                         // Got it
2699                         if (!dflag)
2700                           sim_msg ("%s", line);
2701                         else
2702                           sim_debug (dflag, & cpu_dev, "%s", line);
2703                         //break;
2704                       }
2705                     goto fileDone;
2706                   } // if table start
2707                 if (! foundTable)
2708                   {
2709                     // Can't find the LINE/LOC table; look for listing
2710                     rewind (listing);
2711                     while (! feof (listing))
2712                       {
2713                         fgets (line, 1024, listing);
2714                         if (strncmp (line,
2715                                      offset_str + 4,
2716                                      offset_str_len - 4) == 0)
2717                           {
2718                             if (! dflag)
2719                               sim_msg ("%s", line);
2720                             else
2721                               sim_debug (dflag, & cpu_dev, "%s", line);
2722                             //break;
2723                           }
2724                         //if (strcmp (line, "\fLITERALS\n") == 0)
2725                           //break;
2726                       }
2727                   } // if ! tableFound
2728               } // if PL/I listing
2729 
2730 fileDone:
2731             fclose (listing);
2732           } // if (listing)
2733       }
2734   }
2735 
2736 // STK
2737 
2738 static t_stat stack_trace (UNUSED int32 arg,  UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
2739   {
2740     char * msg;
2741 
2742     word15 icSegno = cpu.PPR.PSR;
2743     word18 icOffset = cpu.PPR.IC;
2744 
2745     sim_msg ("Entry ptr   %05o:%06o\n", icSegno, icOffset);
2746 
2747     char * compname;
2748     word18 compoffset;
2749     char * where = lookup_address (icSegno, icOffset,
2750                                    & compname, & compoffset);
2751     if (where)
2752       {
2753         sim_msg ("%05o:%06o %s\n", icSegno, icOffset, where);
2754         list_source (compname, compoffset, 0);
2755       }
2756     sim_msg ("\n");
2757 
2758     // According to AK92
2759     //
2760     //  pr0/ap operator segment pointer
2761     //  pr6/sp stack frame pointer
2762     //  pr4/lp linkage section for the executing procedure
2763     //  pr7/sb stack base
2764 
2765     word15 fpSegno  = cpu.PR[6].SNR;
2766     word18 fpOffset = cpu.PR[6].WORDNO;
2767 
2768     for (uint frameNo = 1; ; frameNo ++)
2769       {
2770         sim_msg ("Frame %d %05o:%06o\n",
2771                     frameNo, fpSegno, fpOffset);
2772 
2773         word24 fp;
2774         if (dbgLookupAddress (fpSegno, fpOffset, & fp, & msg))
2775           {
2776             sim_msg ("can't lookup fp (%05o:%06o) because %s\n",
2777                     fpSegno, fpOffset, msg);
2778             break;
2779           }
2780 
2781         word15 prevfpSegno  = (word15) ((M[fp + 16] >> 18) & MASK15);
2782         word18 prevfpOffset = (word18) ((M[fp + 17] >> 18) & MASK18);
2783 
2784         sim_msg ("Previous FP %05o:%06o\n", prevfpSegno, prevfpOffset);
2785 
2786         word15 returnSegno  = (word15) ((M[fp + 20] >> 18) & MASK15);
2787         word18 returnOffset = (word18) ((M[fp + 21] >> 18) & MASK18);
2788 
2789         sim_msg ("Return ptr  %05o:%06o\n", returnSegno, returnOffset);
2790 
2791         if (returnOffset == 0)
2792           {
2793             if (frameNo == 1)
2794               {
2795                 // try rX[7] as the return address
2796                 sim_msg ("guessing X7 has a return address....\n");
2797                 where = lookup_address (icSegno, cpu.rX[7] - 1,
2798                                         & compname, & compoffset);
2799                 if (where)
2800                   {
2801                     sim_msg ("%05o:%06o %s\n", icSegno, cpu.rX[7] - 1, where);
2802                     list_source (compname, compoffset, 0);
2803                   }
2804               }
2805           }
2806         else
2807           {
2808             where = lookup_address (returnSegno, returnOffset - 1,
2809                                     & compname, & compoffset);
2810             if (where)
2811               {
2812                 sim_msg ("%05o:%06o %s\n",
2813                             returnSegno, returnOffset - 1, where);
2814                 list_source (compname, compoffset, 0);
2815               }
2816           }
2817 
2818         word15 entrySegno  = (word15) ((M[fp + 22] >> 18) & MASK15);
2819         word18 entryOffset = (word18) ((M[fp + 23] >> 18) & MASK18);
2820 
2821         sim_msg ("Entry ptr   %05o:%06o\n", entrySegno, entryOffset);
2822 
2823         where = lookup_address (entrySegno, entryOffset,
2824                                 & compname, & compoffset);
2825         if (where)
2826           {
2827             sim_msg ("%05o:%06o %s\n", entrySegno, entryOffset, where);
2828             list_source (compname, compoffset, 0);
2829           }
2830 
2831         word15 argSegno  = (word15) ((M[fp + 26] >> 18) & MASK15);
2832         word18 argOffset = (word18) ((M[fp + 27] >> 18) & MASK18);
2833         sim_msg ("Arg ptr     %05o:%06o\n", argSegno, argOffset);
2834 
2835         word24 ap;
2836         if (dbgLookupAddress (argSegno, argOffset, & ap, & msg))
2837           {
2838             sim_msg ("can't lookup arg ptr (%05o:%06o) because %s\n",
2839                     argSegno, argOffset, msg);
2840             goto skipArgs;
2841           }
2842 
2843         word16 argCount  = (word16) ((M[ap + 0] >> 19) & MASK17);
2844         word18 callType  = (word18) (M[ap + 0] & MASK18);
2845         word16 descCount = (word16) ((M[ap + 1] >> 19) & MASK17);
2846         sim_msg ("arg_count   %d\n", argCount);
2847         switch (callType)
2848           {
2849             case 0u:
2850               sim_msg ("call_type Quick internal call\n");
2851               break;
2852             case 4u:
2853               sim_msg ("call_type Inter-segment\n");
2854               break;
2855             case 8u:
2856               sim_msg ("call_type Enviroment pointer\n");
2857               break;
2858             default:
2859               sim_msg ("call_type Unknown (%o)\n", callType);
2860               goto skipArgs;
2861               }
2862         sim_msg ("desc_count  %d\n", descCount);
2863 
2864 
2865 
2866 
2867 
2868 
2869 
2870 
2871           {
2872             for (uint argno = 0; argno < argCount; argno ++)
2873               {
2874                 uint argnoos       = ap + 2 + argno * 2;
2875                 word15 argnoSegno  = (word15) ((M[argnoos] >> 18) & MASK15);
2876                 word18 argnoOffset = (word18) ((M[argnoos + 1] >> 18) & MASK18);
2877                 word24 argnop;
2878                 if (dbgLookupAddress (argnoSegno, argnoOffset, & argnop, & msg))
2879                   {
2880                     sim_msg ("can't lookup arg%d ptr (%05o:%06o) because %s\n",
2881                                 argno, argSegno, argOffset, msg);
2882                     continue;
2883                   }
2884                 word36 argv = M[argnop];
2885                 sim_msg ("arg%d value   %05o:%06o[%08o] "
2886                             "%012llo (%llu)\n",
2887                             argno, argSegno, argOffset, argnop,
2888                             (unsigned long long int)argv, (unsigned long long int)argv);
2889                 sim_msg ("\n");
2890              }
2891          }
2892 skipArgs:;
2893 
2894         sim_msg ("End of frame %d\n\n", frameNo);
2895 
2896         if (prevfpSegno == 077777 && prevfpOffset == 1)
2897           break;
2898         fpSegno  = prevfpSegno;
2899         fpOffset = prevfpOffset;
2900       }
2901     return SCPE_OK;
2902   }
2903 
2904 static t_stat list_source_at (UNUSED int32 arg, UNUSED const char *  buf)
     /* [previous][next][first][last][top][bottom][index][help] */
2905   {
2906     // list seg:offset
2907     uint segno;
2908     uint offset;
2909     if (sscanf (buf, "%o:%o", & segno, & offset) != 2)
2910       return SCPE_ARG;
2911     char * compname;
2912     word18 compoffset;
2913     char * where = lookup_address ((word18) segno, offset,
2914                                    & compname, & compoffset);
2915     if (where)
2916       {
2917         sim_msg ("%05o:%06o %s\n", segno, offset, where);
2918         list_source (compname, compoffset, 0);
2919       }
2920     return SCPE_OK;
2921   }
2922 
2923 static t_stat load_system_book (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
2924   {
2925 // Quietly ignore if not debug enabled
2926 # ifndef SPEED
2927     // Multics 12.5 assigns segment number to collection 3 starting at 0244.
2928     uint c3 = 0244;
2929 
2930 #  define bufSz 257
2931     char filebuf[bufSz];
2932     int  current = -1;
2933 
2934     FILE * fp = fopen (buf, "r");
2935     if (! fp)
2936       {
2937         sim_msg ("error opening file %s\n", buf);
2938         return SCPE_ARG;
2939       }
2940     for (;;)
2941       {
2942         char * bufp = fgets (filebuf, bufSz, fp);
2943         if (! bufp)
2944           break;
2945         //sim_msg ("<%s\n>", filebuf);
2946         char name[BOOK_SEGMENT_NAME_LEN];
2947         uint segno, p0, p1, p2;
2948 
2949         // 32 is BOOK_SEGMENT_NAME_LEN - 1
2950         int cnt = sscanf (filebuf, "%32s %o  (%o, %o, %o)", name, & segno,
2951           & p0, & p1, & p2);
2952         if (filebuf[0] != '\t' && cnt == 5)
2953           {
2954             //sim_msg ("A: %s %d\n", name, segno);
2955             int rc = add_book_segment (name, (int) segno);
2956             if (rc < 0)
2957               {
2958                 sim_warn ("error adding segment name\n");
2959                 fclose (fp);
2960                 return SCPE_ARG;
2961               }
2962             continue;
2963           }
2964         else
2965           {
2966             // Check for collection 3 segment
2967             // 32 is BOOK_SEGMENT_NAME_LEN - 1
2968             cnt = sscanf (filebuf, "%32s  (%o, %o, %o)", name,
2969               & p0, & p1, & p2);
2970             if (filebuf[0] != '\t' && cnt == 4)
2971               {
2972                 if (strstr (name, "fw.") || strstr (name, ".ec"))
2973                   continue;
2974                 //sim_msg ("A: %s %d\n", name, segno);
2975                 int rc = add_book_segment (name, (int) (c3 ++));
2976                 if (rc < 0)
2977                   {
2978                     sim_warn ("error adding segment name\n");
2979                     fclose (fp);
2980                     return SCPE_ARG;
2981                   }
2982                 continue;
2983               }
2984           }
2985         cnt = sscanf (filebuf, "Bindmap for >ldd>h>e>%32s", name);
2986         if (cnt != 1)
2987           cnt = sscanf (filebuf, "Bindmap for >ldd>hard>e>%32s", name);
2988         if (cnt == 1)
2989           {
2990             //sim_msg ("B: %s\n", name);
2991             //int rc = add_book_segment (name);
2992             int rc = lookup_book_segment (name);
2993             if (rc < 0)
2994               {
2995                 // The collection 3.0 segments do not have segment numbers,
2996                 // and the 1st digit of the 3-tuple is 1, not 0. Ignore
2997                 // them for now.
2998                 current = -1;
2999                 continue;
3000                 //sim_warn ("error adding segment name\n");
3001                 //return SCPE_ARG;
3002               }
3003             current = rc;
3004             continue;
3005           }
3006 
3007         uint txt_start, txt_length;
3008         int intstat_start, intstat_length, symbol_start, symbol_length;
3009         cnt = sscanf (filebuf, "%32s %o %o %o %o %o %o", name, & txt_start,
3010                       & txt_length, & intstat_start, & intstat_length,
3011                       & symbol_start, & symbol_length);
3012 
3013         if (cnt == 7)
3014           {
3015             //sim_msg ("C: %s\n", name);
3016             if (current >= 0)
3017               {
3018                 add_book_component (current, name, txt_start, txt_length,
3019                                     intstat_start, intstat_length, symbol_start,
3020                                     symbol_length);
3021               }
3022             continue;
3023           }
3024 
3025         cnt = sscanf (filebuf, "%32s %o  (%o, %o, %o)", name, & segno,
3026           & p0, & p1, & p2);
3027         if (filebuf[0] == '\t' && cnt == 5)
3028           {
3029             //sim_msg ("D: %s %d\n", name, segno);
3030             int rc = add_book_segment (name, (int) segno);
3031             if (rc < 0)
3032               {
3033                 sim_warn ("error adding segment name\n");
3034                 fclose (fp);
3035                 return SCPE_ARG;
3036               }
3037             continue;
3038           }
3039 
3040       }
3041     fclose (fp);
3042 
3043 
3044 
3045 
3046 
3047 
3048 
3049 
3050 
3051 
3052 
3053 
3054 
3055 
3056 
3057 
3058 
3059 
3060 
3061 
3062 
3063 # endif
3064     return SCPE_OK;
3065   }
3066 
3067 static t_stat add_system_book_entry (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3068   {
3069     // asbe segname compname seg txt_start txt_len intstat_start intstat_length
3070     // symbol_start symbol_length
3071     char segname[BOOK_SEGMENT_NAME_LEN];
3072     char compname[BOOK_SEGMENT_NAME_LEN];
3073     uint segno;
3074     uint txt_start, txt_len;
3075     uint  intstat_start, intstat_length;
3076     uint  symbol_start, symbol_length;
3077 
3078     // 32 is BOOK_SEGMENT_NAME_LEN - 1
3079     if (sscanf (buf, "%32s %32s %o %o %o %o %o %o %o",
3080                 segname, compname, & segno,
3081                 & txt_start, & txt_len, & intstat_start, & intstat_length,
3082                 & symbol_start, & symbol_length) != 9)
3083       return SCPE_ARG;
3084 
3085     int idx = add_book_segment (segname, (int) segno);
3086     if (idx < 0)
3087       return SCPE_ARG;
3088 
3089     if (add_book_component (idx, compname, txt_start, txt_len, (int) intstat_start,
3090                            (int) intstat_length, (int) symbol_start,
3091                            (int) symbol_length) < 0)
3092       return SCPE_ARG;
3093 
3094     return SCPE_OK;
3095   }
3096 
3097 // LSB n:n   given a segment number and offset, return a segment name,
3098 //           component and offset in that component
3099 //     sname:cname+offset
3100 //           given a segment name, component name and offset, return
3101 //           the segment number and offset
3102 
3103 static t_stat lookup_system_book (UNUSED int32  arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3104   {
3105     char w1[strlen (buf)];
3106     char w2[strlen (buf)];
3107     char w3[strlen (buf)];
3108     long segno, offset;
3109 
3110     size_t colon = strcspn (buf, ":");
3111     if (buf[colon] != ':')
3112       return SCPE_ARG;
3113 
3114     strncpy (w1, buf, colon);
3115     w1[colon] = '\0';
3116     //sim_msg ("w1 <%s>\n", w1);
3117 
3118     size_t plus = strcspn (buf + colon + 1, "+");
3119     if (buf[colon + 1 + plus] == '+')
3120       {
3121         strncpy (w2, buf + colon + 1, plus);
3122         w2[plus] = '\0';
3123         strcpy (w3, buf + colon + 1 + plus + 1);
3124       }
3125     else
3126       {
3127         strcpy (w2, buf + colon + 1);
3128         strcpy (w3, "");
3129       }
3130     //sim_msg ("w1 <%s>\n", w1);
3131     //sim_msg ("w2 <%s>\n", w2);
3132     //sim_msg ("w3 <%s>\n", w3);
3133 
3134     char * end1;
3135     segno = strtol (w1, & end1, 8);
3136     char * end2;
3137     offset = strtol (w2, & end2, 8);
3138 
3139     if (* end1 == '\0' && * end2 == '\0' && * w3 == '\0')
3140       {
3141         // n:n
3142         char * ans = lookup_address ((word18) segno, (word18) offset, NULL, NULL);
3143         sim_warn ("%s\n", ans ? ans : "not found");
3144       }
3145     else
3146       {
3147         if (* w3)
3148           {
3149             char * end3;
3150             offset = strtol (w3, & end3, 8);
3151             if (* end3 != '\0')
3152               return SCPE_ARG;
3153           }
3154         else
3155           offset = 0;
3156         long comp_offset;
3157         int rc = lookup_system_book_name (w1, w2, & segno, & comp_offset);
3158         if (rc)
3159           {
3160             sim_warn ("not found\n");
3161             return SCPE_OK;
3162           }
3163         sim_msg ("0%o:0%o\n", (uint) segno, (uint) (comp_offset + offset));
3164         abs_addr_n  ((int) segno, (uint) (comp_offset + offset));
3165       }
3166 /*
3167     if (sscanf (buf, "%o:%o", & segno, & offset) != 2)
3168       return SCPE_ARG;
3169     char * ans = lookup_address (segno, offset);
3170     sim_msg ("%s\n", ans ? ans : "not found");
3171 */
3172     return SCPE_OK;
3173   }
3174 
3175 // Assumes unpaged DSBR
3176 
3177 static sdw0_s *fetchSDW (word15 segno)
     /* [previous][next][first][last][top][bottom][index][help] */
3178   {
3179     word36 SDWeven, SDWodd;
3180 
3181     core_read2 ((cpu.DSBR.ADDR + 2u * segno) & PAMASK, & SDWeven, & SDWodd,
3182                  __func__);
3183 
3184     // even word
3185 
3186     sdw0_s *SDW = & cpu._s;
3187     memset (SDW, 0, sizeof (cpu._s));
3188 
3189     SDW->ADDR   = (SDWeven >> 12) & 077777777;
3190     SDW->R1     = (SDWeven >> 9)  & 7;
3191     SDW->R2     = (SDWeven >> 6)  & 7;
3192     SDW->R3     = (SDWeven >> 3)  & 7;
3193     SDW->DF     = TSTBIT (SDWeven,  2);
3194     SDW->FC     = SDWeven & 3;
3195 
3196     // odd word
3197     SDW->BOUND  = (SDWodd >> 21) & 037777;
3198     SDW->R      = TSTBIT (SDWodd,  20);
3199     SDW->E      = TSTBIT (SDWodd,  19);
3200     SDW->W      = TSTBIT (SDWodd,  18);
3201     SDW->P      = TSTBIT (SDWodd,  17);
3202     SDW->U      = TSTBIT (SDWodd,  16);
3203     SDW->G      = TSTBIT (SDWodd,  15);
3204     SDW->C      = TSTBIT (SDWodd,  14);
3205     SDW->EB     = SDWodd & 037777;
3206 
3207     return SDW;
3208   }
3209 
3210 static t_stat virtAddrN (uint address)
     /* [previous][next][first][last][top][bottom][index][help] */
3211   {
3212     if (cpu.DSBR.U) {
3213         for(word15 segno = 0; 2u * segno < 16u * (cpu.DSBR.BND + 1u); segno += 1)
3214         {
3215             sdw0_s *s = fetchSDW(segno);
3216             if (address >= s -> ADDR && address < s -> ADDR + s -> BOUND * 16u)
3217               sim_msg ("  %06o:%06o\n", segno, address - s -> ADDR);
3218         }
3219     } else {
3220         for(word15 segno = 0;
3221             2u * segno < 16u * (cpu.DSBR.BND + 1u);
3222             segno += 512u)
3223         {
3224             word24 y1 = (2u * segno) % 1024u;
3225             word24 x1 = (2u * segno - y1) / 1024u;
3226             word36 PTWx1;
3227             core_read ((cpu.DSBR.ADDR + x1) & PAMASK, & PTWx1, __func__);
3228 
3229             ptw_s PTW1;
3230             PTW1.ADDR = GETHI(PTWx1);
3231             PTW1.U    = TSTBIT(PTWx1, 9);
3232             PTW1.M    = TSTBIT(PTWx1, 6);
3233             PTW1.DF   = TSTBIT(PTWx1, 2);
3234             PTW1.FC   = PTWx1 & 3;
3235 
3236             if (PTW1.DF == 0)
3237                 continue;
3238             //sim_msg ("%06o  Addr %06o U %o M %o DF %o FC %o\n",
3239             //            segno, PTW1.ADDR, PTW1.U, PTW1.M, PTW1.DF, PTW1.FC);
3240             //sim_msg ("    Target segment page table\n");
3241             for (word15 tspt = 0; tspt < 512u; tspt ++)
3242             {
3243                 word36 SDWeven, SDWodd;
3244                 core_read2(((PTW1.ADDR << 6) + tspt * 2u) & PAMASK, & SDWeven,
3245                            & SDWodd, __func__);
3246                 sdw0_s SDW0;
3247                 // even word
3248                 SDW0.ADDR  = (SDWeven >> 12) & PAMASK;
3249                 SDW0.R1    = (SDWeven >> 9)  & 7u;
3250                 SDW0.R2    = (SDWeven >> 6)  & 7u;
3251                 SDW0.R3    = (SDWeven >> 3)  & 7u;
3252                 SDW0.DF    = TSTBIT(SDWeven,   2);
3253                 SDW0.FC    = SDWeven & 3u;
3254 
3255                 // odd word
3256                 SDW0.BOUND = (SDWodd >> 21) & 037777;
3257                 SDW0.R     = TSTBIT(SDWodd,   20);
3258                 SDW0.E     = TSTBIT(SDWodd,   19);
3259                 SDW0.W     = TSTBIT(SDWodd,   18);
3260                 SDW0.P     = TSTBIT(SDWodd,   17);
3261                 SDW0.U     = TSTBIT(SDWodd,   16);
3262                 SDW0.G     = TSTBIT(SDWodd,   15);
3263                 SDW0.C     = TSTBIT(SDWodd,   14);
3264                 SDW0.EB    = SDWodd & 037777;
3265 
3266                 if (SDW0.DF == 0)
3267                     continue;
3268                 //sim_msg ("    %06o Addr %06o %o,%o,%o F%o BOUND %06o "
3269                 //          "%c%c%c%c%c\n",
3270                 //          tspt, SDW0.ADDR, SDW0.R1, SDW0.R2, SDW0.R3, SDW0.F,
3271                 //          SDW0.BOUND, SDW0.R ? 'R' : '.', SDW0.E ? 'E' : '.',
3272                 //          SDW0.W ? 'W' : '.', SDW0.P ? 'P' : '.',
3273                 //          SDW0.U ? 'U' : '.');
3274                 if (SDW0.U == 0)
3275                 {
3276                     for (word18 offset = 0;
3277                          offset < 16u * (SDW0.BOUND + 1u);
3278                          offset += 1024)
3279                     {
3280                         word24 y2 = offset % 1024;
3281                         word24 x2 = (offset - y2) / 1024;
3282 
3283                         // 10. Fetch the target segment PTW(x2) from
3284                         //     SDW(segno).ADDR + x2.
3285 
3286                         word36 PTWx2;
3287                         core_read ((SDW0.ADDR + x2) & PAMASK, & PTWx2, __func__);
3288 
3289                         ptw_s PTW2;
3290                         PTW2.ADDR = GETHI(PTWx2);
3291                         PTW2.U    = TSTBIT(PTWx2, 9);
3292                         PTW2.M    = TSTBIT(PTWx2, 6);
3293                         PTW2.DF   = TSTBIT(PTWx2, 2);
3294                         PTW2.FC   = PTWx2 & 3;
3295 
3296                         //sim_msg ("        %06o  Addr %06o U %o M %o F %o "
3297                         //            "FC %o\n",
3298                         //            offset, PTW2.ADDR, PTW2.U, PTW2.M, PTW2.F,
3299                         //            PTW2.FC);
3300                         if (address >= PTW2.ADDR + offset &&
3301                             address < PTW2.ADDR + offset + 1024)
3302                           sim_msg ("  %06o:%06o\n", tspt, (address - offset) - PTW2.ADDR);
3303 
3304                       }
3305                   }
3306                 else
3307                   {
3308                     if (address >= SDW0.ADDR &&
3309                         address < SDW0.ADDR + SDW0.BOUND * 16u)
3310                       sim_msg ("  %06o:%06o\n", tspt, address - SDW0.ADDR);
3311                   }
3312             }
3313         }
3314     }
3315 
3316     return SCPE_OK;
3317 
3318   }
3319 
3320 // VIRTUAL address
3321 
3322 static t_stat virt_address (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3323   {
3324     uint address;
3325     if (sscanf (buf, "%o", & address) != 1)
3326       return SCPE_ARG;
3327     return virtAddrN (address);
3328   }
3329 
3330 // search path is path:path:path....
3331 
3332 static t_stat set_search_path (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3333   {
3334 // Quietly ignore if debugging not enabled
3335 # ifndef SPEED
3336     if (source_search_path)
3337       FREE (source_search_path);
3338     source_search_path = strdup (buf);
3339     if (!source_search_path)
3340       {
3341         fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
3342                  __func__, __FILE__, __LINE__);
3343 #  if defined(USE_BACKTRACE)
3344 #   ifdef SIGUSR2
3345         (void)raise(SIGUSR2);
3346         /*NOTREACHED*/ /* unreachable */
3347 #   endif /* ifdef SIGUSR2 */
3348 #  endif /* if defined(USE_BACKTRACE) */
3349         abort();
3350       }
3351 # endif
3352     return SCPE_OK;
3353   }
3354 
3355 // Hook for gdb
3356 //
3357 // The idea is that if you want to set a gdb breakpoint for a particularly
3358 // complex condition, you can add a test for the condition to the emulator
3359 // code and call brkbrk() when the condition is met; by doing a gdb
3360 // 'b brkbrk', gdb will see when the condition is met.
3361 //
3362 
3363 t_stat brkbrk (UNUSED int32 arg, UNUSED const char *  buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3364   {
3365     //list_source (buf, 0);
3366     return SCPE_OK;
3367   }
3368 
3369 // SBREAK segno:offset
3370 
3371 static t_stat sbreak (int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3372   {
3373     //printf (">> <%s>\n", buf);
3374     int segno, offset;
3375     int where;
3376     int cnt = sscanf (buf, "%o:%o%n", & segno, & offset, & where);
3377     if (cnt != 2)
3378       {
3379         return SCPE_ARG;
3380       }
3381     char reformatted[strlen (buf) + 20];
3382     sprintf (reformatted, "0%04o%06o%s", segno, offset, buf + where);
3383     //printf (">> <%s>\n", reformatted);
3384     t_stat rc = brk_cmd (arg, reformatted);
3385     return rc;
3386   }
3387 
3388 # ifdef DVFDBG
3389 static t_stat dfx1entry (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3390   {
3391 // divide_fx1, divide_fx3
3392     sim_msg ("dfx1entry\n");
3393     sim_msg ("rA %012"PRIo64" (%llu)\n", rA, rA);
3394     sim_msg ("rQ %012"PRIo64" (%llu)\n", rQ, rQ);
3395     // Figure out the caller's text segment, according to pli_operators.
3396     // sp:tbp -> PR[6].SNR:046
3397     word24 pa;
3398     char * msg;
3399     if (dbgLookupAddress (cpu.PR[6].SNR, 046, & pa, & msg))
3400       {
3401         sim_msg ("text segment number lookup failed because %s\n", msg);
3402       }
3403     else
3404       {
3405         sim_msg ("text segno %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3406       }
3407 sim_msg ("%05o:%06o\n", cpu.PR[2].SNR, cpu.rX[0]);
3408 //dbgStackTrace ();
3409     if (dbgLookupAddress (cpu.PR[2].SNR, cpu.rX[0], & pa, & msg))
3410       {
3411         sim_msg ("return address lookup failed because %s\n", msg);
3412       }
3413     else
3414       {
3415         sim_msg ("scale %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3416       }
3417     if (dbgLookupAddress (cpu.PR[2].SNR, cpu.PR[2].WORDNO, & pa, & msg))
3418       {
3419         sim_msg ("divisor address lookup failed because %s\n", msg);
3420       }
3421     else
3422       {
3423         sim_msg ("divisor %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3424       }
3425     return SCPE_OK;
3426   }
3427 
3428 static t_stat dfx1exit (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3429   {
3430     sim_msg ("dfx1exit\n");
3431     sim_msg ("rA %012"PRIo64" (%llu)\n", rA, rA);
3432     sim_msg ("rQ %012"PRIo64" (%llu)\n", rQ, rQ);
3433     return SCPE_OK;
3434   }
3435 
3436 static t_stat dv2scale (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3437   {
3438     sim_msg ("dv2scale\n");
3439     sim_msg ("rQ %012"PRIo64" (%llu)\n", rQ, rQ);
3440     return SCPE_OK;
3441   }
3442 
3443 static t_stat dfx2entry (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3444   {
3445 // divide_fx2
3446     sim_msg ("dfx2entry\n");
3447     sim_msg ("rA %012"PRIo64" (%llu)\n", rA, rA);
3448     sim_msg ("rQ %012"PRIo64" (%llu)\n", rQ, rQ);
3449     // Figure out the caller's text segment, according to pli_operators.
3450     // sp:tbp -> PR[6].SNR:046
3451     word24 pa;
3452     char * msg;
3453     if (dbgLookupAddress (cpu.PR[6].SNR, 046, & pa, & msg))
3454       {
3455         sim_msg ("text segment number lookup failed because %s\n", msg);
3456       }
3457     else
3458       {
3459         sim_msg ("text segno %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3460       }
3461 
3462 
3463 
3464 
3465 
3466 
3467 
3468 
3469 
3470 
3471 
3472 
3473 
3474 
3475 
3476 
3477 
3478 
3479 
3480 
3481 
3482 
3483 
3484 
3485 
3486 
3487     if (dbgLookupAddress (cpu.PR[2].SNR, cpu.PR[2].WORDNO, & pa, & msg))
3488       {
3489         sim_msg ("divisor address lookup failed because %s\n", msg);
3490       }
3491     else
3492       {
3493         sim_msg ("divisor %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3494         sim_msg ("divisor %012"PRIo64" (%llu)\n", M[pa + 1], M[pa + 1]);
3495       }
3496     return SCPE_OK;
3497   }
3498 
3499 static t_stat mdfx3entry (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3500   {
3501 // operator to form mod(fx2,fx1)
3502 // entered with first arg in q, bp pointing at second
3503 
3504 // divide_fx1, divide_fx2
3505     sim_msg ("mdfx3entry\n");
3506     //sim_msg ("rA %012"PRIo64" (%llu)\n", rA, rA);
3507     sim_msg ("rQ %012"PRIo64" (%llu)\n", rQ, rQ);
3508     // Figure out the caller's text segment, according to pli_operators.
3509     // sp:tbp -> PR[6].SNR:046
3510     word24 pa;
3511     char * msg;
3512     if (dbgLookupAddress (cpu.PR[6].SNR, 046, & pa, & msg))
3513       {
3514         sim_msg ("text segment number lookup failed because %s\n", msg);
3515       }
3516     else
3517       {
3518         sim_msg ("text segno %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3519       }
3520 //sim_msg ("%05o:%06o\n", cpu.PR[2].SNR, cpu.rX[0]);
3521 //dbgStackTrace ();
3522 
3523 
3524 
3525 
3526 
3527 
3528 
3529 
3530 
3531 
3532     if (dbgLookupAddress (cpu.PR[2].SNR, cpu.PR[2].WORDNO, & pa, & msg))
3533       {
3534         sim_msg ("divisor address lookup failed because %s\n", msg);
3535       }
3536     else
3537       {
3538         sim_msg ("divisor %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3539       }
3540     return SCPE_OK;
3541   }
3542 
3543 static t_stat smfx1entry (UNUSED int32 arg, UNUSED const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3544   {
3545 // operator to form mod(fx2,fx1)
3546 // entered with first arg in q, bp pointing at second
3547 
3548 // divide_fx1, divide_fx2
3549     sim_msg ("smfx1entry\n");
3550     //sim_msg ("rA %012"PRIo64" (%llu)\n", rA, rA);
3551     sim_msg ("rQ %012"PRIo64" (%llu)\n", rQ, rQ);
3552     // Figure out the caller's text segment, according to pli_operators.
3553     // sp:tbp -> PR[6].SNR:046
3554     word24 pa;
3555     char * msg;
3556     if (dbgLookupAddress (cpu.PR[6].SNR, 046, & pa, & msg))
3557       {
3558         sim_msg ("text segment number lookup failed because %s\n", msg);
3559       }
3560     else
3561       {
3562         sim_msg ("text segno %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3563       }
3564 sim_msg ("%05o:%06o\n", cpu.PR[2].SNR, cpu.rX[0]);
3565 //dbgStackTrace ();
3566     if (dbgLookupAddress (cpu.PR[2].SNR, cpu.rX[0], & pa, & msg))
3567       {
3568         sim_msg ("return address lookup failed because %s\n", msg);
3569       }
3570     else
3571       {
3572         sim_msg ("scale %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3573       }
3574     if (dbgLookupAddress (cpu.PR[2].SNR, cpu.PR[2].WORDNO, & pa, & msg))
3575       {
3576         sim_msg ("divisor address lookup failed because %s\n", msg);
3577       }
3578     else
3579       {
3580         sim_msg ("divisor %012"PRIo64" (%llu)\n", M[pa], M[pa]);
3581       }
3582     return SCPE_OK;
3583   }
3584 # endif // DVFDBG
3585 
3586 // SEARCHMEMORY value
3587 
3588 static t_stat search_memory (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3589   {
3590     word36 value;
3591     if (sscanf (buf, "%llo", & value) != 1)
3592       return SCPE_ARG;
3593 
3594     uint i;
3595     for (i = 0; i < MEMSIZE; i ++)
3596       if ((M[i] & DMASK) == value)
3597         sim_msg ("%08o\n", i);
3598     return SCPE_OK;
3599   }
3600 
3601 static t_stat set_dbg_cpu_mask (int32 UNUSED arg, const char * UNUSED buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3602   {
3603     uint msk;
3604     int cnt = sscanf (buf, "%u", & msk);
3605     if (cnt != 1)
3606       {
3607         sim_msg ("Huh?\n");
3608         return SCPE_ARG;
3609       }
3610     sim_msg ("mask set to %u\n", msk);
3611     dbgCPUMask = msk;
3612     return SCPE_OK;
3613   }
3614 
3615 #endif // TESTING
3616 
3617 //
3618 // Misc. commands
3619 //
3620 
3621 #ifdef PANEL68
3622 static t_stat scraper (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3623   {
3624     if (strcasecmp (buf, "start") == 0)
3625       return panelScraperStart ();
3626     if (strcasecmp (buf, "stop") == 0)
3627       return panelScraperStop ();
3628     if (strcasecmp (buf, "msg") == 0)
3629       {
3630         return panelScraperMsg (NULL);
3631       }
3632     if (strncasecmp (buf, "msg ", 4) == 0)
3633       {
3634         const char * p = buf + 4;
3635         while (* p == ' ')
3636           p ++;
3637         return panelScraperMsg (p);
3638       }
3639     sim_msg ("err: scraper start|stop|msg\n");
3640     return SCPE_ARG;
3641   }
3642 #endif
3643 
3644 #ifdef YIELD
3645 static t_stat clear_yield (int32 flag, UNUSED const char * cptr)
     /* [previous][next][first][last][top][bottom][index][help] */
3646   {
3647     return SCPE_OK;
3648   }
3649 
3650 static t_stat yield (int32 flag, UNUSED const char * cptr)
     /* [previous][next][first][last][top][bottom][index][help] */
3651   {
3652     return SCPE_OK;
3653   }
3654 #endif
3655 
3656 #ifndef PERF_STRIP
3657 static t_stat set_luf (int32 flag, UNUSED const char * cptr)
     /* [previous][next][first][last][top][bottom][index][help] */
3658   {
3659     luf_flag = flag;
3660     return SCPE_OK;
3661   }
3662 #endif /* ifndef PERF_STRIP */
3663 
3664 #ifdef DBGEVENT
3665 uint n_dbgevents;
3666 struct dbgevent_t dbgevents[max_dbgevents];
3667 struct timespec dbgevent_t0;
3668 
3669 static int dbgevent_compar (const void * a, const void * b)
     /* [previous][next][first][last][top][bottom][index][help] */
3670   {
3671     struct dbgevent_t * ea = (struct dbgevent_t *) a;
3672     struct dbgevent_t * eb = (struct dbgevent_t *) b;
3673     if (ea->segno < eb->segno)
3674       return -1;
3675     if (ea->segno > eb->segno)
3676       return 1;
3677     if (ea->offset < eb->offset)
3678       return -1;
3679     if (ea->offset > eb->offset)
3680       return 1;
3681     return 0;
3682   }
3683 
3684 int dbgevent_lookup (word15 segno, word18 offset)
     /* [previous][next][first][last][top][bottom][index][help] */
3685   {
3686     struct dbgevent_t key = {segno, offset, false};
3687     struct dbgevent_t * p = (struct dbgevent_t *) bsearch (& key, dbgevents, (size_t) n_dbgevents,
3688             sizeof (struct dbgevent_t), dbgevent_compar);
3689     if (! p)
3690       return -1;
3691     return (int) (p - dbgevents);
3692   }
3693 
3694 // "dbbevent segno:offset"
3695 //
3696 // arg: 0 set t0 event
3697 //      1 set event
3698 //      2 clear event
3699 //      3 list events
3700 //      4 clear all events
3701 
3702 // XXX think about per-thread timing?
3703 
3704 static t_stat set_dbgevent (int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3705   {
3706     if (arg == 0 || arg == 1)
3707       {
3708         if (n_dbgevents >= max_dbgevents)
3709           {
3710             sim_printf ("too many dbgevents %u/%u\r\n", n_dbgevents, max_dbgevents);
3711             return SCPE_ARG;
3712           }
3713         if (strlen (buf) > dbgevent_tagsize - 1)
3714           {
3715             sim_printf ("command too long %lu/%u\r\n", strlen (buf), dbgevent_tagsize -1);
3716             return SCPE_ARG;
3717           }
3718 
3719         uint segno;
3720         uint offset;
3721         if (sscanf (buf, "%o:%o", & segno, & offset) != 2)
3722           return SCPE_ARG;
3723         if (segno > MASK15 || offset > MASK18)
3724           return SCPE_ARG;
3725         if (dbgevent_lookup ((word15) segno, (word18) offset) != -1)
3726           {
3727             sim_printf ("not adding duplicate 0%o:0%o\r\n", segno, offset);
3728             return SCPE_ARG;
3729           }
3730         dbgevents[n_dbgevents].segno                     = (word15) segno;
3731         dbgevents[n_dbgevents].offset                    = (word18) offset;
3732         dbgevents[n_dbgevents].t0                        = arg == 0;
3733         strncpy (dbgevents[n_dbgevents].tag, buf, dbgevent_tagsize - 1);
3734         dbgevents[n_dbgevents].tag[dbgevent_tagsize - 1] = 0;
3735         sim_printf ("%o:%o %u(%d) %s\r\n", dbgevents[n_dbgevents].segno,
3736             dbgevents[n_dbgevents].offset,
3737                 dbgevents[n_dbgevents].t0, arg, dbgevents[n_dbgevents].tag);
3738         n_dbgevents ++;
3739         qsort (dbgevents, n_dbgevents, sizeof (struct dbgevent_t), dbgevent_compar);
3740       }
3741     else if (arg == 2)
3742       {
3743         uint segno;
3744         uint offset;
3745         if (sscanf (buf, "%o:%o", & segno, & offset) != 2)
3746           return SCPE_ARG;
3747         int n = dbgevent_lookup ((word15) segno, (word18) offset);
3748         if (n < 0)
3749           {
3750             sim_printf ("0%o:0%o not found\r\n", segno, offset);
3751             return SCPE_ARG;
3752           }
3753         for (int i = n; i < n_dbgevents - 1; i ++)
3754           dbgevents[i] = dbgevents[i + 1];
3755         n_dbgevents --;
3756       }
3757     else if (arg == 3)
3758       {
3759         for (int i = 0; i < n_dbgevents; i ++)
3760          sim_printf ("    %s %05o:%06o %s\r\n", dbgevents[i].t0 ? "T0" : "  ", dbgevents[i].segno,
3761                  dbgevents[i].offset,dbgevents[i].tag);
3762       }
3763     else if (arg == 4)
3764       {
3765         n_dbgevents = 0;
3766         sim_printf ("dbgevents cleared\r\n");
3767       }
3768     else
3769       {
3770         sim_printf ("set_dbgevent bad arg %d\r\n", arg);
3771         return SCPE_ARG;
3772       }
3773     return SCPE_OK;
3774   }
3775 #endif
3776 
3777 //  REWIND name
3778 //
3779 //  rewind tapa_05
3780 //
3781 
3782 t_stat rewind_media (int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
3783   char name[strlen (buf)];
3784 
3785   int rc = sscanf (buf, "%s", name);
3786   if (rc != 1)
3787     return SCPE_ARG;
3788 
3789   for (uint i = 0; i < N_MT_UNITS_MAX; i ++) {
3790     if (strcmp (tape_states[i].device_name, name) == 0) {
3791       UNIT * unitp = & mt_unit [i];
3792       return sim_tape_rewind (unitp);
3793     }
3794   }
3795 
3796   sim_printf ("Can't find name '%s'\r\n", name);
3797   sim_printf ("REWIND device_name\r\n");
3798   return SCPE_ARG;
3799 }
3800 
3801 // [UN]LOAD  name  image_name ro|rw
3802 //
3803 //  load tapea_05  data.tap ro
3804 //
3805 //  load diskb_01  data.dsk rw
3806 //
3807 
3808 t_stat load_media (int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3809   {
3810     // arg 1: load
3811     //     0: unload
3812 
3813     char  name[strlen (buf)];
3814     char fname[strlen (buf)];
3815     char  perm[strlen (buf)];
3816     bool ro = false;
3817     if (arg)
3818       {
3819         int rc = sscanf (buf, "%s %s %s", name, fname, perm);
3820         if (rc != 3)
3821           return SCPE_ARG;
3822         if (strcasecmp (perm, "rw") == 0)
3823           ro = false;
3824         else if (strcasecmp (perm, "ro") == 0)
3825           ro = true;
3826         else
3827           {
3828              sim_print ("'%s' not 'ro' or 'rw'\r\n", perm);
3829              goto usage;
3830           }
3831       }
3832     else
3833       {
3834         int rc = sscanf (buf, "%s", name);
3835         if (rc != 1)
3836           return SCPE_ARG;
3837       }
3838 
3839     for (uint i = 0; i < N_DSK_UNITS_MAX; i ++)
3840       if (strcmp (dsk_states[i].device_name, name) == 0)
3841         {
3842           if (arg)
3843             return loadDisk (i, fname, ro);
3844           return unloadDisk (i);
3845         }
3846 
3847     for (uint i = 0; i < N_MT_UNITS_MAX; i ++)
3848       if (strcmp (tape_states[i].device_name, name) == 0)
3849         {
3850           if (arg)
3851             return loadTape (i, fname, ro);
3852           return unloadTape (i);
3853         }
3854 
3855     sim_printf ("Can't find name '%s'\r\n", name);
3856 usage:
3857     sim_printf ("[UN]LOAD device_name image_name ro|rw\r\n");
3858     return SCPE_ARG;
3859   }
3860 
3861 t_stat ready_media (int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
3862   char name[strlen (buf)];
3863   int rc = sscanf (buf, "%s", name);
3864   if (rc != 1)
3865     return SCPE_ARG;
3866 
3867   for (uint i = 0; i < N_DSK_UNITS_MAX; i ++) {
3868     if (strcmp (dsk_states[i].device_name, name) == 0) {
3869       return signal_disk_ready (i);
3870     }
3871   }
3872 
3873   for (uint i = 0; i < N_MT_UNITS_MAX; i ++) {
3874     if (strcmp (tape_states[i].device_name, name) == 0) {
3875       return signal_tape (i, 0, 020 /* tape drive to ready */); //-V536
3876     }
3877   }
3878 
3879   sim_printf ("Can't find name '%s'\r\n", name);
3880   sim_printf ("[UN]LOAD device_name image_name ro|rw\r\n");
3881   return SCPE_ARG;
3882 }
3883 
3884 ////////////////////////////////////////////////////////////////////////////////
3885 //
3886 // s*mh Command table
3887 //
3888 
3889 #ifdef TESTING
3890 # include "tracker.h"
3891 
3892 static t_stat trkw (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3893   {
3894     trk_init (true);
3895     return SCPE_OK;
3896   }
3897 
3898 static t_stat trkr (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
3899   {
3900     trk_init (false);
3901     return SCPE_OK;
3902   }
3903 #endif
3904 
3905 #ifndef PERF_STRIP
3906 static CTAB dps8_cmds[] =
3907   {
3908 
3909 //
3910 // System configuration
3911 //
3912 
3913     {"DEFAULT_BASE_SYSTEM", set_default_base_system,  0, "Set configuration to defaults\n",             NULL, NULL },
3914 
3915     {"CABLE",               sys_cable,                0, "String a cable.\n",                            NULL, NULL },
3916     {"UNCABLE",             sys_cable,                1, "Unstring a cable.\n",                          NULL, NULL },
3917     {"CABLE_RIPOUT",        sys_cable_ripout,         0, "Remove all cables from the configuration.\n",                       NULL, NULL },
3918     {"CABLE_SHOW",          sys_cable_show,           0, "Show the current cabling configuration.\n",                               NULL, NULL },
3919 
3920     {"FNPSERVERPORT",       set_fnp_server_port,      0, "Set the FNP dialin TELNET port number\n",     NULL, NULL },
3921     {"FNPSERVERADDRESS",    set_fnp_server_address,   0, "Set the FNP dialin server binding address\n", NULL, NULL },
3922     {"FNPSERVER3270PORT",   set_fnp_3270_server_port, 0, "Set the FNP TN3270 dialin port number\n",     NULL, NULL },
3923 
3924 //
3925 // System control
3926 //
3927 
3928     {"SKIPBOOT",  boot_skip,                     0, "Skip forward on boot tape\n",                        NULL, NULL },
3929     {"FNPSTART",  fnp_start,                     0, "Directs the simulator to immediately start listening for FNP connections.\n",            NULL, NULL },
3930     {"MOUNT",     mount_tape,                    0, "Mount tape image and signal Multics\n",              NULL, NULL },
3931     {"LOAD",      load_media,                    1, "Mount disk or tape image and signal Multics\n",      NULL, NULL },
3932     {"UNLOAD",    load_media,                    0, "Unmount disk or tape image and signal Multics\n",    NULL, NULL },
3933     {"READY",     ready_media,                   0, "Signal Multics that media is ready\n",               NULL, NULL },
3934     {"REWIND",    rewind_media,                  0, "Rewind tape\n",                                      NULL, NULL },
3935     {"XF",        do_execute_fault,              0, "Execute fault: Press the execute fault button\n",    NULL, NULL },
3936     {"RESTART",   do_restart,                    0, "Execute fault: Press the execute fault button\n",    NULL, NULL },
3937     {"POLL",      set_sys_polling_interval,      0, "Set polling interval (in milliseconds)\n",           NULL, NULL },
3938     {"SLOWPOLL",  set_sys_slow_polling_interval, 0, "Set slow polling interval (in polling intervals).\n", NULL, NULL },
3939     {"CHECKPOLL", set_sys_poll_check_rate,       0, "Set polling check rate (in polling intervals).\n",    NULL, NULL },
3940     {"BURST",     burst_printer,                 0, "Burst process output from printer.\n",                NULL, NULL },
3941 
3942 //
3943 // Debugging
3944 //
3945 
3946 # ifdef TESTING
3947     {"TRKW",               trkw,                  0, "Start tracking to track.dat\n",                            NULL, NULL},
3948     {"TRKR",               trkr,                  0, "Start comparing with track.dat\n",                         NULL, NULL},
3949     {"DBGMMECNTDWN",       dps_debug_mme_cntdwn,  0, "Enable debug after n MMEs\n",                              NULL, NULL},
3950     {"DBGSKIP",            dps_debug_skip,        0, "Skip first n TRACE debugs\n",                              NULL, NULL},
3951     {"DBGSTART",           dps_debug_start,       0, "Limit debugging to N > Cycle count\n",                     NULL, NULL},
3952     {"DBGSTOP",            dps_debug_stop,        0, "Limit debugging to N < Cycle count\n",                     NULL, NULL},
3953     {"DBGBREAK",           dps_debug_break,       0, "Break when N >= Cycle count\n",                            NULL, NULL},
3954     {"DBGSEGNO",           dps_debug_segno,       1, "Limit debugging to PSR == segno\n",                        NULL, NULL},
3955     {"NODBGSEGNO",         dps_debug_segno,       0, "Reset to debugging all segments\n",                        NULL, NULL},
3956     {"DBGRINGNO",          dps_debug_ringno,      0, "Limit debugging to PRR == ringno\n",                       NULL, NULL},
3957     {"DBGBAR",             dps_debug_bar,         1, "Limit debugging to BAR mode\n",                            NULL, NULL},
3958     {"NODBGBAR",           dps_debug_bar,         0, "Limit debugging to BAR mode\n",                            NULL, NULL},
3959     {"HDBG",               hdbg_size,             0, "Set history debugger buffer size\n",                       NULL, NULL},
3960     {"HDSEG",              hdbgSegmentNumber,     0, "Set history debugger segment number\n",                    NULL, NULL},
3961     {"HDBL",               hdbgBlacklist,         0, "Set history debugger blacklist\n",                         NULL, NULL},
3962     {"PHDBG",              hdbg_print,            0, "Display history size\n",                                   NULL, NULL},
3963     {"HDBG_CPU_MASK",      hdbg_cpu_mask,         0, "Set which CPUs to track (by mask)\n",                      NULL, NULL},
3964     {"ABSOLUTE",           abs_addr,              0, "Compute the absolute address of segno:offset\n",           NULL, NULL},
3965     {"STK",                stack_trace,           0, "Print a stack trace\n",                                    NULL, NULL},
3966     {"LIST",               list_source_at,        0, "List source for address / segno:offset\n",                 NULL, NULL},
3967     {"LD_SYSTEM_BOOK",     load_system_book,      0, "Load a Multics system book for symbolic debugging\n",      NULL, NULL},
3968     {"ASBE",               add_system_book_entry, 0, "Add an entry to the system book\n",                        NULL, NULL},
3969     {"LOOKUP_SYSTEM_BOOK", lookup_system_book,    0, "Lookup an address or symbol in the Multics system book\n", NULL, NULL},
3970     {"LSB",                lookup_system_book,    0, "Lookup an address or symbol in the Multics system book\n", NULL, NULL},
3971     {"VIRTUAL",            virt_address,          0, "Compute the virtual address(es) of segno:offset\n",        NULL, NULL},
3972     {"SPATH",              set_search_path,       0, "Set source code search path\n",                            NULL, NULL},
3973     {"TEST",               brkbrk,                0, "GDB test hook\n",                                          NULL, NULL},
3974 #  ifdef DBGEVENT
3975     {"DBG0EVENT",          set_dbgevent,          0, "Set t0 debug event\n",                                     NULL, NULL},
3976     {"DBGEVENT",           set_dbgevent,          1, "Set debug event\n",                                        NULL, NULL},
3977     {"DBGNOEVENT",         set_dbgevent,          2, "Clear debug event\n",                                      NULL, NULL},
3978     {"DBGLISTEVENTS",      set_dbgevent,          3, "List debug events\n",                                      NULL, NULL},
3979     {"DBGCLEAREVENTS",     set_dbgevent,          4, "Clear debug events\n",                                     NULL, NULL},
3980 #  endif
3981 
3982 // copied from scp.c
3983 #  define SSH_ST 0        /* set */
3984 #  define SSH_SH 1        /* show */
3985 #  define SSH_CL 2        /* clear */
3986     {"SBREAK",       sbreak,           SSH_ST, "Set a breakpoint with segno:offset syntax\n", NULL, NULL},
3987     {"NOSBREAK",     sbreak,           SSH_CL, "Unset an SBREAK\n",                           NULL, NULL},
3988 #  ifdef DVFDBG
3989     // dvf debugging
3990     {"DFX1ENTRY",    dfx1entry,        0,      "\n",                                          NULL, NULL},
3991     {"DFX2ENTRY",    dfx2entry,        0,      "\n",                                          NULL, NULL},
3992     {"DFX1EXIT",     dfx1exit,         0,      "\n",                                          NULL, NULL},
3993     {"DV2SCALE",     dv2scale,         0,      "\n",                                          NULL, NULL},
3994     {"MDFX3ENTRY",   mdfx3entry,       0,      "\n",                                          NULL, NULL},
3995     {"SMFX1ENTRY",   smfx1entry,       0,      "\n",                                          NULL, NULL},
3996 #  endif
3997     // doesn't work
3998     //{"DUMPKST",             dumpKST,                  0, "dumpkst: dump the Known Segment Table\n", NULL},
3999 #  ifndef SPEED
4000     {"WATCH",        set_mem_watch,    1,      "Watch memory location\n",                     NULL, NULL},
4001     {"NOWATCH",      set_mem_watch,    0,      "Unwatch memory location\n",                   NULL, NULL},
4002 #  endif
4003     {"SEARCHMEMORY", search_memory,    0,      "Search memory for value\n",                   NULL, NULL},
4004     {"DBGCPUMASK",   set_dbg_cpu_mask, 0,      "Set per-CPU debug enable mask\n",             NULL, NULL},
4005 # endif // TESTING
4006 
4007     {"SEGLDR",       segment_loader,   0,      "Segment Loader\n",                            NULL, NULL},
4008 
4009 //
4010 // Statistics
4011 //
4012 
4013 # ifdef MATRIX
4014     {"DISPLAYMATRIX", display_the_matrix,  0, "Display instruction usage counts\n", NULL, NULL},
4015 # endif
4016 
4017 //
4018 // Console scripting
4019 //
4020 
4021     {"AUTOINPUT",     add_opc_autoinput,   0, "Set primary console auto-input\n",     NULL, NULL},
4022     {"AI",            add_opc_autoinput,   0, "Set primary console auto-input\n",     NULL, NULL},
4023     {"AUTOINPUT2",    add_opc_autoinput,   1, "Set secondary console auto-input\n",   NULL, NULL},
4024     {"AI2",           add_opc_autoinput,   1, "Set secondary console auto-input\n",   NULL, NULL},
4025     {"CLRAUTOINPUT",  clear_opc_autoinput, 0, "Clear primary console auto-input\n",   NULL, NULL},
4026     {"CLRAUTOINPUT2", clear_opc_autoinput, 1, "Clear secondary console auto-input\n", NULL, NULL},
4027 
4028 //
4029 // Tuning
4030 //
4031 
4032 # if YIELD
4033     {"CLEAR_YIELD",   clear_yield,         1, "Clear yield data points\n",          NULL, NULL},
4034     {"YIELD",         yield,               1, "Define yield data point\n",          NULL, NULL},
4035 # endif
4036 
4037 //
4038 // Hacks
4039 //
4040 
4041     {"LUF",           set_luf,             1, "Enable normal LUF handling\n",       NULL, NULL},
4042     {"NOLUF",         set_luf,             0, "Disable normal LUF handling\n",      NULL, NULL},
4043 
4044 //
4045 // Misc.
4046 //
4047 
4048 # ifdef PANEL68
4049     {"SCRAPER",       scraper,             0, "Control panel scraper\n", NULL, NULL},
4050 # endif
4051     { NULL,           NULL,                0, NULL,                      NULL, NULL}
4052   }; // dps8_cmds
4053 
4054 # ifndef __MINGW64__
4055 #  ifndef __MINGW32__
4056 #   ifndef CROSS_MINGW64
4057 #    ifndef CROSS_MINGW32
4058 #     ifndef PERF_STRIP
4059 static void usr1_signal_handler (UNUSED int sig)
     /* [previous][next][first][last][top][bottom][index][help] */
4060   {
4061     sim_msg ("USR1 signal caught; pressing the EXF button\n");
4062     // Assume the bootload CPU
4063     setG7fault (ASSUME0, FAULT_EXF, fst_zero);
4064     return;
4065   }
4066 #     endif /* ifndef PERF_STRIP */
4067 #    endif /* ifndef CROSS_MINGW32 */
4068 #   endif /* ifndef CROSS_MINGW64 */
4069 #  endif /* ifndef __MINGW32__ */
4070 # endif /* ifndef __MINGW64__ */
4071 
4072 static struct symbol_s symbols [] = {
4073     { "commit_id",              SYM_STATE_OFFSET,  SYM_STRING,    offsetof (struct system_state_s, commit_id) },
4074     { "M[]",                    SYM_STATE_OFFSET,  SYM_ARRAY,     offsetof (struct system_state_s, M) },
4075     { "sizeof(*M)",             SYM_STRUCT_SZ,     SYM_SZ,        sizeof (word36) },
4076 
4077     { "cpus[]",                 SYM_STATE_OFFSET,  SYM_ARRAY,     offsetof (struct system_state_s, cpus) },
4078     { "sizeof(*cpus)",          SYM_STRUCT_SZ,     SYM_SZ,        sizeof (cpu_state_t) },
4079 
4080     { "cpus[].PPR",             SYM_STRUCT_OFFSET, SYM_PTR,       offsetof (cpu_state_t,           PPR) },
4081     { "cpus[].PPR.PRR",         SYM_STRUCT_OFFSET, SYM_UINT8_3,   offsetof (struct ppr_s,          PRR) },
4082     { "cpus[].PPR.PSR",         SYM_STRUCT_OFFSET, SYM_UINT16_15, offsetof (struct ppr_s,          PSR) },
4083     { "cpus[].PPR.P",           SYM_STRUCT_OFFSET, SYM_UINT8_1,   offsetof (struct ppr_s,          P) },
4084     { "cpus[].PPR.IC",          SYM_STRUCT_OFFSET, SYM_UINT32_18, offsetof (struct ppr_s,          IC) },
4085 
4086     { "cpus[].cu",              SYM_STRUCT_OFFSET, SYM_PTR,       offsetof (cpu_state_t,           cu) },
4087     { "cpus[].cu.IWB",          SYM_STRUCT_OFFSET, SYM_UINT64_36, offsetof (ctl_unit_data_t,       IWB) },
4088     { "cpus[].cu.IR",           SYM_STRUCT_OFFSET, SYM_UINT32_18, offsetof (ctl_unit_data_t,       IR) },
4089 
4090     { "cpus[].rA",              SYM_STRUCT_OFFSET, SYM_UINT64_36, offsetof (cpu_state_t,           rA) },
4091 
4092     { "cpus[].rQ",              SYM_STRUCT_OFFSET, SYM_UINT64_36, offsetof (cpu_state_t,           rQ) },
4093 
4094     { "cpus[].rE",              SYM_STRUCT_OFFSET, SYM_UINT64_36, offsetof (cpu_state_t,           rE) },
4095 
4096     { "cpus[].rX[]",            SYM_STRUCT_OFFSET, SYM_ARRAY,     offsetof (cpu_state_t,           rX) },
4097     { "sizeof(*rX)",            SYM_STRUCT_SZ,     SYM_SZ,        sizeof (word18) },
4098     { "cpus[].rX",              SYM_STRUCT_OFFSET, SYM_UINT32_18, 0 },
4099 
4100     { "cpus[].rTR",             SYM_STRUCT_OFFSET, SYM_UINT32_27, offsetof (cpu_state_t,           rTR) },
4101 
4102     { "cpus[].rRALR",           SYM_STRUCT_OFFSET, SYM_UINT8_3,   offsetof (cpu_state_t,           rRALR) },
4103 
4104     { "cpus[].PAR[]",           SYM_STRUCT_OFFSET, SYM_ARRAY,     offsetof (cpu_state_t,           PAR) },
4105     { "sizeof(*PAR)",           SYM_STRUCT_SZ,     SYM_SZ,        sizeof (struct par_s) },
4106 
4107     { "cpus[].PAR[].SNR",       SYM_STRUCT_OFFSET, SYM_UINT16_15, offsetof (struct par_s,          SNR) },
4108     { "cpus[].PAR[].RNR",       SYM_STRUCT_OFFSET, SYM_UINT8_3,   offsetof (struct par_s,          RNR) },
4109     { "cpus[].PAR[].PR_BITNO",  SYM_STRUCT_OFFSET, SYM_UINT8_6,   offsetof (struct par_s,          PR_BITNO) },
4110     { "cpus[].PAR[].WORDNO",    SYM_STRUCT_OFFSET, SYM_UINT32_18, offsetof (struct par_s,          WORDNO) },
4111 
4112     { "cpus[].BAR",             SYM_STRUCT_OFFSET, SYM_PTR,       offsetof (cpu_state_t,           BAR) },
4113     { "cpus[].BAR.BASE",        SYM_STRUCT_OFFSET, SYM_UINT16_9,  offsetof (struct bar_s,          BASE) },
4114     { "cpus[].BAR.BOUND",       SYM_STRUCT_OFFSET, SYM_UINT16_9,  offsetof (struct bar_s,          BOUND) },
4115 
4116     { "cpus[].TPR",             SYM_STRUCT_OFFSET, SYM_PTR,       offsetof (cpu_state_t,           TPR) },
4117     { "cpus[].TPR.TRR",         SYM_STRUCT_OFFSET, SYM_UINT8_3,   offsetof (struct tpr_s,          TRR) },
4118     { "cpus[].TPR.TSR",         SYM_STRUCT_OFFSET, SYM_UINT16_15, offsetof (struct tpr_s,          TSR) },
4119     { "cpus[].TPR.TBR",         SYM_STRUCT_OFFSET, SYM_UINT8_6,   offsetof (struct tpr_s,          TBR) },
4120     { "cpus[].TPR.CA",          SYM_STRUCT_OFFSET, SYM_UINT32_18, offsetof (struct tpr_s,          CA) },
4121 
4122     { "cpus[].DSBR",            SYM_STRUCT_OFFSET, SYM_PTR,       offsetof (cpu_state_t,           DSBR) },
4123     { "cpus[].DSBR.ADDR",       SYM_STRUCT_OFFSET, SYM_UINT32_24, offsetof (struct dsbr_s,         ADDR) },
4124     { "cpus[].DSBR.BND",        SYM_STRUCT_OFFSET, SYM_UINT16_14, offsetof (struct dsbr_s,         BND) },
4125     { "cpus[].DSBR.U",          SYM_STRUCT_OFFSET, SYM_UINT8_1,   offsetof (struct dsbr_s,         U) },
4126     { "cpus[].DSBR.STACK",      SYM_STRUCT_OFFSET, SYM_UINT16_12, offsetof (struct dsbr_s,         STACK) },
4127 
4128     { "cpus[].faultNumber",     SYM_STRUCT_OFFSET, SYM_UINT32,    offsetof (cpu_state_t,           faultNumber) },
4129 # define SYMTAB_ENUM32(e) { #e,  SYM_ENUM,          SYM_UINT32,    e }
4130     SYMTAB_ENUM32 (FAULT_SDF),
4131     SYMTAB_ENUM32 (FAULT_STR),
4132     SYMTAB_ENUM32 (FAULT_MME),
4133     SYMTAB_ENUM32 (FAULT_F1),
4134     SYMTAB_ENUM32 (FAULT_TRO),
4135     SYMTAB_ENUM32 (FAULT_CMD),
4136     SYMTAB_ENUM32 (FAULT_DRL),
4137     SYMTAB_ENUM32 (FAULT_LUF),
4138     SYMTAB_ENUM32 (FAULT_CON),
4139     SYMTAB_ENUM32 (FAULT_PAR),
4140     SYMTAB_ENUM32 (FAULT_IPR),
4141     SYMTAB_ENUM32 (FAULT_ONC),
4142     SYMTAB_ENUM32 (FAULT_SUF),
4143     SYMTAB_ENUM32 (FAULT_OFL),
4144     SYMTAB_ENUM32 (FAULT_DIV),
4145     SYMTAB_ENUM32 (FAULT_EXF),
4146     SYMTAB_ENUM32 (FAULT_DF0),
4147     SYMTAB_ENUM32 (FAULT_DF1),
4148     SYMTAB_ENUM32 (FAULT_DF2),
4149     SYMTAB_ENUM32 (FAULT_DF3),
4150     SYMTAB_ENUM32 (FAULT_ACV),
4151     SYMTAB_ENUM32 (FAULT_MME2),
4152     SYMTAB_ENUM32 (FAULT_MME3),
4153     SYMTAB_ENUM32 (FAULT_MME4),
4154     SYMTAB_ENUM32 (FAULT_F2),
4155     SYMTAB_ENUM32 (FAULT_F3),
4156     SYMTAB_ENUM32 (FAULT_UN1),
4157     SYMTAB_ENUM32 (FAULT_UN2),
4158     SYMTAB_ENUM32 (FAULT_UN3),
4159     SYMTAB_ENUM32 (FAULT_UN4),
4160     SYMTAB_ENUM32 (FAULT_UN5),
4161     SYMTAB_ENUM32 (FAULT_TRB),
4162 
4163     { "",                       SYM_EMPTY,         SYM_UNDEF,     0 },
4164   };
4165 
4166 static void systabInit (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
4167   strncpy (system_state->symbolTable.symtabHdr, SYMTAB_HDR, sizeof (system_state->symbolTable.symtabHdr));
4168   system_state->symbolTable.symtabVer = SYMTAB_VER;
4169   memcpy (system_state->symbolTable.symbols, symbols, sizeof (symbols)); //-V1086
4170 }
4171 #endif /* ifndef PERF_STRIP */
4172 
4173 // Once-only initialization; invoked via SCP
4174 
4175 static void dps8_init (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
4176   int st1ret;
4177   fflush(stderr); fflush(stdout);
4178 #ifndef PERF_STRIP
4179   if (!sim_quiet) {
4180 # if defined(GENERATED_MAKE_VER_H) && defined(VER_H_GIT_VERSION)
4181 #  if defined(VER_H_GIT_PATCH_INT) && defined(VER_H_GIT_PATCH)
4182 #   if VER_H_GIT_PATCH_INT < 1
4183     sim_msg ("%s simulator %s (%ld-bit)",
4184              sim_name, VER_H_GIT_VERSION,
4185              (long)(CHAR_BIT*sizeof(void *)));
4186 #   else
4187     sim_msg ("%s simulator %s+%s (%ld-bit)",
4188              sim_name, VER_H_GIT_VERSION, VER_H_GIT_PATCH,
4189              (long)(CHAR_BIT*sizeof(void *)));
4190 #   endif
4191 #  else
4192     sim_msg ("%s simulator %s (%ld-bit)",
4193              sim_name, VER_H_GIT_VERSION,
4194              (long)(CHAR_BIT*sizeof(void *)));
4195 #  endif
4196 # endif
4197 # if !defined(VER_H_GIT_VERSION) || !defined(GENERATED_MAKE_VER_H)
4198     sim_msg ("%s simulator (%ld-bit)",
4199              sim_name, (long)(CHAR_BIT*sizeof(void *)));
4200 # endif
4201 # ifdef TESTING
4202     sim_msg ("\n Options: ");
4203 #  ifndef HAVE_DPSOPT
4204 #   define HAVE_DPSOPT 1
4205 #  endif
4206     sim_msg ("TESTING");
4207 # endif
4208 # ifdef NEED_128
4209 #  ifdef HAVE_DPSOPT
4210     sim_msg (", ");
4211 #  else
4212     sim_msg ("\n Options: ");
4213 #  endif
4214 #  ifndef HAVE_DPSOPT
4215 #   define HAVE_DPSOPT 1
4216 #  endif
4217     sim_msg ("NEED_128");
4218 # endif
4219 # ifdef ROUND_ROBIN
4220 #  ifdef HAVE_DPSOPT
4221     sim_msg (", ");
4222 #  else
4223     sim_msg ("\n Options: ");
4224 #  endif
4225 #  ifndef HAVE_DPSOPT
4226 #   define HAVE_DPSOPT 1
4227 #  endif
4228     sim_msg ("ROUND_ROBIN");
4229 # endif
4230 # ifndef LOCKLESS
4231 #  ifdef HAVE_DPSOPT
4232     sim_msg (", ");
4233 #  else
4234     sim_msg ("\n Options: ");
4235 #  endif
4236 #  ifndef HAVE_DPSOPT
4237 #   define HAVE_DPSOPT 1
4238 #  endif
4239     sim_msg ("NO_LOCKLESS");
4240 # endif
4241 # if defined(GENERATED_MAKE_VER_H) && defined(VER_H_GIT_HASH)
4242     sim_msg ("\n  Commit: %s", VER_H_GIT_HASH);
4243 # endif
4244     sim_msg ("\r\n\r\n");
4245     fflush(stderr); fflush(stdout);
4246   }
4247 
4248   // special dps8 initialization stuff that can't be done in reset, etc. ...
4249 
4250 # ifdef TESTING
4251   // These are part of the scp interface
4252   sim_vm_parse_addr  = parse_addr;
4253   sim_vm_fprint_addr = fprint_addr;
4254 # endif // TESTING
4255 
4256   sim_vm_cmd = dps8_cmds;
4257 
4258   // This is needed to make sbreak work
4259   sim_brk_types = sim_brk_dflt = SWMASK ('E');
4260 
4261 # ifndef __MINGW64__
4262 #  ifndef __MINGW32__
4263 #   ifndef CROSS_MINGW32
4264 #    ifndef CROSS_MINGW64
4265   // Wire the XF button to signal USR1
4266   signal (SIGUSR1, usr1_signal_handler);
4267   // On line 4,739 of the libuv man page, it recommends this.
4268   signal(SIGPIPE, SIG_IGN);
4269 #    endif /* ifndef CROSS_MINGW64 */
4270 #   endif /* ifndef CROSS_MINGW32 */
4271 #  endif /* ifndef __MINGW32__ */
4272 # endif /* ifndef __MINGW64__ */
4273 
4274 #endif // ! PERF_STRIP
4275 
4276 #if defined(__MINGW64__) || defined(__MINGW32__)
4277 # include "bsd_random.h"
4278 # define random  bsd_random
4279 # define srandom bsd_srandom
4280 #endif /* if defined(__MINGW64__) || defined(__MINGW32__) */
4281 
4282   char   rcap = 0;
4283   char   rnum = 0;
4284   struct timespec ts;
4285 
4286   char   rssuffix[24];
4287   memset(rssuffix, 0, 24);
4288 
4289   char   statenme[32];
4290   memset(statenme, 0, 32);
4291 
4292 #ifdef USE_MONOTONIC
4293   st1ret = clock_gettime(CLOCK_MONOTONIC, &ts);
4294 #else
4295   st1ret = clock_gettime(CLOCK_REALTIME, &ts);
4296 #endif /*ifdef USE_MONOTONIC */
4297   if (st1ret != 0)
4298     {
4299       fprintf (stderr, "\rFATAL: clock_gettime failure! Aborting at %s[%s:%d]\r\n",
4300                __func__, __FILE__, __LINE__);
4301 #if defined(USE_BACKTRACE)
4302 # ifdef SIGUSR2
4303       (void)raise(SIGUSR2);
4304       /*NOTREACHED*/ /* unreachable */
4305 # endif /* ifdef SIGUSR2 */
4306 #endif /* if defined(USE_BACKTRACE) */
4307       abort();
4308     }
4309 
4310   srandom((unsigned int)(getpid() ^ (long)((1LL + (long long)ts.tv_nsec) * (1LL + (long long)ts.tv_sec))));
4311 
4312   for (int i = 1; i < 21; ++i) {
4313     rcap = (int)random() % 2;
4314     rnum = (int)random() % 3;
4315     if (!rnum) rnum = (((int)random() % 10) + 48);
4316     if (!rcap) rcap = 33;
4317     if (rnum >= 48) rssuffix[i-1]=rnum;
4318     else rssuffix[i-1]=(char)(((long)random() % 26) + 64) + rcap;
4319   }
4320 
4321 #if defined(__MINGW64__)   || \
4322     defined(__MINGW32__)   || \
4323     defined(CROSS_MINGW32) || \
4324     defined(CROSS_MINGW64)
4325   system_state = malloc (sizeof (struct system_state_s));
4326 #else
4327   if (sim_randstate)
4328     sprintf(statenme, "%s.state", rssuffix);
4329   else
4330     sprintf(statenme, "state");
4331   if (!sim_nostate)
4332     system_state = (struct system_state_s *)
4333       create_shm (statenme, sizeof (struct system_state_s));
4334   else
4335     system_state = malloc (sizeof (struct system_state_s));
4336 #endif
4337 
4338   if (!system_state) {
4339     int svErrno = errno;
4340     fflush(stderr); fflush(stdout);
4341     sim_warn ("\rFATAL: %s: aborting at %s[%s:%d]\r\n",
4342               strerror (svErrno),
4343               __func__, __FILE__, __LINE__);
4344 #if defined(USE_BACKTRACE)
4345 # ifdef SIGUSR2
4346     (void)raise(SIGUSR2);
4347     /*NOTREACHED*/ /* unreachable */
4348 # endif /* ifdef SIGUSR2 */
4349 #endif /* if defined(USE_BACKTRACE) */
4350     exit (svErrno);
4351   }
4352 
4353 #ifndef PERF_STRIP
4354 
4355 # ifndef VER_H_GIT_HASH
4356 #  define VER_H_GIT_HASH "0000000000000000000000000000000000000000"
4357 # endif
4358 
4359   fflush(stdout); fflush(stderr);
4360   if (strlen (system_state->commit_id) == 0) {
4361     if (!sim_quiet && sim_randstate && sim_randompst)
4362       sim_printf ("Initialized new system state file \"dps8m.%s\"\r\n",
4363                   statenme);
4364   } else {
4365     if (strcmp (system_state->commit_id, VER_H_GIT_HASH) != 0) {
4366       memset(system_state, 0, sizeof(*system_state));
4367       sim_warn ("NOTE: State hash mismatch; system state reset.\r\n");
4368     }
4369   }
4370   fflush(stderr); fflush(stdout);
4371 
4372   strncpy (system_state->stateHdr, STATE_HDR, sizeof (system_state->stateHdr));
4373   system_state->stateVer = STATE_VER;
4374   strncpy (system_state->commit_id, VER_H_GIT_HASH, sizeof (system_state->commit_id));
4375 
4376   systabInit ();
4377 
4378   // sets connect to 0
4379   memset (& sys_opts, 0, sizeof (sys_opts));
4380   // sys_poll_interval 10 ms (100 Hz)
4381   sys_opts.sys_poll_interval      = 10;
4382   // sys_slow_poll_interval 100 polls (1 Hz)
4383   sys_opts.sys_slow_poll_interval = 100;
4384   // sys_poll_check_rate in CPU cycles
4385   sys_opts.sys_poll_check_rate    = 1024;
4386 #endif // ! PERF_STRIP
4387 
4388 #ifdef PERF_STRIP
4389   cpu_init ();
4390 #else
4391   sysCableInit ();
4392   iom_init ();
4393   disk_init ();
4394   mt_init ();
4395 # ifdef WITH_SOCKET_DEV
4396 #  ifndef __MINGW64__
4397 #   ifndef __MINGW32__
4398 #    ifndef CROSS_MINGW64
4399 #     ifndef CROSS_MINGW32
4400   sk_init ();
4401 #     endif /* ifndef CROSS_MINGW32 */
4402 #    endif /* ifndef CROSS_MINGW64 */
4403 #   endif /* ifndef __MINGW64__ */
4404 #  endif /* ifndef __MINGW32__ */
4405 # endif /* ifdef WITH_SOCKET_DEV */
4406   fnpInit ();
4407   console_init (); // must come after fnpInit due to libuv initialization
4408  /* mpc_init (); */
4409   scu_init ();
4410   cpu_init ();
4411   rdr_init ();
4412   pun_init ();
4413   prt_init ();
4414   urp_init ();
4415 # ifdef WITH_ABSI_DEV
4416 #  ifndef __MINGW64__
4417 #   ifndef __MINGW32__
4418 #    ifndef CROSS_MINGW64
4419 #     ifndef CROSS_MINGW32
4420   absi_init ();
4421 #     endif /* CROSS_MINGW32 */
4422 #    endif /* CROSS_MINGW64 */
4423 #   endif /* ifndef __MINGW32__ */
4424 #  endif /* ifndef __MINGW64__ */
4425 # endif /* ifdef WITH_ABSI_DEV */
4426   set_default_base_system (0, NULL);
4427 # ifdef PANEL68
4428   panelScraperInit ();
4429 # endif /* ifdef PANEL68 */
4430 #endif
4431 #if defined(THREADZ) || defined(LOCKLESS)
4432   initThreadz ();
4433 #endif /* if defined(THREADZ) || defined(LOCKLESS) */
4434 }
4435 
4436 // Once-only shutdown; invoked via SCP
4437 
4438 static void dps8_exit (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
4439   console_exit ();
4440   mt_exit ();
4441   fnpExit ();
4442 }
4443 
4444 #ifdef TESTING
4445 static struct pr_table
4446   {
4447     char  * alias;    // pr alias
4448     int   n;          // number alias represents ....
4449   } _prtab[] =
4450   {
4451     {"pr0",   0}, ///< pr0 - 7
4452     {"pr1",   1},
4453     {"pr2",   2},
4454     {"pr3",   3},
4455     {"pr4",   4},
4456     {"pr5",   5},
4457     {"pr6",   6},
4458     {"pr7",   7},
4459 
4460     {"pr[0]", 0}, ///< pr0 - 7
4461     {"pr[1]", 1},
4462     {"pr[2]", 2},
4463     {"pr[3]", 3},
4464     {"pr[4]", 4},
4465     {"pr[5]", 5},
4466     {"pr[6]", 6},
4467     {"pr[7]", 7},
4468 
4469     // See: https://multicians.org/pg/mvm.html
4470     {"ap",    0},
4471     {"ab",    1},
4472     {"bp",    2},
4473     {"bb",    3},
4474     {"lp",    4},
4475     {"lb",    5},
4476     {"sp",    6},
4477     {"sb",    7},
4478     {0,       0}
4479   };
4480 
4481 static int getAddress(int segno, int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
4482 {
4483     // XXX Do we need to 1st check SDWAM for segment entry?
4484 
4485     // get address of in-core segment descriptor word from DSBR
4486     sdw0_s *s = fetchSDW ((word15) segno);
4487 
4488     return (s->ADDR + (word18) offset) & 0xffffff; // keep to 24-bits
4489 }
4490 
4491 static t_addr parse_addr (UNUSED DEVICE * dptr, const char *cptr,
     /* [previous][next][first][last][top][bottom][index][help] */
4492                           const char **optr)
4493   {
4494     // a segment reference?
4495     if (strchr(cptr, '|'))
4496     {
4497         static char addspec[256];
4498         strcpy(addspec, cptr);
4499 
4500         *strchr(addspec, '|') = ' ';
4501 
4502         char seg[256], off[256];
4503         int params = sscanf(addspec, "%s %s", seg, off);
4504         if (params != 2)
4505         {
4506             sim_warn("parse_addr(): illegal number of parameters\n");
4507             *optr = cptr;   // signal error
4508             return 0;
4509         }
4510 
4511         // determine if segment is numeric or symbolic...
4512         char *endp;
4513         word18 PRoffset = 0;   // offset from PR[n] register (if any)
4514         int segno = (int)strtoll(seg, &endp, 8);
4515         if (endp == seg)
4516         {
4517             // not numeric...
4518             // 1st, see if it's a PR or alias thereof
4519             struct pr_table *prt = _prtab;
4520             while (prt->alias)
4521             {
4522                 if (strcasecmp(seg, prt->alias) == 0)
4523                 {
4524                     segno = cpu.PR[prt->n].SNR;
4525                     PRoffset = cpu.PR[prt->n].WORDNO;
4526                     break;
4527                 }
4528 
4529                 prt += 1;
4530             }
4531 
4532             if (!prt->alias)    // not a PR or alias
4533             {
4534               return 0;
4535             }
4536         }
4537 
4538         // determine if offset is numeric or symbolic entry point/segdef...
4539         uint offset = (uint)strtoll(off, &endp, 8);
4540         if (endp == off)
4541         {
4542             // not numeric...
4543             return 0;
4544         }
4545 
4546         // if we get here then seg contains a segment# and offset.
4547         // So, fetch the actual address given the segment & offset ...
4548         // ... and return this absolute, 24-bit address
4549 
4550         word24 abs_addr = (word24) getAddress(segno, (int) (offset + PRoffset));
4551 
4552         // TODO: only by luck does this work FixMe
4553         *optr = endp;   //cptr + strlen(cptr);
4554 
4555         return abs_addr;
4556     }
4557     else
4558     {
4559         // a PR or alias thereof
4560         int segno = 0;
4561         word24 offset = 0;
4562         struct pr_table *prt = _prtab;
4563         while (prt->alias)
4564         {
4565             if (strncasecmp(cptr, prt->alias, strlen(prt->alias)) == 0)
4566             {
4567                 segno  = cpu.PR[prt->n].SNR;
4568                 offset = cpu.PR[prt->n].WORDNO;
4569                 break;
4570             }
4571 
4572             prt += 1;
4573         }
4574         if (prt->alias)    // a PR or alias
4575         {
4576             word24 abs_addr = (word24) getAddress(segno, (int) offset);
4577             *optr = cptr + strlen(prt->alias);
4578 
4579             return abs_addr;
4580         }
4581     }
4582 
4583     // No, determine absolute address given by cptr
4584     return (t_addr)strtol(cptr, (char **) optr, 8);
4585 }
4586 #endif // TESTING
4587 
4588 #ifdef TESTING
4589 static void fprint_addr (FILE * stream, UNUSED DEVICE *  dptr, t_addr simh_addr)
     /* [previous][next][first][last][top][bottom][index][help] */
4590 {
4591     fprintf(stream, "%06o", simh_addr);
4592 }
4593 #endif // TESTING
4594 
4595 // This is part of the scp interface
4596 // Based on the switch variable, symbolically output to stream ofile the data in
4597 //  array val at the specified addr in unit uptr.
4598 // "fprint_sym" – Based on the switch variable, symbolically output to
4599 // stream ofile the data in array val at the specified addr in unit uptr.
4600 
4601 t_stat fprint_sym (UNUSED FILE * ofile, UNUSED t_addr addr,
     /* [previous][next][first][last][top][bottom][index][help] */
4602                    UNUSED t_value *val, UNUSED UNIT *uptr, int32 UNUSED sw)
4603 {
4604 #ifdef TESTING
4605 // XXX Bug: assumes single cpu
4606 // XXX CAC: This seems rather bogus; deciding the output format based on the
4607 // address of the UNIT? Would it be better to use sim_unit.u3 (or some such
4608 // as a word width?
4609 
4610     if (!((uint) sw & SWMASK ('M')))
4611         return SCPE_ARG;
4612 
4613     if (uptr == &cpu_dev.units[0])
4614     {
4615         word36 word1 = *val;
4616         char buf[256];
4617         // get base syntax
4618         char *d = disassemble(buf, word1);
4619 
4620         fprintf(ofile, "%s", d);
4621 
4622         // decode instruction
4623         DCDstruct ci;
4624         DCDstruct * p = & ci;
4625         decode_instruction (word1, p);
4626 
4627         // MW EIS?
4628         if (p->info->ndes > 1)
4629         {
4630             // Yup, just output word values (for now)
4631             // XXX Need to complete MW EIS support in disassemble()
4632 
4633             for(uint n = 0 ; n < p->info->ndes; n += 1)
4634                 fprintf(ofile, " %012llo", (unsigned long long int)val[n + 1]);
4635 
4636             return (t_stat) -p->info->ndes;
4637         }
4638 
4639         return SCPE_OK;
4640 
4641         //fprintf(ofile, "%012"PRIo64"", *val);
4642         //return SCPE_OK;
4643     }
4644 #endif
4645     return SCPE_ARG;
4646 }
4647 
4648 // This is part of the scp interface
4649 //  – Based on the switch variable, parse character string cptr for a
4650 //  symbolic value val at the specified addr in unit uptr.
4651 
4652 t_stat parse_sym (UNUSED const char * cptr, UNUSED t_addr addr,
     /* [previous][next][first][last][top][bottom][index][help] */
4653                   UNUSED UNIT * uptr, UNUSED t_value * val, UNUSED int32 sswitch)
4654   {
4655     return SCPE_ARG;
4656   }
4657 
4658 // from MM
4659 
4660 sysinfo_t sys_opts;
4661 
4662 static t_stat sys_show_config (UNUSED FILE * st, UNUSED UNIT * uptr,
     /* [previous][next][first][last][top][bottom][index][help] */
4663                                UNUSED int  val, UNUSED const void * desc)
4664   {
4665     sim_msg ("IOM connect time:         %d\n",
4666                 sys_opts.iom_times.connect);
4667     return SCPE_OK;
4668 }
4669 
4670 static config_value_list_t cfg_timing_list[] =
4671   {
4672     { "disable", -1 },
4673     {  NULL,      0 }
4674   };
4675 
4676 bool breakEnable = false;
4677 
4678 static t_stat sys_set_break (UNUSED UNIT *  uptr, int32 value,
     /* [previous][next][first][last][top][bottom][index][help] */
4679                              UNUSED const char * cptr, UNUSED void * desc)
4680   {
4681     breakEnable = !! value;
4682     return SCPE_OK;
4683   }
4684 
4685 static t_stat sys_show_break (UNUSED FILE * st, UNUSED UNIT * uptr,
     /* [previous][next][first][last][top][bottom][index][help] */
4686                               UNUSED int  val, UNUSED const void * desc)
4687   {
4688     sim_msg ("BREAK %s\r\n", breakEnable ? "ON" : "OFF" );
4689     return SCPE_OK;
4690   }
4691 
4692 static config_value_list_t cfg_on_off [] =
4693   {
4694     { "off",     0 },
4695     { "on",      1 },
4696     { "disable", 0 },
4697     { "enable",  1 },
4698     {  NULL,     0 }
4699   };
4700 
4701 static config_list_t sys_config_list[] =
4702   {
4703     { "connect_time", -1,  100000, cfg_timing_list },
4704     { "color",         0,  1,      cfg_on_off      },
4705     { NULL,            0,  0,      NULL            }
4706  };
4707 
4708 static t_stat sys_set_config (UNUSED UNIT *  uptr, UNUSED int32 value,
     /* [previous][next][first][last][top][bottom][index][help] */
4709                               const char * cptr, UNUSED void * desc)
4710   {
4711     config_state_t cfg_state = { NULL, NULL };
4712 
4713     for (;;)
4714       {
4715         int64_t v;
4716         int rc = cfg_parse ("sys_set_config", cptr, sys_config_list, & cfg_state,
4717                            & v);
4718         if (rc == -1) // done
4719           {
4720             break;
4721           }
4722         if (rc == -2) // error
4723           {
4724             cfg_parse_done (& cfg_state);
4725             return SCPE_ARG;
4726           }
4727 
4728         const char * p = sys_config_list[rc].name;
4729         if (strcmp (p, "connect_time") == 0)
4730           sys_opts.iom_times.connect = (int) v;
4731         else if (strcmp (p, "color") == 0)
4732           sys_opts.no_color = ! v;
4733         else
4734           {
4735             sim_msg ("error: sys_set_config: Invalid cfg_parse rc <%ld>\n", (long) rc);
4736             cfg_parse_done (& cfg_state);
4737             return SCPE_ARG;
4738           }
4739       } // process statements
4740     cfg_parse_done (& cfg_state);
4741     return SCPE_OK;
4742   }
4743 
4744 static MTAB sys_mod[] =
4745   {
4746     {
4747       MTAB_dev_value,           /* Mask               */
4748       0,                        /* Match              */
4749       (char *) "CONFIG",        /* Print string       */
4750       (char *) "CONFIG",        /* Match string       */
4751       sys_set_config,           /* Validation routine */
4752       sys_show_config,          /* Display routine    */
4753       NULL,                     /* Value descriptor   */
4754       NULL,                     /* Help               */
4755     },
4756     {
4757       MTAB_dev_novalue,         /* Mask               */
4758       1,                        /* Match              */
4759       (char *) "BREAK",         /* Print string       */
4760       (char *) "BREAK",         /* Match string       */
4761       sys_set_break,            /* Validation routine */
4762       sys_show_break,           /* Display routine    */
4763       NULL,                     /* Value descriptor   */
4764       NULL,                     /* Help               */
4765     },
4766     {
4767       MTAB_dev_novalue,         /* Mask               */
4768       0,                        /* Match              */
4769       (char *) "NOBREAK",       /* Print string       */
4770       (char *) "NOBREAK",       /* Match string       */
4771       sys_set_break,            /* Validation routine */
4772       sys_show_break,           /* Display routine    */
4773       NULL,                     /* Value descriptor   */
4774       NULL,                     /* Help               */
4775     },
4776     MTAB_eol
4777   };
4778 
4779 static t_stat sys_reset (UNUSED DEVICE  * dptr)
     /* [previous][next][first][last][top][bottom][index][help] */
4780   {
4781     return SCPE_OK;
4782   }
4783 
4784 static DEVICE sys_dev = {
4785     "SYS",       /* Name                */
4786     NULL,        /* Units               */
4787     NULL,        /* Registers           */
4788     sys_mod,     /* Modifiers           */
4789     0,           /* #Units              */
4790     8,           /* Address radix       */
4791     PASIZE,      /* Address width       */
4792     1,           /* Address increment   */
4793     8,           /* Data radix          */
4794     36,          /* Data width          */
4795     NULL,        /* Examine routine     */
4796     NULL,        /* Deposit routine     */
4797     & sys_reset, /* Reset routine       */
4798     NULL,        /* Boot routine        */
4799     NULL,        /* Attach routine      */
4800     NULL,        /* Detach routine      */
4801     NULL,        /* Context             */
4802     0,           /* Flags               */
4803     0,           /* Debug control flags */
4804     0,           /* Debug flag names    */
4805     NULL,        /* Memory size change  */
4806     NULL,        /* Logical name        */
4807     NULL,        /* Help                */
4808     NULL,        /* Attach_help         */
4809     NULL,        /* Help_ctx            */
4810     NULL,        /* Description         */
4811     NULL         /* End                 */
4812 };
4813 
4814 // This is part of the scp interface
4815 DEVICE * sim_devices[] =
4816   {
4817     & cpu_dev, // dev[0] is special to the scp interface; it is the 'default device'
4818     & iom_dev,
4819     & tape_dev,
4820 #ifdef WITH_SOCKET_DEV
4821 # ifndef __MINGW64__
4822 #  ifndef __MINGW32__
4823 #   ifndef CROSS_MINGW32
4824 #    ifndef CROSS_MINGW64
4825     & skc_dev,
4826 #    endif /* ifndef CROSS_MINGW64 */
4827 #   endif /* ifndef CROSS_MINGW32 */
4828 #  endif /* ifndef __MINGW32__ */
4829 # endif /* ifndef __MINGW64__ */
4830 #endif /* ifdef WITH_SOCKET_DEV */
4831     & mtp_dev,
4832     & fnp_dev,
4833     & dsk_dev,
4834     & ipc_dev,
4835     & msp_dev,
4836     & scu_dev,
4837  /* & mpc_dev, */
4838     & opc_dev,
4839     & sys_dev,
4840     & urp_dev,
4841     & rdr_dev,
4842     & pun_dev,
4843     & prt_dev,
4844 #ifdef WITH_ABSI_DEV
4845 # ifndef __MINGW64__
4846 #  ifndef __MINGW32__
4847 #   ifndef CROSS_MINGW32
4848 #    ifndef CROSS_MINGW64
4849     & absi_dev,
4850 #    endif /* ifndef CROSS_MINGW64 */
4851 #   endif /* ifndef CROSS_MINGW32 */
4852 #  endif /* ifndef __MINGW32__ */
4853 # endif /* ifndef __MINGW64__ */
4854 #endif /* ifdef WITH_ABSI_DEV */
4855     NULL
4856   };
4857 
4858 #ifdef PERF_STRIP
4859 void dps8_init_strip (void)
     /* [previous][next][first][last][top][bottom][index][help] */
4860   {
4861     dps8_init ();
4862   }
4863 #endif

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