Work Remaining on the HP 2100 Simulator ======================================= ------------ Current Work ------------ General ------- + BUG: seek 199/0/0, addrec 199/1/0, init should write to 199/0/0, but trace reports "Initialize to cylinder 199 head 1 sector 0". Manual says that write begins at "CHS from drive, or CH from drive and S from adrec." hp_disclib.c is written to use C from drive and HS from adrec! [FIX: change u4 (Status) into Head_Status and keep drive head there] + ENH: extend diag override to include CHS header values for RFS [FIX: done] + BUG: diag return Defective Track from RFS bombs out before transferring any data; should bomb out at intersector. Problem is da_hpib_accept is setting uptr->wait to 1 and calling activate_unit, which does not use uptr->wait, but hp_disclib does!. FIX: remove uptr->wait = 1. - BUG: MSD/MSC is 14/15. SET MSD SC=13 sets 13/14, but SET MSC SC=14 sets 14/15. Actually, this is documented; from the manual: For devices with two interface cards (e.g., DP), specify the lower select code with either device name; the higher select code will be set automatically, and the cards will be assigned in the correct order. Can this be fixed, maybe as part of the deletion of DEVNO? [FIX: call "hp_set_pair" instead of "hp_set_dib"] - Convert MS to state analysis. + Replace DISCLIB with HP 3000 version and tie in DS. Main benefit is trace coverage (trigger, window, and list), plus less code in DS. NOTE: short diag, old DS = 22 sec, new DS = 25 sec using fast times - Replace TAPELIB with HP 3000 version and tie in MS. Extend to allow tape unit assignments to SIMH units. CPU --- Memory ------ DMA --- MEU --- BACI ---- DA -- DC -- - Power-on condition should enable PPR, per SS/80 3.6. Problem is set_error sets dsptr->state = Optional_Wait, but dc_initialize is looking for dsptr->state = Reporting_Wait before enabling PPR. - Unloading a removable drive should set the user release bit in the status array and enable PPR. Currently, we do not handle release, Set Release, Release, or Release Denied. DI -- DP -- DQ -- DR -- DS -- - HP 3000 disc library is implemented incorrectly. The controller is being called to advance phases in response to 3000 signals, e.g., TOGGLEINXFER, whereas it should be called from the service routine. As a result, commands such as Request Status aren't working in the 2100 DS module because the data transfer phase is never scheduled. Currently, the library is a mix of self-scheduled events and 3000-scheduled events. The controller should schedule itself to push data to the interface, which should have to keep up, just as in the hardware. Correcting this will probably screw up the DA device, which is doing its own scheduling, unless the "extra" schedules are MAC-only (but shouldn't be!). IPL --- LPS --- LPT --- MC -- MPX --- MS -- MT -- MUX --- - Separate diagnostic mode for MUXU/MUXL and MUXC. Rename the latter to DATASET/DIAGNOSTIC. PIF --- PTR --- PTP --- TBG --- TTY --- User's Manual ------------- - Add TRACE STORE sections for devices that have only IOBUS and IOIRQ states. These are: DP, DQ, DR. - Add a section covering alternate boots (2100 MCP mag tape loader, IOP direct load) to the "Running HP 2000 Time-Shared BASIC on SIMH" paper. Software Kits ------------- ================================================================================ ----------- Future Work ----------- General ------- - Change debug printouts to tracing module. - Harmonize existing trace options with new ones for CPU and LPT. - Clean up misguided use of [u]int16 variables. - Add 12732A interface and 9885 floppy disk simulator for RTE-M. Leverage from disc library. Maybe combine MC1/2, as 12732 interfaces are micrcircuits. - Convert MC1/2 to instances? - Convert DCPC1/2 to instances? Auto-set for DMA vs. DCPC? - Review adding REG_X to disc/tape devices (maybe e.g. -M for sector buffers?). - Use *+n and *-n for MRG with displacement within some small number? It's clearer to use SFS 10 / JMP *-1 than SFS 10 / JMP 77743. - Add a "profile" option to the makefile. To profile: - make release CFLAGS="-g -pg" LDFLAGS="-g -pg" LDOPT="" - hp2100 rtep - gprof hp2100.exe > hp2100.log CPU --- - "mem_trace_registers" depends on X and Y = 0 when the CPU is 21xx. They are zeroed in the SET CPU handler but could be set by the user, as they are not hidden in the register list. Should the registers that pertain only to a specific model be hidden (have REG_HRO flag set) when the model changes? - MPCK implementation is wrong. MP violation does not do a microcode abort. Instead, asserting MPV (a) inhibits memory writes, and (b) inhibits IOGSP from setting the IOG enable flip-flop, so I/O signals are not asserted. The MP ERD says that MPV also inhibits stores to the P or S registers, but I can't find anywhere in the schematics where this is done. It may not matter, as if MPV occurs, an interrupt should reset P for the IAK. (But what happens if MP is enabled with the interrupt system off? This is illegal per the ERD; it says that the CPU will permanently freeze until it is reset.) Also, an MEV on read causes the value 177777 (floating S-bus) to be returned. - INCI implementation is wrong. After three levels of indirection, a pending interrupt does do a microcode abort (presuming that a HORI test is done). Currently, the simulator backs out of the "resolve" routine via a special status code return. Each call level must return this special status code until it reaches the main instruction loop, which backs out the instruction and exits. This could be piggy-backed on the current MP abort implementation, with the "abortval" indicating an MP or interrupt or indirect loop abort. - Improve execution performance? 1000-E CPU speed is 15x (optimized), or about 265,000 instructions per 10 msec. 3000 CPU speed is 36x. Reducing IRQ and SRQ handling may help -- these originate in I/O interface calls. - EAU undefined bits not decoded per-machine as is needed. Implement with SS_UNDEF. - Ensure clean compiles regardless of HP_WORD size. Currently, cpu5 and cpu7 compile with dozens of warnings if HP_WORD is uint16. DMA --- MEM --- BACI ---- DA -- + Modify to use 3000 hp_disclib common library. DC -- - Change initialize_media to support cert options (pass number sets pattern to use)? - Verify error handling for Untalking or Unlistening while a read or write is in progress. DI -- DP -- - Add tracing (needed in the past numerous times). - Modify to use 3000 hp_disclib common library? DQ -- - Modify to use 3000 hp_disclib common library? DR -- DS -- - Modify to use 3000 hp_disclib common library. IPL --- - Support 2000C' command tracing. C-to-F differentiation is made by checking for FP firmware in the SP. The former doesn't have it; the latter requires it. LPS --- LPT --- MPX --- MC -- MS -- - Modify MS to use 3000 hp_tapelib common library. MT -- MUX --- - SET MUXL DATASET needed? The 3000 ATC auto-detects this; a control word write directed to a given channel sets that channel's UNIT_MODEM flag to indicate that the serial line status should be updated at each input poll service. Maybe what is wanted is an auto-dataset plus an option to DEFEAT this, as TSB doesn't seem to have ways to configure the terminal modes. A user might NOT want the Telnet session to disconnect at logout. So maybe delete DATASET and add NODTR? - Rewrite using ATC code? ATC is probably a cleaner implementation, and there are some questions as to whether Control PCA implementation is correct. For example, Telnet connections are made regardless of DTR state. Does 2000/Access use DTR down to prevent connections when shutting down or with the DISCONNECT command? - Is there an easy way to simulate the ASR33 PTR and PTP on mux channels? There's no easy way now to get text files into 2000E/F except by copy-and-paste. The system PTR and MSC cannot be used to load user programs, except from a selective dump tape. PIF --- PTR --- PTP --- TBG --- TTY --- - Simulate the PTR on the ASR33? We claim to simulate the HP 2752 but only the keyboard, printer, and punch are implemented. User's Manual ------------- - "Plain text" style ought to have leading margin instead of requiring extra blank lines for paragraph spacing. Maybe change to "Paragraph" style name? - Use "Keep with next" to keep a table and its introductory sentence together. - Create and apply "user manual" and "monograph" style sheets. Software Kits ------------- - Add a 2000C' kit. - Add DOS, DOS-M, RTE, RTE-III, RTE-IVA, RTE-IVB, and RTE-6/VM kits. -------------------------------------------------------------------------------- NOTE: 1:1 device-to-DIB correspondence does not hold, so dibs [*] is needed! Examples: - dibs [1] = ovfl, devs [1] = cpu - dibs [2] = dmas1, devs [2] = dma1 - dibs [3] = dmas2, devs [3] = dma2 - dibs [4] = pwrf, devs [4] = cpu -------------------------------------------------------------------------------- In hardware, IAK sets the interrupt flip-flop (INTPTFF) if mp.control is SET, and clears mp.control, turning MP off. If the trap cell contains an I/O instruction, IOG is asserted before the next fetch, and, if the trap cell instruction is not HLT, IOG sets mp.control to turn MP back on. If the trap cell contains a HLT or a non-IOG instruction, mp.control remains CLEAR. In either case, the next fetch clears INTPTFF, preventing a later IOG from setting mp.control. In simulation, IAK clears mp.control only if the trap cell instruction is not an IOG instruction or it is not HLT. Otherwise, mp.control stays on. To allow the trap cell instruction to execute, "cpu_iog" skips the usual MP check if "in_trap_cell" is TRUE. In essence, hardware turns MP off for one instruction (the trap cell IOG execution) and then back on again, whereas simulation leaves MP on but bypasses the MP check for the IOG instruction. IOG detection is therefore required both in the MP IAK handler and in the IOG instruction executor. An alternate scheme might be: - (mp_interface) IAK sets mp.enabled = mp.control, clears mp.reenable, clears mp.control, and schedules unit service for the next instruction (wait = 0). - (cpu_iog) Calls "mp_check_io" to check for an I/O violation before executing the I/O instruction. - (mp_check_io) If mp.control is set, checks for a violation. If clear, then mp.reenable = mp.enabled if not HLT. Violation check depends only on the instruction, not whether or not it is located in a trap cell. - (mp_service) mp.control = mp.reenable, clears mp.enabled and mp.reenable. -------------------------------------------------------------------------------- DMA calls: - dma_interface: io_dispatch (select code, signals, value) - dma_cycle: io_dispatch (select code, signals, value) [ dma.c does not have access to I/O table or DIBs ] CPU calls: - sim_instr: io_dispatch (CIR, IAK, 0) - sim_instr: io_dispatch (MPPE, IAK, 0) - cpu_iog (instruction): io_dispatch (select code, signals, value) - io_control (sc, uop): io_dispatch (select code, control_set, 0) [ provided only for cpu6.c, which does not have access to I/O table or DIBs ] - io_assert (dptr, assertion): io_dispatch (select code, assert_set, 0) [ provided only for devices; only called with ENF and SIR ] - cpu_interface: io_dispatch (select code, CRS, 0) - initialize_io: io_dispatch (select code, ENF, 0) device calls: - io_assert (device pointer, assertion) [ must look up select code in I/O table to call io_dispatch ] io_dispatch uses: - select code (priority_holdoff_set, interrupt_request_set, dma_assert_SRQ) - iot.dibptr (slot is empty or call io_interface) - iot.devptr (trace) --- old: t_bool io_control (uint32 select_code, IO_GROUP_OP micro_op) -- does MP check on select code -- calls io_dispatch, returns TRUE if skip void io_assert (DEVICE *dptr, IO_ASSERTION assertion) -- calls io_dispatch SKPF_DATA io_dispatch (uint32 select_code, INBOUND_SET inbound_signals, HP_WORD inbound_value) --- new: void io_assert_ENF (DIB *dibptr); if (dibptr != NULL) io_dispatch (dibptr->select_code, ioENF | ioSIR, 0); void io_assert_SIR (DIB *dibptr); etc. Still won't get the correct interface call if I/O table is out of date. But should never be called from a user-interface routine. Should only be called while executing, so table is good. Could zero out I/O table in postlude, so that non-execution call would NOP.... ----- Issue: IOP interrupt to STC is 34 instructions. SP DMA completion to CLC is 4 instructions. So SP must execute max IPL poll wait + 4 instructions before IOP can execute 34. Worst case is SP polls negative on last instruction of quantum, while IOP is blocked for full quantum, then xfers on first instruction. If poll + 4 doesn't fit in a quantum, then IOP will get THREE quanta before SP reaches critical point: - [SP n] polls negative; rendezvous - [IOP 1] xfers - [IOP 2-n] execute; rendezvous - [SP 1] blocks - [IOP 1-n] execute; rendezvous - [SP 2-(n-1)] execute - [SP n] polls positive; rendezvous - [SP 1] blocks - [IOP 1-n] execute through critical point - [SP 2-n] execute through critical point Positive poll must occur at least four instructions before end of quantum, i.e., poll_time = quantum - 4 (or less). If poll = quantum / 2, we have: - [SP n] polls negative; rendezvous - [IOP 1] xfers - [IOP 2-n] execute; rendezvous - [SP 1] blocks - [IOP 1-n] execute; rendezvous - [SP 2-Q/2] execute - [SP Q/2] polls positive - [SP Q/2-n] execute through critical point; rendezvous - [IOP 1-n] execute through critical point - [SP 1-n] execute Criteria are: - Q = IOPTIME / 2 - 1 - Q > SPTIME + POLLTIME ?