1 /* hp2100_cpu.c: HP 21xx/1000 Central Processing Unit simulator
2 
3    Copyright (c) 1993-2016, Robert M. Supnik
4    Copyright (c) 2017-2019, J. David Bryan
5 
6    Permission is hereby granted, free of charge, to any person obtaining a copy
7    of this software and associated documentation files (the "Software"), to deal
8    in the Software without restriction, including without limitation the rights
9    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10    copies of the Software, and to permit persons to whom the Software is
11    furnished to do so, subject to the following conditions:
12 
13    The above copyright notice and this permission notice shall be included in
14    all copies or substantial portions of the Software.
15 
16    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19    AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20    ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 
23    Except as contained in this notice, the names of the authors shall not be
24    used in advertising or otherwise to promote the sale, use or other dealings
25    in this Software without prior written authorization from the authors.
26 
27    CPU          2114C/2115A/2116C/2100A/1000-M/E/F Central Processing Unit
28                 I/O subsystem
29                 Power Fail Recovery System
30 
31    08-Dec-19    JDB     Added "hp_reset_poll" call to "cpu_reset"
32    03-Jul-19    JDB     Substituted BP_EXEC for explicit 'E' switch in sim_brk_test
33    08-Apr-19    JDB     Suppress stop messages for step and breakpoints in DO files
34    06-Feb-19    JDB     Corrected trace report for simulation stop
35    05-Feb-19    JDB     sim_dname now takes a const pointer
36    13-Aug-18    JDB     Renamed "ion_defer" to "cpu_interrupt_enable" and flipped sense
37    24-Jul-18    JDB     Removed unneeded "iotrap" parameter from "cpu_iog" routine
38    20-Jul-18    JDB     Moved memory/MEM/MP and DMA into separate source files
39    29-Jun-18    JDB     Fixed "clear_option" return type definition
40    14-Jun-18    JDB     Renamed PRO device to MPPE
41    05-Jun-18    JDB     Revised I/O model
42    21-May-18    JDB     Changed "access" to "mem_access" to avoid clashing
43    07-May-18    JDB     Modified "io_dispatch" to display outbound signals
44    01-May-18    JDB     Multiple consecutive CLC 0 operations are now omitted
45    02-Apr-18    JDB     SET CPU 21MX now configures an M-Series model
46    22-Feb-18    JDB     Reworked "cpu_ibl" into "cpu_copy_loader"
47    11-Aug-17    JDB     MEM must be disabled when DMS is disabled
48    01-Aug-17    JDB     Changed SET/SHOW CPU [NO]IDLE to use sim_*_idle routines
49    22-Jul-17    JDB     Renamed "intaddr" to CIR; added IR
50    18-Jul-17    JDB     Added CPU stops
51    11-Jul-17    JDB     Moved "hp_enbdis_pair" to hp2100_sys.c
52                         Renamed "ibl_copy" to "cpu_ibl"
53    10-Jul-17    JDB     Renamed the global routine "iogrp" to "cpu_iog"
54    07-Jul-17    JDB     Changed "iotrap" from uint32 to t_bool
55    26-Jun-17    JDB     Moved I/O instruction subopcode constants from hp2100_defs.h
56    16-May-17    JDB     Changed REG_A, REG_B to REG_X
57    19-Apr-17    JDB     SET CPU IDLE now omits idle loop tracing
58    04-Apr-17    JDB     Added "cpu_configuration" for symbolic ex/dep validation
59                         Rejected model change no longer changes options
60    21-Mar-17    JDB     IOP is now illegal on the 1000 F-Series
61    27-Feb-17    JDB     Added BBL load for 21xx machines
62                         ibl_copy no longer returns a status code
63    22-Feb-17    JDB     Added DMA tracing
64    21-Feb-17    JDB     Added bus tracing to the I/O dispatcher
65    19-Jan-17    JDB     Added CPU tracing
66                         Consolidated the memory read and write routines
67    05-Aug-16    JDB     Renamed the P register from "PC" to "PR"
68    13-May-16    JDB     Modified for revised SCP API function parameter types
69    31-Dec-14    JDB     Corrected devdisp data parameters
70    30-Dec-14    JDB     Added S-register parameters to ibl_copy
71    24-Dec-14    JDB     Added casts for explicit downward conversions
72    18-Mar-13    JDB     Removed redundant extern declarations
73    05-Feb-13    JDB     HLT instruction handler now relies on sim_vm_fprint_stopped
74    09-May-12    JDB     Separated assignments from conditional expressions
75    13-Jan-12    JDB     Minor speedup in "is_mapped"
76                         Added casts to cpu_mod, dmasio, dmapio, cpu_reset, dma_reset
77    07-Apr-11    JDB     Fixed I/O return status bug for DMA cycles
78                         Failed I/O cycles now stop on failing instruction
79    28-Mar-11    JDB     Tidied up signal handling
80    29-Oct-10    JDB     Revised DMA for new multi-card paradigm
81                         Consolidated DMA reset routines
82                         DMA channels renamed from 0,1 to 1,2 to match documentation
83    27-Oct-10    JDB     Changed I/O instructions, handlers, and DMA for revised signal model
84                         Changed I/O dispatch table to use DIB pointers
85    19-Oct-10    JDB     Removed DMA latency counter
86    13-Oct-10    JDB     Fixed DMA requests to enable stealing every cycle
87                         Fixed DMA priority for channel 1 over channel 2
88                         Corrected comments for "cpu_set_idle"
89    30-Sep-08    JDB     Breakpoints on interrupt trap cells now work
90    05-Sep-08    JDB     VIS and IOP are now mutually exclusive on 1000-F
91    11-Aug-08    JDB     Removed A/B shadow register variables
92    07-Aug-08    JDB     Moved hp_setdev, hp_showdev to hp2100_sys.c
93                         Moved non-existent memory checks to WritePW
94    05-Aug-08    JDB     Fixed mp_dms_jmp to accept lower bound, check write protection
95    30-Jul-08    JDB     Corrected DMS violation register set conditions
96                         Redefined ABORT to pass address, moved def to hp2100_cpu.h
97                         Combined dms and dms_io routines
98    29-Jul-08    JDB     JSB to 0/1 with W5 out and fence = 0 erroneously causes MP abort
99    11-Jul-08    JDB     Unified I/O slot dispatch by adding DIBs for CPU, MP, and DMA
100    26-Jun-08    JDB     Rewrote device I/O to model backplane signals
101                         EDT no longer passes DMA channel
102    30-Apr-08    JDB     Enabled SIGNAL instructions, SIG debug flag
103    28-Apr-08    JDB     Added SET CPU IDLE/NOIDLE, idle detection for DOS/RTE
104    24-Apr-08    JDB     Fixed single stepping through interrupts
105    20-Apr-08    JDB     Enabled EMA and VIS, added EMA, VIS, and SIGNAL debug flags
106    03-Dec-07    JDB     Memory ex/dep and bkpt type default to current map mode
107    26-Nov-07    JDB     Added SET CPU DEBUG and OS/VMA flags, enabled OS/VMA
108    15-Nov-07    JDB     Corrected MP W5 (JSB) jumper action, SET/SHOW reversal,
109                         mp_mevff clear on interrupt with I/O instruction in trap cell
110    04-Nov-07    JDB     Removed DBI support from 1000-M (was temporary for RTE-6/VM)
111    28-Apr-07    RMS     Removed clock initialization
112    02-Mar-07    JDB     EDT passes input flag and DMA channel in dat parameter
113    11-Jan-07    JDB     Added 12578A DMA byte packing
114    28-Dec-06    JDB     CLC 0 now sends CRS instead of CLC to devices
115    26-Dec-06    JDB     Fixed improper IRQ deferral for 21xx CPUs
116                         Fixed improper interrupt servicing in resolve
117    21-Dec-06    JDB     Added 21xx loader enable/disable support
118    16-Dec-06    JDB     Added 2114 and 2115 CPU options.
119                         Added support for 12607B (2114) and 12578A (2115/6) DMA
120    01-Dec-06    JDB     Added 1000-F CPU option (requires HAVE_INT64)
121                         SHOW CPU displays 1000-M/E instead of 21MX-M/E
122    16-Oct-06    JDB     Moved ReadF to hp2100_cpu1.c
123    12-Oct-06    JDB     Fixed INDMAX off-by-one error in resolve
124    26-Sep-06    JDB     Added iotrap parameter to UIG dispatchers for RTE microcode
125    12-Sep-06    JDB     iogrp returns NOTE_IOG to recalc interrupts
126                         resolve returns NOTE_INDINT to service held-off interrupt
127    16-Aug-06    JDB     Added support for future microcode options, future F-Series
128    09-Aug-06    JDB     Added double integer microcode, 1000-M/E synonyms
129                         Enhanced CPU option validity checking
130                         Added DCPC as a synonym for DMA for 21MX simulations
131    26-Dec-05    JDB     Improved reporting in dev_conflict
132    22-Sep-05    RMS     Fixed declarations (from Sterling Garwood)
133    21-Jan-05    JDB     Reorganized CPU option flags
134    15-Jan-05    RMS     Split out EAU and MAC instructions
135    26-Dec-04    RMS     DMA reset doesn't clear alternate CTL flop (from Dave Bryan)
136                         DMA reset shouldn't clear control words (from Dave Bryan)
137                         Alternate CTL flop not visible as register (from Dave Bryan)
138                         Fixed CBS, SBS, TBS to perform virtual reads
139                         Separated A/B from M[0/1] for DMA IO (from Dave Bryan)
140                         Fixed bug in JPY (from Dave Bryan)
141    25-Dec-04    JDB     Added SET CPU 21MX-M, 21MX-E (21MX defaults to MX-E)
142                         TIMER/EXECUTE/DIAG instructions disabled for 21MX-M
143                         T-register reflects changes in M-register when halted
144    25-Sep-04    JDB     Moved MP into its own device; added MP option jumpers
145                         Modified DMA to allow disabling
146                         Modified SET CPU 2100/2116 to truncate memory > 32K
147                         Added -F switch to SET CPU to force memory truncation
148                         Fixed S-register behavior on 2116
149                         Fixed LIx/MIx behavior for DMA on 2116 and 2100
150                         Fixed LIx/MIx behavior for empty I/O card slots
151                         Modified WRU to be REG_HRO
152                         Added BRK and DEL to save console settings
153                         Fixed use of "unsigned int16" in cpu_reset
154                         Modified memory size routine to return SCPE_INCOMP if
155                         memory size truncation declined
156    20-Jul-04    RMS     Fixed bug in breakpoint test (reported by Dave Bryan)
157                         Back up PC on instruction errors (from Dave Bryan)
158    14-May-04    RMS     Fixed bugs and added features from Dave Bryan
159                         - SBT increments B after store
160                         - DMS console map must check dms_enb
161                         - SFS x,C and SFC x,C work
162                         - MP violation clears automatically on interrupt
163                         - SFS/SFC 5 is not gated by protection enabled
164                         - DMS enable does not disable mem prot checks
165                         - DMS status inconsistent at simulator halt
166                         - Examine/deposit are checking wrong addresses
167                         - Physical addresses are 20b not 15b
168                         - Revised DMS to use memory rather than internal format
169                         - Added instruction printout to HALT message
170                         - Added M and T internal registers
171                         - Added N, S, and U breakpoints
172                         Revised IBL facility to conform to microcode
173                         Added DMA EDT I/O pseudo-opcode
174                         Separated DMA SRQ (service request) from FLG
175    12-Mar-03    RMS     Added logical name support
176    02-Feb-03    RMS     Fixed last cycle bug in DMA output (found by Mike Gemeny)
177    22-Nov-02    RMS     Added 21MX IOP support
178    24-Oct-02    RMS     Fixed bugs in IOP and extended instructions
179                         Fixed bugs in memory protection and DMS
180                         Added clock calibration
181    25-Sep-02    RMS     Fixed bug in DMS decode (found by Robert Alan Byer)
182    26-Jul-02    RMS     Restructured extended instructions, added IOP support
183    22-Mar-02    RMS     Changed to allocate memory array dynamically
184    11-Mar-02    RMS     Cleaned up setjmp/auto variable interaction
185    17-Feb-02    RMS     Added DMS support
186                         Fixed bugs in extended instructions
187    03-Feb-02    RMS     Added terminal multiplexor support
188                         Changed PCQ macro to use unmodified PC
189                         Fixed flop restore logic (found by Bill McDermith)
190                         Fixed SZx,SLx,RSS bug (found by Bill McDermith)
191                         Added floating point support
192    16-Jan-02    RMS     Added additional device support
193    07-Jan-02    RMS     Fixed DMA register tables (found by Bill McDermith)
194    07-Dec-01    RMS     Revised to use breakpoint package
195    03-Dec-01    RMS     Added extended SET/SHOW support
196    10-Aug-01    RMS     Removed register in declarations
197    26-Nov-00    RMS     Fixed bug in dual device number routine
198    21-Nov-00    RMS     Fixed bug in reset routine
199    15-Oct-00    RMS     Added dynamic device number support
200 
201    References:
202      - 2100A Computer Reference Manual
203          (02100-90001, December 1971)
204      - Model 2100A Computer Installation and Maintenance Manual
205          (02100-90002, August 1972)
206      - HP 1000 M/E/F-Series Computers Technical Reference Handbook
207          (5955-0282, March 1980)
208      - HP 1000 M/E/F-Series Computers Engineering and Reference Documentation
209          (92851-90001, March 1981)
210      - HP 1000 Computer Real-Time Systems
211          (5091-4479, August 1992)
212 
213 
214    Hewlett-Packard sold the HP 21xx/1000 family of real-time computers from 1966
215    through 2000.  There are three major divisions within this family: the 21xx
216    core-memory machines, the 1000 (originally 21MX) M/E/F-Series semiconductor-
217    memory machines, and the 1000 L/A-Series machines.  All machines are 16-bit
218    accumulator-oriented CISC machines running the same base instruction set.  A
219    wide range of operating systems run on these machines, from a simple 4K word
220    paper-tape-based monitor to a megaword multi-user, multiprogramming disc-
221    based system and a multi-user time-shared BASIC system.
222 
223    This implementation is a simulator for the 2114, 2115, 2116, 2100, and 1000
224    M/E/F-Series machines.  A large variety of CPU options, device interface
225    cards, and peripherals are provided.  High-speed I/O transfers are performed
226    by Direct Memory Access and Dual-Channel Port Controller options.  This
227    simulator does not model the 1000 L/A-Series machines.
228 
229    All of the machines support a 15-bit logical address space, addressing a
230    maximum of 32K words, divided into 1K-word pages.  Memory-referencing
231    instructions in the base set can directly address the 1024 words of the base
232    page (page 0) or the 1024 words of the current page (the page containing the
233    instruction).  The instructions in the extended set directly address the
234    32768 words in the full logical address space.  The A and B accumulators may
235    be addressed as logical memory addresses 0 and 1, respectively.
236 
237    Peripheral devices are connected to the CPU by interface cards installed in
238    the I/O card cages present in the CPU and optional I/O extender chassis.
239    Each slot in the card cage is assigned an address, called a select code, that
240    may be referenced by I/O instructions in the base set.  Select codes range
241    from 0 to 77 octal, with the first eight select codes reserved for the
242    system, providing connections for 56 possible interfaces.
243 
244    The 211x machines use a hardwired processor providing 70 basic instructions
245    and up to 32K of core memory.  The base instruction set is divided into the
246    Memory Reference Group, the Shift-Rotate Group, the Alter-Skip Group, and the
247    I/O Group.  SRG instruction words may contain from one to four suboperation
248    codes that are executed from left-to-right, and ASG instruction words may
249    contain from one to eight suboperations.  An optional Extended Arithmetic
250    Unit may be added to the 2115 and 2116 that provides hardware multiply and
251    divide, double-load and -store, and double-word shift and rotate
252    instructions.
253 
254    The 2100 machine uses a microprogrammed processor that provides the 80
255    instructions of the base set and the EAU as standard equipment.  Optional
256    floating-point microcode adds six two-word (single-precision) instructions.
257    User microprogramming is also supported.  When used as part of an HP 2000
258    Time-Shared BASIC system, the CPU designated as the I/O processor may be
259    equipped with microcode implementing 18 additional OS accelerator
260    instructions.
261 
262    The 1000 M/E-Series machines also use microprogrammed processors and extend
263    the 2100 instruction set with two new index registers, X and Y, and a new
264    Extended Instruction Group consisting of 32 index-register instructions and
265    10 word-and-byte-manipulation instructions.  The six 2100 floating-point
266    instructions are also standard.  The 1000 F-Series adds a hardware
267    floating-point processor with 18 new triple- and quad-word instructions.  A
268    number of optional microcode extensions are available with the M/E/F-Series.
269 
270    1000 CPUs offer the optional Dynamic Mapping System, which provides memory
271    mapping on a page-by-page basis.  The 5-bit page number of a logical memory
272    address selects one of 32 ten-bit map registers containing physical page
273    numbers.  The ten-bit page number combined with the ten-bit page offset
274    yields a 20-bit physical address capable of accessing a location in a
275    one-megaword memory.  DMS provides separate maps for system and user
276    programs, as well as for the two DCPC channels, and includes microcode that
277    implements the 38 Dynamic Mapping Instructions used to manipulate the mapping
278    system.
279 
280    Optional memory protection is accomplished by dividing the logical address
281    space into protected and unprotected parts.  When protection is enabled, any
282    attempt to write or jump below the fence separating the two parts is
283    inhibited, and an interrupt to the operating system occurs, which aborts the
284    offending user program.  If the DMS option is enabled as well, protection is
285    enhanced by specifying read and write permissions on a page-by-page basis.
286 
287    A note on terminology: the 1000 series of computers was originally called the
288    21MX at introduction.  The 21MX (occasionally, 21MXM) corresponds to the 1000
289    M-Series, and the 21MXE (occasionally, 21XE) corresponds to the 1000
290    E-Series.  The model numbers were changed before the introduction of the 1000
291    F-Series, although some internal HP documentation refers to this machine as
292    the 21MXF.
293 
294    The terms MEM (Memory Expansion Module), MEU (Memory Expansion Unit), DMI
295    (Dynamic Mapping Instructions), and DMS (Dynamic Mapping System) are used
296    somewhat interchangeably to refer to the logical-to-physical memory address
297    translation option provided on the 1000-Series.  DMS consists of the MEM card
298    (12731A) and the DMI firmware (13307A).  However, MEM and MEU have been used
299    interchangeably to refer to the mapping card, as have DMI and DMS to refer to
300    the firmware instructions.
301 
302 
303    These CPU hardware registers are present in all machines:
304 
305      Name  Width  Description
306      ----  -----  ----------------------------------------------
307       A     16    Accumulator (addressable as memory location 0)
308       B     16    Accumulator (addressable as memory location 1)
309       P     15    Program counter
310       S     16    Switch and display register
311       M     15    Memory address register
312       T     16    Memory data register
313       E      1    Extend flag (arithmetic carry out)
314       O      1    Overflow flag (arithmetic overflow)
315 
316    In addition, there are two internal registers that are not visible to the
317    programmer but are used by the hardware:
318 
319      Name  Width  Description
320      ----  -----  ----------------------------------------------
321       IR    16    Instruction register
322      CIR     6    Central interrupt register
323 
324    The Instruction Register holds the current instruction, while the Central
325    Interrupt Register holds the select code identifying an interrupting device.
326 
327    The 1000 Series adds these CPU hardware registers:
328 
329      Name  Width  Description
330      ----  -----  ----------------------------------------------
331       X     16    index register
332       Y     16    index register
333 
334    The data types supported by the base instruction set are:
335 
336      - 8-bit unsigned byte
337      - 16-bit unsigned integer
338      - 16-bit two's-complement integer
339      - 32-bit two's-complement integer
340      - 32-bit two's-complement floating point
341 
342    Multi-word values are stored in memory with the most-significant words in the
343    lowest addresses.  Bytes are stored in memory with the most-significant byte
344    in the upper half of the 16-bit word and the least-significant byte in the
345    lower half.
346 
347    The instruction set is fairly irregular -- a legacy of its original
348    implementation in hardware in the 2116 and the accretion of microprogrammed
349    instructions in the 2100 and 1000 CPUs.  Initially, there were five base-set
350    instruction groups:
351 
352      1. Memory-Reference Group (MRG)
353      2. Shift-Rotate Group (SRG)
354      3. Alter-Skip Group (ASG)
355      4. I/O Group (IOG)
356      5. Macroinstruction Group (MAC)
357 
358    All of the instructions added after the 2116 are in the Macroinstruction
359    Group.
360 
361    The 2116 offers two hardware options that extended the instruction set.  The
362    first is the 12579A Extended Arithmetic Unit.  The second is the 2152A
363    Floating Point Processor, which is interfaced through, and therefore
364    requires, the EAU.  The EAU adds 10 instructions including integer multiply
365    and divide and double-word loads, stores, shifts, and rotates.  The FPP adds
366    30 floating-point arithmetic, trigonometric, logarithmic, and exponential
367    instructions.  The 2116 EAU is compatible with the 2100 and 1000 EAU
368    implementations and is provided by the simulator.  The 2116 FPP is unique
369    to that machine and is not simulated.
370 
371    The base set groups are decoded from bits 15-12 and 10, as follows:
372 
373      15  14-12  10  Group  Address Ranges
374      --  -----  --  -----  -------------------------------
375       x   nnn    x   MRG   010000-077777 and 110000-177777
376       0   000    0   SRG   000000-001777 and 004000-005777
377       0   000    1   ASG   002000-003777 and 006000-007777
378       1   000    1   IOG   102000-103777 and 106000-107777
379       1   000    0   MAC   100000-101777 and 104000-105777
380 
381    Where:
382 
383      x = don't care
384      n = any combination other than all zeros
385 
386    The MAC group is subdivided into the Extended Arithmetic Group (EAG) and the
387    User Instruction Group (UIG), based on bits 11, 9, and 8, as follows:
388 
389      11   9   8  Group  Address Range
390      --  --  --  -----  -------------
391       0   0   0  EAG    100000-100377
392       0   0   1  EAG    100400-100777
393       0   1   0  EAG    101000-101377
394       0   1   1  UIG-1  101400-101777
395       1   0   0  EAG    104000-104377
396       1   0   1  EAG    104400-104777
397       1   1   0  UIG-0  105000-105377
398       1   1   1  UIG-1  105400-105777
399 
400    All of the 2116 FPP instructions are in the UIG sets: 3 use 10144x opcodes
401    and the rest use 1050xx and 1054xx opcodes.  The 2100 decodes only UIG-0
402    instructions, whereas the 1000s use both UIG sets.  In particular, the
403    105740-105777 range is used by the 1000 Extended Instruction Group (EIG),
404    which is part of the 1000-Series base set.
405 
406    The 21xx and 1000 M/E/F-Series machines do not trap unimplemented
407    instructions.  In general, unimplemented EAG instructions cause erroneous
408    execution, and unimplemented UIG instructions execute as NOP.  However, there
409    are machine-to-machine variations, and some unimplemented instructions
410    execute as other, defined instructions.
411 
412    The Memory-Reference Group instructions are encoded as follows:
413 
414       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
415      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
416      | I |    mem op     | P |            memory address             |  MRG
417      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
418 
419      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
420      | I |  mem op   | R | P |            memory address             |  MRG
421      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
422 
423    Where:
424 
425      I = direct/indirect (0/1)
426      R = A/B register (0/1)
427      P = base/current page (0/1)
428 
429    The "mem ops" are encoded as follows:
430 
431      14-11  Mnemonic  Action
432      -----  --------  ---------------------------------------------
433      0010     AND     A = A & M [MA]
434      0011     JSB     M [MA] = P, P = MA + 1
435      0100     XOR     A = A ^ M [MA]
436      0101     JMP     P = MA
437      0110     IOR     A = A | M [MA]
438      0111     ISZ     M [MA] = M [MA] + 1, P = P + 2 if M [MA] == 0
439      1000     ADA     A = A + M [MA]
440      1001     ADB     B = B + M [MA]
441      1010     CPA     P = P + 2 if A != M [MA]
442      1011     CPB     P = P + 2 if B != M [MA]
443      1100     LDA     A = M [MA]
444      1101     LDB     B = M [MA]
445      1110     STA     M [MA] = A
446      1111     STB     M [MA] = B
447 
448    Bits 15 and 10 encode the type of access, as follows:
449 
450      15  10   Access Type            Action
451      --- ---  ---------------------  -----------------------------
452       0   0   base page direct       MA = IR <9:0>
453       0   1   current page direct    MA = P <14:10> | IR <9:0>
454       1   0   base page indirect     MA = M [IR <9:0>]
455       1   1   current page indirect  MA = M [P <14:10> | IR <9:0>]
456 
457 
458    The Shift-Rotate Group instructions are encoded as follows:
459 
460       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
461      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
462      | 0 | 0   0   0 | R | 0 | E |   op 1    | C | E | S |   op 2    |  SRG
463      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
464 
465    Where:
466 
467      R = A/B register (0/1)
468      E = disable/enable op
469      C = CLE
470      S = SL*
471 
472    Bits 8-6 and 2-0 each encode one of eight operations, as follows:
473 
474      Op N  Operation
475      ----  ---------------------------
476      000   Arithmetic left shift
477      001   Arithmetic right shift
478      010   Rotate left
479      011   Rotate right
480      100   Shift left and clear sign
481      101   Rotate right through Extend
482      110   Rotate left through Extend
483      111   Rotate left four bits
484 
485 
486    The Alter-Skip Group instructions are encoded as follows:
487 
488       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
489      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
490      | 0 | 0   0   0 | R | 1 | r op  | e op  | E | S | L | I | Z | V |  ASG
491      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
492 
493    Where:
494 
495      R = A/B register (0/1)
496      E = SEZ
497      S = SS*
498      L = SL*
499      I = IN*
500      Z = SZ*
501      V = RSS
502 
503    Bits 9-8 and 7-6 each encode one of three operations, as follows:
504 
505      9-8  Operation
506      ---  ------------------------
507      01   Clear A/B
508      10   Complement A/B
509      11   Clear and complement A/B
510 
511      7-6  Operation
512      ---  ---------------------------
513      01   Clear Extend
514      10   Complement Extend
515      11   Clear and complement Extend
516 
517 
518    The Input-Output Group instructions are encoded as follows:
519 
520       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
521      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
522      | 1 | 0   0   0 | R | 1 | H |  I/O op   |      select code      |  IOG
523      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
524 
525    Where:
526 
527      R = A/B register (0/1)
528      H = hold/clear flag (0/1)
529 
530    There are ten instructions.  Six are encoded directly by bits 8-6, with
531    bits 11 and 9 assuming the definitions above.  The other four are encoded
532    with bits 11 and 9 differentiating, as follows:
533 
534      11    9   8-6  Operation
535      ---  ---  ---  ---------------------------
536       x    H   000  Halt
537       x    0   001  Set the flag flip-flop
538       x    1   001  Clear the flag flip-flop
539       x    H   010  Skip if the flag is clear
540       x    H   011  Skip if the flag is set
541       R    H   100  Merge input data into A/B
542       R    H   101  Load input data into A/B
543       R    H   110  Store output data from A/B
544       0    H   111  Set the control flip-flop
545       1    H   111  Clear the control flip-flop
546 
547    An I/O group instruction controls the device specified by the select code.
548    Depending on the opcode, the instruction may set or clear the device flag,
549    start or stop I/O, or read or write data.
550 
551 
552    The Macroinstruction Group instructions are encoded with bits 15-12 and 10 as
553    1 000 0.  Bits 11 and 9-0 determine the specific EAU or UIG instruction.
554 
555    The Extended Arithmetic Group instructions are encoded as follows:
556 
557       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
558      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
559      | 1 | 0   0   0 | op| 0 |   operation   | 0   0   0   0   0   0 |  EAG
560      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
561 
562    Operations:
563 
564      11   9-6   Operation
565      ---  ----  -----------------------------------------------------
566       0   0010  Multiply 16 x 16 = 32-bit product
567       0   0100  Divide 32 / 16 = 16-bit quotient and 16-bit remainder
568       1   0010  Double load A and B registers from memory
569       1   0100  Double store A and B registers to memory
570 
571    All other encodings are undefined.
572 
573      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
574      | 1 | 0   0   0 | 0 | 0 |    shift/rotate op    |  shift count  |  EAG
575      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
576 
577    Operations:
578 
579       9-4    Operation
580      ------  --------------------------------------------------
581      100001  Arithmetic shift right A and B registers 1-16 bits
582      000001  Arithmetic shift left A and B registers 1-16 bits
583      100010  Logical shift right A and B registers 1-16 bits
584      000010  Logical shift left A and B registers 1-16 bits
585      100100  Rotate right A and B registers 1-16 bits
586      000100  Rotate left A and B registers 1-16 bits
587 
588    The shift count encodes the number of bits shifted, with a count of zero
589    representing a shift of 16 bits.
590 
591 
592    The User Instruction Group instructions are encoded as follows:
593 
594       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
595      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
596      | 1 | 0   0   0 | R | 0   1 |      module       |   operation   |  UIG
597      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
598 
599    Where:
600 
601      R = A/B register (0/1)
602 
603    Bits 8-4 encode the microcode module containing the instructions, and bits
604    3-0 encode the specific instructions.  See the individual UIG instruction
605    simulator source files for the specific encodings used.
606 
607 
608    I/O device interfaces and their connected devices are simulated by
609    substituting software states for I/O backplane signals.  The set of signals
610    generated by I/O instructions and DMA cycles is dispatched to the target
611    interface simulator for action, and the set of signals asserted or denied in
612    response is returned from the call.  Backplane signals are processed
613    sequentially.  For example, the "STC sc,C" instruction generates the "set
614    control" and the "clear flag" signals that are processed in that order.
615 
616    The HP 21xx/1000 interrupt structure is based on the PRH, PRL, IEN, IRQ, and
617    IAK signals.  PRH indicates that no higher-priority device is interrupting.
618    PRL indicates to lower-priority devices that a given device is not
619    interrupting.  IEN asserts when the interrupt system is enabled.  IRQ
620    indicates that a given device is requesting an interrupt.  IAK indicates that
621    the given device's interrupt request is being acknowledged.
622 
623    Typical I/O interfaces have a flag buffer, a flag, and a control flip-flop.
624    If an interface's flag buffer, flag, and control flip-flops are all set, the
625    interrupt system is enabled, and the interface has the highest priority on
626    the interrupt chain, it requests an interrupt by asserting the IRQ signal.
627    When the interrupt is acknowledged with the IAK signal, the flag buffer is
628    cleared, preventing further interrupt requests from that interface.  The
629    combination of flag set and control set blocks interrupts from lower priority
630    devices.
631 
632    Service requests are used to trigger the DMA service logic.  Setting the
633    interface flag flip-flop typically asserts SRQ, although SRQ may be
634    calculated independently.
635 
636    Most of the I/O signals are generated by execution of IOG instructions or DMA
637    cycles; the target interface simulator is called explicitly to respond to the
638    signal assertions.  However, two hardware signals (ENF and SIR) are periodic,
639    and a direct simulation would call each interface simulator with these
640    signals after each machine instruction.  Instead, the interface simulator is
641    called only when these signals would have an effect on the state of the
642    interface.  Also, two signals (IEN and PRH) are combinatorial, in that
643    changing either potentially affects all interfaces in the system.  These are
644    handled efficiently by saving the states of each interface in bit vectors, as
645    described below.
646 
647    PRH and PRL form a hardware priority chain that extends from interface to
648    interface on the backplane.  For an interface to generate an interrupt, PRH
649    must be asserted by the next-higher-priority interface.  When an interface
650    generates an interrupt, it denies PRL to the next-lower-priority interface.
651    When an interface is not interrupting, it passes PRH to PRL unaltered.  This
652    means that a given interface can interrupt only if all higher-priority
653    devices are receiving PRH asserted and are asserting PRL.  It also means that
654    clearing the interrupt on a given interface, i.e., reasserting PRL, may
655    affect all lower-priority interfaces.
656 
657    As an example, assume that the interface at select code 10 ("SC 10") has its
658    flag buffer, flag, and control flip-flops set, that IEN and PRH are asserted,
659    and that no other interfaces have their flag flip-flops set.  SC 10 will
660    assert IRQ and deny PRL.  SC 11 sees its PRH low (because PRL 10 is connected
661    to PRH 11) and so denies PRL, and this action ripples through all of the
662    lower-priority interfaces.
663 
664    Then, while the interrupt for SC 10 is being serviced, the interface at
665    select code 17 sets its flag buffer, flag, and control flip-flops.  SC 17 is
666    inhibited from interrupting by PRH denied.
667 
668    When the interrupt service routine clears the interrupt by clearing the flag
669    buffer and flag flip-flops, SC 10 reasserts PRL to SC 11, and that signal
670    ripples through the interfaces at select codes 12-16, arriving at SC 17 as
671    PRH assertion.  With PRH asserted, SC 17 generates an interrupt and denies
672    PRL to SC 20 and above.
673 
674    A direct simulation of this hardware behavior would require calling all
675    lower-priority interface simulators in ascending select code (and therefore
676    priority) order with the PRH signal and checking for an asserted IRQ signal
677    or a denied PRL signal.  This is inefficient.
678 
679    To avoid making a potentially long sequence of calls, each interface
680    simulator returns a "conditional IRQ" signal and a "conditional PRL" signal
681    in addition to the standard IRQ and PRL signals.  The conditional signals
682    are those that would result if the higher-priority interface is asserting
683    PRH and the interrupt system is on.  So, for instance, an interface simulator
684    with its flag buffer, flag, and control flip-flops set will assert its
685    conditional IRQ signal and deny its conditional PRL signal.  If PRH and IEN
686    are asserted, then its "real" IRQ and PRL signals are also asserted and
687    denied respectively.
688 
689    For fast assertion checking, the conditional IRQ and PRL signal states are
690    kept in bit vectors, which are updated after each interface simulator call.
691    Each vector is represented as a two-element array of 32-bit unsigned
692    integers, forming a 64-bit vector in which bits 0-31 of the first element
693    correspond to select codes 00-37 octal, and bits 0-31 of the second element
694    correspond to select codes 40-77 octal.  The "interrupt_request_set" array
695    holds conditional IRQ states, and the "priority_holdoff_set" array holds the
696    complement of the conditional PRL states (the complement is used to simplify
697    the priority calculation).  These vectors permit rapid determination of an
698    interrupting interface when a higher-priority interface reasserts PRL or when
699    the interrupt system is reenabled.
700 
701 
702    The simulator provides three stop conditions related to instruction execution
703    that may be enabled with a SET CPU STOP=<stop> command:
704 
705      <stop>  Action
706      ------  ------------------------------------------
707      UNIMPL  stop on an unimplemented instruction
708      UNDEF   stop on an undefined instruction
709      UNSC    stop on an access to an unused select code
710      IOERR   stop on an unreported I/O error
711 
712    If an enabled stop condition is detected, execution ceases with the
713    instruction pending, and control returns to the SCP prompt.  When simulation
714    stops, execution may be resumed in two ways.  If the cause of the stop has
715    not been remedied and the stop has not been disabled, resuming execution with
716    CONTINUE, STEP, GO, or RUN will cause the stop to occur again.  Alternately,
717    specifying the "-B" switch with any of the preceding commands will resume
718    execution while bypassing the stop for the current instruction.
719 
720    The UNIMPL option stops the simulator if execution is attempted of an
721    instruction provided by a firmware option that is not currently installed
722    (e.g., a DAD instruction when the double-integer firmware is not installed)
723    or of an opcode provided by an installed option but not assigned to an
724    instruction (e.g., opcode 105335 from the double-integer firmware).
725    Bypassing the stop will execute the instruction as a NOP (no-operation).
726 
727    The UNDEF option stops the simulator if execution is attempted of an
728    instruction containing a decoded reserved bit pattern other than that defined
729    in the Operating and Reference manual for the CPU.  For example, opcodes
730    101700 and 105700 are not listed as DMS instructions, but they execute as
731    XMM instructions, rather than as NOP.  The intent of this stop is to catch
732    instructions containing reserved fields with values that change the meaning
733    of those instructions.  Bypassing the stop will decode and execute the
734    instruction in the same manner as the selected CPU.
735 
736    The UNSC option stops the simulator if an I/O instruction addresses a select
737    code that is not assigned to an enabled device (equivalent to an empty
738    hardware I/O backplane slot).  Bypassing the stop will read the floating
739    S-bus or I/O-bus for LIA/B and MIA/B instructions or do nothing for all other
740    instructions.
741 
742    The IOERR option stops the simulator if an I/O error condition exists for a
743    device that does not report this status to the CPU.  For example, the paper
744    tape reader device (PTR) does not report "no tape loaded" status, and the
745    processor interconnect device (IPL) does not report "cable disconnected."  In
746    both cases, I/O to the device will simply hang with no indication of the
747    problem.  Enabling the IOERR option will stop the simulator with an error
748    indication for these devices.
749 
750    In addition, a simulation stop will occur if an indirect addressing chain
751    exceeds the maximum length specified by a SET CPU INDIR=<limit> command.
752    Memory addresses may be indirect to indicate that the values point to the
753    target addresses rather than contain the target addresses.  The target of an
754    indirect address may itself be indirect, and the CPU follows this chain of
755    addresses until it finds a direct address.  Indirect addressing is typically
756    only one or two levels deep, but if the chain loops back on itself (e.g., if
757    an indirect address points at itself), then instruction execution will hang.
758 
759    The limit may be set to any number of levels up to 32,768.  This is the
760    absolute maximum number of levels that can be created without an infinite
761    loop -- each location in memory points to the next one except for the last,
762    which contains the target value.  In practice, anything over a few levels
763    likely represents a programming error.  The default setting is 16 levels.
764 
765 
766    The CPU simulator provides extensive tracing capabilities that may be enabled
767    with the SET DEBUG <filename> and SET CPU DEBUG=<trace> commands.  The trace
768    options that may be specified are:
769 
770      Trace  Action
771      -----  -------------------------------------------
772      INSTR  trace instructions executed
773      DATA   trace memory data accesses
774      FETCH  trace memory instruction fetches
775      REG    trace registers
776      OPND   trace instruction operands
777      EXEC   trace matching instruction execution states
778 
779    A section of an example trace is:
780 
781      >>CPU instr: S 0002 05735  103101  CLO
782      >>CPU fetch: S 0002 05736  000036    instruction fetch
783      >>CPU   reg: - **** 01011  042200    A 177777, B 000000, X 177777, Y 000000, e o i
784      >>CPU instr: S 0002 05736  000036  SLA,ELA
785      >>CPU fetch: S 0002 05737  102101    instruction fetch
786      >>CPU   reg: - **** 01011  042200    A 177776, B 000000, X 177777, Y 000000, E o i
787      >>CPU instr: S 0002 05737  102101  STO
788      >>CPU fetch: S 0002 05740  002400    instruction fetch
789      >>CPU   reg: - **** 01011  042200    A 177776, B 000000, X 177777, Y 000000, E O i
790      >>CPU instr: S 0002 05755  102100  STF 0
791      >>CPU fetch: S 0002 05756  102705    instruction fetch
792      >>CPU   reg: - **** 01011  042200    A 177777, B 177777, X 177777, Y 000000, E O I
793      >>CPU instr: S 0002 05756  102705  STC 5
794      >>CPU fetch: S 0002 05757  105736    instruction fetch
795      >>CPU   reg: P **** 01011  042200    A 177777, B 177777, X 177777, Y 000000, E O I
796      >>CPU instr: S 0002 05757  105736  UJP 2111
797      >>CPU fetch: S 0002 05760  002111    instruction fetch
798      >>CPU fetch: U 0001 02111  026111    instruction fetch
799      >>CPU   reg: P **** 01011  042200    A 177777, B 177777, X 177777, Y 000000, E O I
800      >>CPU instr: U 0001 02111  026111  JMP 2111
801      >>CPU instr: U 0001 02111  000011  interrupt
802      >>CPU fetch: S 0000 00011  115013    instruction fetch
803      >>CPU   reg: - **** 01011  042200    A 177777, B 177777, X 177777, Y 000000, E O I
804      >>CPU   reg: - **** *****  ******    MPF 000000, MPV 002111, MES 163011, MEV 030000
805      >>CPU instr: S 0000 00011  115013  JSB 1013,I
806      >>CPU  data: S 0000 01013  005557    data read
807      >>CPU  data: S 0002 05557  002111    data write
808      >>CPU fetch: S 0002 05560  103100    instruction fetch
809      >>CPU   reg: - **** 01011  042200    A 177777, B 177777, X 177777, Y 000000, E O I
810      >>CPU instr: S 0002 05560  103100  CLF 0
811      >>CPU fetch: S 0002 05561  105714    instruction fetch
812      >>CPU   reg: - **** 01011  042200    A 177777, B 177777, X 177777, Y 000000, E O i
813      >>CPU  exec: ********************
814      >>CPU   reg: P **** 01567  000000    A 100036, B 000100, X 000100, Y 074000, E o I
815      >>CPU instr: U 0220 07063  105240  .PMAP
816      >>CPU  data: U 0000 01776  000227    unprotected read
817      >>CPU  data: U 0227 76100  000233    data read
818      >>CPU  opnd: * **** 07065  105240    return location is P+2 (no error)
819      >>CPU fetch: U 0220 07065  127055    instruction fetch
820      >>CPU   reg: P **** 01567  000000    A 100037, B 000101, X 000100, Y 074000, e o I
821 
822    The INSTR option traces instruction executions and interrupts.  Each
823    instruction is printed in symbolic form before it is executed.
824 
825    The DATA option traces reads from and writes to memory.  Each access is
826    classified by its usage type as "data" (using the current or alternate map
827    with access protection) or "unprotected" (using a specified map without
828    protection).
829 
830    The FETCH option traces instruction fetches from memory.  Reads of the
831    additional words in a multiword instruction, such as the target address of a
832    DLD (double load) instruction, are also classified as fetches.
833 
834    The REG option traces register values.  Two sets of registers are printed.
835    After executing each instruction, the working registers (A, B, E, O, S, and,
836    for 1000 CPUs, X and Y) and the state of the interrupt system (on or off) are
837    printed.  After executing an instruction that may alter the Memory Protect or
838    Memory Expansion Module state, the MP fence and violation registers, the MEM
839    status and violation registers, and the current protection state are printed.
840 
841    The OPND option traces operand values.  Some instructions that take memory
842    and register operands that are difficult to decode from DATA or REG traces
843    present the operand values in a higher-level format.  The operand data and
844    value presented are specific to the instruction; see the instruction executor
845    comments for details.
846 
847    The EXEC option traces the execution of instructions that match
848    user-specified criteria.  When a match occurs, all CPU trace options are
849    turned on for the duration of the execution of the matched instruction.  The
850    prior trace settings are restored when a match fails.  This option allows
851    detailed tracing of specified instructions while minimizing the log file size
852    compared to a full instruction trace.
853 
854    The various trace formats are interpreted as follows:
855 
856      >>CPU instr: U 0045 10341  016200  LDA 11200
857                   ~ ~~~~ ~~~~~  ~~~~~~  ~~~~~~~~~
858                   |   |    |       |       |
859                   |   |    |       |       +-- instruction mnemonic
860                   |   |    |       +---------- octal data (instruction opcode)
861                   |   |    +------------------ octal logical address (P register)
862                   |   +----------------------- octal physical page number
863                   +--------------------------- memory map (S/U/- system/user/disabled)
864 
865      >>CPU instr: U 0045 10341  000011  interrupt
866                   ~ ~~~~ ~~~~~  ~~~~~~  ~~~~~~~~~
867                   |   |    |       |       |
868                   |   |    |       |       +-- interrupt classification
869                   |   |    |       +---------- octal device number (CIR register)
870                   |   |    +------------------ octal logical address at interrupt (P register)
871                   |   +----------------------- octal physical page number at interrupt
872                   +--------------------------- memory map (S/U/- system/user/disabled)
873 
874      >>CPU fetch: - 0000 10341  016200    instruction fetch
875      >>CPU  data: U 0013 01200  123003    data read
876      >>CPU  data: S 0013 01200  017200    unprotected write
877                   ~ ~~~~ ~~~~~  ~~~~~~    ~~~~~~~~~~~~~~~~~
878                   |   |    |       |         |
879                   |   |    |       |         +-- memory access classification
880                   |   |    |       +------------ octal data (memory contents)
881                   |   |    +-------------------- octal logical address (effective address)
882                   |   +------------------------- octal physical page number
883                   +----------------------------- memory map (S/U/A/B/- system/user/port A/port B/disabled)
884 
885      >>CPU   reg: P **** 01535  040013    A 123003, B 001340, X 000000, Y 000000, e O I
886                   ~ ~~~~ ~~~~~  ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
887                   |   |    |       |         |
888                   |   |    |       |         +-- A, B, X, Y, E, O, interrupt system registers
889                   |   |    |       |             (lower/upper case = 0/1 or off/on)
890                   |   |    |       +------------ S register
891                   |   |    +-------------------- MEM fence
892                   |   +------------------------- (place holder)
893                   +----------------------------- protection state (P/- protected/unprotected)
894 
895      >>CPU   reg: P **** *****  ******    MPF 00000, MPV 000000, MES 000000, MEV 000000
896                   ~ ~~~~ ~~~~~  ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
897                   |   |    |       |         |
898                   |   |    |       |         +-- memory protect fence and violation registers
899                   |   |    |       |             memory expansion status and violation registers
900                   |   |    |       +------------ (place holder)
901                   |   |    +-------------------- (place holder)
902                   |   +------------------------- (place holder)
903                   +----------------------------- protection state (P/- protected/unprotected)
904 
905 
906 
907      >>CPU  opnd: . **** 36002  101475    return location is P+3 (error EM21)
908      >>CPU  opnd: . **** 22067  105355    entry is for a dynamic mapping violation
909                          ~~~~~  ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
910                            |       |         |
911                            |       |         +-- operand-specific value
912                            |       +------------ operand-specific octal data
913                            +-------------------- octal logical address (P register)
914 
915 
916    Implementation notes:
917 
918     1. The simulator is fast enough, compared to the run-time of the longest
919        instructions, for interruptibility not to matter.  However, the HP
920        diagnostics explicitly test interruptibility in the EIS and DMS
921        instructions and in long indirect address chains.  Accordingly, the
922        simulator does "just enough" to pass these tests.  In particular, if an
923        interrupt is pending but deferred at the beginning of an interruptible
924        instruction, the interrupt is taken at the appropriate point; but there
925        is no testing for new interrupts during execution (that is, the event
926        timer is not called).
927 
928     2. The Power Fail option is not currently implemented.
929 */
930 
931 
932 
933 #include <setjmp.h>
934 
935 #include "hp2100_defs.h"
936 #include "hp2100_cpu.h"
937 #include "hp2100_cpu_dmm.h"
938 
939 
940 
941 /* CPU program constants */
942 
943 /* Alter-Skip Group instruction register fields */
944 
945 #define IR_CMx              0001000u            /* CMA/B */
946 #define IR_CLx              0000400u            /* CLA/B */
947 #define IR_CME              0000200u            /* CME */
948 #define IR_CLE              0000100u            /* CLE */
949 #define IR_SEZ              0000040u            /* SEZ */
950 #define IR_SSx              0000020u            /* SSA/B */
951 #define IR_SLx              0000010u            /* SLA/B */
952 #define IR_INx              0000004u            /* INA/B */
953 #define IR_SZx              0000002u            /* SZA/B */
954 #define IR_RSS              0000001u            /* RSS */
955 
956 #define IR_SSx_SLx_RSS      (IR_SSx | IR_SLx | IR_RSS)          /* a special case */
957 #define IR_ALL_SKIPS        (IR_SEZ | IR_SZx | IR_SSx_SLx_RSS)  /* another special case */
958 
959 /* Shift-Rotate Group instruction register micro-ops */
960 
961 #define IR_xLS              0000000u            /* ALS/BLS */
962 #define IR_xRS              0000001u            /* ARS/BRS */
963 #define IR_RxL              0000002u            /* RAL/RBL */
964 #define IR_RxR              0000003u            /* RAR/RBR */
965 #define IR_xLR              0000004u            /* ALR/BLR */
966 #define IR_ERx              0000005u            /* ERA/ERB */
967 #define IR_ELx              0000006u            /* ELA/ELB */
968 #define IR_xLF              0000007u            /* ALF/BLF */
969 
970 #define SRG_DIS             0000000u            /* micro-op disable */
971 #define SRG1_EN             0000010u            /* micro-op 1 enable */
972 #define SRG2_EN             0000020u            /* micro-op 2 enable */
973 
974 /* Instruction register masks */
975 
976 #define IR_MRG              (MRG | AB_MASK)     /* MRG instructions mask */
977 #define IR_MRG_I            (IR_MRG | IR_IND)   /* MRG indirect instructions mask */
978 
979 #define IR_JSB              0014000u            /* JSB instruction */
980 #define IR_JSB_I            (IR_JSB | IR_IND)   /* JSB,I instruction */
981 #define IR_JMP              0024000u            /* JMP instruction */
982 
983 #define IR_HLT_MASK         0172700u            /* I/O group mask for HLT[,C] instruction */
984 #define IR_CLC_MASK         0176700u            /* I/O group mask for a CLC[,C] instruction */
985 
986 #define IR_HLT              0102000u            /* HLT instruction */
987 #define IR_CLC              0106700u            /* CLC instruction */
988 
989 
990 /* CPU unit flags and accessors.
991 
992       31  30  29  28  27  26  25  24  23  22  21  20  19  18  17  16
993      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
994      | r | - | G | V | O | E | D | F | M | I | P | U |   CPU model   |
995      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
996 
997    Where:
998 
999      r = reserved
1000      G = SIGNAL/1000 firmware is present
1001      V = Vector Instruction Set firmware is present
1002      O = RTE-6/VM VMA and OS firmware is present
1003      E = RTE-IV EMA firmware is present
1004      D = Double Integer firmware is present
1005      F = Fast FORTRAN Processor firmware is present
1006      M = Dynamic Mapping System firmware is present
1007      I = 2000 I/O Processor firmware is present
1008      P = Floating Point hardware or firmware is present
1009      U = Extended Arithmetic Unit is present
1010 */
1011 
1012 #define UNIT_MODEL_SHIFT    (UNIT_V_UF + 0)     /* bits 0- 3: CPU model (OPTION_ID value) */
1013 #define UNIT_OPTION_SHIFT   (UNIT_V_UF + 4)     /* bits 4-15: CPU options installed */
1014 
1015 #define UNIT_MODEL_MASK     0000017u            /* model ID mask */
1016 #define UNIT_OPTION_MASK    0003777u            /* option ID mask */
1017 
1018 #define UNIT_MODEL_FIELD    (UNIT_MODEL_MASK  << UNIT_MODEL_SHIFT)
1019 #define UNIT_OPTION_FIELD   (UNIT_OPTION_MASK << UNIT_OPTION_SHIFT)
1020 
1021 #define UNIT_MODEL(f)       ((f) >> UNIT_MODEL_SHIFT & UNIT_MODEL_MASK)
1022 #define UNIT_OPTION(f)      ((f) >> UNIT_OPTION_SHIFT & UNIT_OPTION_MASK)
1023 
1024 #define TO_UNIT_OPTION(id)  (1u << UNIT_OPTION_SHIFT + (id) - Option_BASE - 1)
1025 
1026 /* Unit models */
1027 
1028 #define UNIT_2116           (Option_2116   << UNIT_MODEL_SHIFT)
1029 #define UNIT_2115           (Option_2115   << UNIT_MODEL_SHIFT)
1030 #define UNIT_2114           (Option_2114   << UNIT_MODEL_SHIFT)
1031 #define UNIT_2100           (Option_2100   << UNIT_MODEL_SHIFT)
1032 #define UNIT_1000_M         (Option_1000_M << UNIT_MODEL_SHIFT)
1033 #define UNIT_1000_E         (Option_1000_E << UNIT_MODEL_SHIFT)
1034 #define UNIT_1000_F         (Option_1000_F << UNIT_MODEL_SHIFT)
1035 
1036 /* Unit options */
1037 
1038 #define UNIT_EAU            TO_UNIT_OPTION (Option_EAU)
1039 #define UNIT_FP             TO_UNIT_OPTION (Option_FP)
1040 #define UNIT_IOP            TO_UNIT_OPTION (Option_IOP)
1041 #define UNIT_DMS            TO_UNIT_OPTION (Option_DMS)
1042 #define UNIT_FFP            TO_UNIT_OPTION (Option_FFP)
1043 #define UNIT_DBI            TO_UNIT_OPTION (Option_DBI)
1044 #define UNIT_EMA            TO_UNIT_OPTION (Option_EMA)
1045 #define UNIT_VMAOS          TO_UNIT_OPTION (Option_VMAOS)
1046 #define UNIT_VIS            TO_UNIT_OPTION (Option_VIS)
1047 #define UNIT_SIGNAL         TO_UNIT_OPTION (Option_SIGNAL)
1048 #define UNIT_DS             TO_UNIT_OPTION (Option_DS)
1049 
1050 #define UNIT_EMA_VMA        (UNIT_EMA | UNIT_VMAOS)
1051 
1052 /* Unit conversions to CPU options */
1053 
1054 #define TO_CPU_MODEL(f)     (CPU_OPTION) (1u << UNIT_MODEL (f))
1055 #define TO_CPU_OPTION(f)    (CPU_OPTION) (UNIT_OPTION (f) << CPU_OPTION_SHIFT)
1056 
1057 /* "Pseudo-option" flags used only for option testing; never set into the UNIT structure */
1058 
1059 #define UNIT_V_PFAIL        (UNIT_V_UF - 1)                 /* Power fail is installed */
1060 #define UNIT_V_DMA          (UNIT_V_UF - 2)                 /* DMA is installed */
1061 #define UNIT_V_MP           (UNIT_V_UF - 3)                 /* Memory protect is installed */
1062 
1063 #define UNIT_PFAIL          (1 << UNIT_V_PFAIL)
1064 #define UNIT_DMA            (1 << UNIT_V_DMA)
1065 #define UNIT_MP             (1 << UNIT_V_MP)
1066 
1067 
1068 /* CPU global SCP data definitions */
1069 
1070 REG *sim_PC = NULL;                             /* the pointer to the P register */
1071 
1072 
1073 /* CPU global data structures */
1074 
1075 
1076 /* CPU registers */
1077 
1078 HP_WORD ABREG [2] = { 0, 0 };                   /* A and B registers */
1079 
1080 HP_WORD PR  = 0;                                /* P register */
1081 HP_WORD SR  = 0;                                /* S register */
1082 HP_WORD MR  = 0;                                /* M register */
1083 HP_WORD TR  = 0;                                /* T register */
1084 HP_WORD XR  = 0;                                /* X register */
1085 HP_WORD YR  = 0;                                /* Y register */
1086 
1087 uint32  E   = 0;                                /* E register */
1088 uint32  O   = 0;                                /* O register */
1089 
1090 HP_WORD IR  = 0;                                /* Instruction Register */
1091 HP_WORD CIR = 0;                                /* Central Interrupt Register */
1092 HP_WORD SPR = 0;                                /* 1000 Stack Pointer Register / 2100 F Register */
1093 
1094 
1095 /* CPU global state */
1096 
1097 FLIP_FLOP      cpu_interrupt_enable  = SET;     /* interrupt enable flip-flop */
1098 uint32         cpu_pending_interrupt = 0;       /* pending interrupt select code or zero if none */
1099 
1100 t_stat         cpu_ss_unimpl   = SCPE_OK;       /* status return for unimplemented instruction execution */
1101 t_stat         cpu_ss_undef    = SCPE_OK;       /* status return for undefined instruction execution */
1102 t_stat         cpu_ss_unsc     = SCPE_OK;       /* status return for I/O to an unassigned select code */
1103 t_stat         cpu_ss_ioerr    = SCPE_OK;       /* status return for an unreported I/O error */
1104 t_stat         cpu_ss_inhibit  = SCPE_OK;       /* CPU stop inhibition mask */
1105 UNIT           *cpu_ioerr_uptr = NULL;          /* pointer to a unit with an unreported I/O error */
1106 
1107 HP_WORD        err_PR         = 0;              /* error PC */
1108 uint16         pcq [PCQ_SIZE] = { 0 };          /* PC queue (must be 16-bits wide for REG array entry) */
1109 uint32         pcq_p          = 0;              /* PC queue pointer */
1110 REG            *pcq_r         = NULL;           /* PC queue register pointer */
1111 
1112 CPU_OPTION_SET cpu_configuration;               /* the current CPU option set and model */
1113 uint32         cpu_speed = 1;                   /* the CPU speed, expressed as a multiplier of a real machine */
1114 
1115 
1116 /* CPU local state.
1117 
1118 
1119    Implementation notes:
1120 
1121     1. The "is_1000" variable is used to index into tables where the row
1122        selected depends on whether or not the CPU is a 1000 M/E/F-series model.
1123        For logical tests that depend on this, it is faster (by one x86 machine
1124        instruction) to test the "cpu_configuration" variable for the presence of
1125        one of the three 1000 model flags.
1126 */
1127 
1128 static jmp_buf   abort_environment;             /* microcode abort environment */
1129 
1130 static FLIP_FLOP interrupt_system  = CLEAR;     /* interrupt system */
1131 static uint32    interrupt_request = 0;         /* the currently interrupting select code or zero if none */
1132 
1133 static uint32    interrupt_request_set [2] = { 0, 0 };  /* device interrupt request bit vector */
1134 static uint32    priority_holdoff_set  [2] = { 0, 0 };  /* device priority holdoff bit vector */
1135 
1136 static uint32    exec_mask        = 0;          /* the current instruction execution trace mask */
1137 static uint32    exec_match       = D16_UMAX;   /* the current instruction execution trace matching value */
1138 static uint32    indirect_limit   = 16;         /* the indirect chain length limit */
1139 
1140 static t_bool    is_1000          = FALSE;      /* TRUE if the CPU is a 1000 M/E/F-Series */
1141 static t_bool    mp_is_present    = FALSE;      /* TRUE if Memory Protect is present */
1142 static uint32    last_select_code = 0;          /* the last select code sent over the I/O backplane */
1143 static HP_WORD   saved_MR         = 0;          /* the M-register value between SCP commands */
1144 
1145 static DEVICE    *loader_rom [4]  = { NULL };   /* the four boot loader ROM sockets in a 1000 CPU */
1146 
1147 
1148 /* CPU local data structures */
1149 
1150 
1151 /* CPU features table.
1152 
1153    The feature table is used to validate CPU feature changes within the subset
1154    of features supported by a given CPU.  Features in the typical list are
1155    enabled when the CPU model is selected.  If a feature appears in the typical
1156    list but NOT in the optional list, then it is standard equipment and cannot
1157    be disabled.  If a feature appears in the optional list, then it may be
1158    enabled or disabled as desired by the user.
1159 */
1160 
1161 typedef struct {                                /* CPU model feature table */
1162     uint32      typ;                            /*   standard features plus typically configured options */
1163     uint32      opt;                            /*   complete list of optional features */
1164     uint32      maxmem;                         /*   maximum configurable memory in 16-bit words */
1165     } FEATURE_TABLE;
1166 
1167 static const FEATURE_TABLE cpu_features [] = {          /* CPU features indexed by OPTION_ID */
1168   { UNIT_DMA | UNIT_MP,                                 /*   Option_2116 */
1169     UNIT_PFAIL | UNIT_DMA | UNIT_MP | UNIT_EAU,
1170     32 * 1024
1171     },
1172 
1173   { UNIT_DMA,                                           /*   Option_2115 */
1174     UNIT_PFAIL | UNIT_DMA | UNIT_EAU,
1175     8 * 1024
1176     },
1177 
1178   { UNIT_DMA,                                           /*   Option_2114 */
1179     UNIT_PFAIL | UNIT_DMA,
1180     16 * 1024
1181     },
1182 
1183   { UNIT_PFAIL | UNIT_MP | UNIT_DMA | UNIT_EAU,         /*   Option_2100 */
1184     UNIT_DMA   | UNIT_FP | UNIT_IOP | UNIT_FFP,
1185     32 * 1024
1186     },
1187 
1188   { UNIT_MP | UNIT_DMA | UNIT_EAU | UNIT_FP | UNIT_DMS, /*   Option_1000_M */
1189     UNIT_PFAIL | UNIT_DMA | UNIT_MP | UNIT_DMS |
1190     UNIT_IOP   | UNIT_FFP | UNIT_DS,
1191     1024 * 1024
1192     },
1193 
1194   { UNIT_MP | UNIT_DMA | UNIT_EAU | UNIT_FP | UNIT_DMS, /*   Option_1000_E */
1195     UNIT_PFAIL | UNIT_DMA | UNIT_MP  | UNIT_DMS |
1196     UNIT_IOP   | UNIT_FFP | UNIT_DBI | UNIT_DS  | UNIT_EMA_VMA,
1197     1024 * 1024
1198     },
1199 
1200   { UNIT_MP  | UNIT_DMA | UNIT_EAU | UNIT_FP |          /*   Option_1000_F */
1201     UNIT_FFP | UNIT_DBI | UNIT_DMS,
1202     UNIT_PFAIL | UNIT_DMA | UNIT_MP     | UNIT_DMS |
1203     UNIT_VIS   | UNIT_DS  | UNIT_SIGNAL | UNIT_EMA_VMA,
1204     1024 * 1024
1205     }
1206   };
1207 
1208 
1209 /* CPU local SCP support routine declarations */
1210 
1211 static INTERFACE cpu_interface;
1212 static INTERFACE ovf_interface;
1213 static INTERFACE pwr_interface;
1214 
1215 static t_stat cpu_examine (t_value *eval, t_addr address, UNIT *uptr, int32 switches);
1216 static t_stat cpu_deposit (t_value value, t_addr address, UNIT *uptr, int32 switches);
1217 
1218 static t_stat cpu_reset (DEVICE *dptr);
1219 static t_stat cpu_boot  (int32  unitno, DEVICE *dptr);
1220 
1221 static t_stat set_stops    (UNIT *uptr, int32 option,    char *cptr, void *desc);
1222 static t_stat set_size     (UNIT *uptr, int32 new_size,  char *cptr, void *desc);
1223 static t_stat set_model    (UNIT *uptr, int32 new_model, char *cptr, void *desc);
1224 static t_stat set_option   (UNIT *uptr, int32 option,    char *cptr, void *desc);
1225 static t_stat clear_option (UNIT *uptr, int32 option,    char *cptr, void *desc);
1226 static t_stat set_loader   (UNIT *uptr, int32 enable,    char *cptr, void *desc);
1227 static t_stat set_roms     (UNIT *uptr, int32 option,    char *cptr, void *desc);
1228 static t_stat set_exec     (UNIT *uptr, int32 option,    char *cptr, void *desc);
1229 
1230 static t_stat show_stops (FILE *st, UNIT *uptr, int32 val, void *desc);
1231 static t_stat show_model (FILE *st, UNIT *uptr, int32 val, void *desc);
1232 static t_stat show_roms  (FILE *st, UNIT *uptr, int32 val, void *desc);
1233 static t_stat show_cage  (FILE *st, UNIT *uptr, int32 val, void *desc);
1234 static t_stat show_exec  (FILE *st, UNIT *uptr, int32 val, void *desc);
1235 static t_stat show_speed (FILE *st, UNIT *uptr, int32 val, void *desc);
1236 
1237 
1238 /* CPU local utility routine declarations */
1239 
1240 static t_stat  mrg_address         (void);
1241 static HP_WORD srg_uop             (HP_WORD value, HP_WORD operation);
1242 static t_stat  machine_instruction (t_bool int_ack, uint32 *idle_save);
1243 static t_bool  reenable_interrupts (void);
1244 
1245 
1246 /* CPU SCP data structures */
1247 
1248 
1249 /* Device information blocks */
1250 
1251 static DIB cpu_dib = {                          /* CPU (select code 0) */
1252     &cpu_interface,                             /*   the device's I/O interface function pointer */
1253     CPU,                                        /*   the device's select code (02-77) */
1254     0,                                          /*   the card index */
1255     NULL,                                       /*   the card description */
1256     NULL                                        /*   the ROM description */
1257     };
1258 
1259 static DIB ovfl_dib = {                         /* Overflow (select code 1) */
1260     &ovf_interface,                             /*   the device's I/O interface function pointer */
1261     OVF,                                        /*   the device's select code (02-77) */
1262     0,                                          /*   the card index */
1263     NULL,                                       /*   the card description */
1264     NULL                                        /*   the ROM description */
1265     };
1266 
1267 static DIB pwrf_dib = {                         /* Power Fail (select code 4) */
1268     &pwr_interface,                             /*   the device's I/O interface function pointer */
1269     PWR,                                        /*   the device's select code (02-77) */
1270     0,                                          /*   the card index */
1271     NULL,                                       /*   the card description */
1272     NULL                                        /*   the ROM description */
1273     };
1274 
1275 
1276 /* Unit list.
1277 
1278    The CPU unit "capac" field is set to the current main memory capacity in
1279    16-bit words by the "set_size" utility routine.  The CPU does not use a unit
1280    event service routine.
1281 */
1282 
1283 static UNIT cpu_unit [] = {
1284     { UDATA (NULL, UNIT_FIX | UNIT_BINK, 0) }
1285     };
1286 
1287 
1288 /* Register list.
1289 
1290    The CPU register list exposes the machine registers for user inspection and
1291    modification.
1292 
1293 
1294    Implementation notes:
1295 
1296     1. All registers that reference variables of type HP_WORD must have the
1297        REG_FIT flag for proper access if HP_WORD is a 16-bit type.
1298 
1299     2. The REG_X flag indicates that the register may be displayed in symbolic
1300        form.
1301 
1302     3. The T register cannot be modified.  To change a memory location value,
1303        the DEPOSIT CPU command must be used.
1304 */
1305 
1306 static REG cpu_reg [] = {
1307 /*    Macro   Name     Location            Radix  Width   Offset       Depth                Flags       */
1308 /*    ------  -------  ------------------  -----  -----  --------  -----------------  ----------------- */
1309     { ORDATA (P,       PR,                         15)                                                  },
1310     { ORDATA (A,       AR,                         16),                               REG_X             },
1311     { ORDATA (B,       BR,                         16),                               REG_X             },
1312     { ORDATA (M,       MR,                         15)                                                  },
1313     { ORDATA (T,       TR,                         16),                               REG_RO | REG_X    },
1314     { ORDATA (X,       XR,                         16),                               REG_X             },
1315     { ORDATA (Y,       YR,                         16),                               REG_X             },
1316     { ORDATA (S,       SR,                         16),                               REG_X             },
1317     { FLDATA (E,       E,                                   0)                                          },
1318     { FLDATA (O,       O,                                   0)                                          },
1319     { ORDATA (CIR,     CIR,                         6)                                                  },
1320 
1321     { FLDATA (INTSYS,  interrupt_system,                    0)                                          },
1322     { FLDATA (INTEN,   cpu_interrupt_enable,                0)                                          },
1323 
1324     { ORDATA (IOPSP,   SPR,                        16)                                                  },
1325     { BRDATA (PCQ,     pcq,                  8,    15,             PCQ_SIZE),         REG_CIRC | REG_RO },
1326 
1327     { ORDATA (IR,      IR,                         16),                               REG_HRO           },
1328     { ORDATA (SAVEDMR, saved_MR,                   32),                               REG_HRO           },
1329     { ORDATA (PCQP,    pcq_p,                       6),                               REG_HRO           },
1330 
1331     { ORDATA (EMASK,   exec_mask,                  16),                               REG_HRO           },
1332     { ORDATA (EMATCH,  exec_match,                 16),                               REG_HRO           },
1333     { DRDATA (ILIMIT,  indirect_limit,             16),                               REG_HRO           },
1334     { ORDATA (FWANXM,  mem_end,                    32),                               REG_HRO           },
1335     { ORDATA (CONFIG,  cpu_configuration,          32),                               REG_HRO           },
1336     { BRDATA (ROMS,    loader_rom,           8,    32,                 4),            REG_HRO           },
1337 
1338     { FLDATA (IS1000,  is_1000,                             0),                       REG_HRO           },
1339     { ORDATA (INTREQ,  interrupt_request,           6),                               REG_HRO           },
1340     { ORDATA (LASTSC,  last_select_code,            6),                               REG_HRO           },
1341 
1342     { ORDATA (WRU,     sim_int_char,                8),                               REG_HRO           },
1343     { ORDATA (BRK,     sim_brk_char,                8),                               REG_HRO           },
1344     { ORDATA (DEL,     sim_del_char,                8),                               REG_HRO           },
1345 
1346     { NULL }
1347     };
1348 
1349 
1350 /* Modifier list.
1351 
1352 
1353    Implementation notes:
1354 
1355     1. The 21MX monikers are deprecated in favor of the 1000 designations.  See
1356        the "HP 1000 Series Naming History" on the back inside cover of the
1357        Technical Reference Handbook.
1358 
1359     2. The string descriptors are used by the "show_model" routine to print the
1360        CPU model numbers prior to appending "loader enabled" or "loader
1361        disabled" to the report.
1362 
1363     3. Each CPU option requires three modifiers.  The two regular modifiers
1364        control the setting and printing of the option, while the extended
1365        modifier controls clearing the option.  The latter is necessary because
1366        the option must be checked before confirming the change, and so the
1367        option value must be passed to the validation routine.
1368 */
1369 
1370 static MTAB cpu_mod [] = {
1371 /*    Mask Value        Match Value  Print String  Match String  Validation     Display      Descriptor        */
1372 /*    ----------------  -----------  ------------  ------------  -------------  -----------  ----------------- */
1373     { UNIT_MODEL_FIELD, UNIT_2116,   "",           "2116",       &set_model,    &show_model, (void *) "2116"   },
1374     { UNIT_MODEL_FIELD, UNIT_2115,   "",           "2115",       &set_model,    &show_model, (void *) "2115"   },
1375     { UNIT_MODEL_FIELD, UNIT_2114,   "",           "2114",       &set_model,    &show_model, (void *) "2114"   },
1376     { UNIT_MODEL_FIELD, UNIT_2100,   "",           "2100",       &set_model,    &show_model, (void *) "2100"   },
1377     { UNIT_MODEL_FIELD, UNIT_1000_E, "",           "1000-E",     &set_model,    &show_model, (void *) "1000-E" },
1378     { UNIT_MODEL_FIELD, UNIT_1000_M, "",           "1000-M",     &set_model,    &show_model, (void *) "1000-M" },
1379 
1380 #if defined (HAVE_INT64)
1381     { UNIT_MODEL_FIELD, UNIT_1000_F, "",           "1000-F",     &set_model,    &show_model, (void *) "1000-F" },
1382 #endif
1383 
1384     { UNIT_MODEL_FIELD, UNIT_1000_M, NULL,         "21MX-M",     &set_model,    &show_model, (void *) "1000-M" },
1385     { UNIT_MODEL_FIELD, UNIT_1000_E, NULL,         "21MX-E",     &set_model,    &show_model, (void *) "1000-E" },
1386 
1387     { UNIT_EAU,         UNIT_EAU,    "EAU",        "EAU",        &set_option,   NULL,        NULL              },
1388     { UNIT_EAU,         0,           "no EAU",     NULL,         NULL,          NULL,        NULL              },
1389     { MTAB_XDV,         UNIT_EAU,     NULL,        "NOEAU",      &clear_option, NULL,        NULL              },
1390 
1391     { UNIT_FP,          UNIT_FP,     "FP",         "FP",         &set_option,   NULL,        NULL              },
1392     { UNIT_FP,          0,           "no FP",      NULL,         NULL,          NULL,        NULL              },
1393     { MTAB_XDV,         UNIT_FP,      NULL,        "NOFP",       &clear_option, NULL,        NULL              },
1394 
1395     { UNIT_IOP,         UNIT_IOP,    "IOP",        "IOP",        &set_option,   NULL,        NULL              },
1396     { UNIT_IOP,         0,           "no IOP",     NULL,         NULL,          NULL,        NULL              },
1397     { MTAB_XDV,         UNIT_IOP,     NULL,        "NOIOP",      &clear_option, NULL,        NULL              },
1398 
1399     { UNIT_DMS,         UNIT_DMS,    "DMS",        "DMS",        &set_option,   NULL,        NULL              },
1400     { UNIT_DMS,         0,           "no DMS",     NULL,         NULL,          NULL,        NULL              },
1401     { MTAB_XDV,         UNIT_DMS,     NULL,        "NODMS",      &clear_option, NULL,        NULL              },
1402 
1403     { UNIT_FFP,         UNIT_FFP,    "FFP",        "FFP",        &set_option,   NULL,        NULL              },
1404     { UNIT_FFP,         0,           "no FFP",     NULL,         NULL,          NULL,        NULL              },
1405     { MTAB_XDV,         UNIT_FFP,     NULL,        "NOFFP",      &clear_option, NULL,        NULL              },
1406 
1407     { UNIT_DBI,         UNIT_DBI,    "DBI",        "DBI",        &set_option,   NULL,        NULL              },
1408     { UNIT_DBI,         0,           "no DBI",     NULL,         NULL,          NULL,        NULL              },
1409     { MTAB_XDV,         UNIT_DBI,     NULL,        "NODBI",      &clear_option, NULL,        NULL              },
1410 
1411     { UNIT_EMA_VMA,     UNIT_EMA,    "EMA",        "EMA",        &set_option,   NULL,        NULL              },
1412     { MTAB_XDV,         UNIT_EMA,     NULL,        "NOEMA",      &clear_option, NULL,        NULL              },
1413 
1414     { UNIT_EMA_VMA,     UNIT_VMAOS,  "VMA",        "VMA",        &set_option,   NULL,        NULL              },
1415     { MTAB_XDV,         UNIT_VMAOS,   NULL,        "NOVMA",      &clear_option, NULL,        NULL              },
1416 
1417     { UNIT_EMA_VMA,     0,           "no EMA/VMA", NULL,         &set_option,   NULL,        NULL              },
1418 
1419 #if defined (HAVE_INT64)
1420     { UNIT_VIS,         UNIT_VIS,    "VIS",        "VIS",        &set_option,   NULL,        NULL              },
1421     { UNIT_VIS,         0,           "no VIS",     NULL,         NULL,          NULL,        NULL              },
1422     { MTAB_XDV,         UNIT_VIS,     NULL,        "NOVIS",      &clear_option, NULL,        NULL              },
1423 
1424     { UNIT_SIGNAL,      UNIT_SIGNAL, "SIGNAL",     "SIGNAL",     &set_option,   NULL,        NULL              },
1425     { UNIT_SIGNAL,      0,           "no SIGNAL",  NULL,         NULL,          NULL,        NULL              },
1426     { MTAB_XDV,         UNIT_SIGNAL,  NULL,        "NOSIGNAL",   &clear_option, NULL,        NULL              },
1427 #endif
1428 
1429 /* Future microcode support.
1430     { UNIT_DS,          UNIT_DS,     "DS",         "DS",         &set_option,   NULL,        NULL              },
1431     { UNIT_DS,          0,           "no DS",      NULL,         NULL,          NULL,        NULL              },
1432     { MTAB_XDV,         UNIT_DS,      NULL,        "NODS",       &clear_option, NULL,        NULL              },
1433 */
1434 
1435 /*    Entry Flags             Value     Print String  Match String     Validation     Display         Descriptor */
1436 /*    -------------------  -----------  ------------  ---------------  -------------  --------------  ---------- */
1437     { MTAB_XDV,                 0,      "IDLE",       "IDLE",          &sim_set_idle, &sim_show_idle, NULL       },
1438     { MTAB_XDV,                 0,      NULL,         "NOIDLE",        &sim_clr_idle, NULL,           NULL       },
1439 
1440     { MTAB_XDV,                 1,      NULL,         "LOADERENABLE",  &set_loader,   NULL,           NULL       },
1441     { MTAB_XDV,                 0,      NULL,         "LOADERDISABLE", &set_loader,   NULL,           NULL       },
1442 
1443     { MTAB_XDV,               4 * 1024, NULL,         "4K",            &set_size,     NULL,           NULL       },
1444     { MTAB_XDV,               8 * 1024, NULL,         "8K",            &set_size,     NULL,           NULL       },
1445     { MTAB_XDV,              12 * 1024, NULL,         "12K",           &set_size,     NULL,           NULL       },
1446     { MTAB_XDV,              16 * 1024, NULL,         "16K",           &set_size,     NULL,           NULL       },
1447     { MTAB_XDV,              24 * 1024, NULL,         "24K",           &set_size,     NULL,           NULL       },
1448     { MTAB_XDV,              32 * 1024, NULL,         "32K",           &set_size,     NULL,           NULL       },
1449     { MTAB_XDV,              64 * 1024, NULL,         "64K",           &set_size,     NULL,           NULL       },
1450     { MTAB_XDV,             128 * 1024, NULL,         "128K",          &set_size,     NULL,           NULL       },
1451     { MTAB_XDV,             256 * 1024, NULL,         "256K",          &set_size,     NULL,           NULL       },
1452     { MTAB_XDV,             512 * 1024, NULL,         "512K",          &set_size,     NULL,           NULL       },
1453     { MTAB_XDV,            1024 * 1024, NULL,         "1024K",         &set_size,     NULL,           NULL       },
1454 
1455     { MTAB_XDV | MTAB_NMO,      0,      "ROMS",       "ROMS",          &set_roms,     &show_roms,     NULL       },
1456     { MTAB_XDV | MTAB_NMO,      0,      "IOCAGE",     NULL,            NULL,          &show_cage,     NULL       },
1457 
1458     { MTAB_XDV | MTAB_NMO,      1,      "STOPS",      "STOP",          &set_stops,    &show_stops,    NULL       },
1459     { MTAB_XDV,                 0,      NULL,         "NOSTOP",        &set_stops,    NULL,           NULL       },
1460     { MTAB_XDV | MTAB_NMO,      2,      "INDIR",      "INDIR",         &set_stops,    &show_stops,    NULL       },
1461 
1462     { MTAB_XDV | MTAB_NMO,      1,      "EXEC",       "EXEC",          &set_exec,     &show_exec,     NULL       },
1463     { MTAB_XDV,                 0,      NULL,         "NOEXEC",        &set_exec,     NULL,           NULL       },
1464 
1465     { MTAB_XDV | MTAB_NMO,      0,      "SPEED",      NULL,            NULL,          &show_speed,    NULL       },
1466 
1467     { 0 }
1468     };
1469 
1470 
1471 /* Trace list */
1472 
1473 static DEBTAB cpu_deb [] = {
1474     { "INSTR", TRACE_INSTR },                   /* trace instruction executions */
1475     { "DATA",  TRACE_DATA  },                   /* trace memory data accesses */
1476     { "FETCH", TRACE_FETCH },                   /* trace memory instruction fetches */
1477     { "REG",   TRACE_REG   },                   /* trace register values */
1478     { "OPND",  TRACE_OPND  },                   /* trace instruction operands */
1479     { "EXEC",  TRACE_EXEC  },                   /* trace matching instruction execution states */
1480     { "NOOS",  DEBUG_NOOS  },                   /* RTE-6/VM will not use OS firmware */
1481     { NULL,    0 }
1482     };
1483 
1484 
1485 /* Simulation stop list.
1486 
1487    The simulator can be configured to detect certain machine instruction
1488    conditions and stop execution when one of them occurs.  Stops may be enabled
1489    or disabled individually with these commands:
1490 
1491      SET CPU STOP=<option>[;<option]
1492      SET CPU NOSTOP=<option>[;<option]
1493 
1494    The CPU stop table is used to parse the commands and set the appropriate
1495    variables to enable or disable the stops.
1496 
1497 
1498    Implementation notes:
1499 
1500     1. To avoid the testing of stop conditions at run time, they are implemented
1501        by setting individual stop status variables either to the appropriate
1502        stop code (if enabled) or to SCPE_OK (if disabled).  This allows the
1503        affected routines to return the status value unconditionally and cause
1504        either a simulator stop or continued execution without a run-time test.
1505 
1506     2. SCPE_IOERR is not actually returned for unreported I/O errors.  Instead,
1507        it is simply a flag that a stop code specific to the detected error
1508        should be returned.
1509 
1510     3. To permit stops to be bypassed for one instruction execution, routines
1511        use the STOP macro to return the value of the applicable stop variable
1512        ANDed with the complement of the value of the "cpu_ss_inhibit" variable.
1513        The latter is set in the instruction prelude to SS_INHIBIT (i.e., all
1514        ones) if a bypass is requested or to SCPE_OK (i.e., all zeros) if not,
1515        and is reset to SCPE_OK after each instruction execution.  The effect is
1516        that SCPE_OK is returned instead of a simulator stop if a stop condition
1517        occurs when a bypass is specified.  This action depends on the value of
1518        SCPE_OK being zero (which is guaranteed).
1519 */
1520 
1521 typedef struct {
1522     const char  *name;                          /* stop name */
1523     t_stat      *status;                        /* pointer to the stop status variable */
1524     t_stat      value;                          /* stop status return value */
1525     } STOPTAB;
1526 
1527 static STOPTAB cpu_stop [] = {
1528     { "UNIMPL", &cpu_ss_unimpl, STOP_UNIMPL },  /* stop on an unimplemented instruction */
1529     { "UNDEF",  &cpu_ss_undef,  STOP_UNDEF  },  /* stop on an undefined instruction */
1530     { "UNSC",   &cpu_ss_unsc,   STOP_UNSC   },  /* stop on I/O to an unassigned select code */
1531     { "IOERR",  &cpu_ss_ioerr,  SCPE_IOERR  },  /* stop on an unreported I/O error */
1532     { NULL,     NULL,           0           }
1533     };
1534 
1535 
1536 /* Device descriptor */
1537 
1538 DEVICE cpu_dev = {
1539     "CPU",                                      /* device name */
1540     cpu_unit,                                   /* unit array */
1541     cpu_reg,                                    /* register array */
1542     cpu_mod,                                    /* modifier array */
1543     1,                                          /* number of units */
1544     8,                                          /* address radix */
1545     PA_WIDTH,                                   /* address width */
1546     1,                                          /* address increment */
1547     8,                                          /* data radix */
1548     16,                                         /* data width */
1549     &cpu_examine,                               /* examine routine */
1550     &cpu_deposit,                               /* deposit routine */
1551     &cpu_reset,                                 /* reset routine */
1552     &cpu_boot,                                  /* boot routine */
1553     NULL,                                       /* attach routine */
1554     NULL,                                       /* detach routine */
1555     &cpu_dib,                                   /* device information block pointer */
1556     DEV_DEBUG,                                  /* device flags */
1557     0,                                          /* debug control flags */
1558     cpu_deb,                                    /* debug flag name table */
1559     NULL,                                       /* memory size change routine */
1560     NULL                                        /* logical device name */
1561     };
1562 
1563 
1564 
1565 /* I/O subsystem local data structures */
1566 
1567 
1568 /* Signal names */
1569 
1570 static const BITSET_NAME inbound_names [] = {   /* Inbound signal names, in INBOUND_SIGNAL order */
1571     "PON",                                      /*   000000000001 */
1572     "IOI",                                      /*   000000000002 */
1573     "IOO",                                      /*   000000000004 */
1574     "SFS",                                      /*   000000000010 */
1575     "SFC",                                      /*   000000000020 */
1576     "STC",                                      /*   000000000040 */
1577     "CLC",                                      /*   000000000100 */
1578     "STF",                                      /*   000000000200 */
1579     "CLF",                                      /*   000000000400 */
1580     "EDT",                                      /*   000000001000 */
1581     "CRS",                                      /*   000000002000 */
1582     "POPIO",                                    /*   000000004000 */
1583     "IAK",                                      /*   000000010000 */
1584     "ENF",                                      /*   000000020000 */
1585     "SIR",                                      /*   000000040000 */
1586     "IEN",                                      /*   000000100000 */
1587     "PRH"                                       /*   000000200000 */
1588     };
1589 
1590 static const BITSET_FORMAT inbound_format =     /* names, offset, direction, alternates, bar */
1591     { FMT_INIT (inbound_names, 0, lsb_first, no_alt, no_bar) };
1592 
1593 
1594 static const BITSET_NAME outbound_names [] = {  /* Outbound signal names, in OUTBOUND_SIGNAL order */
1595     "SKF",                                      /*   000000000001 */
1596     "PRL",                                      /*   000000000002 */
1597     "FLG",                                      /*   000000000004 */
1598     "IRQ",                                      /*   000000000010 */
1599     "SRQ"                                       /*   000000000020 */
1600     };
1601 
1602 static const BITSET_FORMAT outbound_format =    /* names, offset, direction, alternates, bar */
1603     { FMT_INIT (outbound_names, 0, lsb_first, no_alt, no_bar) };
1604 
1605 
1606 /* I/O signal tables.
1607 
1608    These tables contain the set of I/O signals that are appropriate for each I/O
1609    operation.  Two tables are defined.
1610 
1611    The first table defines the backplane signals generated by each I/O Group
1612    operation.  A signal set is sent to the device interface associated with the
1613    select code specified in an IOG instruction to direct the operation of the
1614    interface.  Backplane signals map closely to IOG instructions.  For example,
1615    the SFS instruction asserts the SFS backplane signal to the interface card.
1616 
1617    The hardware ENF and SIR signals are periodic.  In simulation, they are
1618    asserted only when the flag buffer or the flag and control flip-flops are
1619    changed, respectively.
1620 
1621    The second table defines the signals generated in addition to the explicitly
1622    asserted signal.  Specifically, asserting PON also asserts POPIO and CRS,
1623    and asserting POPIO also asserts CRS.  The ENF and SIR signals are asserted
1624    when necessary as described above.
1625 */
1626 
1627 static const INBOUND_SET control_set [] = {     /* indexed by IO_GROUP_OP */
1628     ioNONE,                                     /*   iog_HLT */
1629     ioSTF  | ioENF | ioSIR,                     /*   iog_STF */
1630     ioSFC,                                      /*   iog_SFC */
1631     ioSFS,                                      /*   iog_SFS */
1632     ioIOI,                                      /*   iog_MIx */
1633     ioIOI,                                      /*   iog_LIx */
1634     ioIOO,                                      /*   iog_OTx */
1635     ioSTC          | ioSIR,                     /*   iog_STC */
1636 
1637     ioNONE | ioCLF | ioSIR,                     /*   iog_HLT_C */
1638     ioCLF          | ioSIR,                     /*   iog_CLF */
1639     ioSFC  | ioCLF | ioSIR,                     /*   iog_SFC_C */
1640     ioSFS  | ioCLF | ioSIR,                     /*   iog_SFS_C */
1641     ioIOI  | ioCLF | ioSIR,                     /*   iog_MIx_C */
1642     ioIOI  | ioCLF | ioSIR,                     /*   iog_LIx_C */
1643     ioIOO  | ioCLF | ioSIR,                     /*   iog_OTx_C */
1644     ioSTC  | ioCLF | ioSIR,                     /*   iog_STC_C */
1645 
1646     ioCLC          | ioSIR,                     /*   iog_CLC */
1647     ioCLC  | ioCLF | ioSIR                      /*   iog_CLC_C */
1648     };
1649 
1650 static const INBOUND_SET assert_set [] = {      /* indexed by IO_ASSERTION */
1651     ioENF                             | ioSIR,  /*   ioa_ENF */
1652     ioSIR,                                      /*   ioa_SIR */
1653     ioPON   | ioPOPIO | ioCRS | ioENF | ioSIR,  /*   ioa_PON */
1654     ioPOPIO | ioCRS           | ioENF | ioSIR,  /*   ioa_POPIO */
1655     ioCRS                     | ioENF | ioSIR,  /*   ioa_CRS */
1656     ioIAK                             | ioSIR   /*   ioa_IAK */
1657     };
1658 
1659 
1660 /* Interrupt enable table.
1661 
1662    I/O Group instructions that alter the interrupt priority chain must delay
1663    recognition of interrupts until the following instruction completes.  The HP
1664    1000 microcode does this by executing an IOFF micro-order to clear the
1665    interrupt enable (INTEN) flip-flop.  The table below gives the INTEN state
1666    for each I/O instruction; CLEAR corresponds to an IOFF micro-order, while SET
1667    corresponds to ION.  The table is also indexed by the "is_1000" selector, as
1668    the disable rules are different for the 21xx and 1000 machines.
1669 */
1670 
1671 static const t_bool enable_map [2] [18] = {             /* interrupt enable table, indexed by is_1000 and IO_GROUP_OP */
1672 /*    HLT    STF    SFC    SFS    MIx    LIx    OTx    STC   */
1673 /*    HLT_C  CLF    SFC_C  SFS_C  MIx_C  LIx_C  OTx_C  STC_C */
1674 /*    CLC    CLC_C                                           */
1675 /*    -----  -----  -----  -----  -----  -----  -----  ----- */
1676     { CLEAR, CLEAR, SET,   SET,   SET,   SET,   SET,   CLEAR,   /* 21xx */
1677       CLEAR, CLEAR, SET,   SET,   SET,   SET,   SET,   CLEAR,   /* 21xx */
1678       CLEAR, CLEAR },
1679 
1680     { CLEAR, CLEAR, CLEAR, CLEAR, SET,   SET,   SET,   CLEAR,   /* 1000 */
1681       CLEAR, CLEAR, CLEAR, CLEAR, SET,   SET,   SET,   CLEAR,   /* 1000 */
1682       CLEAR, CLEAR }
1683     };
1684 
1685 
1686 /* I/O access table.
1687 
1688    I/O signals are directed to specific interface cards by specifying their
1689    locations in the I/O card cage.  Each location is assigned a number, called a
1690    select code, that is specified by I/O Group instructions to indicate the
1691    interface card to activate.
1692 
1693    In simulation, the select code corresponding to each interface is stored in
1694    the corresponding Device Information Block (DIB).  To avoid having to scan
1695    the device list each time an I/O instruction is executed, an I/O access table
1696    is filled in as part of I/O initialization in the instruction execution
1697    prelude.  The table is indexed by select code (00-77 octal) and contains
1698    pointers to the device and DIB structures associated with each index.
1699 
1700    Initialization is performed during each "sim_instr" call, as the select code
1701    assignments may have been changed by the user at the SCP prompt.
1702 
1703 
1704    Implementation notes:
1705 
1706     1. The entries for select codes 0 and 1 (the CPU and Overflow Register,
1707        respectively) are initialized here, as they are always present (i.e.,
1708        cannot be disabled) and cannot change.
1709 
1710     2. The table contains constant pointers, but "const" cannot be used here, as
1711        "hp_trace" calls "sim_dname", which takes a variable device pointer even
1712        though it does not change anything.
1713 
1714     3. The "references" entries are used only during table initialization to
1715        ensure that each select code is referenced by only one device.
1716 */
1717 
1718 typedef struct {                            /* I/O access table entry */
1719     DEVICE *devptr;                         /*   a pointer to the DEVICE structure */
1720     DIB    *dibptr;                         /*   a pointer to the DIB structure */
1721     uint32 references;                      /*   a count of the references to this select code */
1722     } IO_TABLE;
1723 
1724 static IO_TABLE iot [SC_MAX + 1] = {         /* index by select code for I/O instruction dispatch */
1725     { &cpu_dev, &cpu_dib,  0 },              /*   select code 00 = interrupt system */
1726     { &cpu_dev, &ovfl_dib, 0 }               /*   select code 01 = overflow register */
1727     };
1728 
1729 
1730 /* I/O subsystem local utility routine declarations */
1731 
1732 static t_bool initialize_io (t_bool is_executing);
1733 
1734 
1735 
1736 /* CPU global SCP support routines */
1737 
1738 
1739 /* Execute CPU instructions.
1740 
1741    This is the instruction decode routine for the HP 21xx/1000 simulator.  It is
1742    called from the simulator control program (SCP) to execute instructions in
1743    simulated memory, starting at the simulated program counter.  It runs until
1744    the status to be returned is set to a value other than SCPE_OK.
1745 
1746    On entry, P points to the instruction to execute, and the "sim_switches"
1747    global contains any command-line switches included with the RUN command.  On
1748    exit, P points at the next instruction to execute.
1749 
1750    Execution is divided into four phases.
1751 
1752    First, the instruction prelude configures the simulation state to resume
1753    execution.  This involves verifying that there are no device conflicts (e.g.,
1754    two devices with the same select code) and initializing the I/O state.  These
1755    actions accommodate reconfiguration of the I/O device settings and program
1756    counter while the simulator was stopped.  The prelude also checks for one
1757    command-line switch: if "-B" is specified, the current set of simulation stop
1758    conditions is bypassed for the first instruction executed.
1759 
1760    Second, the memory protect option is initialized.  MP aborts utilize the
1761    "setjmp/longjmp" mechanism to transfer control out of the instruction
1762    executors without returning through the call stack.  This allows an
1763    instruction to be aborted part-way through execution when continuation is
1764    impossible due to a memory access violation.  An MP abort returns to the main
1765    instruction loop at the "setjmp" routine.
1766 
1767    Third, the instruction execution loop decodes instructions and calls the
1768    individual executors in turn until a condition occurs that prevents further
1769    execution.  Examples of such conditions include execution of a HLT
1770    instruction, a user stop request (CTRL+E) from the simulation console, a
1771    recoverable device error (such as an improperly formatted tape image), a
1772    user-specified breakpoint, and a simulation stop condition (such as execution
1773    of an unimplemented instruction).  The execution loop also polls for I/O
1774    events and device interrupts, and runs DMA channel cycles.  During
1775    instruction execution, the IR register contains the currently executing
1776    instruction, and the P register points to the memory location containing the
1777    next instruction.
1778 
1779    Fourth, the instruction postlude updates the simulation state in preparation
1780    for returning to the SCP command prompt.  Devices that maintain an internal
1781    state different from their external state, such as the MEM status and
1782    violation registers, are updated so that their internal and external states
1783    are fully consistent.  This ensures that the state visible to the user during
1784    the simulation stop is correct.  It also ensures that the program counter
1785    points correctly at the next instruction to execute upon resumption.
1786 
1787 
1788    The instruction execution loop starts by checking for event timer expiration.
1789    If one occurs, the associated device's service routine is called by the
1790    "sim_process_event" routine.  Then a check for DMA service requests is made.
1791    If a request is active, the "dma_service" routine is called to process it.
1792 
1793    DMA cycles are requested by an I/O card asserting its SRQ signal.  If a DMA
1794    channel is programmed to respond to that card's select code, the channel's
1795    service request flag is set in the "dma_request_set".  On each pass through
1796    the instruction execution loop, "dma_request_set" is checked; if it is
1797    non-zero, a DMA cycle will be initiated.  A DMA cycle consists of a memory
1798    cycle and an I/O cycle.  These cycles are synchronized with the control
1799    processor on the 21xx CPUs.  On the 1000s, memory cycles are asynchronous,
1800    while I/O cycles are synchronous.  Memory cycle time is about 40% of the I/O
1801    cycle time.
1802 
1803    With properly designed interface cards, DMA is capable of taking consecutive
1804    I/O cycles.  On all machines except the 1000 M-Series, a DMA cycle freezes
1805    the CPU for the duration of the cycle.  On the M-Series, a DMA cycle freezes
1806    the CPU if it attempts an I/O cycle (including IAK) or a directly-interfering
1807    memory cycle.  An interleaved memory cycle is allowed.  Otherwise, the
1808    control processor is allowed to run.  Therefore, during consecutive DMA
1809    cycles, the M-Series CPU will run until an IOG instruction is attempted,
1810    whereas the other CPUs will freeze completely.  This is simulated by skipping
1811    instruction execution if "dma_request_set" is still non-zero after servicing
1812    the current request, i.e., if the device asserted SRQ again as a result of
1813    the DMA cycle.
1814 
1815    All DMA cards except the 12607B provide two independent channels.  If both
1816    channels are active simultaneously, channel 1 has priority for I/O cycles
1817    over channel 2.
1818 
1819    Most I/O cards assert SRQ no more than 50% of the time.  A few buffered
1820    cards, such as the 12821A and 13175A Disc Interfaces, are capable of
1821    asserting SRQ continuously while filling or emptying the buffer.  If SRQ for
1822    channel 1 is asserted continuously when both channels are active, then no
1823    channel 2 cycles will occur until channel 1 completes.
1824 
1825    After DMA servicing, a check for pending interrupt requests is made.
1826 
1827    Interrupt recognition in the HP 1000 CPU is controlled by three state
1828    variables: "interrupt_system", "cpu_interrupt_enable", and
1829    "interrupt_request".  "interrupt_system" corresponds to the INTSYS flip-flop
1830    in the 1000 CPU, "cpu_interrupt_enable" corresponds to the INTEN flip-flop,
1831    and "interrupt_request" corresponds to the NRMINT flip-flop.  STF 00 and CLF
1832    00 set and clear INTSYS, turning the interrupt system on and off.  Microcode
1833    instructions ION and IOFF set and clear INTEN, enabling or disabling certain
1834    interrupts.  An IRQ signal from a device, qualified by the corresponding PRH
1835    and IEN signals, will set NRMINT to request a normal interrupt; an IOFF or
1836    IAK will clear it.
1837 
1838    Under simulation, "interrupt_system" is controlled by STF/CLF 00.
1839    "cpu_interrupt_enable" is set or cleared as appropriate by the individual
1840    instruction simulators.  "interrupt_request" is set to the successfully
1841    interrupting device's select code, or to zero if there is no qualifying
1842    interrupt request.
1843 
1844    The rules controlling interrupt recognition are:
1845 
1846     1. Power fail (SC 04) may interrupt if "cpu_interrupt_enable" is set; this
1847        is not conditional on "interrupt_system" being set.
1848 
1849     2. Memory protect (SC 05) may interrupt if "interrupt_system" is set; this
1850        is not conditional on "cpu_interrupt_enable" being set.
1851 
1852     3. Parity error (SC 05) may interrupt always; this is not conditional on
1853        either "interrupt_system" or "cpu_interrupt_enable" being set.
1854 
1855     4. All other devices (SC 06 and up) may interrupt only if both
1856       "interrupt_system" and "cpu_interrupt_enable" are set.
1857 
1858    Qualification with "interrupt_system" is performed by the I/O dispatcher,
1859    which asserts IEN to the device interface if the interrupt system is on.  All
1860    interfaces other than Power Fail or Parity Error assert IRQ only if IEN is
1861    asserted.  If IEN is denied, i.e., the interrupt system is off, then only
1862    Power Fail and Parity Error will assert IRQ and thereby set the
1863    "interrupt_request" value to their respective select codes.  Therefore, we
1864    need only qualify by "cpu_interrupt_enable" here.
1865 
1866    At instruction fetch time, a pending interrupt request will be deferred if
1867    the previous instruction was a JMP indirect, JSB indirect, STC, CLC, STF,
1868    CLF, or, for a 1000-series CPU, an SFS, SFC, JRS, DJP, DJS, SJP, SJS, UJP, or
1869    UJS.  The executors for these instructions clear the "cpu_interrupt_enable"
1870    flag, which is then set unilaterally when each instruction is dispatched.
1871    The flag is also cleared by an interrupt acknowledgement, deferring
1872    additional interrupts until after the instruction in the trap cell is
1873    executed.
1874 
1875    On the HP 1000, an interrupt request is always deferred until after the
1876    current instruction completes.  On the 21xx, the request is deferred unless
1877    the current instruction is an MRG instruction other than JMP or JMP,I or
1878    JSB,I.  Note that for the 21xx, SFS and SFC are not included in the deferral
1879    criteria.  In simulation, the "reenable_interrupts" routine is called to
1880    handle this case.
1881 
1882 
1883    When a status other than SCPE_OK is returned from an instruction executor or
1884    event service routine, the instruction execution loop exits into the
1885    instruction postlude.  The set of debug trace flags is restored if it had
1886    been changed by an active execution trace or idle trace suppression.  This
1887    ensures that the simulation stop does not exit with the flags set improperly.
1888    If the simulation stopped for a programmed halt, the 21xx binary loader area
1889    is protected in case it had been unprotected to run the loader.  The MEU
1890    status and violation registers and the program counter queue pointer are
1891    updated to present the proper values to the user interface.  The default
1892    breakpoint type is updated to reflect the current MEU state (disabled, system
1893    map enabled, or user map enabled).  Finally, the P register is reset if the
1894    current instruction is to be reexecuted on reentry (for example, on an
1895    unimplemented instruction stop).
1896 
1897 
1898    Implementation notes:
1899 
1900     1. While the Microsoft VC++ "setjmp" documentation says, "All variables
1901        (except register variables) accessible to the routine receiving control
1902        contain the values they had when longjmp was called," the ISO C99
1903        standard says, "All accessible objects have values...as of the time the
1904        longjmp function was called, except that the values of objects of
1905        automatic storage duration that are local to the function containing the
1906        invocation of the corresponding setjmp macro that do not have
1907        volatile-qualified type and have been changed between the setjmp
1908        invocation and longjmp call are indeterminate."
1909 
1910        Therefore, the "exec_save" and "idle_save" variables are marked static
1911        to ensure that they are reloaded after a longjmp caused by a memory
1912        protect abort (they are not marked volatile to save redundant reloads
1913        within the instruction execution loop).  Also, "status" and "exec_test"
1914        are set before reentering the instruction loop after an abort.  This is
1915        done solely to reassure the compiler that the values are not clobbered,
1916        even though in both cases the values are reestablished after an abort
1917        before they are used.
1918 
1919     2. The C standard requires that the "setjmp" call be made from a frame that
1920        is still active (i.e., still on the stack) when "longjmp" is called.
1921        Consequently, we must call "setjmp" from this routine rather than a
1922        subordinate routine that will have exited (to return to this routine)
1923        when the "longjmp" call is made.
1924 
1925     3. The -P switch is removed from the set of command line switches to ensure
1926        that internal calls to the device reset routines are not interpreted as
1927        "power-on" resets.
1928 
1929     4. A CPU freeze is simulated by skipping instruction execution during the
1930        current loop cycle.
1931 
1932     5. The 1000 M-Series allows some CPU processing concurrently with
1933        continuous DMA cycles, whereas all other CPUs freeze.  The processor
1934        freezes if an I/O cycle is attempted, including an interrupt
1935        acknowledgement.  Because some microcode extensions (e.g., Access IOP,
1936        RTE-6/VM OS) perform I/O cycles, advance detection of I/O cycles is
1937        difficult.  Therefore, we freeze all processing for the M-Series as well.
1938 
1939     6. EXEC tracing is active when exec_save is non-zero.  "exec_save" saves the
1940        current state of the trace flags when an EXEC trace match occurs.  For
1941        this to happen, at least TRACE_EXEC must be set, so "exec_save" will be
1942        set non-zero when a match is active.
1943 
1944     7. The execution trace (TRACE_EXEC) match test is performed in two parts to
1945        display the register values both before and after the instruction
1946        execution.  Consequently, the enable test is done before the register
1947        trace, and the disable test is done after.
1948 
1949     8. A simulation stop bypass is inactivated after the first instruction
1950        execution by the expedient of setting the stop inhibition mask to the
1951        execution status result.  This must be SCPE_OK (i.e., zero) for execution
1952        to continue, which removes the stop inhibition.  If a non-zero status
1953        value is returned, then the inhibition mask will be set improperly, but
1954        that is irrelevant, as execution will stop in this case.
1955 
1956     9. In hardware, the IAK signal is asserted to all devices in the I/O card
1957        cage, as well as to the Memory Protect card.  Only the interrupting
1958        device will respond to IAK.  In simulation, IAK is dispatched to the
1959        interrupting device and, if that device is not the MP card, then to the
1960        MP device as well.
1961 
1962    10. In hardware, execution of the instruction in the trap cell does not use
1963        the FTCH micro-order to avoid changing the MP violation register during
1964        an MP interrupt.  In simulation, we use a Fetch classification to label
1965        the access correctly in a trace listing.  This is OK because the Enable
1966        Violation Register flip-flop has already been reset if this is an MP
1967        interrupt, so the Fetch will not alter the MP VR.
1968 
1969    11. The "meu_assert_IAK" routine sets the "meu_indicator" and "meu_page"
1970        values for the P register before switching to the system map.  Therefore,
1971        on return, they indicate the prior map and page in use when the interrupt
1972        occurred.
1973 */
1974 
sim_instr(void)1975 t_stat sim_instr (void)
1976 {
1977 static uint32 exec_save;                                /* the trace flag settings saved by an EXEC match */
1978 static uint32 idle_save;                                /* the trace flag settings saved by an idle match */
1979 MICRO_ABORT abort_reason;
1980 t_bool      exec_test;                                  /* set after setjmp */
1981 t_bool      interrupt_acknowledge;                      /* set after setjmp */
1982 t_stat      status;                                     /* set after setjmp */
1983 
1984 
1985 /* Instruction prelude */
1986 
1987 if (sim_switches & SWMASK ('B'))                        /* if a simulation stop bypass was requested */
1988     cpu_ss_inhibit = SS_INHIBIT;                        /*   then inhibit stops for the first instruction only */
1989 else                                                    /* otherwise */
1990     cpu_ss_inhibit = SCPE_OK;                           /*   clear the inhibition mask */
1991 
1992 sim_switches &= ~SWMASK ('P');                          /* clear the power-on switch to prevent interference */
1993 
1994 if (initialize_io (TRUE) == FALSE)                      /* set up the I/O table; if there's a select code conflict */
1995     return SCPE_STOP;                                   /*   then inhibit execution */
1996 
1997 mp_is_present = mp_initialize ();                       /* set up memory protect */
1998 
1999 exec_save = 0;                                          /* clear the EXEC match */
2000 idle_save = 0;                                          /*   and idle match trace flags */
2001 
2002 cpu_ioerr_uptr = NULL;                                  /* clear the I/O error unit pointer */
2003 
2004 
2005 /* Microcode abort processor */
2006 
2007 abort_reason = (MICRO_ABORT) setjmp (abort_environment);    /* set the microcode abort handler */
2008 
2009 switch (abort_reason) {                                 /* dispatch on the abort reason */
2010 
2011     case Memory_Protect:                                /* a memory protect abort */
2012         status = SCPE_OK;                               /*   continues execution with FLG 5 asserted */
2013         break;
2014 
2015 
2016     case Interrupt:                                     /* an interrupt in an indirect chain */
2017         PR = err_PR;                                    /*   backs out of the instruction */
2018         status = SCPE_OK;                               /*     and then continues execution to service the interrupt */
2019         break;
2020 
2021 
2022     case Indirect_Loop:                                 /* an indirect chain length exceeding the limit */
2023         status = STOP_INDIR;                            /*   causes a simulator stop */
2024         break;
2025 
2026 
2027     default:                                            /* anything else */
2028         status = SCPE_OK;                               /*   continues execution */
2029         break;
2030     }
2031 
2032 exec_test = FALSE;                                      /* clear the execution test flag */
2033 
2034 
2035 /* Instruction execution loop */
2036 
2037 while (status == SCPE_OK) {                             /* execute until simulator status prevents continuation */
2038 
2039     err_PR = PR;                                        /* save P for error recovery */
2040 
2041     if (sim_interval <= 0) {                            /* if an event is pending */
2042         status = sim_process_event ();                  /*   then call the event service */
2043 
2044         if (status != SCPE_OK)                          /* if the service failed */
2045             break;                                      /*   then stop execution */
2046         }
2047 
2048     if (dma_request_set) {                              /* if a DMA service request is pending */
2049         dma_service ();                                 /*   then service the active channel(s) */
2050 
2051         if (dma_request_set)                            /* if a DMA request is still pending */
2052             continue;                                   /*   then service it before instruction execution */
2053         }
2054 
2055     if (interrupt_request                                       /* if an interrupt request is pending */
2056       && (cpu_interrupt_enable || reenable_interrupts ())) {    /*   and is enabled or reenabled */
2057         if (sim_brk_summ                                        /*     then if any breakpoints are defined */
2058           && sim_brk_test (interrupt_request,                   /*       and an unconditional breakpoint */
2059                            BP_EXEC                              /*         or a breakpoint matching */
2060                              | meu_breakpoint_type (TRUE))) {   /*           the current MEM map is set */
2061             status = STOP_BRKPNT;                               /*             then stop simulation */
2062             break;
2063             }
2064 
2065         CIR = (HP_WORD) interrupt_request;              /* set the CIR to the select code of the interrupting device */
2066         interrupt_request = 0;                          /*   and then clear the request */
2067 
2068         cpu_interrupt_enable = CLEAR;                   /* inhibit interrupts */
2069         interrupt_acknowledge = TRUE;                   /*   while in an interrupt acknowledge cycle */
2070 
2071         if (idle_save != 0) {                           /* if idle loop tracing is suppressed */
2072             cpu_dev.dctrl = idle_save;                  /*   then restore the saved trace flag set */
2073             idle_save = 0;                              /*     and indicate that we are out of the idle loop */
2074             }
2075 
2076         meu_assert_IAK ();                              /* assert IAK to the MEM to switch to the system map */
2077 
2078         tprintf (cpu_dev, TRACE_INSTR, DMS_FORMAT "interrupt\n",
2079                  meu_indicator, meu_page, PR, CIR);
2080 
2081         io_assert (iot [CIR].devptr, ioa_IAK);          /* acknowledge the interrupt */
2082 
2083         if (CIR != MPPE)                                /* if the MP is not interrupting */
2084             io_assert (iot [MPPE].devptr, ioa_IAK);     /*   then notify MP of the IAK too */
2085 
2086         IR = ReadF (CIR);                               /* fetch the trap cell instruction */
2087         }
2088 
2089     else {                                              /* otherwise this is a normal instruction execution */
2090         interrupt_acknowledge = FALSE;                  /*   so clear the interrupt acknowledgement status */
2091 
2092         if (sim_brk_summ                                        /* if any breakpoints are defined */
2093           && sim_brk_test (PR, BP_EXEC                          /*   and an unconditional breakpoint or a */
2094                              | meu_breakpoint_type (FALSE))) {  /*     breakpoint matching the current map is set */
2095             status = STOP_BRKPNT;                               /*       then stop simulation */
2096             break;
2097             }
2098 
2099         IR = ReadF (PR);                                /* fetch the instruction */
2100         PR = PR + 1 & LA_MASK;                          /*   and point at the next memory location */
2101 
2102         cpu_interrupt_enable = SET;                     /* enable interrupts */
2103         }
2104 
2105 
2106     if (TRACING (cpu_dev, TRACE_EXEC | TRACE_REG)) {    /* if execution or register tracing is enabled */
2107         if (cpu_dev.dctrl & TRACE_EXEC)                 /*   then if tracing execution */
2108             exec_test = (IR & exec_mask) == exec_match; /*     then the execution test succeeds if */
2109                                                         /*       the next instruction matches the test criteria */
2110 
2111         if (cpu_dev.dctrl & TRACE_EXEC                  /* if execution tracing is enabled */
2112           && exec_save == 0                             /*   and is currently inactive */
2113           && exec_test) {                               /*     and the matching test succeeds */
2114             exec_save = cpu_dev.dctrl;                  /*       then save the current trace flag set */
2115             cpu_dev.dctrl |= TRACE_ALL;                 /*         and turn on full tracing */
2116             }
2117 
2118         if (cpu_dev.dctrl & TRACE_REG)                  /* if register tracing is enabled */
2119             mem_trace_registers (interrupt_system);     /*   then output the working and MP/MEM registers */
2120 
2121         if (cpu_dev.dctrl & TRACE_EXEC                  /* if execution tracing is enabled */
2122           && exec_save != 0                             /*   and is currently active */
2123           && ! exec_test) {                             /*     and the matching test fails */
2124             cpu_dev.dctrl = exec_save;                  /*       then restore the saved debug flag set */
2125             exec_save = 0;                              /*         and indicate that tracing is disabled */
2126 
2127             hp_trace (&cpu_dev, TRACE_EXEC, EXEC_FORMAT "\n");  /* add a separator to the trace log */
2128             }
2129         }
2130 
2131     if (TRACING (cpu_dev, TRACE_INSTR)) {               /* if instruction tracing is enabled */
2132         hp_trace (&cpu_dev, TRACE_INSTR,                /*   then output the address and opcode */
2133                   DMS_FORMAT,
2134                   meu_indicator, meu_page,
2135                   MR, IR);
2136 
2137         sim_eval [0] = IR;                              /* save the (first) instruction word in the eval array */
2138 
2139         if (fprint_cpu (sim_deb, MR, sim_eval, 0, CPU_Trace) > SCPE_OK) /* print the mnemonic; if that fails */
2140             fprint_val (sim_deb, sim_eval [0], cpu_dev.dradix,          /*   then print the numeric */
2141                         cpu_dev.dwidth, PV_RZRO);                       /*     value again */
2142 
2143         fputc ('\n', sim_deb);                          /* end the trace with a newline */
2144         }
2145 
2146 
2147     sim_interval = sim_interval - 1;                    /* count the instruction */
2148 
2149     status = machine_instruction (interrupt_acknowledge,    /* execute one machine instruction */
2150                                   &idle_save);
2151 
2152     if (status == NOTE_INDINT) {                        /* if an interrupt was recognized while resolving indirects */
2153         PR = err_PR;                                    /*   then back out of the instruction */
2154         status = SCPE_OK;                               /*     to service the interrupt */
2155         }
2156 
2157     cpu_ss_inhibit = status;                            /* clear the simulation stop inhibition mask */
2158     }                                                   /*   and continue the instruction execution loop */
2159 
2160 
2161 /* Instruction postlude */
2162 
2163 if (interrupt_request                                   /* if an interrupt request is pending */
2164   && (cpu_interrupt_enable || reenable_interrupts ()))  /*   and is enabled or reenabled */
2165     cpu_pending_interrupt = interrupt_request;          /*     then report the pending interrupt select code */
2166 else                                                    /*   otherwise */
2167     cpu_pending_interrupt = 0;                          /*     report that no interrupt is pending */
2168 
2169 if (exec_save != 0) {                                   /* if EXEC tracing is active */
2170     cpu_dev.dctrl = exec_save;                          /*   then restore the saved trace flag set */
2171     hp_trace (&cpu_dev, TRACE_EXEC, EXEC_FORMAT "\n");  /*     and add a separator to the trace log */
2172     }
2173 
2174 else if (idle_save != 0)                                /* otherwise if idle tracing is suppressed */
2175     cpu_dev.dctrl = idle_save;                          /*   then restore the saved trace flag set */
2176 
2177 saved_MR = MR;                                          /* save the current M value to detect a user change */
2178 
2179 if (status == STOP_HALT)                                /* if this is a programmed halt */
2180     set_loader (NULL, FALSE, NULL, NULL);               /*   then disable the 21xx loader */
2181 
2182 else if (status <= STOP_RERUN)                          /* otherwise if this is a simulation stop */
2183     PR = err_PR;                                        /*   then restore P to reexecute the instruction */
2184 
2185 meu_update_status ();                                   /* update the MEM status register */
2186 meu_update_violation ();                                /*   and the violation register */
2187 
2188 pcq_r->qptr = pcq_p;                                    /* update the PC queue pointer */
2189 
2190 sim_brk_dflt = meu_breakpoint_type (FALSE);             /* base the default breakpoint type on the current MEM state */
2191 
2192 if (TRACING (cpu_dev, cpu_dev.dctrl)                    /* if instruction tracing is enabled */
2193   && status <= SCPE_LAST)                               /*   and the status is valid */
2194     hp_trace (&cpu_dev, cpu_dev.dctrl,                  /*     then output the simulation stop reason */
2195               DMS_FORMAT "simulation stop: %s\n",
2196               meu_indicator, meu_page, MR, TR,
2197               status >= SCPE_BASE ? sim_error_text (status)
2198                                   : sim_stop_messages [status]);
2199 
2200 if (sim_switches & SIM_SW_HIDE                          /* if executing in a non-echoing command file */
2201   && (status == SCPE_STEP || status == STOP_BRKPNT))    /*   and a step or breakpoint stop occurs */
2202     return SCPE_OK;                                     /*     then do not report the stop reason */
2203 else                                                    /* otherwise */
2204     return status;                                      /*   return the status code that caused the stop */
2205 }
2206 
2207 
2208 /* VM command post-processor.
2209 
2210    This routine is called from SCP after every command before returning to the
2211    command prompt.  We use it to update the T (memory data) register whenever
2212    the M (memory address) register is changed to follow the 21xx/1000 CPU
2213    hardware action.
2214 
2215 
2216    Implementation notes:
2217 
2218     1. The T register must be changed only when M has changed.  Otherwise, if T
2219        is updated after every command, then T will be set to zero if M points
2220        into the protected loader area of the 21xx machines, e.g., after a HLT
2221        instruction in the loader reenables loader protection.
2222 */
2223 
cpu_post_cmd(t_bool from_scp)2224 void cpu_post_cmd (t_bool from_scp)
2225 {
2226 if (MR != saved_MR) {                                   /* if M has changed since the last update */
2227     saved_MR = MR;                                      /*   then save the new M value */
2228     TR = mem_fast_read (MR, Current_Map);               /*     and set T to the contents of the addressed location */
2229     }
2230 
2231 return;
2232 }
2233 
2234 
2235 
2236 /* CPU global utility routines */
2237 
2238 
2239 /* Execute an I/O instruction.
2240 
2241    This routine executes the I/O Group instruction that is passed in the
2242    "instruction" parameter.  The instruction is examined to obtain the I/O
2243    function desired.  A memory protect check is then made to determine if it is
2244    legal to execute the instruction.  If it is, the state of the interrupt
2245    enable flip-flop is set, the set of I/O backplane signals generated by the
2246    instruction are picked up from the "control_set" array, and the signals and
2247    inbound data value are dispatched to the device interface indicated by the
2248    select code contained in the instruction.  The data value and signals
2249    returned from the interface are used as directed by the I/O operation, and
2250    the status of the operation is returned.
2251 
2252 
2253    Implementation notes:
2254 
2255     1. The STC and CLC instructions share the same pattern in bits 9-6 that are
2256        used to decode the rest of the IOG instructions.  These instructions are
2257        differentiated by the A/B selector (bit 11).
2258 
2259     2. If a memory protect violation occurs, the IOG signal from the CPU to the
2260        I/O backplane is denied to disable all I/O signals.  For a LIA/B or MIA/B
2261        instruction, this will load or merge the value of the floating I/O bus
2262        into the A or B registers.  This value is zero on all machines.  Merging
2263        zero doesn't change the register value, so the only the LIA/B case must
2264        be explicitly checked.
2265 */
2266 
cpu_iog(HP_WORD instruction)2267 t_stat cpu_iog (HP_WORD instruction)
2268 {
2269 const uint32 select_code = instruction & SC_MASK;       /* device select code */
2270 const uint32 ab_selector = AB_SELECT (instruction);     /* A/B register selector */
2271 IO_GROUP_OP  micro_op;
2272 HP_WORD      inbound_value;
2273 INBOUND_SET  inbound_signals;
2274 SKPF_DATA    outbound;
2275 
2276 if ((instruction & IR_CLC_MASK) == IR_CLC)              /* if the instruction is CLC or CLC,C */
2277     if (instruction & IR_HCF)                           /*   then if the H/C flag bit is set */
2278         micro_op = iog_CLC_C;                           /*     then it's a CLC,C operation */
2279     else                                                /*   otherwise */
2280         micro_op = iog_CLC;                             /*     it's a CLC operation */
2281 else                                                    /* otherwise */
2282     micro_op = IOG_OP (instruction);                    /*   the operation is decoded directly */
2283 
2284 if (micro_op == iog_LIx || micro_op == iog_LIx_C)       /* if executing an LIA or LIB instruction */
2285     ABREG [ab_selector] = 0;                            /*   then clear the register value in case MP aborts */
2286 
2287 mp_check_io (select_code, micro_op);                    /* check for a memory protect violation */
2288 
2289 cpu_interrupt_enable = enable_map [is_1000] [micro_op]; /* disable interrupts depending on the instruction */
2290 
2291 inbound_signals = control_set [micro_op];               /* get the set of signals to assert to the interface */
2292 
2293 if (micro_op == iog_OTx || micro_op == iog_OTx_C)       /* if the instruction is OTA/B or OTA/B,C */
2294     inbound_value = ABREG [ab_selector];                /*   then send the register value to the interface */
2295 else                                                    /* otherwise */
2296     inbound_value = 0;                                  /*   the interface won't use the inbound value */
2297 
2298 outbound = io_dispatch (select_code, inbound_signals,   /* dispatch the I/O action to the interface */
2299                         inbound_value);
2300 
2301 if (micro_op == iog_LIx || micro_op == iog_LIx_C)       /* if the instruction is LIA/B or LIA/B,C */
2302     ABREG [ab_selector] = outbound.data;                /*   then store the I/O bus data into the register */
2303 
2304 else if (micro_op == iog_MIx || micro_op == iog_MIx_C)  /* otherwise if the instruction is MIA/B or MIA/B,C */
2305     ABREG [ab_selector] |= outbound.data;               /*   then merge the I/O bus data into the register */
2306 
2307 else if (outbound.skip) {                               /* otherwise if the interface asserted SKF */
2308     PR = PR + 1 & R_MASK;                               /*   then bump P to skip then next instruction */
2309     return SCPE_OK;                                     /*     and return success */
2310     }
2311 
2312 else if (micro_op == iog_HLT || micro_op == iog_HLT_C)  /* otherwise if the instruction is HLT or HLT,C */
2313     return STOP_HALT;                                   /*   then stop the simulator */
2314 
2315 if (iot [select_code].devptr == NULL)                   /* if the I/O slot is empty */
2316     return STOP (cpu_ss_unsc);                          /*   then return stop status if enabled */
2317 else                                                    /* otherwise */
2318     return SCPE_OK;                                     /*   the instruction executed successfully */
2319 }
2320 
2321 
2322 /* Resolve an indirect address.
2323 
2324    This routine resolves a possibly indirect memory address into a direct
2325    address by following an indirect chain, if any.  On entry, the M register
2326    contains the address to resolve, and the "interruptible" parameter is set to
2327    TRUE if the instruction is interruptible or FALSE if it is not.  On exit, the
2328    M register contains the direct address, and SCPE_OK is returned.  If an
2329    interrupt is pending and permitted, NOTE_INDINT is returned to abort the
2330    instruction.  If the indirect chain length is greater than the chain limit,
2331    STOP_INDIR is returned to abort execution.  In both abort cases, the M
2332    register content is undefined.
2333 
2334    Logical memory addresses are 15 bits wide, providing direct access to a 32K
2335    logical address space.  Addresses may also be indirect, with bit 15 (the MSB)
2336    serving as the direct/indirect indicator.  An indirect address may point at
2337    either a direct or indirect address.  In the latter case, the chain is
2338    followed until a direct address is obtained.
2339 
2340    Indirect addressing has implications for interrupt handling.  Normally,
2341    interrupts are checked at each level of indirection, and if one is pending,
2342    the CPU will abort execution of the instruction and then service the
2343    interrupt.  On return from the interrupt handler, the instruction will be
2344    restarted.
2345 
2346    Detection of interrupts is dependent on the Interrupt Enable flip-flop being
2347    set.  Certain instructions, such as JMP indirect, JSB indirect, and most IOG
2348    instructions, clear the enable flag to hold off interrupts until the current
2349    and following instructions complete, including complete resolution of the
2350    indirect chain.  If the chain is unresolvable (i.e., it points to itself, as
2351    in the instruction sequence JMP *+1,I and DEF *,I), then interrupts are held
2352    off forever.
2353 
2354    To prevent a user program from freezing a protected OS with an infinite
2355    indirect chain, and to permit real-time interrupts to be handled while
2356    resolving a long indirect chain, the Memory Protect accessory counts indirect
2357    levels during address resolution and will reenable interrupt recognition
2358    after the third level.  Operating systems that run without MP installed are
2359    subject to freezing as above, but those employing MP will be able to regain
2360    control from an infinite indirect chain.
2361 
2362    In simulation, the SET CPU INDIR=<limit> command sets the maximum number of
2363    levels; the default is 16.  If the level is exceeded during address
2364    resolution, the simulator will stop.  The maximum limit is 32768, which is
2365    the maximum possible address chain without an infinite loop, but an indirect
2366    chain over a few levels deep almost certainly represents a programming error.
2367 
2368 
2369    Implementation notes:
2370 
2371     1. Virtually all valid indirect references are one level deep, so we
2372        optimize for this case.  Also, we protect against entry with a direct
2373        address simply by returning the address, but the overhead can be saved by
2374        calling this routine only for indirect addresses.
2375 
2376     2. The 12892B Memory Protect accessory jumper W6 ("INT") controls whether
2377        pending interrupts with the Interrupt Enable flip-flop clear are serviced
2378        immediately (jumper removed) or after three levels of indirection (jumper
2379        installed).  If the jumper is removed, MP must be enabled (control
2380        flip-flop set) for the interrupt disable to be overridden.
2381 
2382        The jumper state need not be checked here, however, because this routine
2383        can be entered with an interrupt pending, i.e., "interrupt_request" is
2384        non-zero, only if "cpu_interrupt_enable" and "mp_reenable_interrupts" are
2385        both false.  If either is true, the pending interrupt would have been
2386        serviced before calling the instruction executor that called this routine
2387        to resolve its address.  For "mp_reenable_interrupts" to return false,
2388        the INT jumper must be installed or the MP control flip-flop must be
2389        clear.
2390 
2391     3. When employing the indirect counter, the hardware clears a pending
2392        interrupt deferral after the third level of indirection and aborts the
2393        instruction after the fourth.
2394 
2395     4. The JRS, DJP, DJS, SJP, SJS, UJP, and UJS instructions also hold off
2396        interrupts for three indirect levels, but they count levels internally
2397        and do not depend on the presence of the MP accessory to reenable
2398        interrupt recognition.  However, DMS requires MP, so simulation uses the
2399        MP indirect counter for these instructions as well.
2400 
2401     5. In hardware, it is possible to execute an instruction with an infinite
2402        indirect loop (e.g., JMP *+1,I and DEF *,I).  If MP is not installed,
2403        this freezes the CPU with interrupts disabled until HALT is pressed.  In
2404        simulation, the instruction executes until the indirect limit is reached,
2405        whereupon the simulator stops with "Indirect address loop" status.
2406        Modelling the hardware CPU freeze would be difficult, as the simulation
2407        console would have to be polled locally to watch for CTRL+E (the
2408        simulation equivalent of the CPU front panel HALT button).
2409 
2410     6. In hardware, all instructions that resolve indirects are interruptible.
2411        In simulation, some instruction executors are not written to handle an
2412        instruction abort (e.g., the P register is not backed up properly to
2413        rerun the instruction); these will pass FALSE for the "interruptible"
2414        parameter.
2415 */
2416 
cpu_resolve_indirects(t_bool interruptible)2417 t_stat cpu_resolve_indirects (t_bool interruptible)
2418 {
2419 uint32 level;
2420 t_bool pending;
2421 
2422 if (MR & IR_IND) {                                      /* if the address is indirect */
2423     MR = ReadW (MR & LA_MASK);                          /*   then follow the chain (first level) */
2424 
2425     if (MR & IR_IND) {                                  /* if the address is still indirect */
2426         pending = interruptible && interrupt_request;   /*   then see if an interrupt request is pending */
2427 
2428         if (pending && cpu_interrupt_enable)            /* if it's pending and enabled */
2429             return NOTE_INDINT;                         /*   then service the interrupt now */
2430         else                                            /* otherwise */
2431             pending = pending && mp_is_present;         /*   a pending interrupt is recognized only if MP is present */
2432 
2433         for (level = 2; MR & IR_IND; level++) {         /* follow the chain from level 2 until the address is direct */
2434             if (level > indirect_limit)                 /* if the limit is exceeded */
2435                 return STOP_INDIR;                      /*   then stop the simulator */
2436 
2437             else if (pending)                           /* otherwise if an interrupt is pending */
2438                 if (level == 3)                         /*   then if this is the third level */
2439                     cpu_interrupt_enable = SET;         /*     then reenable interrupts */
2440                 else if (level == 4)                    /*   otherwise if this is the fourth level */
2441                     return NOTE_INDINT;                 /*     then service the interrupt now */
2442 
2443             MR = ReadW (MR & LA_MASK);                  /* follow the address chain */
2444             }
2445         }
2446     }
2447 
2448 return SCPE_OK;
2449 }
2450 
2451 
2452 /* Abort an instruction.
2453 
2454    This routine performs a microcode abort for the reason passed in the
2455    "abort_reason" parameter.  In hardware, microcode aborts are implemented by
2456    direct jumps to the FETCH label in the base set (microcode address 0).  This
2457    is typically done when an interrupt is detected while executing a lengthy
2458    instruction or during resolution of an indirect chain.  In simulation, this
2459    is performed by a "longjmp" back to the start of the instruction execution
2460    loop.  It is the caller's responsibility to restore the machine state, e.g.,
2461    to back up the P register to rerun the instruction.
2462 */
2463 
cpu_microcode_abort(MICRO_ABORT abort_reason)2464 void cpu_microcode_abort (MICRO_ABORT abort_reason)
2465 {
2466 longjmp (abort_environment, (int) abort_reason);        /* jump back to the instruction execution loop */
2467 }
2468 
2469 
2470 /* Install a bootstrap loader into memory.
2471 
2472    This routine copies the bootstrap loader specified by "boot" into the last 64
2473    words of main memory, limited by a 32K memory size.  If "sc" contains the
2474    select code of an I/O interface (i.e., select code 10 or above), this routine
2475    will configure the I/O instructions in the loader to the supplied select
2476    code.  On exit, the P register will be set to point at the loader starting
2477    program address, and the S register will be altered as directed by the
2478    "sr_clear" and "sr_set" masks if the current CPU is a 1000.  The updated P
2479    register value is returned to the caller.
2480 
2481    The currently configured CPU family (21xx or 1000) determines which of two
2482    BOOT_LOADER structures is accessed from the "boot" array.  Each structure
2483    contains the 64-word loader array and three indices into the loader
2484    array that specify the start of program execution, the element containing the
2485    DMA control word, and the element containing the (negative) address of the
2486    first loader word in memory.
2487 
2488    21xx-series loaders consist of subsections handling one or two devices.  A
2489    two-part loader is indicated by a starting program index other than 0, i.e.,
2490    other than the beginning of the loader.  An example is the Basic Moving-Head
2491    Disc Loader (BMDL), which consists of a paper tape loader section starting at
2492    index 0 and a disc loader section starting at index 50 octal.  For these
2493    loaders, I/O configuration depends on the "start_index" field of the selected
2494    BOOTSTRAP structure: I/O instructions before the starting index are
2495    configured to the current paper-tape reader select code, and instructions at
2496    or after the starting index are configured to the device select code
2497    specified by "sc".  Single-part loaders specify a starting index of 0, and
2498    all I/O instructions are configured to the "sc" select code.
2499 
2500    1000-series loaders are always single part and always start at index 0, so
2501    they are always configured to use the "sc" select code.
2502 
2503    If a given device does not have both a 21xx-series and a 1000-series loader,
2504    the "start_index" field of the undefined loader will be set to the "IBL_NA"
2505    value.  If this routine is called to copy an undefined loader, it will reject
2506    the call by returning a starting address of zero to the caller.  In this
2507    case, neither P nor S are changed.
2508 
2509    If I/O configuration is requested, each instruction in the loader array is
2510    examined as it is copied.  If the instruction is a non-HLT I/O instruction
2511    referencing a select code >= 10, the select code will be reset by subtracting
2512    10 and adding the value of the select code supplied by the "sc" parameter (or
2513    the paper-tape reader select code, as above).  This permits configuration of
2514    loaders that address two- or three-card interfaces.  Passing an "sc" value of
2515    0 will inhibit configuration, and the loader array will be copied verbatim.
2516 
2517    As an example, passing an "sc" value of 24 octal will alter these I/O-group
2518    instructions as follows:
2519 
2520         Loader    Configured
2521      Instruction  Instruction  Note
2522      -----------  -----------  ------------------------------
2523        OTA 10       OTA 24     Normal configuration
2524        LIA 11       LIA 25     Second card configuration
2525        STC  6       STC  6     DCPC configuration not changed
2526        HLT 11       HLT 11     Halt instruction not changed
2527 
2528    If configuration is performed, two additional operations may be performed.
2529    First, the routine will alter the word at the index specified by the
2530    "dma_index" field of the selected BOOTSTRAP structure unconditionally as
2531    above.  This word is assumed to contain a DMA control word; it is configured
2532    to reference the supplied select code.  Second, it will set the word at the
2533    index specified by the "fwa_index" field to the two's-complement of the
2534    starting address of the loader in memory.  This value may be used by the
2535    loader to check that it will not be overwritten by loaded data.
2536 
2537    If either field is set to the IBL_NA value, then the corresponding
2538    modification is not made.  For example, the 21xx Basic Binary Loader (BBL)
2539    does not use DMA, so its "dma_index" field is set to IBL_NA, and so no DMA
2540    control word modification is done.
2541 
2542    The starting address for loader execution is derived from the "start_index"
2543    field and the starting memory address to which the loader is copied.
2544 
2545    Finally, if the current CPU is a 1000-series machine, the S register bits
2546    corresponding to those set in the "sr_clear" value are masked off, and the
2547    bits corresponding to those in the "sr_set" value are set.  In addition, the
2548    select code from the "sc" value is shifted left and ORed into the value.
2549    This action presets the S-register to the correct value for the selected
2550    loader.
2551 
2552 
2553    Implementation notes:
2554 
2555     1. The paper-tape reader's select code is determined on each entry to the
2556        routine to accommodate select code reassignment by the user.
2557 */
2558 
cpu_copy_loader(const LOADER_ARRAY boot,uint32 sc,HP_WORD sr_clear,HP_WORD sr_set)2559 uint32 cpu_copy_loader (const LOADER_ARRAY boot, uint32 sc, HP_WORD sr_clear, HP_WORD sr_set)
2560 {
2561 uint32      index, loader_start, ptr_sc;
2562 MEMORY_WORD loader [IBL_SIZE];
2563 MEMORY_WORD word;
2564 DEVICE      *ptr_dptr;
2565 
2566 if (boot [is_1000].start_index == IBL_NA)               /* if the bootstrap is not defined for the current CPU */
2567     return 0;                                           /*   then reject the command */
2568 
2569 else if (boot [is_1000].start_index > 0 && sc > 0) {    /* if this is a two-part loader with I/O reconfiguration */
2570     ptr_dptr = find_dev ("PTR");                        /*   then get a pointer to the paper tape reader device */
2571 
2572     if (ptr_dptr == NULL)                               /* if the PTR device is not present */
2573         return 0;                                       /*   then something is seriously wrong */
2574     else                                                /* otherwise */
2575         ptr_sc = ((DIB *) ptr_dptr->ctxt)->select_code; /*   get the select code from the device's DIB */
2576     }
2577 
2578 else                                                    /* otherwise this is a single-part loader */
2579     ptr_sc = 0;                                         /*   or I/O reconfiguration is not requested */
2580 
2581 loader_start = mem_size - 1 & ~IBL_MASK & LA_MASK;          /* get the base memory address of the loader */
2582 PR = loader_start + boot [is_1000].start_index & R_MASK;    /*   and store the starting program address in P */
2583 
2584 set_loader (NULL, TRUE, NULL, NULL);                    /* enable the loader (ignore errors if not 21xx) */
2585 
2586 for (index = 0; index < IBL_SIZE; index++) {            /* copy the bootstrap loader to memory */
2587     word = boot [is_1000].loader [index];               /* get the next word */
2588 
2589     if (sc == 0)                                        /* if reconfiguration is not requested */
2590         loader [index] = word;                          /*   then copy the instruction verbatim */
2591 
2592     else if (IOGOP (word)                                           /* otherwise if this is an I/O instruction */
2593       && (word & SC_MASK) >= SC_VAR                                 /*   and the referenced select code is >= 10B */
2594       && (word & IR_HLT_MASK) != IR_HLT)                            /*   and it's not a halt instruction */
2595         if (index < boot [is_1000].start_index)                     /*   then if this is a split loader */
2596             loader [index] = word + (ptr_sc - SC_VAR) & DV_MASK;    /*     then reconfigure the paper tape reader */
2597         else                                                        /*   otherwise */
2598             loader [index] = word + (sc - SC_VAR) & DV_MASK;        /*     reconfigure the target device */
2599 
2600     else if (index == boot [is_1000].dma_index)             /* otherwise if this is the DMA configuration word */
2601         loader [index] = word + (sc - SC_VAR) & DV_MASK;    /*   then reconfigure the target device */
2602 
2603     else if (index == boot [is_1000].fwa_index)         /* otherwise if this is the starting address word */
2604         loader [index] = NEG16 (loader_start);          /*   then set the negative starting address of the bootstrap */
2605 
2606     else                                                /* otherwise the word is not a special one */
2607         loader [index] = word;                          /*   so simply copy it */
2608     }
2609 
2610 mem_copy_loader (loader, loader_start, To_Memory);      /* copy the loader to memory */
2611 
2612 if (cpu_configuration & CPU_1000)                       /* if the CPU is a 1000 */
2613     SR = SR & sr_clear | sr_set | IBL_TO_SC (sc);       /*   then modify the S register as indicated */
2614 
2615 return PR;                                              /* return the starting execution address of the loader */
2616 }
2617 
2618 
2619 /* Check for an I/O stop condition.
2620 
2621    Entering the SET CPU STOP=IOERR command at the SCP command prompt stops the
2622    simulator if an I/O error occurs on a device that does not return error
2623    status to the CPU.  For example, while the paper tape punch returns low- or
2624    out-of-tape status, the paper tape reader gives no indication that a tape is
2625    loaded.  If the reader is commanded to read when no tape is mounted, the
2626    interface hangs while waiting for the handshake with the device to complete.
2627 
2628    In hardware, the CPU can detect this condition only by timing the operation
2629    and concluding that the tape is missing if the timeout is exceeded.  However,
2630    if an IOERR stop has been set, then the simulator will stop with an error
2631    message to permit the condition to be fixed.  For instance, attempting to
2632    read from the paper tape reader with no paper tape image file attached will
2633    print "No tape loaded in the PTR device" and will stop the simulator.
2634 
2635    Such devices will call this routine and pass a pointer to the unit that
2636    encountered the error condition.  The routine returns TRUE and saves the
2637    pointer to the failing unit if the IOERR stop is enabled, and FALSE
2638    otherwise.
2639 */
2640 
cpu_io_stop(UNIT * uptr)2641 t_bool cpu_io_stop (UNIT *uptr)
2642 {
2643 if (cpu_ss_ioerr != SCPE_OK) {                          /* if the I/O error stop is enabled */
2644     cpu_ioerr_uptr = uptr;                              /*   then save the failing unit */
2645     return TRUE;                                        /*     and return TRUE to indicate that the stop is enabled */
2646     }
2647 
2648 else                                                    /* otherwise */
2649     return FALSE;                                       /*   return FALSE to indicate that the stop is disabled */
2650 }
2651 
2652 
2653 
2654 /* I/O subsystem global utility routines */
2655 
2656 
2657 /* Device I/O signal dispatcher.
2658 
2659    This routine calls the I/O interface handler of the device corresponding to
2660    the supplied "select_code" value, passing the "inbound_signals" and
2661    "inbound_value" to the interface.  The combined skip status and outbound data
2662    value from the handler is returned to the caller.
2663 
2664    The 21xx/1000 I/O structure requires that no empty slots exist between
2665    interface cards.  This is due to the hardware priority chaining (PRH/PRL)
2666    that is passed from card-to-card.  If it is necessary to leave unused I/O
2667    slots, HP 12777A Priority Jumper Cards must be installed in them to maintain
2668    priority continuity.
2669 
2670    Under simulation, every unassigned I/O slot behaves as though a 12777A were
2671    resident.  In this configuration, I/O instructions addressed to one of these
2672    slots read the floating bus for LIA/B and MIA/B instructions or do nothing
2673    for all other instructions.
2674 
2675    If the slot is occupied, then the routine first determines the rank (0 or 1)
2676    and bit (0 to 31) corresponding to the select code of the interface.  These
2677    will be used to access the interrupt, priority, and service request bit
2678    vectors.  Then it augments the supplied inbound signals set with IEN if the
2679    interrupt system flip-flop is set, and PRH if no higher priority interface is
2680    denying PRL.
2681 
2682    In hardware, PRH of each interface is connected to PRL of the next higher
2683    priority (lower select code) interface, so that a PRH-to-PRL chain is formed.
2684    An interface receives PRH if every higher-priority interface is asserting
2685    PRL.  When an interface denies PRL, each lower-priority interface has PRH
2686    denied and so denies PRL to the next interface in the chain.
2687 
2688    To avoid checking calling each device simulator's higher-priority interface
2689    routine to ascertain its PRL status, the priority holdoff bit vector is
2690    checked.  This vector has a bit set for each interface currently denying PRL.
2691    The check is made as in the following example:
2692 
2693      sc bit      :  ...0 0 1 0 0 0 0 0 0 0 0 0   (dispatching to SC 11)
2694      sc bit - 1  :  ...0 0 0 1 1 1 1 1 1 1 1 1   (PRH required thru SC 10)
2695      pri holdoff :  ...0 0 1 0 0 1 0 0 0 0 0 0   (PRL denied for SC 06 and 11)
2696      ANDed value :  ...0 0 0 0 0 1 0 0 0 0 0 0   (PRL blocked at SC 06)
2697 
2698    If the ANDed value is 0, then there are no higher priority devices in this
2699    rank that are denying PRL.  If the rank is 0, then PRH is asserted to the
2700    current select code.  If the rank is 1, then PRH is asserted only if all rank
2701    0 priority holdoff bits are zero, i.e., if no rank 0 interfaces are denying
2702    PRL.
2703 
2704    The device interface handler is obtained from the "dibs" array, and the
2705    interface is called to process the inbound signals.
2706 
2707    On return, the outbound signals from the interface are examined.  The
2708    interrupt vector bit is set to the state of the IRQ signal, and the priority
2709    vector bit is set to the state of the PRL signal.
2710 
2711    If the IRQ signal is present, then the interface is the highest priority
2712    device requesting an interrupt (otherwise the interface would not have
2713    received PRH, which is a term in asserting IRQ), so the select code of the
2714    interrupting device is set.  Otherwise, if the interface asserted its PRL
2715    condition from a prior denied state, then lower priority devices are checked
2716    to see if any now have a valid interrupt request.
2717 
2718    If the SRQ signal is asserted, a DMA request is made; if the device is under
2719    DMA control, a DMA cycle will be initiated at the start of the next pass
2720    through the instruction execution loop.  Finally, the skip condition is set
2721    if the SKF signal is asserted, and the skip state and outbound value from the
2722    interface are returned to the caller.
2723 
2724 
2725    Implementation notes:
2726 
2727     1. For select codes < 10 octal, an IOI signal reads the floating S-bus
2728        (high on the 1000, low on the 21xx).  For select codes >= 10 octal, an
2729        IOI reads the floating I/O bus (low on all machines).
2730 
2731     2. The last select code used is saved for use by the CPU I/O handler in
2732        detecting consecutive CLC 0 executions.
2733 
2734     3. The IRQ and FLG signals always assert together on HP 21xx/1000 machines.
2735        They are physically tied together on all interface cards, and the CPUs
2736        depend on their concurrent assertion for correct operation.  In
2737        simulation, we check only IRQ from the interface, although FLG will be
2738        asserted as well.
2739 
2740     4. The IRQ and SRQ signals usually assert together, which means that an
2741        interrupt is pending before the DMA request is serviced.  However, DMA
2742        cycles always assert CLF, which clears the interrupt request before
2743        interrupts are checked.  In hardware, an SRQ to an active channel asserts
2744        DMALO (DMA lock out), which inhibits IRQ from setting the interrupt
2745        request flip-flop until the DMA cycle completes.  In simulation, IRQ is
2746        never asserted because the CLF is processed by the interface simulator
2747        before IRQ is determined.
2748 
2749     5. An interface will assert "cnVALID" if the conditional PRL and IRQ were
2750        determined.  If "cnVALID" is not asserted by the interface, then the
2751        states of the "cnPRL" and "cnIRQ" signals cannot be inferred from their
2752        presence or absence in the outbound signal set.
2753 
2754     6. The "cnVALID" pseudo-signal is required because although most interfaces
2755        determine the PRL and IRQ states in response to an SIR assertion, not all
2756        do.  In particular, the 12936A Privileged Interrupt Fence determines PRL
2757        in response to an IOO signal.
2758 */
2759 
io_dispatch(uint32 select_code,INBOUND_SET inbound_signals,HP_WORD inbound_value)2760 SKPF_DATA io_dispatch (uint32 select_code, INBOUND_SET inbound_signals, HP_WORD inbound_value)
2761 {
2762 SKPF_DATA     result;
2763 SIGNALS_VALUE outbound;
2764 uint32        sc_rank, sc_bit, previous_holdoff;
2765 
2766 if (iot [select_code].dibptr == NULL) {                 /* if the I/O slot is empty */
2767     result.skip = FALSE;                                /*   then SKF cannot be asserted */
2768 
2769     if (inbound_signals & ioIOI && select_code < SC_VAR /* if this is an input request for an internal device */
2770       && cpu_configuration & CPU_1000)                  /*   of a 1000 CPU */
2771         result.data = D16_UMAX;                         /*     then the empty slot reads as all ones */
2772     else                                                /* otherwise */
2773         result.data = 0;                                /*   the empty slot reads as all zeros */
2774     }
2775 
2776 else {                                                  /* otherwise the slot is occupied */
2777     sc_rank = select_code / 32;                         /*   so set the rank */
2778     sc_bit  = 1u << select_code % 32;                   /*     and bit of the interface */
2779 
2780     if (interrupt_system == SET) {                      /* if the interrupt system is on */
2781         inbound_signals |= ioIEN;                       /*   then assert IEN to the interface */
2782 
2783         if ((sc_bit - 1 & priority_holdoff_set [sc_rank]) == 0  /* if no higher priority device */
2784           && (sc_rank == 0 || priority_holdoff_set [0] == 0))   /*   is denying PRL */
2785             inbound_signals |= ioPRH;                           /*     then assert PRH to our interface */
2786         }
2787 
2788     tpprintf (iot [select_code].devptr, TRACE_IOBUS, "Received data %06o with signals %s\n",
2789               inbound_value, fmt_bitset (inbound_signals, inbound_format));
2790 
2791     outbound =                                                          /* call the device interface */
2792       iot [select_code].dibptr->io_interface (iot [select_code].dibptr, /*   with the device select code */
2793                                               inbound_signals,          /*     and inbound signal set */
2794                                               inbound_value);           /*       and data value */
2795 
2796     tpprintf (iot [select_code].devptr, TRACE_IOBUS, "Returned data %06o with signals %s\n",
2797               outbound.value, fmt_bitset (outbound.signals, outbound_format));
2798 
2799     last_select_code = select_code;                     /* save the select code for CLC 0 detection */
2800     previous_holdoff = priority_holdoff_set [sc_rank];  /*   and the current priority holdoff for this rank */
2801 
2802     if (outbound.signals & cnVALID) {                   /* if the IRQ and PRL signals are valid */
2803         if (outbound.signals & cnIRQ)                   /*   then if the conditional interrupt request signal is present */
2804             interrupt_request_set [sc_rank] |= sc_bit;  /*     then set the interrupt request bit */
2805         else                                            /*   otherwise */
2806             interrupt_request_set [sc_rank] &= ~sc_bit; /*     clear the request bit */
2807 
2808         if (outbound.signals & cnPRL)                   /* if the conditional priority low signal is present */
2809             priority_holdoff_set [sc_rank] &= ~sc_bit;  /*   then clear the priority inhibit bit */
2810         else                                            /* otherwise */
2811             priority_holdoff_set [sc_rank] |= sc_bit;   /*   set the inhibit bit */
2812         }
2813 
2814     if (outbound.signals & ioIRQ)                       /* if the interrupt request signal is present */
2815         interrupt_request = select_code;                /*   then indicate that the select code is interrupting */
2816 
2817     else if (previous_holdoff & ~priority_holdoff_set [sc_rank] & sc_bit)   /* otherwise if priority is newly asserted */
2818         interrupt_request = io_poll_interrupts (interrupt_system);          /*   then check interrupt requests */
2819 
2820     if (outbound.signals & ioSRQ)                       /* if SRQ is asserted */
2821         dma_assert_SRQ (select_code);                   /*   then check if DMA is controlling this interface */
2822 
2823     result.skip = (outbound.signals & ioSKF) != 0;      /* return TRUE if the skip-on-flag signal is present */
2824     result.data = outbound.value;                       /*   and return the outbound data from the interface */
2825     }
2826 
2827 return result;                                          /* return the result of the I/O operation */
2828 }
2829 
2830 
2831 /* Execute an I/O control operation.
2832 
2833    This routine performs an I/O control operation on the interface specified by
2834    the "select_code" parameter.  I/O control operations are all those that do
2835    not pass data to or from the interface.  The routine returns TRUE if the
2836    interface asserted the SKF signal as a result of the operation and FALSE if
2837    it did not.
2838 
2839    Certain microcode extension instructions perform I/O operations as part of
2840    their execution.  In hardware, this is done by setting bits 11-6 of the
2841    Instruction Register to a code describing the operation and then issuing the
2842    IOG micro-order to generate the appropriate backplane signals.  In
2843    simulation, this relatively lightweight routine performs the same action,
2844    avoiding much of the overhead of the "cpu_iog" routine.
2845 
2846    The routine performs a memory protect check and then dispatches the operation
2847    to the interface indicated by the supplied select code.
2848 */
2849 
io_control(uint32 select_code,IO_GROUP_OP micro_op)2850 t_bool io_control (uint32 select_code, IO_GROUP_OP micro_op)
2851 {
2852 SKPF_DATA result;
2853 
2854 mp_check_io (select_code, micro_op);                    /* check that the I/O operation is permitted */
2855 
2856 result = io_dispatch (select_code,                      /* send the signal set */
2857                       control_set [micro_op], 0);       /*   to the indicated interface */
2858 
2859 return result.skip;                                     /* return TRUE if the interface asserted SKF */
2860 }
2861 
2862 
2863 /* Assert an I/O backplane signal.
2864 
2865    This routine is called by a device interface simulator to assert a specific
2866    I/O backplane signal.  The supported signal assertions are ENF, SIR, PON,
2867    POPIO, CRS, and IAK.  In hardware, these signals would be asserted by logic
2868    gates on the interface; in simulation, they are asserted by calls to this
2869    routine.
2870 
2871    The operation is dispatched via the I/O access table by the "io_dispatch"
2872    routine, so we first ensure that the table entry is set correctly.  During
2873    instruction execution, this is redundant, as the table has been set up during
2874    the execution prelude.  However, this routine is also called by each
2875    interface simulator's device reset routine in response to a RESET ALL or
2876    RESET <device> SCP command.  At that point, the table may not have been
2877    initialized or may contain incorrect entries (if the device has been enabled
2878    or reassigned since the last time the table was set up).
2879 */
2880 
io_assert(DEVICE * dptr,IO_ASSERTION assertion)2881 void io_assert (DEVICE *dptr, IO_ASSERTION assertion)
2882 {
2883 DIB    *dibptr;
2884 uint32 select_code;
2885 
2886 if (dptr != NULL && dptr->ctxt != NULL) {               /* if the device points to a valid DIB */
2887     dibptr = (DIB *) dptr->ctxt;                        /*   then get the DIB pointer */
2888     select_code = dibptr->select_code;                  /*     and associated select code */
2889 
2890     iot [select_code].devptr = dptr;                    /* set the current device and DIB pointer assignments */
2891     iot [select_code].dibptr = dibptr;                  /*   into the table */
2892 
2893     io_dispatch (select_code, assert_set [assertion], 0);   /* assert the signal set to the indicated interface */
2894     }
2895 
2896 return;
2897 }
2898 
2899 
2900 /* Poll for a new interrupt request.
2901 
2902    This routine is called when an interface asserts a previously denied PRL
2903    signal, i.e., when PRL goes from low to high on the I/O backplane.  It
2904    determines if any interfaces lower in the priority chain are now ready to
2905    interrupt.  If so, the select code of the highest priority interrupting
2906    interface is returned; otherwise, 0 is returned.
2907 
2908    In hardware, PRH and PRL form a priority chain that extends from interface to
2909    interface on the backplane.  For an interface to generate an interrupt, PRH
2910    must be asserted by the next-higher-priority interface.  An interface
2911    receiving PRH asserts IRQ to request an interrupt, and it denies PRL to
2912    prevent lower-priority devices from interrupting.  IRQ is cleared by an
2913    interrupt acknowledge (IAK) signal.  PRL generally remains low while a
2914    device's interrupt service routine is executing to prevent preemption.
2915 
2916    IRQ and PRL indicate one of four possible states for a device:
2917 
2918      IRQ  PRL  Device state
2919      ---  ---  ----------------------
2920       0    1   Not interrupting
2921       1    0   Interrupt requested
2922       0    0   Interrupt acknowledged
2923       1    1   (not allowed)
2924 
2925    PRL must be denied when requesting an interrupt (IRQ asserted).  This is a
2926    hardware requirement of the 21xx/1000 series.  The IRQ lines from the
2927    backplane are not priority encoded.  Instead, the PRL chain expresses the
2928    priority by allowing only one IRQ line to be active at a time.  This allows a
2929    simple pull-down encoding of the CIR inputs.
2930 
2931    When a given interface denies PRL, the PRH-to-PRL chain through all
2932    lower-priority interfaces also denies.  When that interface reasserts PRL,
2933    the chain reasserts through intervening interfaces until it reaches one that
2934    is ready to request an interrupt or through all interfaces if none are ready.
2935    An interface that is ready to interrupt except for a denied PRH will assert
2936    IRQ when the higher-priority PRH-to-PRL chain reasserts.
2937 
2938    A direct simulation of this hardware behavior would require polling all
2939    lower-priority interfaces in order by calling their interface routines,
2940    asserting PRH to each, and checking each for an asserted IRQ or a denied PRL
2941    in response.  Two avoid this inefficiency, two bit vectors are kept that
2942    reflect the states of each interface's IRQ and PRL signals conditional on PRH
2943    being asserted.  The "interrupt_request_set" bit vector reflects each
2944    interface's readiness to interrupt if its associated PRH signal is asserted,
2945    and the "priority_holdoff_set" reflects the (inverted) state of each
2946    interface's PRL signal, i.e., a zero-bit indicates that the interface is
2947    ready to assert PRL if its associated PRH signal is asserted.  Each vector is
2948    represented as a two-element array of 32-bit unsigned integers, forming a
2949    64-bit vector in which bits 0-31 of the first element correspond to select
2950    codes 00-37 octal, and bits 0-31 of the second element correspond to select
2951    codes 40-77 octal.
2952 
2953    The routine begins by seeing if an interrupt is pending.  If not, it returns
2954    0.  Otherwise, the PRH-to-PRL chain is checked to see if PRL is denied
2955    anywhere upstream of the highest priority interrupting interface.  If it is,
2956    then no interface can interrupt.  If all higher-priority PRL signals are
2957    asserted, then the interrupt request of that interface is granted.
2958 
2959    Recognition of interrupts depends on the current state of the interrupt
2960    system and interrupt enable flip-flops, as follows:
2961 
2962      INTSYS  INTEN   Interrupts Recognized
2963      ------  ------  ----------------------------
2964      CLEAR   CLEAR   Parity error
2965      CLEAR   SET     Parity error, power fail
2966      SET     CLEAR   Parity error, memory protect
2967      SET     SET     All sources
2968 
2969    Memory protect and parity error share select code 05, but the interrupt
2970    sources are differentiated on the MP card -- setting the flag buffer for a
2971    memory protect violation is qualified by the IEN signal that reflects
2972    the INTSYS state, whereas no qualification is used for a parity error.
2973    Therefore, an interrupt on select code 05 with the interrupt system off must
2974    be a parity error interrupt.
2975 
2976    The end of the priority chain is marked by the highest-priority
2977    (lowest-order) bit that is set.  We calculate a priority mask by ANDing the
2978    the PRL bits with its two's complement using the IOPRIORITY macro.  Only the
2979    lowest-order bit will differ.  For example:
2980 
2981      pri holdoff :  ...0 0 1 0 0 1 0 0 0 0 0 0  (PRL denied for SC 06 and 11)
2982      one's compl :  ...1 1 0 1 1 0 1 1 1 1 1 1
2983      two's compl :  ...1 1 0 1 1 1 0 0 0 0 0 0
2984      ANDed value :  ...0 0 0 0 0 1 0 0 0 0 0 0  (chain is broken at SC 06)
2985 
2986    The interrupt requests are then ANDed with the priority masks to determine if
2987    a request is pending:
2988 
2989      pri mask    :  ...0 0 0 0 0 1 0 0 0 0 0 0  (allowed interrupt source)
2990      int request :  ...0 0 1 0 0 1 0 0 0 0 0 0  (interfaces asserting IRQ)
2991      ANDed value :  ...0 0 0 0 0 1 0 0 0 0 0 0  (request to grant)
2992 
2993    The select code corresponding to the granted request is then returned to the
2994    caller.
2995 
2996 
2997    Implementation notes:
2998 
2999     1. Recognition of an interrupt in the second half of the request set (i.e.,
3000        for select codes 40-77 octal) occurs only if the priority set for the
3001        first half is 0, i.e., if the PRH-to-PRL chain is unbroken through select
3002        code 37.
3003 
3004     2. If an interrupt for select codes 00-37 is pending but is inhibited, then
3005        all higher select code interrupts are inhibited as well, so we only need
3006        to check requests for the lower half or the upper half, but not both.
3007 
3008     3. Splitting the interrupt request and priority holdoff sets into two 32-bit
3009        parts is actually more efficient on 32-bit host CPUs than using a single
3010        64-bit set, especially when right-shifting to obtain the bit number.
3011        Efficiency is also aided by the fact that interface select codes are
3012        typically below 40 octal and therefore are represented in the first bit
3013        set(s).
3014 */
3015 
io_poll_interrupts(FLIP_FLOP interrupt_system)3016 uint32 io_poll_interrupts (FLIP_FLOP interrupt_system)
3017 {
3018 const uint32 unmaskable = 1u << PWR | 1u << MPPE;       /* these interrupts are not inhibited by INTSYS clear */
3019 uint32 sc, rank, priority_mask, request_granted;
3020 
3021 if (interrupt_request_set [0]) {                                    /* if a lower pending interrupt exists */
3022     priority_mask = IOPRIORITY (priority_holdoff_set [0]);          /*   then calculate the first priority mask */
3023     request_granted = priority_mask & interrupt_request_set [0];    /*     and the request to grant */
3024     rank = 0;                                                       /*       for interrupt sources SC 00-37 */
3025 
3026     if (interrupt_system == CLEAR)                      /* if the interrupt system is off */
3027         request_granted &= unmaskable;                  /*   then only Power Fail and Parity Error may interrupt */
3028     }
3029 
3030 else if (interrupt_request_set [1]                                  /* otherwise if an upper pending interrupt exists */
3031   && priority_holdoff_set [0] == 0) {                               /*   and the priority chain is intact */
3032     priority_mask = IOPRIORITY (priority_holdoff_set [1]);          /*     then calculate the second priority mask */
3033     request_granted = priority_mask & interrupt_request_set [1];    /*       and the request to grant */
3034     rank = 32;                                                      /*         for interrupt sources SC 40-77 */
3035     }
3036 
3037 else                                                    /* otherwise no interrupts are pending */
3038     return 0;                                           /*   so return */
3039 
3040 if (request_granted == 0)                               /* if no request was granted */
3041     return 0;                                           /*   then return */
3042 
3043 else {                                                  /* otherwise */
3044     for (sc = rank; !(request_granted & 1); sc++)       /*   determine the interrupting select code */
3045         request_granted = request_granted >> 1;         /*     by counting the bits until the set bit is reached */
3046 
3047     return sc;                                          /* return the interrupting select code */
3048     }
3049 }
3050 
3051 
3052 
3053 /* CPU local SCP support routines */
3054 
3055 
3056 /* CPU interface (select code 00).
3057 
3058    I/O operations directed to select code 0 manipulate the interrupt system.
3059    STF and CLF turn the interrupt system on and off, and SFS and SFC test the
3060    state of the interrupt system.  When the interrupt system is off, only Power
3061    Fail and Parity Error interrupts are allowed.  The PRL signal follows the
3062    state of the interrupt system.
3063 
3064    CLC asserts CRS to all interfaces from select code 6 upward.
3065 
3066    A PON reset initializes certain CPU registers.  The 1000 series does a
3067    microcoded memory clear and leaves the T and P registers set as a result.
3068 
3069 
3070    Implementation notes:
3071 
3072     1. An IOI signal reads the floating I/O bus (0 on all machines).
3073 
3074     2. A CLC 0 issues CRS to all devices, not CLC.  While most cards react
3075        identically to CRS and CLC, some do not, e.g., the 12566B when used as an
3076        I/O diagnostic target.
3077 
3078     3. RTE uses the undocumented SFS 0,C instruction to both test and turn off
3079        the interrupt system.  This is confirmed in the "RTE-6/VM Technical
3080        Specifications" manual (HP 92084-90015), section 2.3.1 "Process the
3081        Interrupt", subsection "A.1 $CIC":
3082 
3083         "Test to see if the interrupt system is on or off.  This is done with
3084          the SFS 0,C instruction.  In either case, turn it off (the ,C does
3085          it)."
3086 
3087        ...and in section 5.8, "Parity Error Detection":
3088 
3089         "Because parity error interrupts can occur even when the interrupt
3090          system is off, the code at $CIC must be able to save the complete
3091          system status.  The major hole in being able to save the complete state
3092          is in saving the interrupt system state.  In order to do this in both
3093          the 21MX and the 21XE the instruction 103300 was used to both test the
3094          interrupt system and turn it off."
3095 
3096     4. Select code 0 cannot interrupt, so the SIR handler does not assert IRQ.
3097 
3098     5. To guarantee proper initialization, the 12920A terminal multiplexer
3099        requires that the Control Reset (CRS) I/O signal be asserted for a
3100        minimum of 100 milliseconds.  In practice, this is achieved by executing
3101        131,072 (128K) CLC 0 instructions in a tight loop.  This is not necessary
3102        in simulation, and in fact is detrimental, as 262,000+ trace lines will
3103        be written for each device that enables IOBUS tracing.  To avoid this,
3104        consecutive CLC 0 operations after the first are omitted.  This is
3105        detected by checking the select code and signal set of the last I/O
3106        operation.
3107 */
3108 
cpu_interface(const DIB * dibptr,INBOUND_SET inbound_signals,HP_WORD inbound_value)3109 static SIGNALS_VALUE cpu_interface (const DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value)
3110 {
3111 static INBOUND_SET last_signal_set = ioNONE;            /* the last set of I/O signals processed */
3112 INBOUND_SIGNAL     signal;
3113 INBOUND_SET        working_set = inbound_signals;
3114 SIGNALS_VALUE      outbound    = { ioNONE, 0 };
3115 uint32             sc;
3116 
3117 while (working_set) {                                   /* while signals remain */
3118     signal = IONEXTSIG (working_set);                   /*   isolate the next signal */
3119 
3120     switch (signal) {                                   /* dispatch the I/O signal */
3121 
3122         case ioCLF:                                     /* Clear Flag flip-flop */
3123             interrupt_system = CLEAR;                   /* turn the interrupt system off */
3124 
3125             if (interrupt_request > MPPE)               /* if any interrupt other than power fail or parity error */
3126                 interrupt_request = 0;                  /*   is pending, then clear it */
3127             break;
3128 
3129 
3130         case ioSTF:                                     /* Set Flag flip-flop */
3131             interrupt_system = SET;                     /* turn the interrupt system on */
3132             break;
3133 
3134 
3135         case ioSFC:                                     /* Skip if Flag is Clear */
3136             if (interrupt_system == CLEAR)              /* if the interrupt system is off */
3137                 outbound.signals |= ioSKF;              /*   then assert the Skip on Flag signal */
3138             break;
3139 
3140 
3141         case ioSFS:                                     /* Skip if Flag is Set */
3142             if (interrupt_system == SET)                /* if the interrupt system is on */
3143                 outbound.signals |= ioSKF;              /*   then assert the Skip on Flag signal */
3144             break;
3145 
3146 
3147         case ioIOI:                                     /* I/O input */
3148             outbound.value = 0;                         /* returns 0 */
3149             break;
3150 
3151 
3152         case ioPON:                                     /* Power On Normal */
3153             AR = 0;                                     /* clear A register */
3154             BR = 0;                                     /* clear B register */
3155             SR = 0;                                     /* clear S register */
3156             TR = 0;                                     /* clear T register */
3157             E = 1;                                      /* set E register */
3158 
3159             if (cpu_configuration & CPU_1000) {         /* if the CPU is a 1000-series machine */
3160                 mem_zero (0, mem_size);                 /*   then power on clears memory */
3161 
3162                 MR = LA_MAX;                            /* set the M register to the maximum logical address */
3163                 PR = MR + 1;                            /*   and the P register to one more than that */
3164                 }
3165 
3166             else {                                      /* otherwise is a 21xx-series machine */
3167                 MR = 0;                                 /*   which clears the M register */
3168                 PR = 0;                                 /*     and the P register */
3169                 }
3170             break;
3171 
3172 
3173         case ioPOPIO:                                   /* Power-On Preset to I/O */
3174             O = 0;                                      /* clear the overflow register */
3175 
3176             interrupt_system = CLEAR;                   /* turn off the interrupt system */
3177             cpu_interrupt_enable = SET;                 /*   and enable interrupts */
3178             break;
3179 
3180 
3181         case ioCLC:                                             /* Clear Control flip-flop */
3182             if (last_select_code != 0                           /* if the last I/O instruction */
3183               || (last_signal_set & ioCLC) == 0)                /*   was not a CLC 0 */
3184                 for (sc = SC_CRS; sc <= SC_MAX; sc++)           /*     then assert the CRS signal */
3185                     if (iot [sc].devptr != NULL)                /*       to all occupied I/O slots  */
3186                         io_assert (iot [sc].devptr, ioa_CRS);   /*         from select code 6 and up */
3187             break;
3188 
3189 
3190         case ioSIR:                                             /* Set Interrupt Request */
3191             if (interrupt_system)                               /* if the interrupt system is on */
3192                 outbound.signals |= ioPRL | cnPRL | cnVALID;    /*   then assert PRL */
3193             else                                                /* otherwise */
3194                 outbound.signals |= cnVALID;                    /*   deny PRL */
3195             break;
3196 
3197 
3198         case ioIOO:                                     /* not used by this interface */
3199         case ioSTC:                                     /* not used by this interface */
3200         case ioEDT:                                     /* not used by this interface */
3201         case ioCRS:                                     /* not used by this interface */
3202         case ioIAK:                                     /* not used by this interface */
3203         case ioENF:                                     /* not used by this interface */
3204         case ioIEN:                                     /* not used by this interface */
3205         case ioPRH:                                     /* not used by this interface */
3206             break;
3207         }
3208 
3209     IOCLEARSIG (working_set, signal);                   /* remove the current signal from the set */
3210     }                                                   /*   and continue until all signals are processed */
3211 
3212 last_signal_set = inbound_signals;                      /* save the current signal set for the next call */
3213 
3214 return outbound;                                        /* return the outbound signals and value */
3215 }
3216 
3217 
3218 /* Overflow and S-register interface (select code 01).
3219 
3220    I/O operations directed to select code 1 manipulate the overflow (O) and
3221    switch (S) registers.  On the 2115 and 2116, there is no S-register
3222    indicator, so it is effectively read-only.  On the other machines, a
3223    front-panel display of the S-register is provided.  On all machines,
3224    front-panel switches are provided to set the contents of the S register.
3225 
3226 
3227    Implementation notes:
3228 
3229     1. Select code 1 cannot interrupt, so there is no SIR handler, and PRH is
3230        passed through to PRL.
3231 */
3232 
ovf_interface(const DIB * dibptr,INBOUND_SET inbound_signals,HP_WORD inbound_value)3233 static SIGNALS_VALUE ovf_interface (const DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value)
3234 {
3235 INBOUND_SIGNAL signal;
3236 INBOUND_SET    working_set = inbound_signals;
3237 SIGNALS_VALUE  outbound    = { ioNONE, 0 };
3238 
3239 while (working_set) {                                   /* while signals remain */
3240     signal = IONEXTSIG (working_set);                   /*   isolate the next signal */
3241 
3242     switch (signal) {                                   /* dispatch the I/O signal */
3243 
3244         case ioCLF:                                     /* Clear Flag flip-flop */
3245             O = 0;                                      /* clear the overflow register */
3246             break;
3247 
3248 
3249         case ioSTF:                                     /* Set Flag flip-flop */
3250             O = 1;                                      /* set the overflow register */
3251             break;
3252 
3253 
3254         case ioSFC:                                     /* Skip if Flag is Clear */
3255             if (O == 0)                                 /* if the overflow register is clear */
3256                 outbound.signals |= ioSKF;              /*   then assert the Skip on Flag signal */
3257             break;
3258 
3259 
3260         case ioSFS:                                     /* Skip if Flag is Set */
3261             if (O != 0)                                 /* if the overflow register is set */
3262                 outbound.signals |= ioSKF;              /*   then assert the Skip on Flag signal */
3263             break;
3264 
3265 
3266         case ioIOI:                                     /* I/O data input */
3267             outbound.value = SR;                        /* read switch register value */
3268             break;
3269 
3270 
3271         case ioIOO:                                             /* I/O data output */
3272             if (!(cpu_configuration & (CPU_2115 | CPU_2116)))   /* on all machines except the 2115 and 2116 */
3273                 SR = inbound_value & R_MASK;                    /*   write the value to the S-register display */
3274             break;
3275 
3276 
3277         case ioPRH:                                     /* Priority High */
3278             outbound.signals |= ioPRL;                  /* assert PRL */
3279             break;
3280 
3281 
3282         case ioSTC:                                     /* not used by this interface */
3283         case ioCLC:                                     /* not used by this interface */
3284         case ioEDT:                                     /* not used by this interface */
3285         case ioCRS:                                     /* not used by this interface */
3286         case ioPOPIO:                                   /* not used by this interface */
3287         case ioPON:                                     /* not used by this interface */
3288         case ioIAK:                                     /* not used by this interface */
3289         case ioENF:                                     /* not used by this interface */
3290         case ioIEN:                                     /* not used by this interface */
3291         case ioSIR:                                     /* not used by this interface */
3292             break;
3293         }
3294 
3295     IOCLEARSIG (working_set, signal);                   /* remove the current signal from the set */
3296     }                                                   /*   and continue until all signals are processed */
3297 
3298 return outbound;                                        /* return the outbound signals and value */
3299 }
3300 
3301 
3302 /* Power fail interface (select code 04).
3303 
3304    Power fail detection is standard on 2100 and 1000 systems and is optional on
3305    21xx systems.  Power fail recovery is standard on the 2100 and optional on
3306    the others.  Power failure or restoration will cause an interrupt on select
3307    code 4 and will deny PRL, preventing all other devices from interrupting
3308    while the power fail routine is executing.  Asserting either STC or CLC
3309    clears the interrupt and reasserts PRL.  The direction of power change (down
3310    or up) can be tested by SFC, which will skip if power is failing.
3311 
3312    Asserting IOI to select code 4 reads the Central Interrupt Register value.
3313 
3314 
3315    Implementation notes:
3316 
3317     1. Currently, power fail is not simulated, and the interface is provided
3318        solely to read the CIR.  As a result, PRL is always asserted.
3319 */
3320 
pwr_interface(const DIB * dibptr,INBOUND_SET inbound_signals,HP_WORD inbound_value)3321 static SIGNALS_VALUE pwr_interface (const DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value)
3322 {
3323 INBOUND_SIGNAL signal;
3324 INBOUND_SET    working_set = inbound_signals;
3325 SIGNALS_VALUE  outbound    = { ioNONE, 0 };
3326 
3327 while (working_set) {                                   /* while signals remain */
3328     signal = IONEXTSIG (working_set);                   /*   isolate the next signal */
3329 
3330     switch (signal) {                                   /* dispatch the I/O signal */
3331 
3332         case ioSTC:                                     /* Set Control flip-flop */
3333         case ioCLC:                                     /* Clear Control flip-flop */
3334             break;                                      /* reinitializes power fail */
3335 
3336 
3337         case ioSFC:                                     /* Skip if Flag is Clear */
3338             break;                                      /* skips if power is failing */
3339 
3340 
3341         case ioIOI:                                     /* I/O data input */
3342             outbound.value = CIR;                       /* return the select code of the interrupting interface */
3343             break;
3344 
3345 
3346         case ioPRH:                                     /* Priority High */
3347             outbound.signals |= ioPRL;                  /* assert PRL */
3348             break;
3349 
3350 
3351         case ioSTF:                                     /* not used by this interface */
3352         case ioCLF:                                     /* not used by this interface */
3353         case ioSFS:                                     /* not used by this interface */
3354         case ioIOO:                                     /* not used by this interface */
3355         case ioEDT:                                     /* not used by this interface */
3356         case ioCRS:                                     /* not used by this interface */
3357         case ioPOPIO:                                   /* not used by this interface */
3358         case ioPON:                                     /* not used by this interface */
3359         case ioIAK:                                     /* not used by this interface */
3360         case ioENF:                                     /* not used by this interface */
3361         case ioIEN:                                     /* not used by this interface */
3362         case ioSIR:                                     /* not used by this interface */
3363             break;
3364         }
3365 
3366     IOCLEARSIG (working_set, signal);                   /* remove the current signal from the set */
3367     }                                                   /*   and continue until all signals are processed */
3368 
3369 return outbound;                                        /* return the outbound signals and value */
3370 }
3371 
3372 
3373 /* Examine a CPU memory location.
3374 
3375    This routine is called by the SCP to examine memory.  The routine retrieves
3376    the memory location indicated by "address" as modified by any "switches" that
3377    were specified on the command line and returns the value in the first element
3378    of "eval_array".  The "uptr" parameter is not used.
3379 
3380    On entry, the "meu_map_address" routine is called to translate a logical
3381    address to a physical address.  If "switches" includes SIM_SW_REST or "-N",
3382    then the address is a physical address, and the routine returns the address
3383    unaltered.
3384 
3385    Otherwise, the address is a logical address interpreted in the context of the
3386    translation map implied by the specified switch and is mapped to a physical
3387    address.  If memory expansion is disabled but a map is specified, then the
3388    command is rejected.  Otherwise if the resulting address is beyond the
3389    current memory limit, or if mapping is implied or explicit but the address
3390    specified is outside of the logical address space, "address space exceeded"
3391    status is returned.
3392 
3393    Otherwise, the value is obtained from memory or the A/B register and returned
3394    in the first word of "eval_array."
3395 */
3396 
cpu_examine(t_value * eval_array,t_addr address,UNIT * uptr,int32 switches)3397 static t_stat cpu_examine (t_value *eval_array, t_addr address, UNIT *uptr, int32 switches)
3398 {
3399 uint32 index;
3400 
3401 index = meu_map_address ((HP_WORD) address, switches);  /* map the supplied address as directed by the switches */
3402 
3403 if (index == D32_UMAX)                                  /* if the MEM is disabled but a mapping mode was given */
3404     return SCPE_NOFNC;                                  /*   then the command is not allowed */
3405 
3406 else if (index >= mem_size)                             /* otherwise if the address is beyond the memory limit */
3407     return SCPE_NXM;                                    /*   then return non-existent memory status */
3408 
3409 else if (eval_array == NULL)                            /* otherwise if the value pointer was not supplied */
3410     return SCPE_IERR;                                   /*   then return internal error status */
3411 
3412 else                                                    /* otherwise */
3413     *eval_array = (t_value) mem_examine (index);        /*   then return the memory or A/B register value */
3414 
3415 return SCPE_OK;                                         /* return success status */
3416 }
3417 
3418 
3419 /* Deposit to a CPU memory location.
3420 
3421    This routine is called by the SCP to deposit to memory.  The routine stores
3422    the supplied "value" into memory at the "address" location as modified by any
3423    "switches" that were specified on the command line.
3424 
3425    On entry, the "meu_map_address" routine is called to translate a logical
3426    address to a physical address.  If "switches" includes SIM_SW_REST or "-N",
3427    then the address is a physical address, and the routine returns the address
3428    unaltered.
3429 
3430    Otherwise, the address is a logical address interpreted in the context of the
3431    translation map implied by the specified switch and is mapped to a physical
3432    address.  If memory expansion is disabled but a map is specified, then the
3433    command is rejected.  Otherwise if the resulting address is beyond the
3434    current memory limit, or if mapping is implied or explicit but the address
3435    specified is outside of the logical address space, "address space exceeded"
3436    status is returned.
3437 
3438    Otherwise, the value is stored into memory or the A/B register.
3439 */
3440 
cpu_deposit(t_value value,t_addr address,UNIT * uptr,int32 switches)3441 static t_stat cpu_deposit (t_value value, t_addr address, UNIT *uptr, int32 switches)
3442 {
3443 uint32 index;
3444 
3445 index = meu_map_address ((HP_WORD) address, switches);  /* map the supplied address as directed by the switches */
3446 
3447 if (index == D32_UMAX)                                  /* if the MEM is disabled but a mapping mode was given */
3448     return SCPE_NOFNC;                                  /*   then the command is not allowed */
3449 
3450 else if (index >= mem_size)                             /* otherwise if the address is beyond the memory limit */
3451     return SCPE_NXM;                                    /*   then return non-existent memory status */
3452 
3453 else                                                    /* otherwise */
3454     mem_deposit (index, (HP_WORD) value);               /*   write the memory or A/B register value */
3455 
3456 return SCPE_OK;                                         /* return success status */
3457 }
3458 
3459 
3460 /* Reset the CPU.
3461 
3462    This routine is called for a RESET, RESET CPU, RUN, or BOOT CPU command.  It
3463    is the simulation equivalent of an initial power-on condition (corresponding
3464    to PON, POPIO, and CRS signal assertion in the CPU) or a front-panel PRESET
3465    button press (corresponding to POPIO and CRS assertion).  SCP delivers a
3466    power-on reset to all devices when the simulator is started.
3467 
3468    If this is the first call after simulator startup, the initial memory array
3469    is allocated, the SCP-required program counter pointer is set to point to the
3470    REG array element corresponding to the P register, and the default CPU and
3471    memory size configuration is set.  In addition, the loader ROM sockets of the
3472    1000-series CPUs are populated with the initial ROM set, and the Basic Binary
3473    Loader (BBL) is installed in the protected memory (the upper 64 words of the
3474    defined memory size) of the 2116.
3475 
3476 
3477    Implementation notes:
3478 
3479     1. Setting the sim_PC value at run time accommodates changes in the register
3480        order automatically.  A fixed setting runs the risk of it not being
3481        updated if a change in the register order is made.
3482 
3483     2. The initial set of installed HP 1000 boot loader ROMs is:
3484 
3485          Socket   ROM    Boot Device
3486          ------  ------  ------------------------
3487            0     12992K  2748 Paper Tape Reader
3488            1     12992A  7900 or 2883 Disc Drive
3489            2     12992D  7970 Magnetic Tape Drive
3490            3     12992B  7905/06/20/25 Disc Drive
3491 */
3492 
cpu_reset(DEVICE * dptr)3493 static t_stat cpu_reset (DEVICE *dptr)
3494 {
3495 t_stat status;
3496 
3497 if (sim_PC == NULL) {                                   /* if this is the first call after simulator start */
3498     status = mem_initialize (PA_MAX);                   /*   then allocate main memory */
3499 
3500     if (status == SCPE_OK) {                            /* if memory initialization succeeds */
3501         for (sim_PC = dptr->registers;                  /*   then find the P register entry */
3502              sim_PC->loc != &PR && sim_PC->loc != NULL; /*     in the register array */
3503              sim_PC++);                                 /*       for the SCP interface */
3504 
3505         if (sim_PC == NULL)                             /* if the P register entry is not present */
3506             return SCPE_NXREG;                          /*   then there is a serious problem! */
3507 
3508         pcq_r = find_reg ("PCQ", NULL, dptr);           /* get the PC queue pointer */
3509 
3510         if (pcq_r == NULL)                              /* if the PCQ register is not present */
3511             return SCPE_IERR;                           /*   then something is seriously wrong */
3512         else                                            /* otherwise */
3513             pcq_r->qptr = 0;                            /*   initialize the register's queue pointer */
3514 
3515         mem_size = 32768;                               /* set the initial memory size to 32K */
3516         set_model (NULL, UNIT_2116, NULL, NULL);        /*   and the initial CPU model */
3517 
3518         loader_rom [0] = find_dev ("PTR");              /* install the 12992K ROM in socket 0 */
3519         loader_rom [1] = find_dev ("DQC");              /*   and the 12992A ROM in socket 1 */
3520         loader_rom [2] = find_dev ("MSC");              /*   and the 12992D ROM in socket 2 */
3521         loader_rom [3] = find_dev ("DS");               /*   and the 12992B ROM in socket 3 */
3522 
3523         loader_rom [0]->boot (0, loader_rom [0]);       /* install the BBL via the paper tape reader boot routine */
3524         set_loader (NULL, FALSE, NULL, NULL);           /*   and then disable the loader, which had been enabled */
3525         }
3526 
3527     else                                                /* otherwise memory initialization failed */
3528         return status;                                  /*   so report the error and abort the simulator */
3529     }
3530 
3531 if (sim_switches & SWMASK ('P'))                        /* if this is a power-on reset */
3532     io_assert (&cpu_dev, ioa_PON);                      /*   then issue the PON signal to the CPU */
3533 else                                                    /* otherwise */
3534     io_assert (&cpu_dev, ioa_POPIO);                    /*   issue a PRESET */
3535 
3536 hp_reset_poll ();                                       /* restart the keyboard poll */
3537 
3538 sim_brk_dflt = SWMASK ('N');                            /* the default breakpoint type is "nomap" as MEM is disabled */
3539 
3540 return SCPE_OK;
3541 }
3542 
3543 
3544 /* Device boot routine.
3545 
3546    This routine is called by the BOOT CPU and LOAD CPU commands to copy the
3547    specified boot loader ROM program into the upper 64 words of the logical
3548    address space.  It is equivalent to pressing the IBL (Initial Binary Loader)
3549    button on the front panel of a 1000 M/E/F-Series CPU.
3550 
3551    On entry, the S register must be set to indicate the specific boot loader ROM
3552    and the associated device select code to be copied, as follows:
3553 
3554       15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
3555      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
3556      | ROM # | -   - |      select code      | -   -   -   -   -   - |
3557      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
3558 
3559    Bits 15-14 select one of four loader ROM sockets on the CPU board that may
3560    contain ROMs.  If the specified socket does, the contents of the ROM are
3561    copied into the upper 64 words of memory and configured to use the specified
3562    select code.  The unspecified bits of the S register are available for use by
3563    the bootstrap program.
3564 
3565    If the select code is less than 10 octal, the loader is not copied, and the
3566    O (overflow) register is set to 1.  A successful copy and configuration
3567    clears the O register.
3568 
3569    The 21xx-series CPUs do not provide the IBL function.  If this routine is
3570    invoked while the CPU is configured as one of these machines, the command is
3571    rejected.
3572 
3573 
3574    Implementation notes:
3575 
3576     1. In hardware, a non-existent ROM (i.e., an empty socket) reads as though
3577        all words contain 177777 octal.  This would result in the loader area of
3578        memory containing 62 all-ones words, followed by a word set to 177777 +
3579        SC - 000010, where SC is the configured select code, followed by a word
3580        set to the negative starting address of the loader.  This is not
3581        simulated; instead, an attempt to boot from an empty socket is rejected
3582        with "Non-existent device."
3583 */
3584 
cpu_boot(int32 unitno,DEVICE * dptr)3585 static t_stat cpu_boot (int32 unitno, DEVICE *dptr)
3586 {
3587 const int32 select_code = IBL_SC  (SR);                 /* the select code from S register bits 11-6 */
3588 const int32 rom_socket  = IBL_ROM (SR);                 /* the ROM socket number from S register bits 15-14 */
3589 
3590 if (cpu_configuration & CPU_1000)                       /* if this is a 1000-series CPU */
3591     if (select_code < SC_VAR) {                         /*   then if the select code is invalid */
3592         O = 1;                                          /*     then set the overflow register */
3593         return SCPE_ARG;                                /*       and reject the IBL with "Invalid argument" */
3594         }
3595 
3596     else if (loader_rom [rom_socket] == NULL)           /*   otherwise if the ROM socket is empty */
3597         return SCPE_NXDEV;                              /*     then reject with "Non-existent device" */
3598 
3599     else {                                                          /*   otherwise */
3600         O = 0;                                                      /*     clear overflow to indicate a good IBL */
3601         return loader_rom [rom_socket]->boot (select_code, NULL);   /*       and copy the ROM into memory */
3602         }
3603 
3604 else                                                    /* otherwise this is a 21xx machine */
3605     return SCPE_NOFNC;                                  /*   and IBL isn't supported */
3606 }
3607 
3608 
3609 /* Set the CPU simulation stop conditions.
3610 
3611    This validation routine is called to configure the set of CPU stop
3612    conditions.  The "option" parameter is 0 to clear the stops, 1 to set the
3613    stops, and 2 to set the indirect chain length limit.  "cptr" points to the
3614    first character of the name of the stop to be cleared or set.  The unit and
3615    description pointers are not used.
3616 
3617    The routine processes commands of the form:
3618 
3619      SET CPU STOP
3620      SET CPU STOP=<stopname>[;<stopname>...]
3621      SET CPU NOSTOP
3622      SET CPU NOSTOP=<stopname>[;<stopname>...]
3623      SET CPU INDIR=<limit>
3624 
3625    The valid <stopname>s are contained in the "cpu_stop" table.  If names are
3626    not specified, all stop conditions are enabled or disabled.
3627 
3628 
3629    Implementation notes:
3630 
3631     1. The maximum indirect limit value is 32K, as an indirect chain cannot
3632        exceed the logical memory size without being in a loop.
3633 */
3634 
set_stops(UNIT * uptr,int32 option,char * cptr,void * desc)3635 static t_stat set_stops (UNIT *uptr, int32 option, char *cptr, void *desc)
3636 {
3637 char gbuf [CBUFSIZE];
3638 t_stat status;
3639 uint32 stop;
3640 
3641 if (cptr == NULL)                                               /* if there are no arguments */
3642     if (option == 0)                                            /*   then if we're clearing the stops */
3643         for (stop = 0; cpu_stop [stop].name != NULL; stop++)    /*     then loop through the flags */
3644             *cpu_stop [stop].status = SCPE_OK;                  /*       and clear each stop status */
3645 
3646     else if (option == 1)                                       /* otherwise if we're setting the stops */
3647         for (stop = 0; cpu_stop [stop].name != NULL; stop++)    /*   then loop through the flags */
3648             *cpu_stop [stop].status = cpu_stop [stop].value;    /*     and set each stop status */
3649 
3650     else                                                        /* otherwise */
3651         return SCPE_MISVAL;                                     /*   report the missing indirect limit value */
3652 
3653 else if (*cptr == '\0')                                 /* otherwise if the argument is empty */
3654     return SCPE_MISVAL;                                 /*   then report the missing value */
3655 
3656 else if (option == 2) {                                         /* otherwise if we're setting the indirect limit */
3657     stop = (uint32) get_uint (cptr, 10, LA_MAX + 1, &status);   /*   then parse the limit value */
3658 
3659     if (status != SCPE_OK)                              /* if a parsing error occurred */
3660         return status;                                  /*   then return the error status */
3661     else                                                /* otherwise */
3662         indirect_limit = stop;                          /*   set the indirect limit */
3663     }
3664 
3665 else                                                    /* otherwise at least one stop argument is present */
3666     while (*cptr) {                                     /* loop through the arguments */
3667         cptr = get_glyph (cptr, gbuf, ';');             /* get the next argument */
3668 
3669         for (stop = 0; cpu_stop [stop].name != NULL; stop++)            /* loop through the flags */
3670             if (strcmp (cpu_stop [stop].name, gbuf) == 0) {             /*   and if the argument matches */
3671                 if (option == 1)                                        /*     then if it's a STOP argument */
3672                     *cpu_stop [stop].status = cpu_stop [stop].value;    /*       then set the stop status */
3673                 else                                                    /*     otherwise it's a NOSTOP argument */
3674                     *cpu_stop [stop].status = SCPE_OK;                  /*       so clear the stop status */
3675 
3676                 break;                                  /* this argument has been processed */
3677                 }
3678 
3679         if (cpu_stop [stop].name == NULL)               /* if the argument was not found */
3680             return SCPE_ARG;                            /*   then report it */
3681         }
3682 
3683 return SCPE_OK;                                         /* the stops were successfully processed */
3684 }
3685 
3686 
3687 /* Change the CPU memory size.
3688 
3689    This validation routine is called to configure the CPU memory size.  The
3690    "new_size" parameter is set to the size desired and will be one of the
3691    discrete sizes supported by the simulator.  The "uptr" parameter points to
3692    the CPU unit and is used to obtain the CPU model.  The other parameters are
3693    not used.
3694 
3695    The routine processes commands of the form:
3696 
3697      SET [-F] CPU <memsize>
3698 
3699    If the new memory size is larger than the supported size for the CPU model
3700    currently selected, the routine returns an error.  If the new size is smaller
3701    than the previous size, and if the area that would be lost contains non-zero
3702    data, the user is prompted to confirm that memory should be truncated.  If
3703    the user denies the request, the change is rejected.  Otherwise, the new size
3704    is set.  The user may omit the confirmation request and force truncation by
3705    specifying the "-F" switch on the command line.
3706 
3707    On a 21xx CPU, the last 64 words in memory are reserved for the binary
3708    loader.  Before changing the memory size, the current loader is copied to the
3709    shadow RAM to preserve any manual changes that were made.  Then the new
3710    memory size is set, with the beginning of the loader area set as the first
3711    word of non-existent memory.
3712 
3713    Finally, non-existent memory is zeroed, so that the mem_read routine does not
3714    need any special handling for addresses beyond the end of defined memory.
3715 
3716 
3717    Implementation notes:
3718 
3719     1. In hardware, reads from non-existent memory return zero, and writes are
3720        ignored.  In simulation, the largest possible memory is instantiated and
3721        initialized to zero.  Therefore, only writes need to be checked against
3722        memory size.
3723 
3724     2. On the 21xx machines, doing SET CPU LOADERDISABLE decreases available
3725        memory size by 64 words.
3726 */
3727 
set_size(UNIT * uptr,int32 new_size,char * cptr,void * desc)3728 static t_stat set_size (UNIT *uptr, int32 new_size, char *cptr, void *desc)
3729 {
3730 static char confirm [] = "Really truncate memory [N]?";
3731 const uint32 model = UNIT_MODEL (cpu_unit [0].flags);   /* the current CPU model index */
3732 int32 old_size = (int32) mem_size;                      /* current memory size */
3733 
3734 if ((uint32) new_size > cpu_features [model].maxmem)    /* if the new memory size is not supported on current model */
3735     return SCPE_NOFNC;                                  /*   then report the error */
3736 
3737 if (!(sim_switches & SWMASK ('F'))                      /* if truncation is not explicitly forced */
3738   && ! mem_is_empty (new_size)                          /*   and the truncated part is not empty */
3739   && get_yn (confirm, FALSE) == FALSE)                  /*     and the user denies confirmation */
3740     return SCPE_INCOMP;                                 /*       then abort the command */
3741 
3742 if (cpu_configuration & CPU_1000)                       /* if the CPU is a 1000-series machine */
3743     cpu_unit [0].capac = mem_size = mem_end = new_size; /*   then memory is not reserved for the loader */
3744 
3745 else {                                                  /* otherwise */
3746     set_loader (uptr, FALSE, NULL, NULL);               /* save loader to shadow RAM */
3747     cpu_unit [0].capac = mem_size = new_size;           /* set new memory size */
3748     mem_end = mem_size - IBL_SIZE;                      /* reserve memory for loader */
3749     }
3750 
3751 if (old_size > new_size)                                /* if the new size is smaller than the prior size */
3752     mem_zero (mem_end, old_size - new_size);            /*   then zero the newly non-existent memory area */
3753 
3754 return SCPE_OK;
3755 }
3756 
3757 
3758 /* Change the CPU model.
3759 
3760    This validation routine is called to configure the CPU model.  The
3761    "new_model" parameter is set to the unit flag corresponding to the model
3762    desired.  The "uptr" parameter points to the CPU unit.  The other parameters
3763    are not used.
3764 
3765    Validation starts by setting the new memory size.  If the current memory size
3766    is within the range of memory sizes permitted by the new CPU model, it is
3767    kept; otherwise, it is reduced to the maximum size permitted.  If memory is
3768    to be truncated, the "set_size" routine verifies either that it is blank
3769    (i.e., filled with zero values) or that the user confirms that truncation is
3770    allowable.
3771 
3772    If the new memory size is accepted, the CPU options are set to the typical
3773    configuration supported by the new model.  Memory Protect and DMA are then
3774    configured as specified by the CPU feature table.  Memory expansion is
3775    enabled if the DMS instruction set is present.  Finally, the "is_1000" flag
3776    and memory reserved for the binary loader are set as directed by the new
3777    model.
3778 
3779    On return, the "cpu_configuration" bit set is updated to indicate the new
3780    model configuration.
3781 
3782 
3783    Implementation notes:
3784 
3785     1. "cpu_configuration" is used by the symbolic examine and deposit routines
3786        and instruction tracing to determine whether the firmware implementing a
3787        given opcode is present.  It is a copy of the CPU unit option flags with
3788        the encoded CPU model decoded into model flag bits.  This allows a simple
3789        (and fast) AND operation with a firmware feature word to determine
3790        applicability, saving the multiple masks and comparisons that would
3791        otherwise be required.
3792 
3793     2. The 'is_1000" variable is used to index into tables where the row
3794        selected depends on whether or not the CPU is a 1000 M/E/F-series model.
3795        For logical tests that depend on this, it is faster (by one x86 machine
3796        instruction) to test the "cpu_configuration" variable for the presence of
3797        one of the three 1000 model flags.
3798 */
3799 
set_model(UNIT * uptr,int32 new_model,char * cptr,void * desc)3800 static t_stat set_model (UNIT *uptr, int32 new_model, char *cptr, void *desc)
3801 {
3802 const FEATURE_TABLE new_cpu = cpu_features [UNIT_MODEL (new_model)];    /* get the features describing the new model */
3803 uint32 new_memsize;
3804 t_stat result;
3805 
3806 if (mem_size > new_cpu.maxmem)                          /* if the current memory size is too large for the new model */
3807     new_memsize = new_cpu.maxmem;                       /*   then set it to the maximum size supported */
3808 else                                                    /* otherwise */
3809     new_memsize = mem_size;                             /*   leave it unchanged */
3810 
3811 result = set_size (uptr, new_memsize, NULL, NULL);      /* set the new memory size */
3812 
3813 if (result == SCPE_OK) {                                /* if the change succeeded */
3814     cpu_configuration = TO_CPU_OPTION (new_cpu.typ)     /*   then set the typical options */
3815                           | CPU_BASE                    /*     and the base instruction set bit */
3816                           | TO_CPU_MODEL (new_model);   /*       and the new CPU model flag */
3817 
3818     cpu_unit [0].flags = cpu_unit [0].flags & ~UNIT_OPTION_FIELD    /* enable the typical features */
3819                           | new_cpu.typ & UNIT_OPTION_FIELD;        /*   for the new model */
3820 
3821     mp_configure ((new_cpu.typ & UNIT_MP) != 0,         /* configure MP, specifying whether */
3822                   (new_cpu.opt & UNIT_MP) != 0);        /*   it is enabled and optional */
3823 
3824     dma_configure ();                                   /* configure DMA for the new model */
3825 
3826     if (new_cpu.typ & UNIT_DMS)                         /* if DMS instructions are present */
3827         meu_configure (ME_Enabled);                     /*   then enable the MEM device */
3828     else                                                /* otherwise */
3829         meu_configure (ME_Disabled);                    /*   disable the MEM and mapping */
3830 
3831     if (cpu_configuration & CPU_1000) {                 /* if the CPU is a 1000-series machine */
3832         is_1000 = TRUE;                                 /*   then set the model index */
3833         mem_end = mem_size;                             /* memory is not reserved for the loader  */
3834         }
3835 
3836     else {                                              /* otherwise this is a 2100 or 211x */
3837         is_1000 = FALSE;                                /*   so set the model index */
3838         mem_end = mem_size - IBL_SIZE;                  /*     and reserve memory for the loader */
3839         }
3840     }
3841 
3842 return result;
3843 }
3844 
3845 
3846 /* Set a CPU option.
3847 
3848    This validation routine is called to add an option to the current CPU
3849    configuration.  The "option" parameter is set to the unit flag corresponding
3850    to the option desired.  The "uptr" parameter points to the CPU unit and is
3851    used to obtain the CPU model.  The other parameters are not used.
3852 
3853    The routine processes commands of the form:
3854 
3855      SET CPU <option>[,<option>...]
3856 
3857    The option must be valid for the current CPU model, or the command will be
3858    rejected.
3859 
3860 
3861    Implementation notes:
3862 
3863     1. "cpu_configuration" is used by the symbolic examine and deposit routines
3864        and instruction tracing to determine whether the firmware implementing a
3865        given opcode is present.  It is a copy of the CPU unit option flags with
3866        the encoded CPU model decoded into model flag bits.  This allows a simple
3867        (and fast) AND operation with a firmware feature word to determine
3868        applicability, saving the multiple masks and comparisons that would
3869        otherwise be required.
3870 */
3871 
set_option(UNIT * uptr,int32 option,char * cptr,void * desc)3872 static t_stat set_option (UNIT *uptr, int32 option, char *cptr, void *desc)
3873 {
3874 const uint32 model = UNIT_MODEL (uptr->flags);          /* the current CPU model index */
3875 
3876 if ((cpu_features [model].opt & option) == 0)           /* if the option is not available for the current CPU */
3877     return SCPE_NOFNC;                                  /*   then reject the request */
3878 
3879 if (option == UNIT_DMS)                                 /* if DMS instructions are being enabled */
3880     meu_configure (ME_Enabled);                         /*   then enable the MEM device */
3881 
3882 if (cpu_configuration & CPU_2100) {                     /* if the current CPU is a 2100 */
3883     if ((option == UNIT_FP) || (option == UNIT_FFP))    /*   then the IOP option */
3884         uptr->flags &= ~UNIT_IOP;                       /*     and the FP and FFP options */
3885     else if (option == UNIT_IOP)                        /*       are */
3886         uptr->flags &= ~(UNIT_FP | UNIT_FFP);           /*         mutually exclusive */
3887 
3888     if (option == UNIT_FFP)                             /* the FFP option */
3889         uptr->flags |= UNIT_FP;                         /*   requires FP as well */
3890     }
3891 
3892 cpu_configuration = cpu_configuration & ~CPU_OPTION_MASK    /* update the CPU configuration */
3893                       | TO_CPU_OPTION (uptr->flags)         /*   with any revised option settings */
3894                       | CPU_BASE;                           /*     and the base set bit */
3895 
3896 if (option & UNIT_EMA_VMA)                              /* if EMA or VMA is being set */
3897     cpu_configuration &= ~UNIT_EMA_VMA;                 /*   then first remove both as they are mutually exclusive */
3898 
3899 cpu_configuration |= TO_CPU_OPTION (option);            /* include the new setting in the configuration */
3900 
3901 return SCPE_OK;
3902 }
3903 
3904 
3905 /* Clear a CPU option.
3906 
3907    This validation routine is called to remove an option from the current CPU
3908    configuration.  The "option" parameter is set to the unit flag corresponding
3909    to the option desired.  The "uptr" parameter points to the CPU unit and is
3910    used to obtain the CPU model.  The other parameters are not used.
3911 
3912    The routine processes commands of the form:
3913 
3914      SET CPU NO<option>[,NO<option>...]
3915 
3916    The option must be valid for the current CPU model, or the command will be
3917    rejected.
3918 */
3919 
clear_option(UNIT * uptr,int32 option,char * cptr,void * desc)3920 static t_stat clear_option (UNIT *uptr, int32 option, char *cptr, void *desc)
3921 {
3922 const uint32 model = UNIT_MODEL (uptr->flags);          /* the current CPU model index */
3923 
3924 if ((cpu_features [model].opt & option) == 0)           /* if the option is not available for the current CPU */
3925     return SCPE_NOFNC;                                  /*   then reject the request */
3926 
3927 uptr->flags &= ~option;                                 /* disable the option */
3928 
3929 if (option == UNIT_DMS)                                 /* if DMS instructions are being disabled */
3930     meu_configure (ME_Disabled);                        /*   then disable the MEM device */
3931 
3932 if (cpu_configuration & CPU_2100 && option == UNIT_FP)  /* if the FP option on a 2100 is being disabled */
3933     uptr->flags &= ~UNIT_FFP;                           /*   then disable the FFP as well */
3934 
3935 cpu_configuration = cpu_configuration & ~CPU_OPTION_MASK    /* update the CPU configuration */
3936                       | TO_CPU_OPTION (uptr->flags)         /*   with the revised option settings */
3937                       | CPU_BASE;                           /*     and the base set bit */
3938 
3939 return SCPE_OK;
3940 }
3941 
3942 
3943 /* Enable or disable the 21xx binary loader.
3944 
3945    The 21xx CPUs store their initial binary loaders in the last 64 words of
3946    available memory.  This memory is protected by a LOADER ENABLE switch on the
3947    front panel.  When the switch is off (disabled), main memory effectively ends
3948    64 locations earlier, i.e., the loader area is treated as non-existent.
3949    Because these are core machines, the loader is retained when system power is
3950    off.
3951 
3952    1000 CPUs do not have a protected loader feature.  Instead, loaders are
3953    stored in PROMs and are copied into main memory for execution by the IBL
3954    switch.
3955 
3956    Under simulation, we keep both a total configured memory size (mem_size) and
3957    a current configured memory size (mem_end = "first word address of
3958    non-existent memory").  When the two are equal, the loader is enabled.  When
3959    the current size is less than the total size, the loader is disabled.
3960 
3961    Disabling the loader copies the last 64 words to a shadow array, zeros the
3962    corresponding memory, and decreases the last word of addressable memory by
3963    64.  Enabling the loader reverses this process.
3964 
3965    Disabling may be done manually by user command or automatically when a halt
3966    instruction is executed.  Enabling occurs only by user command.  This differs
3967    slightly from actual machine operation, which additionally disables the
3968    loader when a manual halt is performed.  We do not do this to allow
3969    breakpoints within and single-stepping through the loaders.
3970 
3971 
3972    Implementation notes:
3973 
3974     1. In hardware, reads from non-existent memory return zero.  In simulation,
3975        the largest possible memory is instantiated and initialized to zero, so
3976        that reads need not be checked against memory size.  To preserve this
3977        model for the protected loader, we save and then zero the memory area
3978        when the loader is disabled.
3979 */
3980 
set_loader(UNIT * uptr,int32 enable,char * cptr,void * desc)3981 static t_stat set_loader (UNIT *uptr, int32 enable, char *cptr, void *desc)
3982 {
3983 static MEMORY_WORD loader [IBL_SIZE];                       /* the shadow memory for the currently disabled loader */
3984 const  t_bool currently_enabled = (mem_end == mem_size);    /* TRUE if the loader is currently enabled */
3985 
3986 if (cpu_configuration & CPU_1000)                       /* if the current CPU is a 1000-series */
3987     return SCPE_NOFNC;                                  /*   then the protected loader does not exist */
3988 
3989 if (currently_enabled && enable == 0) {                 /* if the enabled loader is being disabled */
3990     mem_end = mem_size - IBL_SIZE;                      /*   then decrease available memory */
3991     mem_copy_loader (loader, mem_end, From_Memory);     /*     and shadow the loader and zero memory */
3992     }
3993 
3994 else if (!currently_enabled && enable == 1) {           /* otherwise if the disabled loader is being enabled */
3995     mem_copy_loader (loader, mem_end, To_Memory);       /*   then copy the shadow loader to memory */
3996     mem_end = mem_size;                                 /*     and increase available memory */
3997     }
3998 
3999 return SCPE_OK;
4000 }
4001 
4002 
4003 /* Change the set of installed loader ROMs.
4004 
4005    This validation routine is called to install loader ROMs in the four
4006    available sockets of a 1000-series CPU.  The routine processes commands of
4007    the form:
4008 
4009      SET CPU ROMS=[<dev0>][;[<dev1>][;[<dev2>][;[<dev3>]]]]
4010 
4011    On entry, "cptr" points at the the first character of the ROM list.  The
4012    option value and the unit and description pointers are not used.
4013 
4014    All four ROM sockets are set for each command.  If no devices are specified,
4015    then all sockets are emptied.  Otherwise, specifying a valid device name
4016    installs the device loader ROM into the socket corresponding to the position
4017    of the device name in the list.  Sockets may be left empty by omitting the
4018    corresponding device name or by supplying fewer than four device names.
4019 
4020    Loader ROMs may only be altered if the current CPU model is a 1000-series
4021    machine, and a device must be bootable and have a loader ROM assigned, or the
4022    command will be rejected.  A rejected command does not alter any of the ROM
4023    assignments.
4024 
4025    Example commands and their effects on the installed ROM sockets follow:
4026 
4027      Command                Action
4028      ---------------------  -------------------------------------------------
4029      SET CPU ROMS=          Remove ROMs from sockets 0-3
4030      SET CPU ROMS=PTR       Install PTR in 0; leave 1-3 empty
4031      SET CPU ROMS=DS;MS     Install DS in 0 and MS in 1; leave 2 and 3 empty
4032      SET CPU ROMS=;;DPC     Install DPC in 2; leave 0, 1, and 3 empty
4033      SET CPU ROMS=DQC;;;DA  Install DQC in 0 and DA in 3; leave 1 and 2 empty
4034 
4035 
4036    Implementation notes:
4037 
4038     1. Entering "SET CPU ROMS" without an equals sign or list is rejected with a
4039        "Missing value" error.  This is to prevent accidental socket clearing
4040        when "SHOW CPU ROMS" was intended.
4041 */
4042 
set_roms(UNIT * uptr,int32 option,char * cptr,void * desc)4043 static t_stat set_roms (UNIT *uptr, int32 option, char *cptr, void *desc)
4044 {
4045 DEVICE *dptr;
4046 char   gbuf [CBUFSIZE];
4047 uint32 socket = 0;
4048 DEVICE *rom [4] = { NULL };
4049 
4050 if (!(cpu_configuration & CPU_1000))                    /* if the CPU is not a 1000-series unit */
4051     return SCPE_NOFNC;                                  /*   then reject the command */
4052 
4053 else if (cptr == NULL)                                  /* otherwise if the list is not specified */
4054     return SCPE_MISVAL;                                 /*   then report that the list is missing */
4055 
4056 else if (*cptr == '\0') {                               /* otherwise if the list is null */
4057     loader_rom [0] = NULL;                              /*   then empty */
4058     loader_rom [1] = NULL;                              /*     all of the */
4059     loader_rom [2] = NULL;                              /*       ROM sockets */
4060     loader_rom [3] = NULL;
4061     }
4062 
4063 else {                                                  /* otherwise */
4064     while (*cptr) {                                     /*   loop through the arguments */
4065         cptr = get_glyph (cptr, gbuf, ';');             /* get the next argument */
4066 
4067         if (socket == 4)                                /* if all four sockets have been set */
4068             return SCPE_2MARG;                          /*   then reject the command */
4069 
4070         else if (gbuf [0] == '\0')                      /* otherwise if the device name is omitted */
4071             rom [socket++] = NULL;                      /*   then empty the corresponding socket */
4072 
4073         else {                                          /* otherwise we have a device name */
4074             dptr = find_dev (gbuf);                     /*   so find the associated DEVICE pointer */
4075 
4076             if (dptr == NULL)                           /* if the device name is not valid */
4077                 return SCPE_NXDEV;                      /*   then reject the command */
4078 
4079             else if (dptr->boot == NULL)                /* otherwise if it's valid but not bootable */
4080                 return SCPE_NOFNC;                      /*   then reject the command */
4081 
4082             else                                        /* otherwise */
4083                 rom [socket++] = dptr;                  /*   install the boot loader ROM */
4084             }
4085         }
4086 
4087     loader_rom [0] = rom [0];                           /* install the ROM set */
4088     loader_rom [1] = rom [1];                           /*   now that we have */
4089     loader_rom [2] = rom [2];                           /*     a valid */
4090     loader_rom [3] = rom [3];                           /*       device list */
4091     }
4092 
4093 return SCPE_OK;                                         /* report that the command succeeded */
4094 }
4095 
4096 
4097 /* Change the instruction execution trace criteria.
4098 
4099    This validation routine is called to configure the criteria that select
4100    instruction execution tracing.  The "option" parameter is 0 to clear and 1 to
4101    set the criteria, and "cptr" points to the first character of the match value
4102    to be set.  The unit and description pointers are not used.
4103 
4104    The routine processes commands of the form:
4105 
4106      SET CPU EXEC=<match>[;<mask>]
4107      SET CPU NOEXEC
4108 
4109    If the <mask> value is not supplied, a mask of 177777 octal is used.  The
4110    values are entered in the current CPU data radix, which defaults to octal,
4111    unless an override switch is present on the command line.
4112 */
4113 
set_exec(UNIT * uptr,int32 option,char * cptr,void * desc)4114 static t_stat set_exec (UNIT *uptr, int32 option, char *cptr, void *desc)
4115 {
4116 char   gbuf [CBUFSIZE];
4117 uint32 match, mask, radix;
4118 t_stat status;
4119 
4120 if (option == 0)                                        /* if this is a NOEXEC request */
4121     if (cptr == NULL) {                                 /*   then if there are no arguments */
4122         exec_match = D16_UMAX;                          /*     then set the match and mask values */
4123         exec_mask  = 0;                                 /*       to prevent matching */
4124         return SCPE_OK;                                 /*         and return success */
4125         }
4126 
4127     else                                                /*   otherwise there are extraneous characters */
4128         return SCPE_2MARG;                              /*     so report that there are too many arguments */
4129 
4130 else if (cptr == NULL || *cptr == '\0')                 /* otherwise if the EXEC request supplies no arguments */
4131     return SCPE_MISVAL;                                 /*   then report a missing value */
4132 
4133 else {                                                  /* otherwise at least one argument is present */
4134     cptr = get_glyph (cptr, gbuf, ';');                 /*   so get the match argument */
4135 
4136     if (sim_switches & SWMASK ('O'))                    /* if an octal override is present */
4137         radix = 8;                                      /*   then parse the value in base 8 */
4138     else if (sim_switches & SWMASK ('D'))               /* otherwise if a decimal override is present */
4139         radix = 10;                                     /*   then parse the value in base 10 */
4140     else if (sim_switches & SWMASK ('H'))               /* otherwise if a hex override is present */
4141         radix = 16;                                     /*   then parse the value in base 16 */
4142     else                                                /* otherwise */
4143         radix = cpu_dev.dradix;                         /*   use the current CPU data radix */
4144 
4145     match = (uint32) get_uint (gbuf, radix, D16_UMAX, &status); /* parse the match value */
4146 
4147     if (status != SCPE_OK)                              /* if a parsing error occurred */
4148         return status;                                  /*   then return the error status */
4149 
4150     else if (*cptr == '\0') {                           /* otherwise if no more characters are present */
4151         exec_match = match;                             /*   then set the match value */
4152         exec_mask  = D16_MASK;                          /*     and default the mask value */
4153         return SCPE_OK;                                 /*       and return success */
4154         }
4155 
4156     else {                                              /* otherwise another argument is present */
4157         cptr = get_glyph (cptr, gbuf, ';');             /*   so get the mask argument */
4158 
4159         mask = (uint32) get_uint (gbuf, radix, D16_UMAX, &status);  /* parse the mask value */
4160 
4161         if (status != SCPE_OK)                          /* if a parsing error occurred */
4162             return status;                              /*   then return the error status */
4163 
4164         else if (*cptr == '\0')                         /* if no more characters are present */
4165             if (mask == 0)                              /*   then if the mask value is zero */
4166                 return SCPE_ARG;                        /*     then the match will never succeed */
4167 
4168             else {                                      /*   otherwise */
4169                 exec_match = match;                     /*     set the match value */
4170                 exec_mask  = mask;                      /*       and the mask value */
4171                 return SCPE_OK;                         /*         and return success */
4172                 }
4173 
4174         else                                            /* otherwise extraneous characters are present */
4175             return SCPE_2MARG;                          /*   so report that there are too many arguments */
4176         }
4177     }
4178 }
4179 
4180 
4181 /* Show the CPU simulation stop conditions.
4182 
4183    This display routine is called to show the set of CPU stop conditions or the
4184    indirect chain length limit.  The "st" parameter is the open output stream,
4185    and "val" is 1 to show the stops and 2 to show the indirect limit.  The other
4186    parameters are not used.
4187 
4188    To show stops, the routine searches through the stop table for status
4189    variables that are set to values other than SCPE_OK.  For each one it finds,
4190    the routine prints the corresponding stop name.  If none are found, it
4191    reports that all stops are disabled.
4192 
4193    This routine services an extended modifier entry, so it must add the trailing
4194    newline to the output before returning.
4195 */
4196 
show_stops(FILE * st,UNIT * uptr,int32 val,void * desc)4197 static t_stat show_stops (FILE *st, UNIT *uptr, int32 val, void *desc)
4198 {
4199 uint32 stop;
4200 t_bool need_spacer = FALSE;
4201 
4202 if (val == 2)                                           /* if the indirect limit is requested */
4203     fprintf (st, "Limit=%d\n", indirect_limit);         /*   then show it */
4204 
4205 else {                                                      /* otherwise show the enabled stops */
4206     for (stop = 0; cpu_stop [stop].name != NULL; stop++)    /* loop through the set of stops in the table */
4207         if (*cpu_stop [stop].status != SCPE_OK) {           /* if the current stop is enabled */
4208             if (need_spacer)                                /*   then if a spacer is needed */
4209                 fputc (';', st);                            /*     then add it first */
4210             else                                            /* otherwise this is the first one reported */
4211                 fputs ("Stop=", st);                        /*   so print the report label */
4212 
4213             fputs (cpu_stop [stop].name, st);               /* report the stop name */
4214 
4215             need_spacer = TRUE;                             /* a spacer will be needed next time */
4216             }
4217 
4218     if (need_spacer)                                    /* if at least one simulation stop was enabled */
4219         fputc ('\n', st);                               /*   then add the required trailing newline */
4220     else                                                /* otherwise no enabled stops were found */
4221         fputs ("Stops disabled\n", st);                 /*   so report that all are disabled */
4222     }
4223 
4224 return SCPE_OK;                                         /* report the success of the display */
4225 }
4226 
4227 
4228 /* Display the CPU model and optional loader status.
4229 
4230    Loader status is displayed for 21xx models and suppressed for 1000 models.
4231 */
4232 
show_model(FILE * st,UNIT * uptr,int32 val,void * desc)4233 static t_stat show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
4234 {
4235 fputs ((const char *) desc, st);                        /* output the CPU model name */
4236 
4237 if (!(cpu_configuration & CPU_1000))                    /* if the CPU is a 2100 or 21xx */
4238     if (mem_end < mem_size)                             /*   then if the loader area is non-existent */
4239         fputs (", loader disabled", st);                /*     then report that the loader is disabled */
4240     else                                                /*   otherwise */
4241         fputs (", loader enabled", st);                 /*     report that it is enabled */
4242 
4243 return SCPE_OK;
4244 }
4245 
4246 
4247 /* Show the set of installed loader ROMs.
4248 
4249    This display routine is called to show the set of installed loader ROMs in
4250    the four available sockets of a 1000-series CPU.  On entry, the "st"
4251    parameter is the open output stream.  The other parameters are not used.
4252 
4253    The routine prints a table of ROMs in this format:
4254 
4255      Socket  Device  ROM Description
4256      ------  ------  -----------------------------------------
4257        0      PTR    12992K Paper Tape Loader
4258        1      DA     12992H 7906H/7920H/7925H/9895 Disc Loader
4259        2      MSC    12992D 7970 Magnetic Tape Loader
4260        3     (none)  (empty socket)
4261 
4262    If a given socket contains a ROM, the associated device name, HP part number,
4263    and description of the loader ROM are printed.  Loader ROMs may be displayed
4264    only if the current CPU model is a 1000-series machine; if it is not, the
4265    command will be rejected.
4266 
4267    This routine services an extended modifier entry, so it must add the trailing
4268    newline to the output before returning.
4269 
4270 
4271    Implementation notes:
4272 
4273     1. SCP does not honor the status return from display routines, so we must
4274        explicitly print the rejection error message if the routine is called for
4275        a non-1000 CPU.
4276 
4277     2. sim_dname is called instead of using dptr->name directly to ensure that
4278        we pick up assigned logical device names.
4279 */
4280 
show_roms(FILE * st,UNIT * uptr,int32 val,void * desc)4281 static t_stat show_roms (FILE *st, UNIT *uptr, int32 val, void *desc)
4282 {
4283 const char *cname, *dname;
4284 DIB    *dibptr;
4285 uint32 socket;
4286 
4287 if (!(cpu_configuration & CPU_1000)) {                  /* if the CPU is not a 1000-series unit */
4288     fputs (sim_error_text (SCPE_NOFNC), st);            /*   then print the rejection message */
4289     fputc ('\n', st);                                   /*     and add a line feed */
4290 
4291     return SCPE_NOFNC;                                  /* reject the command */
4292     }
4293 
4294 fputc ('\n', st);                                           /* skip a line */
4295 fputs ("Socket  Device  ROM Description\n", st);            /*   and print */
4296 fputs ("------  ------  "                                   /*     the table header */
4297        "-----------------------------------------\n", st);
4298 
4299 for (socket = 0; socket < 4; socket++)                      /* loop through the sockets */
4300     if (loader_rom [socket] == NULL)                        /* if the socket is empty */
4301         fprintf (st, "  %u     (none)  (empty socket)\n",   /*   then report it as such */
4302                  socket);
4303 
4304     else {                                              /* otherwise the socket is occupied */
4305         dname = sim_dname (loader_rom [socket]);        /*   so get the device name */
4306         dibptr = (DIB *) loader_rom [socket]->ctxt;     /*     and a pointer to that device's DIB */
4307         cname = dibptr->rom_description;                /*       to get the ROM description */
4308 
4309         if (cname == NULL)                              /* if there is no description */
4310             cname = "";                                 /*   then use a null string */
4311 
4312         fprintf (st, "  %u      %-4s   %s\n",           /* print the ROM information */
4313                  socket, dname, cname);
4314         }
4315 
4316 return SCPE_OK;                                         /* return success status */
4317 }
4318 
4319 
4320 /* Show the currently configured I/O card cage.
4321 
4322    This display routine is called to show the set of interfaces installed in the
4323    I/O card cage.  On entry, the "st" parameter is the open output stream.  The
4324    other parameters are not used.
4325 
4326    The routine prints the installed I/O cards in this format:
4327 
4328      SC  Device  Interface Description
4329      --  ------  ---------------------------------------------------------------
4330      10   PTR    12597A-002 Tape Reader Interface
4331      11   TTY    12531C Buffered Teleprinter Interface
4332      12   PTP    12597A-005 Tape Punch Interface
4333      13   TBG    12539C Time Base Generator Interface
4334      14  (none)  12777A Priority Jumper Card
4335      15   LPT    12845B Line Printer Interface
4336      [...]
4337 
4338    If a given I/O slot contains an interface card, the associated device name,
4339    HP part number, and description of the interface are printed.  If the slot is
4340    empty, it is displayed as though a 12777A Priority Jumper Card is installed.
4341    The list terminates with the last occupied I/O slot.
4342 
4343    If select code conflicts exist, the invalid assignments are printed before
4344    the interface list, and the corresponding entries in the list are flagged.
4345    For example:
4346 
4347      Select code 13 conflict (TBG and LPS)
4348 
4349      SC  Device  Interface Description
4350      --  ------  ------------------------------------------------------------------
4351      10   PTR    12597A-002 Tape Reader Interface
4352      11   TTY    12531C Buffered Teleprinter Interface
4353      12   PTP    12597A-005 Tape Punch Interface
4354      13   ---    (multiple assignments)
4355      14  (none)  12777A Priority Jumper Card
4356      15   LPT    12845B Line Printer Interface
4357      [...]
4358 
4359    This routine services an extended modifier entry, so it must add the trailing
4360    newline to the output before returning.
4361 */
4362 
show_cage(FILE * st,UNIT * uptr,int32 val,void * desc)4363 static t_stat show_cage (FILE *st, UNIT *uptr, int32 val, void *desc)
4364 {
4365 const char *cname, *dname;
4366 uint32 sc, last_sc;
4367 
4368 fputc ('\n', st);                                       /* skip a line */
4369 
4370 if (initialize_io (FALSE) == FALSE)                     /* set up the I/O tables; if a conflict was reported */
4371     fputc ('\n', st);                                   /*   then separate it from the interface list */
4372 
4373 fputs ("SC  Device  Interface Description\n", st);      /* print */
4374 fputs ("--  ------  "                                   /*   the table header */
4375        "------------------------------------------------------------------\n", st);
4376 
4377 for (last_sc = SC_MAX; last_sc > SC_VAR; last_sc--)     /* find the last occupied I/O slot */
4378     if (iot [last_sc].devptr != NULL                    /*   with an assigned device */
4379       && !(iot [last_sc].devptr->flags & DEV_DIS))      /*     that is currently enabled */
4380         break;
4381 
4382 for (sc = SC_VAR; sc <= last_sc; sc++)                                      /* loop through the select codes */
4383     if (iot [sc].devptr == NULL || iot [sc].devptr->flags & DEV_DIS)        /* if the slot is unassigned or disabled */
4384         fprintf (st, "%02o  (none)  12777A Priority Jumper Card\n", sc);    /*   then report a jumper card */
4385 
4386     else if (iot [sc].references > 1)                               /* otherwise if a conflict exists */
4387         fprintf (st, "%02o   ---    (multiple assignments)\n", sc); /*   then report the multiple assignment */
4388 
4389     else {                                              /* otherwise the slot is valid */
4390         dname = sim_dname (iot [sc].devptr);            /*   so get the device name */
4391         cname = iot [sc].dibptr->card_description;      /*     and interface card description */
4392 
4393         if (cname == NULL)                              /* if there is no description */
4394             cname = "";                                 /*   then use a null string */
4395 
4396         fprintf (st, "%02o   %-4s   %s\n", sc, dname, cname);   /* report the interface in the slot */
4397         }
4398 
4399 return SCPE_OK;                                         /* return success status */
4400 }
4401 
4402 
4403 /* Show the instruction execution trace criteria.
4404 
4405    This display routine is called to show the criteria that select instruction
4406    execution tracing.  The "st" parameter is the open output stream.  The other
4407    parameters are not used.
4408 
4409    This routine services an extended modifier entry, so it must add the trailing
4410    newline to the output before returning.
4411 */
4412 
show_exec(FILE * st,UNIT * uptr,int32 val,void * desc)4413 static t_stat show_exec (FILE *st, UNIT *uptr, int32 val, void *desc)
4414 {
4415 uint32 radix;
4416 
4417 if (exec_mask == 0)                                     /* if the instruction is entirely masked */
4418     fputs ("Execution trace disabled\n", st);           /*   then report that matching is disabled */
4419 
4420 else {                                                  /* otherwise */
4421     if (sim_switches & SWMASK ('O'))                    /*   if an octal override is present */
4422         radix = 8;                                      /*     then print the value in base 8 */
4423     else if (sim_switches & SWMASK ('D'))               /*   otherwise if a decimal override is present */
4424         radix = 10;                                     /*     then print the value in base 10 */
4425     else if (sim_switches & SWMASK ('H'))               /*   otherwise if a hex override is present */
4426         radix = 16;                                     /*     then print the value in base 16 */
4427     else                                                /*   otherwise */
4428         radix = cpu_dev.dradix;                         /*     use the current CPU data radix */
4429 
4430     fputs ("Execution trace match = ", st);                         /* print the label */
4431     fprint_val (st, exec_match, radix, cpu_dev.dwidth, PV_RZRO);    /*   and the match value */
4432 
4433     fputs (", mask = ", st);                                        /* print a separator */
4434     fprint_val (st, exec_mask, radix, cpu_dev.dwidth, PV_RZRO);     /*   and the mask value */
4435 
4436     fputc ('\n', st);                                               /* tie off the line */
4437     }
4438 
4439 return SCPE_OK;                                         /* report the success of the display */
4440 }
4441 
4442 
4443 /* Show the current CPU simulation speed.
4444 
4445    This display routine is called to show the current simulation speed.  The
4446    "st" parameter is the open output stream.  The other parameters are not used.
4447 
4448    The CPU speed, expressed as a multiple of the hardware speed, is calculated
4449    by the console poll service routine.  It is only representative when the CPU
4450    is not idling.
4451 */
4452 
show_speed(FILE * st,UNIT * uptr,int32 val,void * desc)4453 static t_stat show_speed (FILE *st, UNIT *uptr, int32 val, void *desc)
4454 {
4455 fprintf (st, "Simulation speed = %ux\n", cpu_speed);    /* display the current CPU speed */
4456 return SCPE_OK;                                         /*   and report success */
4457 }
4458 
4459 
4460 
4461 /* CPU local utility routine declarations */
4462 
4463 
4464 /* Execute one machine instruction.
4465 
4466    This routine executes the CPU instruction present in the IR.  The CPU state
4467    (registers, memory, interrupt status) is modified as necessary, and the
4468    routine return SCPE_OK if the instruction executed successfully.  Any other
4469    status indicates that execution should cease, and control should return to
4470    the simulator console.  For example, a programmed HALT instruction returns
4471    STOP_HALT status.
4472 
4473    This routine implements the main instruction dispatcher.  Instructions
4474    corresponding to the MRG, SRG, and ASG are executed inline.  IOG, EAG, and
4475    UIG instructions are executed by external handlers.
4476 
4477    The JMP instruction executor handles CPU idling.  The 21xx/1000 CPUs have no
4478    "wait for interrupt" instruction.  Idling in HP operating systems consists of
4479    sitting in "idle loops" that end with JMP instructions.  We test for certain
4480    known patterns when a JMP instruction is executed to decide if the simulator
4481    should idle.
4482 
4483    Idling must not occur if an interrupt is pending.  As mentioned before, the
4484    CPU will defer pending interrupts when certain instructions are executed.  OS
4485    interrupt handlers exit via such deferring instructions.  If there is a
4486    pending interrupt when the OS is otherwise idle, the idle loop will execute
4487    one instruction before reentering the interrupt handler.  If we call
4488    sim_idle() in this case, we will lose interrupts.
4489 
4490    Consider the situation in RTE.  Under simulation, the TTY and TBG events are
4491    co-scheduled, so their event routines are called sequentially during a single
4492    "sim_process_event" call.  If the TTY has received an input character from
4493    the console poll, then both devices are ready to interrupt.  Assume that the
4494    TTY has priority.  When the TTY interrupts, $CIC in RTE is entered.  The TBG
4495    interrupt is held off through the JSB $CIC,I / JMP $CIC0,I / SFS 0,C
4496    instruction entry sequence, which defers interrupts until the interrupt
4497    system is turned off.  When $CIC returns via $IRT, one instruction of the
4498    idle loop is executed, even though the TBG interrupt is still pending,
4499    because the UJP instruction used to return also defers interrupts.
4500 
4501    If "sim_idle" is called at this point, the simulator will sleep when it
4502    should be handling the pending TBG interrupt.  When it awakes, TTY expiration
4503    will be moved forward to the next instruction.  The still-pending TBG
4504    interrupt will then be recognized, and $CIC will be entered.  But the TTY and
4505    TBG will then expire and attempt to interrupt again, although they are
4506    deferred by the $CIC entry sequence.  This causes the second TBG interrupt to
4507    be missed, as processing of the first one is just now being started.
4508 
4509    Similarly, at the end of the TBG handling, the TTY interrupt is still
4510    pending.  When $IRT returns to the idle loop, "sim_idle" would be called
4511    again, so the TTY and then TBG interrupt a third time.  Because the second
4512    TTY interrupt is still pending, $CIC is entered, but the third TTY interrupt
4513    is lost.
4514 
4515    We solve this problem by testing for a pending interrupt before calling
4516    "sim_idle".  The system isn't really quiescent if it is just about to handle
4517    an interrupt.
4518 
4519 
4520    Implementation notes:
4521 
4522     1. Instruction decoding is based on the HP 1000, which does a 256-way branch
4523        on the upper eight bits of the instruction, as follows:
4524 
4525          15 14 13 12 11 10  9  8  Instruction Group
4526          -- -- -- -- -- -- -- --  -------------------------------------------
4527           x  n  n  n  x  x  x  x  Memory Reference (n n n not equal to 0 0 0)
4528           0  0  0  0  x  0  x  x  Shift-Rotate
4529           0  0  0  0  x  1  x  x  Alter-Skip
4530           1  0  0  0  x  1  x  x  I/O
4531           1  0  0  0  0  0  x  0  Extended Arithmetic
4532           1  0  0  0  0  0  0  1  divide (decoded as 100400)
4533           1  0  0  0  1  0  0  0  double load (decoded as 104000)
4534           1  0  0  0  1  0  0  1  double store (decoded as 104400)
4535           1  0  0  0  1  0  1  0  Extended Instruction 0 (A/B is set)
4536           1  0  0  0  x  0  1  1  Extended Instruction 1 (A/B is ignored)
4537 
4538     2. JSB is tricky.  It is possible to generate both an MP and a DM violation
4539        simultaneously, as the MP and MEM cards validate in parallel.  Consider a
4540        JSB to a location under the MP fence and on a write-protected page.  This
4541        situation must be reported as a DM violation, because it has priority
4542        (SFS 5 and SFC 5 check only the MEVFF, which sets independently of the MP
4543        fence violation).  Under simulation, this means that DM violations must
4544        be checked, and the MEVFF must be set, before an MP abort is taken.  This
4545        is done by the "mp_check_jmp" routine.
4546 
4547     3. Although MR (and TR) will be changed by reads of an indirect chain, the
4548        idle loop JMP will be direct, and so MR will contain the correct value
4549        for the "idle loop omitted" trace message.
4550 
4551     4. The Alter-Skip Group RSS micro-op reverses the skip sense of the SEZ,
4552        SSA/SSB, SLA/SLB, and SZA/SZB micro-op tests.  Normally, the instruction
4553        skips if any test is true.  However, the specific combination of SSA/SSB,
4554        SLA/SLB, and RSS micro-ops causes a skip if BOTH of the skip cases are
4555        true, i.e., if both the MSB and LSB of the register value are ones.  We
4556        handle this as a special case, because without RSS, the instruction skips
4557        if EITHER the MSB or LSB is zero.  The other reversed skip cases (SEZ,RSS
4558        and SZA,RSS/SZB,RSS) are independent.
4559 */
4560 
machine_instruction(t_bool int_ack,uint32 * idle_save)4561 static t_stat machine_instruction (t_bool int_ack, uint32 *idle_save)
4562 {
4563 uint32  ab_selector, result, skip;
4564 HP_WORD data;
4565 t_bool  rss;
4566 t_stat  status = SCPE_OK;
4567 
4568 switch (UPPER_BYTE (IR)) {                              /* dispatch on bits 15-8 of the instruction */
4569 
4570 /* Memory Reference Group */
4571 
4572     case 0020: case 0021: case 0022: case 0023:         /* AND */
4573     case 0024: case 0025: case 0026: case 0027:
4574     case 0220: case 0221: case 0222: case 0223:         /* AND,I */
4575     case 0224: case 0225: case 0226: case 0227:
4576         status = mrg_address ();                        /* get the memory reference address */
4577 
4578         if (status == SCPE_OK)                          /* if the address resolved */
4579             AR = AR & ReadW (MR);                       /*   then AND the accumulator and memory */
4580         break;
4581 
4582 
4583     case 0230: case 0231: case 0232: case 0233:         /* JSB,I */
4584     case 0234: case 0235: case 0236: case 0237:
4585         cpu_interrupt_enable = CLEAR;                   /* defer interrupts */
4586 
4587     /* fall through into the JSB case */
4588 
4589     case 0030: case 0031: case 0032: case 0033:         /* JSB */
4590     case 0034: case 0035: case 0036: case 0037:
4591         status = mrg_address ();                        /* get the memory reference address */
4592 
4593         if (status == SCPE_OK) {                        /* if the address resolved */
4594             mp_check_jsb (MR);                          /*   then validate the jump address */
4595 
4596             WriteW (MR, PR);                            /* store P into the target memory address */
4597 
4598             PCQ_ENTRY;                                  /* save P in the queue */
4599             PR = MR + 1 & LA_MASK;                      /*   and jump to the word after the target address */
4600             }
4601         break;
4602 
4603 
4604     case 0040: case 0041: case 0042: case 0043:         /* XOR */
4605     case 0044: case 0045: case 0046: case 0047:
4606     case 0240: case 0241: case 0242: case 0243:         /* XOR,I */
4607     case 0244: case 0245: case 0246: case 0247:
4608         status = mrg_address ();                        /* get the memory reference address */
4609 
4610         if (status == SCPE_OK)                          /* if the address resolved */
4611             AR = AR ^ ReadW (MR);                       /*   then XOR the accumulator and memory */
4612         break;
4613 
4614 
4615     case 0250: case 0251: case 0252: case 0253:         /* JMP,I */
4616     case 0254: case 0255: case 0256: case 0257:
4617         cpu_interrupt_enable = CLEAR;                   /* defer interrupts */
4618 
4619     /* fall through into the JMP case */
4620 
4621     case 0050: case 0051: case 0052: case 0053:         /* JMP */
4622     case 0054: case 0055: case 0056: case 0057:
4623         status = mrg_address ();                        /* get the memory reference address */
4624 
4625         if (status != SCPE_OK)                          /* if the address failed to resolve */
4626             break;                                      /*   then abort execution */
4627 
4628         mp_check_jmp (MR, 0);                           /* validate the jump address */
4629 
4630         if (sim_idle_enab && interrupt_request == 0     /* if idle is enabled and no interrupt is pending */
4631           && mem_is_idle_loop ()) {                     /*   and execution is in the DOS or RTE idle loop */
4632             tprintf (cpu_dev, cpu_dev.dctrl,
4633                      DMS_FORMAT "idle loop execution omitted\n",
4634                      meu_indicator, meu_page, MR, IR);
4635 
4636             if (cpu_dev.dctrl != 0) {                   /*     then if tracing is enabled */
4637                 *idle_save = cpu_dev.dctrl;             /*       then save the current trace flag set */
4638                 cpu_dev.dctrl = 0;                      /*         and turn off tracing for the idle loop */
4639                 }
4640 
4641             sim_idle (TMR_POLL, FALSE);                 /* idle the simulator */
4642             }
4643 
4644         PCQ_ENTRY;                                      /* save P in the queue */
4645         PR = MR;                                        /*   and jump to the target address */
4646         break;
4647 
4648 
4649     case 0060: case 0061: case 0062: case 0063:         /* IOR */
4650     case 0064: case 0065: case 0066: case 0067:
4651     case 0260: case 0261: case 0262: case 0263:         /* IOR,I */
4652     case 0264: case 0265: case 0266: case 0267:
4653         status = mrg_address ();                        /* get the memory reference address */
4654 
4655         if (status == SCPE_OK)                          /* if the address resolved */
4656             AR = AR | ReadW (MR);                       /*   then OR the accumulator and memory */
4657         break;
4658 
4659 
4660     case 0070: case 0071: case 0072: case 0073:         /* ISZ */
4661     case 0074: case 0075: case 0076: case 0077:
4662     case 0270: case 0271: case 0272: case 0273:         /* ISZ,I */
4663     case 0274: case 0275: case 0276: case 0277:
4664         status = mrg_address ();                        /* get the memory reference address */
4665 
4666         if (status == SCPE_OK) {                        /* if the address resolved */
4667             data = ReadW (MR) + 1 & D16_MASK;           /*   then increment the memory word */
4668             WriteW (MR, data);                          /*     and write it back */
4669 
4670             if (data == 0)                              /* if the value rolled over to zero */
4671                 PR = PR + 1 & LA_MASK;                  /*   then increment P */
4672             }
4673         break;
4674 
4675 
4676     case 0100: case 0101: case 0102: case 0103:         /* ADA */
4677     case 0104: case 0105: case 0106: case 0107:
4678     case 0300: case 0301: case 0302: case 0303:         /* ADA,I */
4679     case 0304: case 0305: case 0306: case 0307:
4680         status = mrg_address ();                        /* get the memory reference address */
4681 
4682         if (status == SCPE_OK) {                        /* if the address resolved */
4683             data = ReadW (MR);                          /*   then get the target word */
4684             result = AR + data;                         /*     and add the accumulator to memory */
4685 
4686             if (result > D16_UMAX)                      /* if the result overflowed */
4687                 E = 1;                                  /*   then set the Extend register */
4688 
4689             if (~(AR ^ data) & (AR ^ result) & D16_SIGN)    /* if the sign of the result differs from the signs */
4690                 O = 1;                                      /*   of the operands, then set the Overflow register */
4691 
4692             AR = result & R_MASK;                       /* store the sum into the accumulator */
4693             }
4694         break;
4695 
4696 
4697     case 0110: case 0111: case 0112: case 0113:         /* ADB */
4698     case 0114: case 0115: case 0116: case 0117:
4699     case 0310: case 0311: case 0312: case 0313:         /* ADB,I */
4700     case 0314: case 0315: case 0316: case 0317:
4701         status = mrg_address ();                        /* get the memory reference address */
4702 
4703         if (status == SCPE_OK) {                        /* if the address resolved */
4704             data = ReadW (MR);                          /*   then get the target word */
4705             result = BR + data;                         /*     and add the accumulator to memory */
4706 
4707             if (result > D16_UMAX)                      /* if the result overflowed */
4708                 E = 1;                                  /*   then set the Extend register */
4709 
4710             if (~(BR ^ data) & (BR ^ result) & D16_SIGN)    /* if the sign of the result differs from the signs */
4711                 O = 1;                                      /*   of the operands, then set the Overflow register */
4712 
4713             BR = result & R_MASK;                       /* store the sum into the accumulator */
4714             }
4715         break;
4716 
4717 
4718     case 0120: case 0121: case 0122: case 0123:         /* CPA */
4719     case 0124: case 0125: case 0126: case 0127:
4720     case 0320: case 0321: case 0322: case 0323:         /* CPA,I */
4721     case 0324: case 0325: case 0326: case 0327:
4722         status = mrg_address ();                        /* get the memory reference address */
4723 
4724         if (status == SCPE_OK)                          /* if the address resolved */
4725             if (AR != ReadW (MR))                       /*   then if the accumulator and memory differ */
4726                 PR = PR + 1 & LA_MASK;                  /*     then increment P */
4727         break;
4728 
4729 
4730     case 0130: case 0131: case 0132: case 0133:         /* CPB */
4731     case 0134: case 0135: case 0136: case 0137:
4732     case 0330: case 0331: case 0332: case 0333:         /* CPB,I */
4733     case 0334: case 0335: case 0336: case 0337:
4734         status = mrg_address ();                        /* get the memory reference address */
4735 
4736         if (status == SCPE_OK)                          /* if the address resolved */
4737             if (BR != ReadW (MR))                       /*   then if the accumulator and memory differ */
4738                 PR = PR + 1 & LA_MASK;                  /*     then increment P */
4739         break;
4740 
4741 
4742     case 0140: case 0141: case 0142: case 0143:         /* LDA */
4743     case 0144: case 0145: case 0146: case 0147:
4744     case 0340: case 0341: case 0342: case 0343:         /* LDA,I */
4745     case 0344: case 0345: case 0346: case 0347:
4746         status = mrg_address ();                        /* get the memory reference address */
4747 
4748         if (status == SCPE_OK)                          /* if the address resolved */
4749             AR = ReadW (MR);                            /*   then load the accumulator from memory */
4750         break;
4751 
4752 
4753     case 0150: case 0151: case 0152: case 0153:         /* LDB */
4754     case 0154: case 0155: case 0156: case 0157:
4755     case 0350: case 0351: case 0352: case 0353:         /* LDB,I */
4756     case 0354: case 0355: case 0356: case 0357:
4757         status = mrg_address ();                        /* get the memory reference address */
4758 
4759         if (status == SCPE_OK)                          /* if the address resolved */
4760             BR = ReadW (MR);                            /*   then load the accumulator from memory */
4761         break;
4762 
4763 
4764     case 0160: case 0161: case 0162: case 0163:         /* STA */
4765     case 0164: case 0165: case 0166: case 0167:
4766     case 0360: case 0361: case 0362: case 0363:         /* STA,I */
4767     case 0364: case 0365: case 0366: case 0367:
4768         status = mrg_address ();                        /* get the memory reference address */
4769 
4770         if (status == SCPE_OK)                          /* if the address resolved */
4771             WriteW (MR, AR);                            /*   then write the accumulator to memory */
4772         break;
4773 
4774 
4775     case 0170: case 0171: case 0172: case 0173:         /* STB */
4776     case 0174: case 0175: case 0176: case 0177:
4777     case 0370: case 0371: case 0372: case 0373:         /* STB,I */
4778     case 0374: case 0375: case 0376: case 0377:
4779         status = mrg_address ();                        /* get the memory reference address */
4780 
4781         if (status == SCPE_OK)                          /* if the address resolved */
4782             WriteW (MR, BR);                            /*   then write the accumulator to memory */
4783         break;
4784 
4785 
4786 /* Alter/Skip Group */
4787 
4788     case 0004: case 0005: case 0006: case 0007:         /* ASG */
4789     case 0014: case 0015: case 0016: case 0017:
4790         skip = 0;                                       /* assume that no skip is needed */
4791 
4792         rss = (IR & IR_RSS) != 0;                       /* get the Reverse Skip Sense flag */
4793 
4794         ab_selector = AB_SELECT (IR);                   /* get the A/B register selector */
4795         data = ABREG [ab_selector];                     /*   and the register data */
4796 
4797         if (IR & IR_CLx)                                /* if the CLA/CLB micro-op is enabled */
4798             data = 0;                                   /*   then clear the value */
4799 
4800         if (IR & IR_CMx)                                /* if the CMA/CMB micro-op is enabled */
4801             data = data ^ D16_MASK;                     /*   then complement the value */
4802 
4803         if (IR & IR_SEZ && (E == 0) ^ rss)              /* if SEZ[,RSS] is enabled and E is clear [set] */
4804             skip = 1;                                   /*   then skip the next instruction */
4805 
4806         if (IR & IR_CLE)                                /* if the CLE micro-op is enabled */
4807             E = 0;                                      /*   then clear E */
4808 
4809         if (IR & IR_CME)                                /* if the CME micro-op is enabled */
4810             E = E ^ LSB;                                /*   then complement E */
4811 
4812         if ((IR & IR_SSx_SLx_RSS) == IR_SSx_SLx_RSS) {  /* if the SSx, SLx, and RSS micro-ops are enabled together */
4813             if ((data & D16_SIGN_LSB) == D16_SIGN_LSB)  /*   then if both sign and least-significant bits are set */
4814                 skip = 1;                               /*     then skip the next instruction */
4815             }
4816 
4817         else {                                              /* otherwise */
4818             if (IR & IR_SSx && !(data & D16_SIGN) ^ rss)    /*   if SSx[,RSS] is enabled and the MSB is clear [set] */
4819                 skip = 1;                                   /*     then skip the next instruction */
4820 
4821             if (IR & IR_SLx && !(data & LSB) ^ rss)     /*   if SLx[,RSS] is enabled and the LSB is clear [set] */
4822                 skip = 1;                               /*     then skip the next instruction */
4823             }
4824 
4825         if (IR & IR_INx) {                              /* if the INA/INB micro-op is enabled */
4826             data = data + 1 & D16_MASK;                 /*   then increment the value */
4827 
4828             if (data == 0)                              /* if the value wrapped around to zero */
4829                 E = 1;                                  /*   then set the Extend register */
4830 
4831             else if (data == D16_SIGN)                  /* otherwise if the value overflowed into the sign bit */
4832                 O = 1;                                  /*   then set the Overflow register */
4833             }
4834 
4835         if (IR & IR_SZx && (data == 0) ^ rss)           /* if SZx[,RSS] is enabled and the value is zero [non-zero] */
4836             skip = 1;                                   /*   then skip the next instruction */
4837 
4838         if ((IR & IR_ALL_SKIPS) == IR_RSS)              /* if RSS is present without any other skip micro-ops */
4839             skip = 1;                                   /*   then skip the next instruction unconditionally */
4840 
4841         ABREG [ab_selector] = data;                     /* store the result in the selected register */
4842         PR = PR + skip & LA_MASK;                       /*   and skip the next instruction if indicated */
4843         break;
4844 
4845 
4846 /* Shift/Rotate Group */
4847 
4848     case 0000: case 0001: case 0002: case 0003:         /* SRG */
4849     case 0010: case 0011: case 0012: case 0013:
4850         ab_selector = AB_SELECT (IR);                   /* get the A/B register selector */
4851         data = ABREG [ab_selector];                     /*   and the register data */
4852 
4853         data = srg_uop (data, SRG1 (IR));               /* do the first shift */
4854 
4855         if (IR & SRG_CLE)                               /* if the CLE micro-op is enabled */
4856             E = 0;                                      /*   then clear E */
4857 
4858         if (IR & SRG_SLx && (data & LSB) == 0)          /* if SLx is enabled and the LSB is clear */
4859             PR = PR + 1 & LA_MASK;                      /*   then skip the next instruction */
4860 
4861         ABREG [ab_selector] = srg_uop (data, SRG2 (IR));    /* do the second shift and set the accumulator */
4862         break;
4863 
4864 
4865 /* I/O Group */
4866 
4867     case 0204: case 0205: case 0206: case 0207:         /* IOG */
4868     case 0214: case 0215: case 0216: case 0217:
4869         status = cpu_iog (IR);                          /* execute the I/O instruction */
4870         break;
4871 
4872 
4873 /* Extended Arithmetic Group */
4874 
4875     case 0200:                                          /* EAU group 0 */
4876     case 0201:                                          /* DIV */
4877     case 0202:                                          /* EAU group 2 */
4878     case 0210:                                          /* DLD */
4879     case 0211:                                          /* DST */
4880         status = cpu_eau ();                            /* execute the extended arithmetic instruction */
4881         break;
4882 
4883 
4884 /* User Instruction Group */
4885 
4886     case 0212:                                              /* UIG 0 */
4887         status = cpu_uig_0 (interrupt_request, int_ack);    /* execute the user instruction opcode */
4888         break;
4889 
4890 
4891     case 0203:
4892     case 0213:                                          /* UIG 1 */
4893         status = cpu_uig_1 (interrupt_request);         /* execute the user instruction opcode */
4894         break;
4895     }                                                   /* all cases are handled */
4896 
4897 
4898 return status;                                          /* return the execution status */
4899 }
4900 
4901 
4902 /* Get the effective address from an MRG instruction.
4903 
4904    Memory references are contained in bits 15, 10, and 9-0 of instructions in
4905    the Memory Reference Group.  Bits 9-0 specify one of 1024 locations within
4906    either the base page (if bit 10 is 0) or the current page (if bit 10 is 1).
4907    If bit 15 is 0, the address is direct.  If bit 15 is 1, then the address is
4908    indirect and specifies the location containing the target address.  That
4909    address itself may be direct or indirect as indicated by bit 15, with bits
4910    14-0 specifying a location within the 32K logical address space.
4911 
4912    On entry, the instruction register (IR) contains the MRG instruction to
4913    resolve, and the memory address register (MR) contains the address of the
4914    instruction.  This routine examines the instruction; if the address is
4915    direct, then the full 15-bit address is returned in the MR register.
4916    Otherwise, the indirect chain is followed until the address is direct, a
4917    pending interrupt is recognized, or the length of the indirect address chain
4918    exceeds the allowable limit.  The resulting direct address is returned in
4919    the MR register.
4920 */
4921 
mrg_address(void)4922 static t_stat mrg_address (void)
4923 {
4924 if (IR & IR_CP)                                         /* if the instruction specifies the current page */
4925     MR = IR & (IR_IND | IR_OFFSET) | MR & MR_PAGE;      /*   then merge the current page and the instruction offset */
4926 else                                                    /* otherwise */
4927     MR = IR & (IR_IND | IR_OFFSET);                     /*   the offset is on the base page */
4928 
4929 if (MR & IR_IND)                                        /* if the address is indirect */
4930     return cpu_resolve_indirects (TRUE);                /*   then resolve it to a direct address with interruptibility */
4931 else                                                    /* otherwise */
4932     return SCPE_OK;                                     /*   the address in MR is already direct */
4933 }
4934 
4935 
4936 /* Execute a Shift-Rotate Group micro-operation.
4937 
4938    SRG instructions consist of two shift/rotate micro-operations plus a CLE and
4939    a SLA/SLB micro-op.  This routine implements the shift and rotate operation.
4940 
4941    Each of the two shift-rotate operations has an enable bit that must be set to
4942    enable the operation.  If the bit is not set, the operation is a NOP, with
4943    the exception that an ELA/ELB or ERA/ERB operation alters the E register (but
4944    not the A/B register).  We accommodate this by including the enable/disable
4945    bit with the three-bit operation code and decode the disabled operations of
4946    ELA/ELB and ERA/ERB separately from their enabled operations.
4947 
4948    On entry, "value" is the value of the selected accumulator (A/B), and
4949    "operation" is the micro-op and enable bit.  The routine returns the updated
4950    accumulator value and modifies the E register as indicated.
4951 
4952 
4953    Implementation notes:
4954 
4955     1. The enable bit is located adjacent to the three-bit encoded operation for
4956        the first shift-rotate micro-op, but it is spaced one bit away from the
4957        encoded operation for the second micro-op.  It is faster to decode
4958        separate values for each location rather than move the second enable bit
4959        adjacent to its encoded operation.  The former imposes no time penalty;
4960        the jump table for the "switch" statement is simply somewhat larger.
4961 */
4962 
srg_uop(HP_WORD value,HP_WORD operation)4963 static HP_WORD srg_uop (HP_WORD value, HP_WORD operation)
4964 {
4965 uint32 extend;
4966 
4967 switch (operation) {                                        /* dispatch on the micro operation */
4968 
4969     case SRG1_EN | IR_xLS:
4970     case SRG2_EN | IR_xLS:                                  /* ALS/BLS */
4971         return value & D16_SIGN | value << 1 & D16_SMAX;    /* arithmetic left shift */
4972 
4973 
4974     case SRG1_EN | IR_xRS:
4975     case SRG2_EN | IR_xRS:                                  /* ARS/BRS */
4976         return value & D16_SIGN | value >> 1;               /* arithmetic right shift */
4977 
4978 
4979     case SRG1_EN | IR_RxL:
4980     case SRG2_EN | IR_RxL:                                  /* RAL/RBL */
4981         return (value << 1 | value >> 15) & D16_MASK;       /* rotate left */
4982 
4983 
4984     case SRG1_EN | IR_RxR:
4985     case SRG2_EN | IR_RxR:                                  /* RAR/RBR */
4986         return (value >> 1 | value << 15) & D16_MASK;       /* rotate right */
4987 
4988 
4989     case SRG1_EN | IR_xLR:
4990     case SRG2_EN | IR_xLR:                                  /* ALR/BLR */
4991         return value << 1 & D16_SMAX;                       /* arithmetic left shift, clear sign */
4992 
4993 
4994     case SRG_DIS | IR_ERx:                                  /* disabled ERA/ERB */
4995         E = value & LSB;                                    /* rotate the LSB right into E */
4996         return value;                                       /*   and return the original value */
4997 
4998 
4999     case SRG1_EN | IR_ERx:
5000     case SRG2_EN | IR_ERx:                                  /* ERA/ERB */
5001         extend = E;                                         /* save the original E value */
5002         E = value & LSB;                                    /* rotate the LSB right into E */
5003         return value >> 1 | (HP_WORD) extend << 15;         /*   and rotate right with E filling the MSB */
5004 
5005 
5006     case SRG_DIS | IR_ELx:                                  /* disabled ELA/ELB */
5007         E = value >> 15 & LSB;                              /* rotate the MSB left into E */
5008         return value;                                       /*   and return the original value */
5009 
5010 
5011     case SRG1_EN | IR_ELx:
5012     case SRG2_EN | IR_ELx:                                  /* ELA/ELB */
5013         extend = E;                                         /* save the original E value */
5014         E = value >> 15 & LSB;                              /* rotate the MSB left into E */
5015         return (value << 1 | (HP_WORD) extend) & D16_MASK;  /*   and rotate left with E filling the LSB */
5016 
5017 
5018     case SRG1_EN | IR_xLF:
5019     case SRG2_EN | IR_xLF:                                  /* ALF/BLF */
5020         return (value << 4 | value >> 12) & D16_MASK;       /* rotate left four */
5021 
5022 
5023     default:                                                /* all other (disabled) cases */
5024         return value;                                       /*   return the original value */
5025     }
5026 }
5027 
5028 
5029 /* Reenable interrupt recognition.
5030 
5031    Certain instructions clear the "cpu_interrupt_enable" flag to defer
5032    recognition of pending interrupts until the succeeding instruction completes.
5033    However, the interrupt deferral rules differ for the 21xx vs. the 1000.
5034 
5035    The 1000 always defers until the completion of the instruction following the
5036    deferring instruction.  The 21xx defers unless the following instruction is
5037    an MRG instruction other than JMP or JMP,I or JSB,I.  If it is, then the
5038    deferral is inhibited, i.e., the pending interrupt will be recognized.
5039 
5040    In either case, if the interrupting device is the memory protect card, or if
5041    the INT jumper is out on the 12892B MP card, then a pending interrupt is
5042    always recognized, regardless of the "cpu_interrupt_enable" flag setting.
5043 
5044    See the "Set Phase Logic Flowchart" for the transition from phase 1A to phase
5045    1B, and "Section III Theory of Operation," "Control Section Detailed Theory"
5046    division, "Phase Control Logic" subsection, "Phase 1B" paragraph (3-241) in
5047    the Model 2100A Computer Installation and Maintenance Manual for details.
5048 */
5049 
reenable_interrupts(void)5050 static t_bool reenable_interrupts (void)
5051 {
5052 HP_WORD next_instruction;
5053 
5054 if (!(cpu_configuration & CPU_1000)) {                  /* if the CPU is a 21xx model */
5055     next_instruction = mem_fast_read (PR, Current_Map); /*   then prefetch the next instruction */
5056 
5057     if (MRGOP (next_instruction)                        /* if it is an MRG instruction */
5058       && (next_instruction & IR_MRG_I) != IR_JSB_I      /*   but not JSB,I */
5059       && (next_instruction & IR_MRG)   != IR_JMP)       /*   and not JMP or JMP,I */
5060         return TRUE;                                    /*     then reenable interrupts */
5061     }
5062 
5063 if (interrupt_request == MPPE || mp_reenable_interrupts ()) /* if MP is interrupting or the INT jumper is out */
5064     return TRUE;                                            /*   then reenable interrupts */
5065 else                                                        /* otherwise */
5066     return FALSE;                                           /*   interrupts remain disabled */
5067 }
5068 
5069 
5070 
5071 /* I/O subsystem local utility routine declarations */
5072 
5073 
5074 /* Initialize the I/O system.
5075 
5076    This routine is called in the instruction prelude to set up the I/O access
5077    table prior to beginning execution.  The table is indexed by select code, and
5078    each entry records pointers to the device and DIB structures associated with
5079    that select code.  This allows fast access to the device trace flags and to
5080    the device interface routine by the I/O instruction executors, respectively.
5081 
5082    As part of the device scan, the sizes of the largest device name and active
5083    trace flag name among the devices enabled for tracing are accumulated for use
5084    in aligning the trace statements.
5085 
5086    The "is_executing" parameter indicates whether or not initialization is being
5087    performed from the instruction execution prelude.  If it is, the routine also
5088    sets the priority holdoff and interrupt request bit vectors by asserting the
5089    SIR signal to each enabled device interface routine.  Sending SIR to all
5090    devices will set the "interrupt_request" variable if an interrupt is pending,
5091    so no explicit poll is needed after initialization.
5092 
5093    After initializing the I/O access table, a check is made for device
5094    conflicts.  These occur if two or more devices are assigned to the same
5095    select code.
5096 
5097    Each select code must be unique among the enabled devices.  This requirement
5098    is checked as part of the instruction execution prelude; this allows the user
5099    to exchange two select codes simply by setting each device to the other's
5100    select code.  If conflicts were enforced instead at the time the codes were
5101    entered, the first device would have to be set to an unused select code
5102    before the second could be set to the first device's code.
5103 
5104    If any conflicts exist, the device table is scanned to find the DIBs whose
5105    select codes match the conflicting values, and the device names associated
5106    with the conflicts are printed.
5107 
5108    This routine returns the success or failure of I/O initialization; failure
5109    is reported if any select code conflicts exist.
5110 
5111 
5112    Implementation notes:
5113 
5114     1. If this routine is called from the instruction prelude, the console and
5115        optional log file have already been put into "raw" output mode.
5116        Therefore, newlines are not translated to the correct line ends on
5117        systems that require it.  Before reporting a conflict, "sim_ttcmd" is
5118        called to restore the console and log file translation.  This is OK
5119        because a conflict will abort the run and return to the command line
5120        anyway.
5121 
5122     2. sim_dname is called instead of using dptr->name directly to ensure that
5123        we pick up an assigned logical device name.
5124 
5125     3. Only the names of active trace (debug) options are accumulated to produce
5126        the most compact trace log.  However, if the CPU device's EXEC option is
5127        enabled, then all of the CPU option names are accumulated, as EXEC
5128        enables all trace options for a given instruction or instruction class.
5129 */
5130 
initialize_io(t_bool is_executing)5131 static t_bool initialize_io (t_bool is_executing)
5132 {
5133 DEVICE       *dptr;
5134 DIB          *dibptr;
5135 const DEBTAB *tptr;
5136 uint32       dev, sc, count;
5137 size_t       device_length, flag_length, device_size, flag_size;
5138 t_bool       is_conflict = FALSE;
5139 
5140 interrupt_request_set [0] = interrupt_request_set [1] = 0;  /* clear all interrupt requests */
5141 priority_holdoff_set  [0] = priority_holdoff_set  [1] = 0;  /* clear all priority inhibits */
5142 
5143 device_size = 0;                                        /* reset the device and flag name sizes */
5144 flag_size = 0;                                          /*   to those of the devices actively tracing */
5145 
5146 memset (&iot [2], 0, sizeof iot - 2 * sizeof iot [0]);  /* clear the I/O pointer table */
5147 
5148 for (dev = 0; sim_devices [dev] != NULL; dev++) {       /* loop through all of the devices */
5149     dptr = sim_devices [dev];                           /* get a pointer to the device */
5150     dibptr = (DIB *) dptr->ctxt;                        /*   and to that device's DIB */
5151 
5152     if (dibptr != NULL && !(dptr->flags & DEV_DIS)) {   /* if the DIB exists and the device is enabled */
5153         sc = dibptr->select_code;
5154         iot [sc].devptr = dptr;                         /*   then set the device pointer into the device table */
5155         iot [sc].dibptr = dibptr;                       /*     and set the DIB pointer into the dispatch table */
5156 
5157         if (sc >= SC_VAR && ++iot [sc].references > 1)  /* increment the count of references; if more than one */
5158             is_conflict = TRUE;                         /*   then a conflict occurs */
5159 
5160         if (is_executing)                               /* if the CPU is executing instructions */
5161             io_assert (dptr, ioa_SIR);                  /*   then set the interrupt request state */
5162         }
5163 
5164     if (sim_deb && dptr->dctrl) {                       /* if tracing is active for this device */
5165         device_length = strlen (sim_dname (dptr));      /*   then get the length of the device name */
5166 
5167         if (device_length > device_size)                /* if it's greater than the current maximum */
5168             device_size = device_length;                /*   then reset the size */
5169 
5170         if (dptr->debflags)                             /* if the device has a trace flags table */
5171             for (tptr = dptr->debflags;                 /*   then scan the table */
5172                  tptr->name != NULL; tptr++)
5173                 if (dev == 0 && dptr->dctrl & TRACE_EXEC    /* if the CPU device is tracing executions */
5174                   || tptr->mask & dptr->dctrl) {            /*   or this trace option is active */
5175                     flag_length = strlen (tptr->name);      /*     then get the flag name length */
5176 
5177                     if (flag_length > flag_size)            /* if it's greater than the current maximum */
5178                         flag_size = flag_length;            /*   then reset the size */
5179                     }
5180         }
5181     }
5182 
5183 
5184 if (is_conflict) {                                      /* if a conflict exists */
5185     if (is_executing)                                   /*   then if execution has started */
5186         sim_ttcmd ();                                   /*     then restore the console and log I/O mode */
5187 
5188     for (sc = 0; sc <= SC_MAX; sc++)                    /* search the conflict table for the next conflict */
5189         if (iot [sc].references > 1) {                  /* if a conflict is present for this value */
5190             count = iot [sc].references;                /*   then get the number of conflicting devices */
5191 
5192             cprintf ("Select code %o conflict (", sc);  /* report the multiply-assigned select code */
5193 
5194             for (dev = 0; sim_devices [dev] != NULL; dev++) {   /* loop through all of the devices */
5195                 dptr = sim_devices [dev];                       /* get a pointer to the device */
5196                 dibptr = (DIB *) dptr->ctxt;                    /*   and to that device's DIB */
5197 
5198                 if (dibptr != NULL && !(dptr->flags & DEV_DIS)  /* if the DIB exists and the device is enabled */
5199                   && dibptr->select_code == sc) {               /*   to find the conflicting entries */
5200                     if (count < iot [sc].references)            /*     and report them to the console */
5201                         cputs (" and ");
5202 
5203                     cputs (sim_dname (dptr));           /* report the conflicting device name */
5204                     count = count - 1;                  /*   and drop the count of remaining conflicts */
5205 
5206                     if (count == 0)                     /* if all devices have been reported */
5207                         break;                          /*   then there's no need to look farther */
5208                     }
5209                 }                                       /* loop until all conflicting devices are reported */
5210 
5211             cputs (")\n");                              /* tie off the line */
5212             }                                           /*   and continue to look for other conflicting select codes */
5213 
5214     return FALSE;                                       /* report that initialization has failed */
5215     }
5216 
5217 else {                                                  /* otherwise no conflicts were found */
5218     iot [PWR].devptr = &cpu_dev;                        /* for now, powerfail is always present */
5219     iot [PWR].dibptr = &pwrf_dib;                       /*   and is controlled by the CPU */
5220 
5221     if (iot [DMA1].devptr) {                            /* if the first DMA channel is enabled */
5222         iot [DMALT1] = iot [DMA1];                      /*   then set up  */
5223         iot [DMALT1].dibptr++;                          /*     the secondary device handler */
5224         }
5225 
5226     if (iot [DMA2].devptr) {                            /* if the second DMA channel is enabled */
5227         iot [DMALT2] = iot [DMA2];                      /*   then set up  */
5228         iot [DMALT2].dibptr++;                          /*     the secondary device handler */
5229         }
5230 
5231     hp_initialize_trace (device_size, flag_size);       /* initialize the trace routine */
5232     return TRUE;                                        /*   and report that initialization has succeeded */
5233     }
5234 }
5235