- 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.
201 lines
8.4 KiB
C
201 lines
8.4 KiB
C
/* hp3000_cpu_ims.h: HP 3000 CPU-to-IOP/MPX/SEL interface declarations
|
|
|
|
Copyright (c) 2016, J. David Bryan
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Except as contained in this notice, the name of the author shall not be used
|
|
in advertising or otherwise to promote the sale, use or other dealings in
|
|
this Software without prior written authorization from the author.
|
|
|
|
11-Jun-16 JDB Bit mask constants are now unsigned
|
|
05-Sep-15 JDB First release version
|
|
11-Dec-12 JDB Created
|
|
|
|
|
|
This file contains declarations used by the CPU to interface with the HP 3000
|
|
I/O Processor, Multiplexer Channel, and Selector Channel.
|
|
*/
|
|
|
|
|
|
|
|
/* Global data structures */
|
|
|
|
|
|
/* I/O commands.
|
|
|
|
The enumeration values correspond to the IOP bus IOCMD0-2 signal
|
|
representations.
|
|
*/
|
|
|
|
typedef enum {
|
|
ioSIN = 0, /* set interrupt */
|
|
ioCIO = 1, /* control I/O */
|
|
ioSIO = 2, /* start I/O */
|
|
ioWIO = 3, /* write I/O */
|
|
ioRIN = 4, /* reset interrupt */
|
|
ioTIO = 5, /* test I/O */
|
|
ioSMSK = 6, /* set interrupt mask */
|
|
ioRIO = 7 /* read I/O */
|
|
} IO_COMMAND;
|
|
|
|
|
|
/* SIO program orders.
|
|
|
|
32-bit I/O program words are formed from a 16-bit I/O control word (IOCW) and
|
|
a 16-bit I/O address word (IOAW). The Interrupt, Control, Sense, Write, and
|
|
Read orders use this format:
|
|
|
|
0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
| C | order | control word 1/word count | IOCW
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
| control word 2/status/address | IOAW
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|
|
For the Write and Read orders only, bit 0 of the IOCW is the "data chain"
|
|
flag. If it is set, then this transfer is a continuation of the previous
|
|
Write or Read transfer.
|
|
|
|
The Jump, End, Return Residue, and Set Bank orders require an additional bit
|
|
(IOCW bit 4) to define their orders fully:
|
|
|
|
0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
| - | order | - - - - - - - - - - - | IOCW
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
| address/status/count | IOAW
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
| - - - - - - - - - - - - | bank | IOAW
|
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|
|
In simulation, IOCW bits 0-4 are used to index into a 32-element lookup table
|
|
to produce the final I/O order (because some of the orders define IOCW bit 4
|
|
as "don't care", there are only thirteen distinct orders).
|
|
|
|
|
|
Implementation notes:
|
|
|
|
1. The IOCW_COUNT(w) macro sign-extends the 12-bit two's-complement word
|
|
count in the IOCW for the Read and Write orders.
|
|
|
|
2. The sioWRITE, sioWRITEC, sioREAD, and sioREADC enumeration constants must
|
|
be contiguous and the final four values, so that a ">= sioWRITE" test
|
|
identifies all four cases.
|
|
*/
|
|
|
|
#define IOCW_DC 0100000u /* data chain */
|
|
#define IOCW_SIO_MASK 0070000u /* general SIO order mask */
|
|
#define IOCW_ORDER_MASK 0174000u /* fully decoded I/O order mask */
|
|
#define IOCW_CNTL_MASK 0007777u /* control word mask */
|
|
#define IOCW_WCNT_MASK 0007777u /* word count mask */
|
|
|
|
#define IOAW_BANK_MASK 0000017u /* bank number mask */
|
|
|
|
#define IOCW_ORDER_SHIFT 11 /* I/O order alignment shift */
|
|
#define IOCW_CNTL_SHIFT 0 /* control word alignment shift */
|
|
#define IOCW_WCNT_SHIFT 0 /* word count alignment shift */
|
|
|
|
#define IOAW_BANK_SHIFT 0 /* bank number alignment shift */
|
|
|
|
#define IOCW_ORDER(w) to_sio_order [((w) & IOCW_ORDER_MASK) >> IOCW_ORDER_SHIFT]
|
|
|
|
#define IOCW_CNTL(w) (((w) & IOCW_CNTL_MASK) >> IOCW_CNTL_SHIFT)
|
|
#define IOCW_WCNT(w) (((w) & IOCW_WCNT_MASK) >> IOCW_WCNT_SHIFT)
|
|
#define IOCW_COUNT(w) (- (int32) (~(w) + 1 & IOCW_WCNT_MASK))
|
|
|
|
#define IOAW_BANK(w) (((w) & IOAW_BANK_MASK) >> IOAW_BANK_SHIFT)
|
|
|
|
|
|
typedef enum {
|
|
sioJUMP, /* Jump unconditionally */
|
|
sioJUMPC, /* Jump conditionally */
|
|
sioRTRES, /* Return residue */
|
|
sioSBANK, /* Set bank */
|
|
sioINTRP, /* Interrupt */
|
|
sioEND, /* End */
|
|
sioENDIN, /* End with interrupt */
|
|
sioCNTL, /* Control */
|
|
sioSENSE, /* Sense */
|
|
sioWRITE, /* Write */
|
|
sioWRITEC, /* Write chained */
|
|
sioREAD, /* Read */
|
|
sioREADC /* Read chained */
|
|
} SIO_ORDER;
|
|
|
|
|
|
/* Global CPU routine declarations */
|
|
|
|
extern t_bool cpu_read_memory (ACCESS_CLASS classification, uint32 offset, HP_WORD *value);
|
|
extern t_bool cpu_write_memory (ACCESS_CLASS classification, uint32 offset, HP_WORD value);
|
|
|
|
|
|
/* Global SIO order structures.
|
|
|
|
to_sio_order : translates IOCW bits 1-4 to an SIO_ORDER
|
|
sio_order_name : the name of the orders indexed by SIO_ORDER
|
|
*/
|
|
|
|
extern const SIO_ORDER to_sio_order [];
|
|
extern const char *const sio_order_name [];
|
|
|
|
|
|
/* Global I/O processor state and functions.
|
|
|
|
iop_interrupt_request_set : the set of devices requesting interrupts
|
|
|
|
iop_initialize : initialize the I/O processor
|
|
iop_poll : poll the interfaces for an active interrupt request
|
|
iop_read_memory : read memory via the module control unit
|
|
iop_write_memory : write memory via the module control unit
|
|
iop_direct_io : dispatch an I/O command to an interface
|
|
*/
|
|
|
|
extern uint32 iop_interrupt_request_set;
|
|
|
|
extern uint32 iop_initialize (void);
|
|
extern uint32 iop_poll (void);
|
|
extern HP_WORD iop_direct_io (HP_WORD device_number, IO_COMMAND io_cmd, HP_WORD write_value);
|
|
|
|
|
|
/* Global multiplexer channel state and functions.
|
|
|
|
mpx_request_set : the set of pending channel service requests
|
|
|
|
mpx_initialize : initialize the multiplexer channel
|
|
mpx_service : poll the interfaces for an active service request
|
|
*/
|
|
|
|
extern uint32 mpx_request_set;
|
|
|
|
extern void mpx_initialize (void);
|
|
extern void mpx_service (uint32 ticks_elapsed);
|
|
|
|
|
|
/* Global selector channel state and functions
|
|
|
|
sel_request : TRUE if a pending channel service request
|
|
|
|
sel_initialize : initialize the selector channel
|
|
sel_service : service the interface with an active service request
|
|
*/
|
|
|
|
extern t_bool sel_request;
|
|
|
|
extern void sel_initialize (void);
|
|
extern void sel_service (uint32 ticks_elapsed);
|