HP 3000 Simulation Notes ======================== The minimum set of files necessary for a simulation framework are: - hp3000_defs.h : architectural definitions - hp3000_cpu.h : CPU definitions - hp3000_sys.c : SCP interface - hp3000_cpu.c : CPU simulator - hp3000_cpu_base.c : base set instruction simulator - hp3000_iop.c : IOP simulator A minimum functioning simulator requires the following VM support routines: - simulator name string char sim_name []; - array of pointers to simulated devices DEVICE *sim_devices []; - pointer to saved PC register descriptor REG *sim_PC; - array of pointers to stop messages const char *sim_stop_messages []; - instruction execution routine t_stat sim_instr (void); - binary loader routine t_stat sim_load (FILE *ptr, char *cptr, char *fnam, int32 flag); - maximum number of words in an instruction int32 sim_emax; - print symbolic output t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val, UNIT *uptr, int32 sw); - parse symbolic input t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw); The sim_instr routine is called to run the simulation. To enable the user to stop the simulation, the console must be polled for entry of the stop character (CTRL+E). Normally, this is done as part of the input poll for the console device (typically a teletype simulation). However, in the absence of all I/O devices in this initial version, the console keyboard must be polled explicitly. The input poll time is usually established by a calibrated timer and is typically set to 10 milliseconds. If a calibrated timer is not available, a default poll time of 10,000 machine instructions is used. In this initial version, a dummy CPU service routine is used to call the SCP routine sim_poll_kbd every 10,000 instructions. ======================== Initial Things Not Clear ======================== - How does pipeline interact with microcode? For example, if Q in STORE field in current microinstruction, does Q in SBUS field of next microinstruction get the previous Q value or the newly stored Q value? Ditto for memory reads; BUS in current microinstruction and OPND in next sometime seems to get value just read and sometimes the value of a PRIOR memory read! For example, BUS at 2705 starts read of M [PL - STT], but OPND at 2706 gets M [PL] from BUS at 3105. - In what state does system power-up? How is restore from power-fail differentiated from initial power-up? Is there an MLOST equivalent? (Pre-Series-II CE handbook page CPU-8 says interrupt #1 is power fail and interrupt #2 is power on.) If memory array powers up randomly, then ECC bits will be wrong, and any memory read will indicate ECC error. Seems as though each memory location must be written once before ECC is valid. Cold load does fill memory with HALTs, so maybe that serves as initializer. But power-on microcode (PWR at 2742 via address 1) reads ZI and then [ZI+1] from memory before deciding whether or not to halt (saved CPX2 value). Unless those values are valid AND have bit 15 = 0, it appears that the CPU heads off into the weeds! Some circuitry on MCL PCA (30007-60005 sheet 2, bottom-right corner) is sensitive to PON and +5BATT state, but I don't see what it does. - Does COLD LOAD end with a (microcode) halt or with immediate execution of the cold-load interrupt service routine? If a halt, what is the CIR value? SRM 6-17 says, "The status register is set to 100001 (octal) to indicate privileged mode and code segment 1. Then the CPU halts." But I can't find in the microcode where the CPU halts. For CPU diag, S/III CE handbook page 1-30 says, "LOAD, tape movement, RUN, pause, RUN, RUN, test runs" (first RUN implies a halt after tape movement is complete). Page 5-1 of the Series III Installation Manual (30000-90147, July 1980) says to cold load the system, "Enter %3006 in the System Switch Register (on the CPU bay). Press ENABLE and LOAD. Wait for the RUN light to go out, and the motion of the tape to stop. Press RUN on the CPU panel, then Carriage Return on the system console." All of these halts could be in the code that was loaded, of course. - Is it necessary to model the TOS registers? Programs use the logical stack pointer S, but the hardware uses the memory stack pointer SM plus the register stack counter SR and stack registers RA-RD. Bounds checking is performed on SM, rather than S, so a violation will not necessarily occur when S exceeds DB or Z. The diagnostic surely will test for this; does MPE depend on it as well? - If an SIO instruction is followed immediately by a HALT, won't the I/O program continue to execute, even though the machine is halted? Do we have to duplicate this? Or can we "halt" the channel and resume once simulation is continued? =========================== System Information Required =========================== Hardware PCAs and Manuals ------------------------- * = have > = need - 30003A CPU * 30000-90023 HP 3000 Series II Microprogram Manual - 30003B CPU * 30000-90018 System Service Manual * 30000-90020 HP 3000 Series II/III System Reference Manual * 30000-90022 Machine Instruction Set Reference Manual - 30000-90076 3000 Series II Computer System Engineering Diagram Set * 30000-90141 HP 3000 Series III Engineering Diagrams Set * 30000-90143 HP 3000 Series III Reference/Training Manual > 30000-90136 Series III Microprogram Listing Manual > 30000-90139 Series III System Block Diagram or 30000-90058 Series II System Block Diagram - 30008A 32K Word ECC RAM (S-II) or 30008B 128K Word ECC RAM (S-III) - 30135A System Clock/Fault Logging Interface - 30135-60063 System Clock/FLI PCA - 30032B Asynchronous Terminal Controller with 1-16 Serial Terminals - 30032-60001 Terminal Data Interface - 30061-60001 Terminal Control Interface - system console occupies ATC port 0 * 30032-90004 ATC Installation and Service Manual - 30229A Disc Controller Interface with 1-8 7920/25A disc drives (30129A Subsystem) - 13037-60001 Microprocessor - 13037-60024 ROM/ECC - 13037-60028 Device controller - 30229-60001 Disc Interface * 30129-90003 30129A Cartridge Disc (7905A) Subsystem Installation and Service - 30215A Magnetic Tape Controller Interface with 1-4 7970B/E tape drives (30115A Subsystem) - 30215-60002 tape processor PCA - 30215-60006 tape controller PCA * 30115-90001 30115A Magnetic Tape Subsystem Maintenance Manual - 30209A Line Printer Interface with 2607A/13A/17A/18A Line Printer (30118A Subsystem) - 30051-60001 Universal Interface (Differential) * 30051-90001 Universal Interface (Differential) Maintenance Manual > 30209-90006 HP2607, HP2613, HP2617, HP2618 Line Printers Installation and Service Manual > 30209-90008 Line Printer Operating and Programming Manual - 30204A Paper Tape Reader Interface with 2748B Paper Tape Reader (30104A Subsystem) - 30050-60001 Universal Interface (TTL) > 30050-90001 Universal Interface (TTL) Maintenance Manual > 30104-90001 30104A Tape Reader (2748B) Subsystem Maintenance Manual [al has!] - 30205A Paper Tape Punch Interface with 2895A Paper Tape Punch (30105A Subsystem) - 30050-60001 Universal Interface (TTL) > 30050-90001 Universal Interface (TTL) Maintenance Manual > 30105-90001 30105A Paper Tape Punch (2895B) Subsystem Maintenance Manual - 32234A COBOL II Firmware - 32234-90001 3000 Series COBOL II Installation Guide - HP-IB Systems - 30070-90006 HP 3000 Series 33 Microcode Manual * 30070-90010 HP 3000 HP-IB Version Computer Systems CE Handbook * 30090-90001 Series 40/44 Reference/Training Manual - 30090-90002 Series 44 Installation Manual - 30090-90003 Series 44 System Block Diagram - 30090-90004 Series 40/44 Microcode Listing - 30090-90009 Series 44 Engineering Diagram Set * 30090-90034 HP 3000 Series 39/40/42/44/48 Computer Systems Engineering Diagrams Set * 30140-90004 Series 64/68 A/B System Block Diagrams and Assembly Drawings Manual * 30140-90005 Series 64 Reference/Training Manual * 30140-90006 Series 64/68 CE Handbook * 30140-90045 Series 64/68/70 Computer Systems Microcode Manual * 30140-90046 HP 3000 Series 64/68 A/B Computer Systems Engineering Diagrams Set - ATP - 30144-90002 Advanced Terminal Processor (DSN/ATP) Installation Manual - 30144-90003 Advanced Terminal Processor (DSN/ATP) Off-line (diag manual?) - 30144-90004 Advanced Terminal Processor (DSN/ATP) On-line (diag manual?) Software and Manuals -------------------- * = have > = need MPE Operating System: * 32002-11018 MPE V/R FOS tape image (SIO) Diagnostics: - Diagnostics source tape is 32230-1x001 * 30000-1x016 CPU cold load diagnostic tape ("CPU064" and "CPU1KS3") * D420A Series II/III CPU Diagnostic (14 sections) * D420 30003-90001 Stand-Alone HP 30003A/B CPU Diagnostic * 30000-1x017 non-CPU cold load diagnostic tape ("DIAGIOTP") * D419A 7905A Disc Cartridge Diagnostic * D419A 30129-90007 Stand-Alone HP 30129A (7905A) Disc Cartridge Diagnostic * D421A Series II Memory Pattern Diagnostic > D421 03000-90028 Memory Pattern Test Diagnostic [Series II] * D422A Multiplexer Channel Diagnostic * D422A 30036-90001 Stand-Alone HP 30036A/B Multiplexer Channel Diagnostic * D426A System Clock/FLI Diagnostic * D426A 32230-90005 Stand-Alone System Clock Diagnostic * D427A Terminal Data Interface Diagnostic * D427A 30032-90011 Stand-Alone HP 30032B Terminal Data Interface Diagnostic * D429A Selector Channel Diagnostic * D429A 30030-90011 Stand-Alone HP 30030B/C Selector Channel Diagnostic * D430A Memory Diagnostic [ECC/FLI] * D430A 30008-90001 Stand-Alone HP 30008A/30009A Error Correction Memory Diagnostic * D430B 30000-90004 Stand-Alone Memory Diagnostic * D431A Extended Instruction Set Diagnostic * D431 30012-90001 Stand-Alone HP 30012A Extended Instruction Set Diagnostic * D433A 7970B/E Magnetic Tape Diagnostic * D433 30115-90014 Stand-Alone HP 30115A (7970B/E) Magnetic Tape (NRZI-PE) Diagnostic * D435A Universal Interface Diagnostic * D435A 30050-90012 Stand-Alone HP 30050A/51A Universal IF and HP 30219A Card Reader Punch IF Diagnostic * D438A Terminal Control Interface Diagnostic * D438A 30061-90004 Stand-Alone HP 30061A Terminal Control Interface Diagnostic Other Diagnostics Manuals: - Manuals set is 32230-60001 and 32230-60002 * 03000-90123 D411A Stand-Alone SLEUTH Diagnostic * 30102-90015 D423 Stand-Alone HP 30102A (2888A) Disc File Diagnostic * 30110-90012 D424A Stand-Alone HP 30110A (7900A) Cartridge Disc Diagnostic * 30031-90008 D425A Stand-Alone HP 30031A System Clock/Console Diagnostic * 30103-90015 D428A Stand-Alone HP 30103A (2660A) Fixed Head Disc Diagnostic * 30360-90007 D432 HP 30360A Hardwired Serial Interface Stand-Alone Diagnostic Program * 30055-90008 D434A Stand-Alone HP 30055A Synchronous Line Contoller Diagnostic D434B 30055A ASYNCHRONOUS SINGLE LINE CONTROLLER TEST (HP D434B.01.02) D436A HIGH-SPEED UNIVERSAL INTERFACE TEST * 30226-90009 D439 Stand-Alone HP 30226A Plotter Interface Diagnostic > 32234-90002 D441A COBOL-IIA FIRMWARE DIAGNOSTIC (D441A.00.00) > 32234-90002 D442A COBOL-IIB FIRMWARE DIAGNOSTIC (D442A.00.00) * 30209-90007 D466 Verification Program Manual [Line Printers] - The multiplexer channel diagnostic requires a 30033A Selector Channel Maintenance PCA - diag tests parity errors, state values; no doc for state values - mpx card responds to CIO, TIO, RIO, and WIO; documented in mpx diag manual - SCMP responds to SIN, RIN, SIO, CIO, TIO, RIO, and WIO; CIO, TIO documented in mpx diag manual; others may have normal device meaning A list of the stand-alone diagnostics is on page 5-2 of the Series III Installation Manual. Internals Information --------------------- MPE Disc Cache: In Perspective HP 3000 IUG Proceedings, October 1983 pages 1012-1029 Architectural Changes for MPE V HP 3000 IUG Proceedings, October 1983 pages 1030-1054 MPE V: Product Overview, Project Development Strategy, and Implementation Methodology HP 3000 IUG Proceedings, October 1983 pages 1062-1071 =============== System Overview =============== SIMH for the HP 3000 simulates this set of minimum hardware: - 30003B S-III CPU/IOP + 128K, 256K, 384K, 512K, 768K, or 1024K words of memory - 30012A Extended Instruction Set (standard on S-II/III) - 30030C Selector channel - 30033A Selector Channel Maintenance Board - 30036B Multiplexer channel - 30135A System Clock/Fault Logging Interface - 30032B Asynchronous Terminal Controller + 1-16 terminals - 30215A Tape controller + 1-4 7970B/E drives (30115A Magnetic Tape Subsystem) - 30229A Disc controller + 1-8 7920/25 drives (30129A Cartridge Disc Subsystem) The following additional simulations are desirable: - 30209A Line Printer controller + 2607/2613/17/18 line printer The HP 3000 Series III simulation consists of the following devices: - CPU (central processing unit) - IOP (I/O processor) - MPX (multiplexer channel) - SEL (selector channel) - SCMB (selector channel maintenance board) - ATCD (async terminal controller data) - ATCC (async terminal controller control) - CLK (system clock) - LP (line printer) - DS (disc controller) - MS (mag tape controller) ? FLI (fault logic interface) The instruction loop interleaves CPU instruction, selector channel, and multiplexer channel execution. The selector and multiplexer channels are driven by service requests; if none are pending, the channels are quiescent. The usual instruction loop is complicated by the requirement that the selector or multiplexer channel operates while the CPU is halted. This is to support the cold load and dump routines. Cold load requires the channel to drive the selected device and terminate with an external interrupt that places the CPU into run mode. So the loop must be able to run I/O but not the CPU while halted. The Series II and III place the system console on port 0 of the first ATC multiplexer. So there is no "TTY" device connected to the SIMH console as is usual. This has two implications: 1. A dummy device is needed to poll the SIMH console keyboard for CTRL+E. 2. Console scripting will not work (e.g., for diagnostics). The latter is a significant drawback. So an alternative is to code the ATC to do port 0 I/O through the SIMH console instead of through a Telnet port (Telnet still can be used for the system console with the SET CONSOLE TELNET= command). Note that the IBM 7094 COM device simulator does this by special-casing one port of the multiplexer. =========================== Simulator Development Order =========================== 1. Cold-load the stand-alone CPU diagnostics tape. - SCP framework - CPU registers and instruction loop - memory - IOP - external interrupts - multiplexer channel - 7970 tape controller Read/FSR/FSF/Rewind - cold-load microcode - symbolic examine 2. Develop the CPU simulator. - instruction executors - microcode aborts (longjmp vs. status return) - debug tracing provides "logic analyzer" report 3. Run the CPU diagnostics successfully. - CPU instructions - bounds checking - internal interrupts and traps - symbolic deposit 4. Develop the 7970 simulator. - SIO and PAUS instructions - test via SIO and debug printouts - external interrupt causes sim stop for examination - rework 1000 MS as MX with tapelib; get it to pass the 1000 diag 5. Develop the system clock simulator. - CIO, TIO, RIO, WIO instructions (single-step) - clock is used by mag tape and ATC diagnostics - needs a DIAG mode that counts instructions instead of wall time to support correct peripheral diagnostics timing 6. Develop the ATC simulator. - CIO, TIO, RIO, WIO instructions (single-step) - ATC port 0 is used by the diagnostics - diags use speed-sense via diagnostic channels - leverage 1000 MUX (control/status almost identical) 7. Load and run the peripheral diagnostics successfully. - system clock - ATC - 7970 8. Develop the selector channel and 7905 simulator. - SIO and PAUS instructions - test via SIO and debug printouts - external interrupt causes sim stop for examination 9. Develop the SCMB simulator. 10. Load and run the peripheral diagnostics successfully. - SIMB - selector channel - multiplexer channel - 7905 disc controller 11. Load and run MPE. - extended instruction set - 2607 line printer controller ----------------------------------- Series III Module Development Order ----------------------------------- Milestones: - 2012-12-11 Project started - 2015-04-01 First successful run of MPE-V/R through account login - 2016-03-07 First public release Created Pass Diag Module --------- --------- ----------------- 11-Dec-12 hp3000_cpu.c 11-Dec-12 hp3000_cpu_base.c 11-Dec-12 hp3000_iop.c 11-Dec-12 hp3000_sys.c 10-Feb-13 11-Sep-14 hp3000_mpx.c 10-Feb-13 26-Oct-14 hp3000_ms.c 10-Feb-13 27-Jan-15 hp3000_sel.c 24-Mar-13 hp_tapelib.c 05-Jul-14 12-Aug-14 hp3000_clk.c 28-Jul-14 31-Jul-15 hp3000_atc.c 07-Jan-15 12-Jan-15 hp3000_scmb.c 15-Feb-15 15-Jun-15 hp3000_ds.c 21-Feb-15 hp_disclib.c 29-Mar-15 01-Apr-15 hp3000_cpu_fp.c 24-Mar-16 27-Apr-16 hp3000_lp.c 21-Sep-16 19-Oct-16 hp3000_cpu_cis.c 10-Oct-16 hp3000_mem.c ==================== Required VM Routines ==================== SCP declares these routines external and call them for various reasons. A VM (back end) must provide these. - sim_load() LOAD/DUMP command Implement as a memory image load/store to aid early debugging. Eventually will become cold load/cold dump. - sim_vm_cmd [] LOAD command (overrides the standard LOAD command) Simulates the front panel LOAD + ENABLE switches. An optional octal value may be supplied. If supplied, the value is stored in the switch register before cold loading. If not supplied, the value of the SWCH register is used. An invalid or not-ready device (IOP timeout) results in a system halt. Cold load completes with the system running; the first instruction is the interrupt handler associated with the load DRT (Series II). BOOT CPU is equivalent to LOAD, i.e., the current value of the SWCH register is used. BOOT MS, BOOT DS, etc. load SWCH with the correct value to cold load the mag tape, disc, etc. (Adding a COLDLOAD command would mean that entering "C" for CONTINUE wouldn't work, as VM-defined commands are searched before SCP-defined commands.) - sim_vm_cmd [] DUMP command (overrides the standard DUMP command) Simulates the front panel DUMP + ENABLE switches. An optional octal value may be supplied. If supplied, the value is stored in the switch register before cold dumping. If not supplied, the value of the DUMPNO and DUMPCTL device values are stored in the switch register and then used. An invalid or not-ready device (IOP timeout) results in a system halt. Cold dump completes with simulation stop and CIR = count of 64K memory banks (256K = 4, 320K = 5, ..., 1024K = 16). (Adding a COLDDUMP command would mean that entering "C" for CONTINUE wouldn't work.) - sim_vm_cmd [] GO and RUN commands The GO and RUN commands clear the CPU pause state, whereas CONTINUE and STEP do not. To detect this, we provide our own routines that clears the pause state before calling the SCP-provided run_cmd() routine. - fprint_sym() and parse_sym() The 3000 has no assembler. However, the SPL compiler does provide an ASSEMBLE statement, so the syntax of that is the closest thing to official assembler documentation. The accepted machine language mnemonics and operand syntax are documented in the SPL manual (30000-90024 December 1976). - REG_VMIO for CIR, NIR, and STA Adding REG_VMIO to a register causes "ex_reg" to call "fprint_sym" in lieu of or before calling "fprint_val" to print the register value, and it causes "dep_reg" to call "parse_sym" in lieu of or before calling "get_uint" to parse the register value. In both cases, SIM_SW_REG is included in the "switch" parameter, and the register's display radix is passed in the "addr" parameter. No register identification is passed, and the radix cannot be used as a code to indicate the register, because it's also used to parse the value in the ASSERT command. Basically, this flag only allows VM-defined switches to affect the value. Adding the flag to CIR and NIR means that they can be examined with the "-m" switch to print their values as instruction mnemonics, although the default remains to print them in octal. Adding the flag to STA means that it can be examined with the "-s" switch to display , though again the default remains octal. It would be nice for these registers if the default were the mnemonic forms, but there appears to be no way to specify this. [ NOTE: Enhancement 252 adds register-specific defaults to REG_VMIO. ] - REG_VMAD Adding REG_VMAD to a register causes "ex_reg" to call "sim_vm_fprint_addr" (if defined) in lieu of "fprint_sym" or "fprint_val" to print the register value, and it causes "dep_reg" to call "sim_vm_parse_addr" (if defined) in lieu of calling "parse_sym" or "get_uint" to parse the register value. - "sim_vm_fprint_addr" and "sim_vm_parse_addr" If defined, "sim_vm_fprint_addr" is called to print the address and REG_VMAD register values for the [I]EXAMINE command, the program counter address for a simulation stop, and the address for the SHOW BREAKPOINT command. If defined, "sim_vm_parse_addr" is called to parse the address ranges for the [I]EXAMINE, [I]DEPOSIT, and BREAK commands, the REG_VMAD register value for the [I]DEPOSIT command, and the program counter addresses for the RUN and GO commands. =========================== Device External Definitions =========================== CPU --- Registers: - CIR 16 Current Instruction Register (REG_HRO) - NIR 16 Next Instruction Register (REG_HRO) - PB 16 Program Base - P 16 Program Counter - PL 16 Program Limit - PBANK 4 Program Segment Bank - DL 16 Data Limit - DB 16 Data Base - DBANK 4 Data Segment Bank - Q 16 Stack Marker - S 16 Stack Pointer (SM + SR?) - Z 16 Stack Limit - SBANK 4 Stack Segment Bank - RA 16 Top of stack (REG_HIDDEN) (for diags) - RB 16 Top of stack - 1 (REG_HIDDEN) - RC 16 Top of stack - 2 (REG_HIDDEN) - RD 16 Top of stack - 3 (REG_HIDDEN) - X 16 Index Register - STA 16 Status Register (MITROC + CC + codeseg, REG_VMIO) - SWCH 16 Switch Register - CPX1 16 Run-Mode Interrupt Flags - CPX2 16 Halt-Mode Interrupt Flags - PCLK 16 Process Clock Register Modifiers: - CPU SERIES=II, III (default is III) - CPU 128K, 256K, 384K, 512K, 768K, 1024K (default is 1024K) - CPU EIS, NOEIS (default is EIS) - CPU CALTIME, REALTIME (default is CALTIME) - CPU IDLE, NOIDLE - CPU DUMPDEV=0-127 (default is 6) - CPU DUMPCTL=0-%377 (default is 4) - CPU STOP, NOSTOP - CPU POWERFAIL, POWERUP - CPU DEBUG, NODEBUG Debug Flags: - INSTR - DATA - FETCH - REG Simulation Stops: - LOOP - PAUSE - UNDEF - UNIMPL Examine/Deposit Switches: - n (interpret as 20-bit physical address; default) - p (interpret as 16-bit virtual address using PB-Bank) - d (interpret as 16-bit virtual address using DB-Bank) - s (interpret as 16-bit virtual address using S-Bank) - i (interpret as IOP order) Breakpoint Switches: - e (unconditionally) IOP --- Registers: - IOA 8 I/O Address Register Modifiers: - IOP FILTER, NOFILTER - IOP DEBUG, NODEBUG Debug Flags: - DIO Direct I/O commands - IRQ Interrupt requests and service - DATA MPX --- Registers: - STATR[0:15] 4 State RAM - AUX[0:15] 6 Auxiliary RAM - ORDER[0:15] 4 I/O Control Word RAM - CNTR[0:15] 12 I/O Control Word RAM - ADDR[0:15] 16 I/O Address Word RAM Modifiers: - MPX DEVNO=0-127 (default is 127) - MPX DEBUG, NODEBUG Debug Flags: - CSRW - PIO Programmed I/O commands - STATE State changes - SR Service requests - IOBUS SEL --- Registers: - IDLE 1 Active FF (not-Q) - DEVNO 8 Device number - BANK 4 Memory bank - RESIDUE 12 Residue - IOPC 16 I/O Program Counter - IOCW 16 I/O Control Word - IOORDER 4 I/O Control Word (order) - IOCNTR 12 I/O Address Word (counter) - INBUF 16 Input Buffer - OUTBUF 16 Output Buffer Modifiers: - SEL DEBUG, NODEBUG Debug Flags: - CSRW - PIO Programmed I/O commands - STATE State changes - SR Service requests - DATA CLK --- Registers: - CNTL 16 Control Register - STAT 16 Status Register - COUNT 16 Count Register - LIMIT 16 Limit Register Modifiers: - CLK CALTIME, REALTIME - CLK DEVNO=0-127 (default is 3) - CLK INTPRI=0-31 (default is 1) - CLK DEBUG, NODEBUG Debug Flags: - CSRW - SERV - IOBUS ATCD ---- Registers: - CNTL 16 Control Register - STAT 16 Status Register - STA[0:20] 16 line status, lines 0-20 - RPAR[0:20] 16 receive parameters, lines 0-20 - XPAR[0:15] 16 transmit parameters, lines 0-15 - RBUF[0:20] 16 receive buffer, lines 0-20 - XBUF[0:15] 16 transmit buffer, lines 0-15 - RCHP[0:20] 1 receive character present, lines 0-20 - XDON[0:15] 1 transmit done, lines 0-15 - BDFR[0:15] 1 break deferred, lines 0-15 - TIME[0:15] 24 transmit time, lines 0-15 Modifiers: - ATCDn UC, 7B, 7P, 8B - ATCDn DATASET, NODATASET - ATCDn LOG=file, NOLOG - ATCDn DISCONNECT - ATCD TERM, DIAG - ATCD CONSOLE, NOCONSOLE - ATCD DEVNO=0-127 (default is 7) - ATCD INTMASK=0-15/E/D (default is E) - ATCD INTPRI=0-31 (default is 0) - ATCD DEBUG, NODEBUG Debug Flags: - CSRW Interface control, status, read, and write actions - LSERV Line unit service scheduling calls - PSERV Poll unit service scheduling calls - XFER Data reads and writes - IOBUS I/O bus signals and data words received and returned ATCC ---- Registers: - CNTL 16 Control Register - STAT 16 Status Register - SCAN 1 scan enabled - CHAN 4 current line - DSO[0:15] 6 C2,C1,ES2,ES1,SS2,SS1, lines 0-15 - DSI[0:15] 2 S2,S1, lines 0-15 Modifiers: - ATCC LINEORDER=n - ATCC DIAG, TERM - ATCC CONNECTIONS, STATISTICS - ATCC DEVNO=0-127 (default is 8) - ATCC INTMASK=0-15/E/D (default is E) - ATCC INTPRI=0-31 - ATCC DEBUG, NODEBUG Debug Flags: - IOPB Signals and data words sent or received on the IOP bus - CMDS Command initiations and completions MS -- Registers: - CNTL 16 Control Register - STAT 16 Status Register - DBUF[0:65535] 8 transfer buffer - BPTR 17 buffer pointer (reads and writes) - BMAX 17 buffer size (reads and writes) - STA 12 tape status - BUF 16 buffer - USEL 2 currently selected unit - FSVC 1 first service flip-flop - POS[0:3] 32 tape position - BTIME 24 BOT start delay time - CTIME 24 command delay time - GTIME 24 gap traversal time - ITIME 24 IRG traversal time - RTIME 24 rewind initiation time - XTIME 24 inter-word transfer delay time - STOP_IOE 1 stop on I/O error Modifiers: - MSn 7970B, 7970E - MSn CAPACITY=n - MSn REEL=n - MSn OFFLINE, ONLINE - MSn FORMAT=f - MS FASTTIME, REALTIME - MS DEVNO=0-127 (default is 6) - MS INTMASK=0-15/E/D (default is E) - MS INTPRI=0-31 (default is 14) - MS SRNO=0-15 (default is 3) - MS DEBUG, NODEBUG Debug Flags: - FUNC Subsystem command functions - CMD Controller command initiations and completions - CSRW Interface control, status, read, and write actions - PHASE Controller phase changes - SERV Unit service scheduling calls - XFER Data reads and writes - IOBUS I/O bus signals and data words received and returned DS -- Registers: - CNTL 16 Control Register - STAT 16 Status Register - CMD 16 command register - FIFO[0:15] 16 data FIFO - SR1 16 status register 1 - VCTR 16 verify counter - FMASK 8 file mask - CYL 16 cylinder address register - HS 16 head/sector address register - STATE 2 controller state - LASTA 3 last unit polled for attention - FIP 4 FIFO insertion pointer - FRP 4 FIFO removal pointer - FCNT 5 FIFO counter - BUSY 1 visible busy status - CMDF 1 command follows flag - CMDP 1 command pending flag - EOC 1 end of cylinder flag - EOD 1 end of data flag - DBUF[0:127] 16 sector buffer - DPTR 8 sector buffer pointer - CTIME 24 command response time - DTIME 24 data transfer response - STIME 24 seek time (per cylinder) - RTIME 24 rotation time - TIMEOUT 31 controller timeout Modifiers: - DSn 7905, 7906, 7920, 7925 - DSn LOAD, UNLOAD - DSn PROTECT, UNPROTECT - DSn FORMAT, NOFORMAT - DS DEVNO=0-127 (default is 4) - DS INTMASK=0-15/E/D (default is E) - DS INTPRI=0-31 (default is 4) - DS DEBUG, NODEBUG Debug Flags: - FUNC Subsystem command functions - CMD Controller command initiations and completions - CSRW Interface control, status, read, and write actions - PHASE Controller phase changes - SERV Unit service scheduling calls - XFER Data reads and writes - IOBUS I/O bus signals and data words received and returned LP -- Registers: - CNTL 16 Control Register - STAT 16 Status Register - BUFFER 16 Output Buffer - BUF 7 last data item processed - LCNT 7 line count within page - POS 32 position in the output file - CTIME 24 time between characters - PTIME 24 time for a print operation - STOP_IOE 1 stop on I/O error Modifiers: - LP ONLINE, OFFLINE - LP DEVNO=0-127 (default is 14) - LP INTMASK=0-15/E/D (default is E) - LP INTPRI=0-31 - LP SRNO=0-15 (default is 11) - LP DEBUG, NODEBUG Debug Flags: - IOPB Signals and data words sent or received on the IOP bus - XFER I/O data transfers via the line printer SCMB ---- Registers: - CNTL 16 Control Register - STAT 16 Status Register - CTRBUF 16 Counter/Buffer Register Modifiers: - SCMB SC,MX (default is MX) - SCMB DEVNO=0-127 (default is 65) - SCMB INTPRI=0-31 (default is 10) - SCMB SRNO=0-15 (default is 0) - SCMB DEBUG, NODEBUG Debug Flags: - CSRW - XFER - SERV - IOBUS ----------------- Calibrated Timers ----------------- Three timing sources in the simulator must be calibrated to wall-clock time. These are the process clock, the system clock, and the ATC poll timer. The process clock is always enabled and running, although the PCLK register only increments if the CPU is not executing on the ICS. The system clock and poll timer run continuously if their respective devices are enabled. If the ATC is disabled, then the process clock takes over polling for the simulation console. The three sources must be synchronized to allow efficient simulator idling. This is accomplished by designating the process clock as the master device, which calls the SCP timer calibration routines, and setting the system clock and ATC poll timer to the process clock wait. All three devices will then enter their respective service routines concurrently. Two problems complicate the idle implementation. First, the process clock period is fixed at 1 millisecond, and the system clock period, while potentially variable, is set by MPE to 1 millisecond with an interrupt every 100 ticks. These periods are too short to allow idling, as the host OS clock resolution is also 1 millisecond. Second, lengthening the service periods to, e.g., 10 milliseconds and updating the counters by 10 each time won't work, as some MPE processes read the clock counters and expect them to change every millisecond (i.e., any change in value is considered to be an elapsed time of one millisecond). Fortunately, only the system clock interrupts and at a period of 100 milliseconds. Therefore, the idling demands and those of MPE may be satisfied by extending the service time to a multiple of one millisecond (e.g., to ten milliseconds) and then having the "read clock" routines adjust the current count return values by the amount of time, in simulated milliseconds, that has elapsed since the service was scheduled. To illustrate, assume that the process clock rate is set to a calibrated 10 milliseconds. Therefore, at every service entry, the PCLK counter is incremented by 10. Also, when an RCLK is done, the fraction of the elapsed service period in milliseconds is calculated, and that is added to the current PCLK counter to yield the return value. For example, assume that sim_activate has been called with an interval of 50,000 (corresponding to 10 milliseconds of wall time), that the PCLK value is currently 70, and that when an RCLK is done, 23,500 counts remain in the service interval (as returned by sim_activate_time). RCLK will calculate that 26,500 / 50,000 = 53% of the interval has elapsed. 53% of 10 milliseconds, truncated to the nearest millisecond, is 5. So RCLK will return 70 + 5 = 75. - The HP 3000 simulator uses three independent timers: ATCD poll, PCLK, and CLK. The ATCD poll timer is always calibrated and set to 10 msec; PCLK and CLK may or may not be. ATCD and CLK may be disabled; PCLK cannot be. - Idling only occurs when the CPU is executing a PAUS instruction. Note that the diagnostics (including SLEUTH) do not use PAUS when waiting for a keyboard response; instead, they test the ATC console completion flag in a loop: TIO 0 BL P-1 EXF #4:#1 CMPI 0 BE P-4 So only MPE will allow the simulator to idle. Idling also requires SET CPU IDLE, SET CPU CALTIME, and SET CLK CALTIME. - To allow idling, all timers must run at periods of no less than 5 msec, and the three must be synchronized to maximize the time between successive events. - MPE sets CLK to use a 1 msec period, a 100 tick limit, and an interrupt on count = limit. As PCLK uses a fixed 1 msec period, idling cannot occur even if both timers are calibrated. Idling also cannot occur with either set for REALTIME, as the event interval is too short (400 instructions). - To permit idling, PCLK and CLK (when set for 1 msec) use a 10 msec service interval and adjust the count returned by an RCLK and RIO to account for the time elapsed within the current interval. - When PCLK is calibrated, the global value cpu_is_calibrated is TRUE, and CLK and the ATCD poll synchronize to the PCLK event count by calling sync_time. When PCLK is uncalibrated, cpu_is_calibrated is FALSE, and CLK and the ATCD poll use their own event timers, which may be calibrated or uncalibrated in the case of the CLK (if PCLK is uncalibrated, idling is impossible due to the short event time, so whether or not CLK and the ATCD poll are synchronized is irrelevant). - PCLK sets its service interval to 400 if REALTIME, or to 10 msec calibrated if CALTIME. - CLK sets its service interval to clk_delay[] counts if REALTIME, or to sync_time() counts if CALTIME and cpu_is_calibrated is TRUE and period is 1 msec, or to the specified period calibrated if CALTIME and period is not 1 msec or cpu_is_calibrated is FALSE. - ATCD sets its service interval to sync_time() counts if cpu_is_calibrated is TRUE, or to 10 msec calibrated if cpu_is_calibrated is FALSE. If ATCD is disabled, the service is stopped. - If SET CPU REALTIME, CLK and ATCD calibrate independently. If SET CPU CALTIME, CLK and ATCD must resync with PCLK by calling sync_time with the INITIAL mode. - If SET ATCD NOCONSOLE, PCLK service polls the keyboard at either the REALTIME or CALTIME rate. If SET ATCD CONSOLE, ATCD service polls the keyboard at its calibrated rate. - A device cannot be disabled if it has an active unit, so can't disable ATCD while using ATCD16 as the poll unit. SCP provides: - int32 sim_rtcn_init (int32 clock_interval, int32 clk) - int32 sim_rtcn_calb (int32 tickspersecond, int32 clk) where: - clk is the timer ID number (0-7) - clock_interval is the initial delay in simulated instruction counts - tickspersecond is the number of clock time intervals per second - sim_rtcn_init return value is the initial clock activation time - sim_rtcn_calb return value is the updated clock activation time The HP 1000 TBG may be programmed for interrupt intervals of 100 microseconds to 1000 seconds in decade increments. For the 1 second to 1000 second intervals, the simulation clock is set to 10 ticks per second (100 milliseconds per tick), and an internal counter is used to issue an interrupt after a set multiple of ticks (10, 100, 1000, and 10000, respectively). The HP 3000 system clock provides intervals from 10 microseconds to 10 seconds in decade increments. For the 1 and 10 second intervals, the simulation clock is set to 10 ticks per second (100 milliseconds per tick), and an internal counter is used to update the count register after a set multiple of ticks (10 and 100, respectively). Notes: - The clock does not run if rate 0 is set in the control word. - The clock starts as soon as a rate other than zero is set. ------------- Trace Logging ------------- In the tables below, the values of global flags start at bit 0 and increase, while private flags start at bit 30 and decrease. Flag Name P/G Trace Decription ----------- --- ----------------------------------------------------------- TRACE_CMD G Interface or controller commands TRACE_INCO G Interface or controller command initiations and completions TRACE_CSRW G Interface control, status, read, and write actions TRACE_STATE G State changes TRACE_SERV G Unit service scheduling calls and entries TRACE_PSERV G Periodic unit service scheduling calls and entries TRACE_XFER G Data receptions and transmissions TRACE_FIFO G Data buffer reads and writes TRACE_IOBUS G I/O bus signals and data words received and returned TRACE_INSTR P Instruction executions TRACE_DATA P Memory data accesses TRACE_FETCH P Memory instruction fetches TRACE_REG P Register values TRACE_OPND P Instruction operands TRACE_EXEC P Matching instruction execution states TRACE_DIO P Direct I/O commands TRACE_PIO P Programmed I/O commands TRACE_IRQ P Interrupt requests TRACE_SR P Service requests --------- Global --------- | ----------------------------- Private ------------------------------ Device CSRW STATE PSERV IOBUS | INSTR DATA FETCH REG OPND EXEC DIO PIO IRQ SR ------ ----- ----- ----- ----- | ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- CPU - - x - | x x x x x x - - - - IOP - - - - | - x - - - - x - x - MPX x x - x | - - - - - - - x - x SEL x x - - | - x - - - - - x - x ----------------------- Global ----------------------- Device CMD INCO CSRW STATE SERV PSERV XFER IOBUS ------ ----- ----- ----- ----- ----- ----- ----- ----- ATCC - - x - - x x x ATCD - - x - x x x x CLK - - x - - x - x DS L L x L L - L x LP x - x x x - x x MS L L x L x - L x SCMB - - x - x - x x --------------------- REALTIME and FASTTIME --------------------- The ATC, DS, and MS devices want to support two timing modes: REALTIME, which times device actions based on the time a real device took to operate, and FASTTIME, which times actions as fast as the operating system can take them. FASTTIME will be the default mode, and the times will be exposed to the user via REGs, so that they may be tuned as needed. REALTIME values will not be exposed, nor can they be changed, as they are properties of the real devices. In addition, FASTTIME will also enable some operations that reduce timing still further. For the ATC, ENQ/ACK handshaking will be done locally rather than over the communication line. For MS, gap and file mark (GFM) commands are processed as WFM (write file mark) commands, i.e., the preceding GAP is not performed. Also, the initial gap that normally precedes the first data record or EOF mark at the beginning of the tape is omitted. For ATC: - REALTIME sets line delays to match the baud rates, based on the 2.5 usec instruction time. - FASTTIME sets line delays to some low, fixed value, regardless of baud rate. The value shall be accessible via a REG entry. - REALTIME is not calibrated; there's no point to slowing transmissions down to the orginal, glacial speeds. For MS/DS: - REALTIME/FASTTIME commands should be handled entirely by the controller. - The controller should supply REG definitions to set or show the fast times. - As there may be multiple controllers (e.g., DS/DA), the fast time values for a given controller must be accessible from the cvptr. - Different units within a controller may have different REALTIMES (e.g., 7970B vs. 7970E, or 7908 vs. 7910) but must have the same FASTTIMEs. - Some of the REALTIME values must be used in calculating the activation times (e.g., total_seek_time = per_cylinder_seek_time * distance_to_move), whereas the corresponding FASTTIME value is used verbatim. - Some of the activation times may not be known until partway through the operation, e.g., a tape FSR time won't be known until the record has been skipped during the traverse phase, so it can't be set up when the command is started. Note that testing a bit (flags & UNIT_FASTTIME) is faster than setting a Boolean value once and using that! The former compiles to TESTB / BCC, whereas the latter is MOV / SHR / AND / MOV to set, and then MOV / Bcc. Brute force method; CV contains fields for FASTTIME delays: if (cvptr->device->flags & UNIT_FASTTIME) wait = cvptr->seek_time; else wait = drive_props [cvptr->type] [uptr->type].seek_time * distance; Alternate: CV contains array [unit] of drive_prop pointers that are set when controller or unit types are changed: if (cvptr->device->flags & UNIT_FASTTIME) wait = cvptr->seek_time; else wait = cvptr->propptrs [unit]->seek_time * distance; Alternate: array of propptrs are all set to point at a single FASTTIME structure, so run-time check for FASTTIME isn't needed. BUT a test is still necessary to account for times that are distance-related (and the same problem exists if we try to index by phase instead of using explicit fields): wait = cvptr->propptrs [unit]->seek_time; if (!(cvptr->device->flags & UNIT_FASTTIME)) wait = wait * distance; Unless: wait = cvptr->propptrs [unit]->seek_time + cvptr->propptrs [unit]->cyl_time * distance; ...where seek_time is overhead and cyl_time is per-cylinder additional (set to "n" and "0", respectively, for FASTTIME). Probably need this for REALTIME too, as a 400-cylinder seek is not simply 400 times the single-cylinder seek time. Revision: property record contains a time record, and array contains pointers to associated time records for REALTIME or to single internal time record for FASTTIME. Problem is that in FASTTIME, still need props from real device for cylinder limit, etc. (can't have all props the same when FASTTIME, i.e., all pointers point at the same record). So even in FASTTIME, still need real prop pointer for each unit. typedef struct { int32 eot_time; /* end-of-track read untalk delay time */ int32 seek_delay; /* per-cylinder seek delay time */ int32 sector_delay; /* intersector delay time */ int32 data_delay; /* data transfer response time */ int32 command_delay; /* command delay */ int32 wait_time; /* command timeout delay */ } CNTLR_TIMES; typedef struct { ... CNTLR_TIMES fast; CNTLR_TIMES *tptr [UNIT_COUNT]; ... } CNTLR_VARS; typedef struct { char *name; /* drive name */ uint32 sectors; /* sectors per head */ uint32 heads; /* heads per cylinder*/ uint32 cylinders; /* cylinders per drive */ uint32 words; /* words per drive */ uint32 remov_heads; /* number of removable-platter heads */ uint32 fixed_heads; /* number of fixed-platter heads */ CNTLR_TIMES times; /* physical access times */ } DRIVE_PROPS; For DS, use STAT as propindex/stat upper/lower (STAT only has bits changed, not set wholesale) For DS, the controller timeout (1.74 seconds) is not affected by FASTTIME, nor is it calibrated. For DS, only one REALTIME setting is needed per controller. The 13037 controls four types of discs, but they have identical characteristics. The ICD and CS/80 controllers only handle one disc apiece, so while disc-to-disc characteristics may vary, only one REALTIME setting will be needed per controller. Because four ICD units (DA) want to use the same FASTTIME settings, CNTLR_VARS must contain a pointer to the FASTTIME structure, rather than the structure itself. That allows all four controllers to point at a single FASTTIME structire. Otherwise, there'd be four independent FASTTIME structures. For MS, the 30115 controller supports 7970B and 7970E drives simultaneously, and they have different timings, so four REALTIME settings (one per unit) will be needed. Also, an HP-IB interface can interface four drives, and while those drives have their own controllers, they will be modeled as a single controller handling four units. So again, even for Amigo drives, the controller will need to support four REALTIME settings. ============== CPU Simulation ============== Simulation of the CPU is provided by the sim_instr() routine. This routine consists of a prelude that sets up the conditions needed for execution, a loop that executes machine instructions, services the multiplexer and selector channels, and checks for interrupts, and a postlude that cleans up after execution is terminated. Unlike most machines, the HP 3000 is capable of reading and writing to peripheral devices while the CPU is halted. Cold load and dump routines are executed in microcode and operate the I/O channels. Under simulation, sim_instr() may be called when the machine is halted (as indicated by the Run FF status bit being clear. In this case, machine instructions must not be executed while the simulated microcode routines are running. --------------- Microcode Aborts ---------------- There are a number of microcode aborts (e.g., bounds check, system halt) that bail out of the middle of instructions. These may be modeled in one of three ways: 1. with exceptions 2. with setjmp/longjmp 3. with error status returns Exceptions would provide the cleanest implementation, but C doesn't support them. Existing SIMH simulators use the setjmp/longjmp functions to implement aborts. For example, the HP 1000 simulator models memory protect violations by longjmp calls from within the instruction simulator. Error status returns, wherein each routine returns a true/false abort indication, provide a more structured approach than the non-local GOTO provided by longjmp. However, a significant drawback is that there is no language mechanism that enforces propagation up the call chain. Each location that calls a lower-level routine that might abort must be prepared to handle the abort status. The longjmp method does not depend on intermediate routines propagating abort status upward. One problem with longjmp is that a handler for each abort condition must be present in the setjmp block. We can mitigate this by defining an enum for the conditions and using a switch statement without a default case. ----------------- Instruction Fetch ----------------- A two-stage instruction pipeline is used in hardware, but this is not necessary under simulation. The current instruction is fetched into and is decoded from the Current Instruction Register (CIR). The Next Instruction Register (NIR) is not used. However, it must be presented to the user on simulation stop, i.e., whenever sim_instr exits. When sim_instr is entered, P points to the instruction to execute. The instruction is loaded into the CIR, P is incremented, and the instruction is dispatched. Each pass through the execution loop performs the same steps. When the instruction loop terminates after executing a "normal" instruction or a programmed HALT, P and CIR are unchanged (i.e., still points at the next instruction and still contains the HALT or other instruction, respectively). If execution was stopped during a PAUS instruction or after the first of two stack operations, P will have been decremented to point back to the current instruction, which is contained in the CIR. In either case, NIR is loaded with the memory value pointed to by P before exiting sim_instr. ---------------------- CPU Instruction Decode ---------------------- consolidated coding sheet: 03000-90002 p.145 (software applications) ------------------- Instruction Prelude ------------------- if CPX & system_halt_ff_state = True then goto Instruction Postlude if not iop_initialize (interrupt_request_set, interrupt_poll_set) then return SCPE_STOP if not multiplexer_initialize (multiplexer_request_set) then return SCPE_STOP selector_initialize (selector_request_set) ---------------- Instruction Loop ---------------- if sim_interval <= 0 sim_process_event() if selector_request_set /= 0 then selector_poll() if multiplexer_request_set /= 0 then multiplexer_poll() if I_bit set in Status_Register then iop_intpoll() if CPX & run_ff_state = False then if CPX & system_halt_ff_state = True then exit loop sim_interval = sim_interval - 1 if CPX & halt_mode_interrupt_mask /= 0 then halt_mode_interrupt() continue loop elsif selector_is_idle and multiplexer_is_idle then exit loop else continue loop if CPX & run_mode_interrupt_mask /= 0 then run_mode_interrupt() elsif paused then if idle_enabled then sim_idle(idle_timer, TRUE) else sim_interval = sim_interval - 1 continue loop sim_interval = sim_interval - 1 machine_instruction() -------------------- Instruction Postlude -------------------- When the instruction loop is exited, a simulator stop message is printed and control returns to SCP. Upon return, P points at the next instruction to execute, i.e., the instruction that will execute when the instruction loop is reentered. The simulator stop message is: , {CIR: (),} {P: ()} Examples: Simulation stopped, P: 24713 (LOAD 1) Simulation stopped, CIR: 030020 (PAUS), P: 12345 (PAUS) HALT instruction, CIR: 030360 (HALT 0), P: 00101 (DNEG,DADD) System halt, P: 00101 (DNEG,DADD) Dump complete, CIR: 000020 NOTE: some of these require a VM-specific message printer. See "SIMH Enhancements" for details. -------------------- Instruction Decoding -------------------- The microcode detects certain unimplemented instructions and traps to the operating system. Under simulation, a stop on attempted execution of an unimplemented instruction is available by entering SET CPU STOP=UI. The hardware does not fully decode all instructions. Some instruction have "reserved" bits that are specified as zeros but are handled as "don't cares" in the microcode. The UI stop setting affects execution and symbolic display of the instructions that are not fully decoded. If the stop is not set, then execution and symbolic display follow the hardware, i.e., if the hardware would execute an instruction with reserved bits set to a non-zero value, then the instruction will decode to the same mnemonic as the one with a zero value. If the stop is set, then only the defined opcode listed in the Machine Instruction Set manual will execute or decode; the others will cause a UI stop and will display in octal. For example, the PAUS opcode is defined as 030020. However, bits 12-15 are not decoded, so opcodes 030021-030037 will execute and display as PAUS if the UI stop is disabled. With the UI stop enabled, only 030020 will display or execute; 030021-030037 will cause a UI stop and will display as octal values. Unimplemented instructions that are detected by the microcode will cause a UI stop if enabled. Continuation after a UI stop, or execution if UI stops are disabled, will result in a UI trap. ---------------- Interrupt Status ---------------- The CPU maintains a 32-bit interrupt status word, CPX, that concatenates the 16-bit CPX1 and CPX2 hardware registers. The bits correspond as follows: Bit CPX Int Val Description --- --- --- --- ----------------------------- 31 1 1 - Integer Overflow 30 1 1 - Bounds Violation 29 1 1 - Illegal Address 28 1 1 0 (CPU Timer) 27 1 1 0 (System Parity Error) 26 1 1 0 (Address Parity Error) 25 1 1 0 (Data Parity Error) 24 1 1 0 (Module Interrupt) 23 1 1 - External Interrupt 22 1 1 0 (Power Fail Interrupt) 21 1 - 0 (unused) 20 1 - - ICS Flag 19 1 - - DISP Flag 18 1 - 0 (Emulator) 17 1 - - I/O Timer 16 1 - 0 (Firmware Option Present) 15 2 1 - Run Switch 14 2 1 - Dump Switch 13 2 1 - Load Switch 12 2 1 0 (Load Register) 11 2 1 0 (Load Address) 10 2 1 0 (Load Memory) 9 2 1 0 (Display Memory) 8 2 1 0 (Single Step) 7 2 1 0 (Execute Switch) 6 2 - 0 (Increment Address) 5 2 - 0 (Decrement Address) 4 2 - 0 (unused) 3 2 - 0 (unused) 2 2 - 0 (Inhibit Auto-Restart Switch) 1 2 - - System Halt Flip-Flop State 0 2 - - Run Flip-Flop State () = not simulated; always 0 Run-mode interrupt requests are tested by ANDing with the "Int" bits for CPX1, and halt-mode interrupt requests are tested by ANDing with the "Int" bits for CPX2. ------------------ Run and Halt Modes ------------------ A simulated CPU normally operates in "run mode" when it is executing the instruction simulation loop (sim_instr) and "halt mode" when the loop exits back to the SCP console prompt. A RUN, GO, CONTINUE, or STEP command places the CPU in run mode, and a HALT instruction, simulation stop (e.g., a breakpoint or I/O error), or console interrupt (CTRL+E) returns the CPU to halt mode. CPUs that execute microcode during halt mode are normally not simulated directly. Rather, the functions provided by the halt mode microcode, e.g., displaying or setting register contents, are provided instead by SCP commands. For example, the HP 1000 "IBL" (Initial Binary Loader) function is provided by the halt-mode microcode in hardware and is simulated by the BOOT CPU command. Pressing IBL in hardware copies the contents of a loader ROM into memory; entering BOOT CPU does the same thing in simulation. The CPU is then run to execute the loaded machine instructions, which read a bootstrap program from a disc or tape. The corresponding HP 3000 function, "cold load," is similarly initiated in hardware by pressing the LOAD and ENABLE buttons and in simulation by entering the BOOT CPU command. However, cold load does not copy and run a set of machine instructions. Instead, it loads an I/O program into memory that is executed by the multiplexer or selector channel (i.e., DMA), which reads additional I/O programs and eventually CPU code from the target cold load device. During this process, the CPU remains halted, i.e., no machine instructions are executed. The cold load function could be simulated entirely in the associated command processor. That routine could call functions in the channel simulators that execute I/O programs, which in turn would call functions in the device simulators. It would also have to handle the eventual cold load interrupt that occurs when the I/O program terminates. This would require duplicating some of the run-mode code that handles the same functions. One drawback to this is that an unresponsive I/O program could not be interrupted, because the normal CTRL+E handler is not active when commands are executing. So an extra handler would be needed to allow the cold load command to be aborted. Another drawback is that the "cold dump" function would require much of the same code, involving more duplication. A simpler solution would be to provide the halt-mode actions within the "sim_instr" execution loop, where channel operations are already implemented. The 3000 maintains a "run flip-flop" that indicates to the microcode whether the CPU is in run mode or halt mode, which in turn decides which micro-routines are executed. The "sim_instr" routine could test this to determine its mode. As the normal CTRL+E handler is active, no special action is needed to allow the user to abort a hung cold load sequence. While in halt mode, the instruction loop would not call the machine instruction executor. Instead, only channel cycles would be run. When the cold load interrupt occurs, the simulator would set the run flip-flop, so that the next pass through the loop would begin executing the loaded program. Transitions between run and halt modes are controlled by SCP commands and execution of the HALT instruction. In hardware, the run flip-flop is set by the completion of the cold load sequence or by the operator pressing the RUN/HALT button. The flip-flop is cleared by executing a HALT instruction or by the operator pressing the RUN/HALT button again (it toggles the run state). Transitions under simulation are less clear. Executing a HALT instruction behaves as in hardware. However, should simulator stops clear the run flip-flop? A CTRL+E is analogous to pressing the HALT button, but should the run flip-flop be cleared, or should control revert to the simulation console while the flip-flop remains set? Similarly, should a breakpoint stop, for which there is no analog, clear the run flip-flop? It would seem that RUN, GO, CONTINUE, and STEP should set the run flip-flop. However, consider a CTRL+E during a cold load that stops in the middle of a channel transfer. Clearly, a CONTINUE should resume the transfer from where it was stopped, which means leaving the machine in halt mode. But a CONTINUE from a programmed HALT should put the machine back into run mode, so simply leaving the mode untouched is not possible. To address these issues, the rule adopted is that "sim_instr" sets or clears the run flip-flop, based on whether any halt-mode interrupt flags are set in CPX2. If they are, then a halt-mode action, such as cold load, was interrupted via CTRL+E and is being resumed. If they are not, then the CPU is switched to run mode, and machine instruction execution is resumed. --------------- The RUN Command --------------- In SIMH, the RUN and BOOT commands call each of the device reset routines, including the CPU reset routine, before beginning instruction execution. This is appropriate behavior for the BOOT command, as the hardware front panel LOAD button asserts -CPURST and -IORESET before initiating the cold load microcode. However, the RUN button asserts neither signal; it simply moves microcode execution from the halt to the run loop. Therefore, the GO or CONT commands are equivalent to the RUN button. As a cold load is the only way to set up the initial segment base and limit registers, and as execution begins on the ICS after the load completes, and as -CPURST clears the ICS flag in CPX1, issuing a RUN command after a BOOT will fail. Indeed, RUN can never be used in the 3000 simulator, as there's no "bare" machine mode where beginning execution immediately after a CPU reset is appropriate. Therefore, the RUN command is intercepted to alter the execution flag from RU_RUN to RU_GO, making the simulator commands equivalent. BOOT will still call cpu_reset, as will RESET and RESET CPU. There is no way to assert -IORESET by itself, although RESET will assert -IORESET to the named device only. However, there is no user switch in hardware that asserts just -IORESET except DUMP, which also invokes the cold dump microcode as well. ----------------------- Power Fail and Power On ----------------------- Power failure and restoration can be indicated by the user in several possible ways. The method selected should be applicable to the 1000 simulator as well, as implementing power failure and restoration on that machine in the future is desirable. In hardware, a power failure is a more-or-less random event and may occur either while the machine is halted or running. In the former case, the power fail action does nothing other than record the machine state, and power restoration also does nothing other than leave the machine halted. In the latter case, though, the machine gets a power fail interrupt and executes its power-down routine, ending with a HALT to wait for power to die. Power restoration also causes an interrupt (1000) or initiates a trap (3000) to execute the power up routine and continue execution. In general, the operations to cycle power on an executing simulation would be: - Break simulation. - Indicate a power failure. - Resume simulation to allow the power-fail routine to execute. - Simulation stops with a HALT instruction. - Indicate a power restoration. - Resume simulation to allow the power-up routine to execute. Cycling power on a halted simulation is effectively a null operation: - Indicate a power failure. - Indicate a power restoration. Power restoration cancels the power failure indication, leaving the machine in the same halted condition as before. The only observable result is that the machine has been reset to the power-on condition (i.e., a RESET -P has been performed). It is therefore arguable that simulating the halted case is not required. Regardless of the command forms chosen, the simulator must not allow a power restoration to be performed without a prior power failure. That is, the target OS must not be directed to its power-up routine without its power-fail routine having been executed. Attempting to do so must result in a "Command not allowed" error message. With these considerations in mind, the choices to designate power cycling are: 1. SET CPU POWERFAIL or SET CPU POWEROFF SET CPU POWERRESTORE or SET CPU POWERON 2. RUN/GO/CONT -F RUN/GO/CONT -R 3. POWERFAIL or POWER FAIL or POWER OFF POWERRESTORE or POWER RESTORE or POWER ON The first choice makes power failure and restoration an option of the CPU. But it's really an option of the entire simulated machine. Power restoration pulses the -CPURST and -IORESET signals, simulated by a RESET -P, so it affects all devices. Power failure also sends the PFWARN signal to all devices. While there are currently no SET POWEROFF/ON commands in the 3000 simulator, there are ones in the 1000 simulator (for the line printers), so it's tempting to reuse this nomenclature. However, there is a difference in semantics: SET LP POWEROFF affects only the (1000) line printer, whereas SET CPU POWEROFF affects all devices. The interaction of a SET CPU option with other, unrelated devices is not implied by the command name. This choice permits the user to power-cycle the machine while it is halted. It also requires that the user continue execution after entering the SET CPU commands. Interaction would therefore be: - CTRL+E to break simulation. - SET CPU POWERFAIL to indicate a power failure. - CONT to resume simulation to allow the power-fail routine to execute. - Simulation stops with a HALT instruction. - SET CPU POWERRESTORE to indicate a power restoration. - CONT to resume simulation to allow the power-up routine to execute. (While SET CPU POWERFAIL/POWERRESTORE could include an automatic CONT, this would differ from all other SET