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