Previously, the history would always use a register value as source or
destination as if the mode were zero, even when it wasn't. Also, now
the destination value reflects the destination after instruction
execution rather than before.
Rather than use a simh event to increment/decrement the counter register
for each 'clock cycle', compute the time the interrupt will eventually fire
and schedule a single event to deal with that. If the clock counter is
referenced before the interrupt fires, interpolate the value based on the
number of instructions that have actually been executed.
sim_activate_after() is used here, and the time value for the scheduled
activation is a uint32 representing microseconds. The range of values
that the PCLK can programmatically specify could be large enough
to exceed an uint32 when number of microseconds is converted to
a count of instructions. This is an issue that has minimal consequences,
but should be addressed internal to the implementation of
sim_activate_after().
273. ENHANCEMENT: Burst-fill only the first of two MPX receive buffers in FASTTIME mode.
OBSERVATION: When the 8-channel multiplexer is set for "optimized timing"
mode, buffered characters are transferred in blocks to and from the Telnet
connection. That is, the line service routine will send or receive
characters as long as they are available. This is more efficient than the
"realistic timing" mode, which sends or receives one character per service
invocation. Effectively, this means that up to 508 characters (two buffers
of 254 bytes each) may be sent or received between one CPU instruction or
DCPC cycle and the next. This works well for sending, but it can cause
buffer overflows when receiving.
Consider an application (such as Kermit) that receives large blocks of data
at high speed from a client. The multiplexer is designed to handle this
condition by interrupting the CPU when the first buffer is filled and
filling the second buffer while the CPU is unloading data from the first.
In realistic mode at 19,200 baud, the CPU has approximately 800
instructions or DCPC cycles available per character received. With a
second buffer of 254 bytes, the CPU has approximately 203,000 instructions
available to unload the first buffer after receiving the interrupt
notification. Once started, the DCPC transfer takes no more than 508
instruction times, so the CPU can easily keep up with data arriving at the
maximum baud rate.
In fast timing mode, however, the first buffer burst-fills in a single CPU
instruction time, and, if available from the Telnet connection, the second
buffer fills in the next instruction time. At that point, any additional
characters received will result in a buffer overflow condition. The
problem is that the CPU has no time between the first burst and the second
to empty the first buffer.
RESOLUTION: Modify "mpx_line_svc" (hp2100_mpx.c) to shift from burst
transfers to character-at-a-time transfers when a receive buffer is full
and awaiting unloading by the CPU. This allows the CPU and DCPC time to
read the buffer contents into memory before the second multiplexer buffer
is full. Once the completed buffer is freed, the service routine returns
to burst mode to fill the remainder of the other buffer, permitting the
efficiency of block transfers while avoiding buffer overruns with large
data transfers.
274. PROBLEM: A second connection to the BACI device leaves the client unresponsive.
OBSERVATION: The BACI device supports a single terminal client connection.
If a second connection is attempted, the client connects but is otherwise
unresponsive. It would be better if the client received the "All
connections busy" message that is reported by the terminal multiplexers
(MPX and MUX devices) when the number of connections is exceeded.
CAUSE: The "baci_poll_svc" is calling the "tmxr_poll_conn" routine only if
the port is not connected. The routine should be called unilaterally, so
that it will report an error and disconnect the client when all lines are
in use and another connection is attempted.
RESOLUTION: Modify "baci_poll_svc" (hp2100_baci.c) to call
"tmxr_poll_conn" unconditionally, so that a second concurrent connection
attempt will be rejected with "All connections busy".
275. PROBLEM: The exported program counter name (PC) clashes with other libraries.
OBSERVATION: In HP 21xx/1000 systems, the P register is the program
counter. In keeping with the naming of the other register variables (e.g.,
for A register, B register, etc.) in the simulator, the variable used
should be named "PR". However, for traditional reasons, the program
counter in SIMH is named "PC".
The main CPU module declares its hardware register variables as global, so
that they may be accessed by other CPU helper modules. Unfortunately, the
"curses" library also declares the symbol "PC" as global, leading to
conflicts when it is loaded by SCP. A workaround had been implemented that
renamed "PC" to "PC_Global" in the HP2100 simulator, but that meant that
the new name had to be used when debugging, which was awkward.
CAUSE: A poor choice of global symbol names from the "termcap" library,
which was inherited by the "curses" library.
RESOLUTION: Change the program counter variable name from "PC" to "PR"
(hp2100_cpu.c, hp2100_cpu1.c, hp2100_cpu2.c, hp2100_cpu3.c, hp2100_cpu4.c,
hp2100_cpu5.c, hp2100_cpu6.c, hp2100_cpu7.c, hp2100_dr.c, and hp2100_ipl.c)
to avoid a name clash and for register naming consistency.
- add internal help entries
- add descriptions to the register, modifier and debug tables.
- changed device CD name to CDD to avoid name conflict with the CD command
The goal being to have output to physical serial ports complete without host
OS level buffering so that what is transmitted via the serial port has correct
timing with respect to I/O completion status within a simulator.
Linux, OS X, and various other *nix host platforms still need work here.
ASCII mode for the paper tape reader and punch didn't <quite> work.
In ASCII mode, the <simulator> must create the leader and trailer. The
leader was already there. There shouldn't be nulls in an ASCII file. The
whole point is to be able to prepare and look at input and output files
with a normal text editor.
So this version should work right. It "autogens" trailer more or less
forever. It doesn't really need to return a STOP code on EOF, but users
would probably forget to put form feed at the end, so it doesn't hurt.
1. Implemented Expensive Typewriter mode for TTO.
2. Added ASCII conversion on paper tape punch as well as reader.
3. Changed conversion tables to recognize form feed (014) as FIODEC STOP.
PROBLEM: Attempting to LOAD after a RESTORE of an MPE session aborts
the simulator with an "integer division by zero" exception.
OBSERVATION: Stopping the simulator during an idle MPE session,
saving the state to a file, exiting, restarting, restoring, and
attempting to perform a cold load aborts with a "divide by 0" error.
CAUSE: The "clk_update_counter" routine in hp3000_clk.c is called as
part of the instruction postlude to update the clock's counter
register. A calculation divides the elapsed time since the last tick
by the clock unit's "wait" value. The developer's manual stated that
this field is saved and restored automatically, but this is not true.
When the simulator is restarted, the "wait" field is initially zero.
If "clk_update_counter" is called before the clock's event service
routine resets the value, the calculation will divide by zero, which
causes the abort.
RESOLUTION: Modify "clk_reg" (hp3000_clk.c) to preset the unit wait
field with the MPE clock resolution value.
- This release of the HP 3000 simulator adds the following device simulation:
- 30209A Line Printer Controller with One 2607/13/17/18 Line Printer
The simulation supports the use of custom VFU tape images, as well as the
built-in HP-standard VFU tape. The simulated device name is "LP". The full set
of configurable options is detailed in a new section of the HP 3000 Simulator
User's Guide.
In addition, the preconfigured MPE-V/R disc image has been updated to add the
following features:
- The MPE cold load command files attach the line printer to the "lp.txt"
output file and specify the "-n" option to clear the file before use.
- Preinstalled User-Defined Commands (UDCs) provide access to the COBOL 74
compiler with the MPE-V/E :COBOLII, :COBOLIIPREP, and :COBOLIIGO commands,
and to the COBOL 85 compiler with :COBOLIIX, :COBOLIIXPREP, and :COBOLIIXGO.
However, see the implementation note below.
--------------------
Implementation Notes
--------------------
- MPE requires a line printer, so it is recommended that the MPE startup
simulator command file include an ATTACH LP <filename> command to load paper
into the printer before cold loading. If the printer is not attached, it
will appear to MPE to be out of paper.
- The line printer terminates each print line with an HP-standard CR/LF pair.
If the output file is to be retained as a text file on a Unix system, removal
of the carriage returns, e.g., via the "dos2unix" utility, may be desirable.
- The simulator currently does not provide the HP 32234A COBOL II firmware
instructions, so programs generated by the COBOLII compiler will abort at run
time with an "ILLEGAL INSTRUCTION" error. Programs generated by the COBOL
compiler do not use these instructions and therefore are not affected.
----------
Bugs Fixed
----------
1. PROBLEM: The effective address of a byte pointer with a negative index is
calculated incorrectly.
VERSION: Release 1
OBSERVATION: Defining a :WELCOME message in MPE appears to work, but when
the next logon attempts to print the message, an infinite number of CRLFs
are printed instead.
CAUSE: The welcome message is stored in an extra data segment. The format
for each message line is a line length stored in the lower byte of the word
preceding the message string. The code defines BYTE POINTER NEXTLINE and
points NEXTLINE to the first message character. The line length is set
with NEXTLINE(-1) := IOCOUNT. This generates a LOAD <IOCOUNT> ; LDXN 1 ;
STB <NEXTLINE>,I,X sequence.
In the "cpu_ea" routine, the indexing adds the X register value (-1) to the
byte pointer (NEXTLINE). This causes an overflow that is not masked to 16
bits. For a word access, this displacement is added to the base register
and then masked to 16 bits, which gives the correct value. However, for
byte accesses, the displacement is divided by 2 and then added, and the sum
is masked. Dividing by 2 shifts the overflow bit into the MSB, causing the
addition result to be off by 32K. The STB goes to the wrong location, the
original zero in the length byte location is retained, and when the welcome
message is printed, a zero-length line is printed, and the byte pointer is
incremented by zero, so the null line is printed forever.
RESOLUTION: Modify "cpu_ea" (hp3000_cpu.c) to mask indexed displacements
to 16 bits after adding the X register value.
STATUS: Fixed in Release 2.
2. PROBLEM: An SMSK instruction may clear the interrupt mask flip-flop of a
device that specifies that it is should be "always enabled."
VERSION: Release 1
OBSERVATION: If the TOS word is zero, an SMSK instruction will clear the
interrupt mask flip-flop of a device whose mask jumper is set to "E"
(always enabled).
CAUSE: In response to a DSETMASK signal, device interfaces set their
interrupt mask flip-flops by "anding" the incoming data word with the
interrupt mask jumper setting. The jumper setting value for "always
enabled" is %177777, which sets the mask flip-flop in all cases, except
when the data word is zero.
RESOLUTION: Modify hp3000_atc.c, hp3000_ds.c, and hp3000_ms.c to set their
mask flip-flops unconditionally if the jumper setting is "E".
STATUS: Fixed in Release 2.
3. PROBLEM: The "SET <dev> INTMASK=<n>" command sets the wrong bit in the
device interface's interrupt mask jumper setting.
VERSION: Release 1
OBSERVATION: The interrupt mask jumper on a device interface is set by
specifying the mask bit number in a "SET <dev> INTMASK=<n>" command. This
sets a bit in the device's interrupt mask jumper word corresponding to the
bit number requested. However, the bit numbering is incorrect; setting the
jumper for bit 15, for example, sets bit 0 of the jumper word. Therefore,
the interface's mask flip-flop is not set as expected when an SMSK
instruction is executed.
CAUSE: The bit numbers were counted from the wrong end of the word.
RESOLUTION: Modify "hp_set_dib" and "hp_show_dib" (hp3000_sys.c) to number
the bits from the MSB instead of the LSB.
STATUS: Fixed in Release 2.
4. PROBLEM: The Multiplexer Channel is not generating the ACKSR signal
correctly.
VERSION: Release 1
OBSERVATION: The line printer controller hangs when an SIO chained write
is performed. The first programmed write completes normally, but the
second does not start. The channel is waiting for a service request that
does not occur.
CAUSE: The service request from the last write of the first block transfer
is being cleared by an ACKSR generated by the Multiplexer Channel when it
performs the IOCW fetch in State A for the second write request. The
channel should omit this ACKSR when the previous I/O order was a chained
read or write. However, the simulator is testing the order just fetched
(Write) instead of the order that has just completed (Write Chained).
RESOLUTION: Modify "mpx_service" (hp3000_mpx.c) to test the correct I/O
order in State A.
STATUS: Fixed in Release 2.
- Previous changes made to support 32V's 60HZ clock tick introduced changes
which didn't properly handle increments and interrupt generation while single
stepping the timer.
- The icr_rd routine returned an incorrect value when interpolation was
necessary due to a missing cast when converting from double to uint32.
- Properly start the timer from the current state of the interval count register
when the timer was previously stopped.
When PNG support is available, both .png and .bmp screenshots can be
generated based on the file extension specified by the user on the SCREENSHOT
command. If no extension is specified, then a PNG format screenshot will be
produced.
Reworked all priority adjustment code to leverage a new
sim_os_set_thread_priority API which is coded to use pthreads or OS
priority adjustment APIs as necessary.
The new RUN/GO command syntax supports a stop criteria.
There are two forms of stop criteria:
1) A normal breakpoint (which exists only until it is encountered)
2) A user specified output string is emitted by the simulated system.
Command syntax is:
RUN|GO {START-PC-VALUE} {UNTIL breakpoint|"output-string"}
Multiple rules with the same match string are processed in the order the EXPECT
commands are entered. NOEXPECT will remove all pending EXPECT rules which
have the match string provided on the NOEXPECT line.
Compilation under Cygwin with gcc 5.3.0 - missing const gave rise to
incompatible pointer type warning, and _eth_get_system_id for _WIN32
was included under a conditional for either _WIN32 or __CYGWIN__
and later redefined for !_WIN32