HP3000: HP 3000 release 6

See HP3000/hp3000_release.txt for details of the release
This commit is contained in:
Mark Pizzolato 2017-09-09 13:56:50 -07:00
parent 68edc24b66
commit 7dc585d479
12 changed files with 545 additions and 276 deletions

View file

@ -1,6 +1,6 @@
/* hp3000_atc.c: HP 3000 30032B Asynchronous Terminal Controller simulator
Copyright (c) 2014-2016, J. David Bryan
Copyright (c) 2014-2017, J. David Bryan
Copyright (c) 2002-2012, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a copy
@ -26,6 +26,7 @@
ATCD,ATCC HP 30032B Asynchronous Terminal Controller
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
16-Sep-16 JDB Fixed atcd_detach to skip channel cancel if SIM_SW_REST
12-Sep-16 JDB Changed DIB register macro usage from SRDATA to DIB_REG
20-Jul-16 JDB Corrected poll_unit "wait" field initializer.
@ -926,17 +927,17 @@ static REG atcd_reg [] = {
/* ------ ------ ------------------- ----- ----- ------ ---------------- --------------- */
{ ORDATA (CNTL, tdi_control_word, 16), REG_FIT },
{ ORDATA (STAT, tdi_status_word, 16), REG_FIT },
{ ORDATA (READ, tdi_read_word, 16), REG_A | REG_FIT },
{ ORDATA (WRITE, tdi_write_word, 16), REG_A | REG_FIT },
{ ORDATA (READ, tdi_read_word, 16), REG_X | REG_FIT },
{ ORDATA (WRITE, tdi_write_word, 16), REG_X | REG_FIT },
{ FLDATA (FLAG, tdi_data_flag, 0) },
{ FLDATA (MASK, tdi_interrupt_mask, 0) },
{ DRDATA (FTIME, fast_data_time, 24), PV_LEFT },
{ BRDATA (RSTAT, recv_status, 8, 16, RECV_CHAN_COUNT) },
{ BRDATA (RPARM, recv_param, 8, 16, RECV_CHAN_COUNT) },
{ BRDATA (RBUFR, recv_buffer, 8, 16, RECV_CHAN_COUNT), REG_A },
{ BRDATA (RBUFR, recv_buffer, 8, 16, RECV_CHAN_COUNT), REG_X },
{ BRDATA (SSTAT, send_status, 8, 16, SEND_CHAN_COUNT) },
{ BRDATA (SPARM, send_param, 8, 16, SEND_CHAN_COUNT) },
{ BRDATA (SBUFR, send_buffer, 8, 16, SEND_CHAN_COUNT), REG_A },
{ BRDATA (SBUFR, send_buffer, 8, 16, SEND_CHAN_COUNT), REG_X },
{ FLDATA (POLL, atc_is_polling, 0), REG_HRO },
DIB_REGS (atcd_dib),

View file

@ -25,6 +25,8 @@
CPU HP 3000 Series III Central Processing Unit
05-Sep-17 JDB Removed the -B (binary display) option; use -2 instead
Changed REG_A (permit any symbolic override) to REG_X
19-Jan-17 JDB Added comments describing the OPND and EXEC trace options
29_Dec-16 JDB Changed the status mnemonic flag from REG_S to REG_T
07-Nov-16 JDB Renamed cpu_byte_to_word_ea to cpu_byte_ea
@ -1024,8 +1026,7 @@ UNIT cpu_unit [] = {
modification. User flags describe the permitted and default display formats,
as follows:
- REG_A permits any display
- REG_B permits binary display
- REG_X permits any symbolic display
- REG_M defaults to CPU instruction mnemonic display
- REG_T defaults to CPU status mnemonic display
@ -1058,15 +1059,15 @@ static REG cpu_reg [] = {
{ ORDATA (SR, SR, 3), REG_FIT }, /* stack register counter */
{ ORDATA (Z, Z, 16), REG_FIT }, /* stack limit register */
{ ORDATA (SBANK, SBANK, 4), REG_FIT }, /* stack segment bank register */
{ ORDATA (RA, TR [0], 16), REG_A | REG_FIT }, /* top of stack register */
{ ORDATA (RB, TR [1], 16), REG_A | REG_FIT }, /* top of stack - 1 register */
{ ORDATA (RC, TR [2], 16), REG_A | REG_FIT }, /* top of stack - 2 register */
{ ORDATA (RD, TR [3], 16), REG_A | REG_FIT }, /* top of stack - 3 register */
{ ORDATA (X, X, 16), REG_A | REG_FIT }, /* index register */
{ ORDATA (STA, STA, 16), REG_T | REG_B | REG_FIT }, /* status register */
{ ORDATA (SWCH, SWCH, 16), REG_A | REG_FIT }, /* switch register */
{ ORDATA (CPX1, CPX1, 16), REG_B | REG_FIT }, /* run-mode interrupt flags */
{ ORDATA (CPX2, CPX2, 16), REG_B | REG_FIT }, /* halt-mode interrupt flags */
{ ORDATA (RA, TR [0], 16), REG_X | REG_FIT }, /* top of stack register */
{ ORDATA (RB, TR [1], 16), REG_X | REG_FIT }, /* top of stack - 1 register */
{ ORDATA (RC, TR [2], 16), REG_X | REG_FIT }, /* top of stack - 2 register */
{ ORDATA (RD, TR [3], 16), REG_X | REG_FIT }, /* top of stack - 3 register */
{ ORDATA (X, X, 16), REG_X | REG_FIT }, /* index register */
{ ORDATA (STA, STA, 16), REG_T | REG_FIT }, /* status register */
{ ORDATA (SWCH, SWCH, 16), REG_X | REG_FIT }, /* switch register */
{ ORDATA (CPX1, CPX1, 16), REG_FIT }, /* run-mode interrupt flags */
{ ORDATA (CPX2, CPX2, 16), REG_FIT }, /* halt-mode interrupt flags */
{ ORDATA (PCLK, PCLK, 16), REG_FIT }, /* process clock register */
{ ORDATA (CNTR, CNTR, 6), REG_HRO | REG_FIT }, /* microcode counter */
{ ORDATA (MOD, MOD, 16), REG_HRO | REG_FIT }, /* module control register */
@ -1331,8 +1332,8 @@ DEVICE cpu_dev = {
volatile-qualified type and have been changed between the setjmp
invocation and longjmp call are indeterminate."
Therefore, after a microcode abort, we cannot depend upon the values of
any local variables.
Therefore, the "device" and "status" variables are marked volatile to
ensure that they are reloaded after a longjmp caused by a micrcode abort.
2. In hardware, the NEXT microcode order present at the end of each
instruction transfers the NIR content to the CIR, reads the memory word
@ -1398,10 +1399,11 @@ static const char *const stack_formats [] = { /* stack register displa
};
int abortval;
HP_WORD label, parameter, device;
HP_WORD label, parameter;
TRAP_CLASS trap;
t_bool exec_test;
t_stat status = SCPE_OK;
volatile HP_WORD device;
volatile t_stat status = SCPE_OK;
/* Instruction prelude */

View file

@ -147,10 +147,12 @@
/* Device register display mode flags */
#define REG_A (1u << REG_V_UF + 0) /* permit any display */
#define REG_B (1u << REG_V_UF + 1) /* permit binary display */
#define REG_M (1u << REG_V_UF + 2) /* default to instruction mnemonic display */
#define REG_T (1u << REG_V_UF + 3) /* default to status mnemonic display */
#define REG_X REG_VMIO /* permit symbolic display overrides */
#define REG_A (1u << REG_V_UF + 0) /* default format is -A (one ASCII character) */
#define REG_C (1u << REG_V_UF + 1) /* default format is -C (two ASCII characters) */
#define REG_M (1u << REG_V_UF + 2) /* default format is -M (mnemonic) */
#define REG_T (1u << REG_V_UF + 3) /* default format is -T (status mnemonic) */
/* Register macros.

View file

@ -1,6 +1,6 @@
/* hp3000_ds.c: HP 3000 30229B Cartridge Disc Interface simulator
Copyright (c) 2016, J. David Bryan
Copyright (c) 2016-2017, 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
@ -25,6 +25,7 @@
DS HP 30229B Cartridge Disc Interface
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
12-Sep-16 JDB Changed DIB register macro usage from SRDATA to DIB_REG
09-Jun-16 JDB Added casts for ptrdiff_t to int32 values
08-Jun-16 JDB Corrected %d format to %u for unsigned values
@ -435,7 +436,7 @@ static REG ds_reg [] = {
{ FLDATA (OVRUN, flags, 5) },
{ FLDATA (XFRNG, flags, 6) },
{ ORDATA (BUFFER, buffer_word, 16), REG_A | REG_FIT | PV_RZRO },
{ ORDATA (BUFFER, buffer_word, 16), REG_X | REG_FIT | PV_RZRO },
{ ORDATA (STATUS, status_word, 16), REG_FIT | PV_RZRO },
{ DRDATA (RETRY, retry_counter, 4), REG_FIT | PV_LEFT },

View file

@ -25,6 +25,12 @@
LP HP 30209A Line Printer Interface
07-Sep-17 JDB Changed PCHR and UPCHR registers to PUNCHR and UNPCHR
Changed PRTBUF, OVPCHR, PUNCHR, and UNPCHR to REG_A
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
20-Jul-17 JDB Added a forced detach option (-F switch) to "lp_detach"
24-Jun-17 JDB Added "report_error", fixed "lp_set_model" times bug
22-Jun-17 JDB Moved deferred offline/detach cancel to SET ONLINE
26-Apr-17 JDB Fixed "lp_service" return for VFU channel not punched
Restricted auto-print on buffer full to the 2607
Paper fault is now delayed until the TOF for the 2607
@ -205,19 +211,17 @@
issued while the print buffer contains data or the printer unit is busy
executing a print action.
The SET LP OFFLINE and SET LP DETACH commands check for data in the print
buffer or a print operation in progress. If either condition is true, they
set their respective deferred-action flags and display "Command deferred." A
SHOW LP will show that the device is still online and attached. Once
The SET LP OFFLINE and DETACH LP commands check for data in the print buffer
or a print operation in progress. If either condition is true, they set
their respective deferred-action flags and display "Command not completed."
A SHOW LP will show that the device is still online and attached. Once
simulation is resumed and the print operation completes, the printer is set
offline or detached as requested. No console message reports this, as it is
assumed that the executing program will detect the condition and report
accordingly. A subsequent SHOW LP will indicate the new status.
A SET LP ONLINE or ATTACH LP command when the corresponding deferred-action
flag is set simply clears the flag. In particular, an ATTACH LP command must
not specify a new image filename; if one is specified while a deferred detach
is in progress, the routine returns SCPE_NOFNC ("Command not allowed").
A SET LP ONLINE command when a deferred-action flag is set simply clears the
flag, which cancels the pending offline or detach condition.
A RESET LP command also clears the deferred-action flags and so clears any
pending offline or detach. However, it also clears the print buffer and
@ -480,11 +484,22 @@
#define DEV_REALTIME (1u << DEV_REALTIME_SHIFT) /* realistic timing flag */
/* Printer unit flags */
/* Printer unit flags.
#define UNIT_MODEL_SHIFT (UNIT_V_UF + 0) /* bits 0-2: printer model ID */
#define UNIT_EXPAND_SHIFT (UNIT_V_UF + 3) /* bits 3-3: printer uses expanded output */
#define UNIT_OFFLINE_SHIFT (UNIT_V_UF + 4) /* bits 4-4: printer is offline */
UNIT_V_UF + 7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| - | - | - | O | E | model |
+---+---+---+---+---+---+---+---+
Where:
O = offline
E = expanded output
*/
#define UNIT_MODEL_SHIFT (UNIT_V_UF + 0) /* printer model ID */
#define UNIT_EXPAND_SHIFT (UNIT_V_UF + 3) /* printer uses expanded output */
#define UNIT_OFFLINE_SHIFT (UNIT_V_UF + 4) /* printer is offline */
#define UNIT_MODEL_MASK 0000007u /* model ID mask */
@ -541,10 +556,10 @@ typedef enum {
This table contains the characteristics that vary between printer models.
The "char_set" field values reflect printer Option 001, 96/128-character set.
The "not_ready" field indicates whether a paper fault sets not-ready status
or simply takes the printer offline. The "fault_at_eol" field indicates
whether a paper fault is reported at the end of any line (TRUE) or only at
the top of the next form (FALSE).
The "not_ready" field indicates whether a paper fault sets a separate
not-ready status or simply takes the printer offline. The "fault_at_eol"
field indicates whether a paper fault is reported at the end of any line or
only at the top of the next form.
*/
typedef struct {
@ -579,9 +594,10 @@ static const PRINTER_PROPS print_props [] = { /* printer properties, indexed b
Implementation notes:
1. Although all of the printers operate more slowly with a 96/128-character
set than with a 64-character set, the times reflect the smaller set size.
Also, some models provide different print rates, depending on how many
and/or which characters are printed. These variances are not simulated.
set installed than with a 64-character set, the times reflect the smaller
set size. Also, some models provide different print rates, depending on
how many and/or which characters are printed. These variations are not
simulated.
*/
typedef struct {
@ -1046,7 +1062,7 @@ static t_bool power_warning = FALSE; /* PFWARN is not asserted to the
/* Printer state */
static t_bool paper_fault = TRUE; /* TRUE if the printer is out of paper */
static t_bool tape_fault = FALSE; /* TRUE if there is no punch in a VFU channel command */
static t_bool tape_fault = FALSE; /* TRUE if there is no punch in a commanded VFU channel */
static t_bool offline_pending = FALSE; /* TRUE if an offline request is waiting for the printer to finish */
static uint32 overprint_char = DEL; /* character to use if overprinted */
static uint32 current_line = 1; /* current form line */
@ -1077,6 +1093,7 @@ static t_stat ui_reset (DEVICE *dptr);
static t_stat master_reset (t_bool programmed_clear);
static void clear_interface_logic (void);
static void activate_unit (UNIT *uptr);
static void report_error (FILE *stream);
static OUTBOUND_SET set_interrupt (uint32 interrupt);
static OUTBOUND_SET set_device_status (uint32 status_mask, uint32 new_status_word);
static OUTBOUND_SET handshake_xfer (void);
@ -1177,12 +1194,12 @@ static REG lp_reg [] = {
{ ORDATA (CNTL, control_word, 16), PV_RZRO },
{ ORDATA (ISTAT, int_status_word, 16), PV_RZRO },
{ ORDATA (DSTAT, dev_status_word, 16), PV_RZRO },
{ ORDATA (READ, read_word, 16), PV_RZRO | REG_A },
{ ORDATA (WRITE, write_word, 16), PV_RZRO | REG_A },
{ ORDATA (READ, read_word, 16), PV_RZRO | REG_X },
{ ORDATA (WRITE, write_word, 16), PV_RZRO | REG_X },
{ YRDATA (J2WX, jumper_set, 10, PV_RZRO) },
{ ORDATA (DATOUT, data_out, 16), PV_RZRO | REG_A },
{ ORDATA (DATIN, data_in, 16), PV_RZRO | REG_A },
{ ORDATA (DATOUT, data_out, 16), PV_RZRO | REG_X },
{ ORDATA (DATIN, data_in, 16), PV_RZRO | REG_X },
{ FLDATA (DCOUT, device_command_out, 0) },
{ FLDATA (DFIN, device_flag_in, 0) },
@ -1206,8 +1223,8 @@ static REG lp_reg [] = {
{ DRDATA (FORMLN, form_length, 8), PV_LEFT | REG_RO },
{ BRDATA (TITLE, vfu_title, 8, 8, LINE_SIZE), REG_HRO },
{ BRDATA (VFU, VFU, 2, VFU_WIDTH, VFU_SIZE), PV_RZRO | REG_RO },
{ ORDATA (PCHR, punched_char, 8), PV_RZRO | REG_A },
{ ORDATA (UPCHR, unpunched_char, 8), PV_RZRO | REG_A },
{ ORDATA (PUNCHR, punched_char, 8), PV_RZRO | REG_A },
{ ORDATA (UNPCHR, unpunched_char, 8), PV_RZRO | REG_A },
{ DRDATA (BTIME, fast_times.buffer_load, 24), PV_LEFT | REG_NZ },
{ DRDATA (PTIME, fast_times.print, 24), PV_LEFT | REG_NZ },
@ -1795,7 +1812,7 @@ return SCPE_OK; /* return success */
Implementation notes:
1. Calling "master_clear" with a FALSE parameter indicates that this is a
1. Calling "master_reset" with a FALSE parameter indicates that this is a
commanded reset. This allows the connected device-specific reset
routines to distinguish from a Programmed Master Clear.
*/
@ -1911,6 +1928,23 @@ return;
}
/* Report a stream I/O error to the console.
If a stream I/O error has been detected, this routine will print an error
message to the simulation console and clear the stream's error indicator.
*/
static void report_error (FILE *stream)
{
cprintf ("%s simulator printer I/O error: %s\n", /* report the error to the console */
sim_name, strerror (errno));
clearerr (stream); /* clear the error */
return;
}
/* Set an interrupt.
The interrupt bit specified is set in the interrupt status word. If enabled,
@ -2491,11 +2525,12 @@ return outbound_signals; /* return INTREQ if any
conclude the handshake.
Control word bit 10 determines whether the code on the data out lines is
interpreted as a character (0) or a format command (1). Character data is
loaded into the buffer; if the line length is exceeded, the printer
automatically prints the buffer contents, advances the paper one line, and
stores the new character in the empty buffer. If a control character is sent
but the printer cannot print it, a space is loaded in its place.
interpreted as a character (0) or a format command (1). If there is room in
the print buffer, the character is loaded. If not, then depending on the
model, the printer either discards the character or automatically prints the
buffer contents, advances the paper one line, and stores the new character in
the empty buffer. If a control character is sent but the printer cannot
print it, a space is loaded in its place.
A format command causes the current buffer to be printed, and then the paper
is advanced by a prescribed amount. Two output modes are provided: compact
@ -2545,14 +2580,18 @@ return outbound_signals; /* return INTREQ if any
Implementation notes:
1. Because attached files are opened in binary mode, newline translation
1. When a paper-out condition is detected, the 2607 printer goes offline
only when the next top-of-form is reached. The 2613/17/18 printers go
offline as soon as the current line completes.
2. Because attached files are opened in binary mode, newline translation
(i.e., from LF to CR LF) is not performed by the host system. Therefore,
we write explicit CR LF pairs to end lines, even in compact mode, as
required for fidelity to HP peripherals. If bare LFs are used by the
host system, the printer output file must be postprocessed to remove the
CRs.
2. Overprinting in expanded mode is simulated by merging the lines in the
3. Overprinting in expanded mode is simulated by merging the lines in the
buffer. A format command to suppress spacing resets the buffer index but
saves the previous buffer length as a "high water mark" that will be
extended if the overlaying line is longer. This process may be repeated
@ -2565,25 +2604,31 @@ return outbound_signals; /* return INTREQ if any
"overprint character" (which defaults to DEL, but can be changed by the
user) replaces the character in the buffer.
3. Printers that support 12-channel VFUs treat the VFU format command as
4. Printers that support 12-channel VFUs treat the VFU format command as
modulo 16. Printers that support 8-channel VFUs treat the command as
modulo 8.
4. As a convenience to the user, the printer output file is flushed when a
TOF operation is performed.
5. As a convenience to the user, the printer output file is flushed when a
TOF operation is performed. This permits inspection of the output file
from the SCP command prompt while output is ongoing.
5. The user may examine the TFAULT and PFAULT registers to determine why the
6. The user may examine the TFAULT and PFAULT registers to determine why the
printer went offline.
6. The transfer service may be called with a null pointer to update the
7. The transfer service may be called with a null pointer to update the
potential change in the flag state.
7. If printing is attempted with the printer offline, this routine will be
8. If printing is attempted with the printer offline, this routine will be
called with STROBE asserted (device_command_in TRUE) and DEMAND denied
(device_flag_in TRUE). The printer ignores STROBE if DEMAND is not
asserted, so we simply return in this case. This will hang the handshake
until the printer is set online, and we are reentered with DEMAND
asserted.
asserted. As a consequence, explicit protection against "uptr->fileref"
being NULL is not required.
9. Explicit tests for lowercase and control characters are much faster and
are used rather than calls to "islower" and "iscntrl", which must
consider the current locale.
*/
static t_stat lp_service (UNIT *uptr)
@ -2829,10 +2874,7 @@ else if (device_flag_in == FALSE) { /* otherwise if STROBE h
}
if (ferror (uptr->fileref)) { /* if a host file system error occurred */
cprintf ("%s simulator printer I/O error: %s\n", /* then report the error to the console */
sim_name, strerror (errno));
clearerr (uptr->fileref); /* clear the error */
report_error (uptr->fileref); /* then report the error to the console */
lp_set_alarm (uptr); /* set an alarm condition */
return SCPE_IOERR; /* and stop the simulator */
@ -2849,7 +2891,7 @@ return SCPE_OK; /* return event service
equivalent of loading paper into the printer and pressing the ONLINE button.
The transition from offline to online causes an interrupt.
A new image file may be requested by giving the "-N" switch to the attach
A new image file may be requested by giving the "-N" switch to the ATTACH
command. If an existing file is specified with "-N", it will be cleared; if
specified without "-N", printer output will be appended to the end of the
existing file content. In all cases, the paper is positioned at the top of
@ -2869,7 +2911,7 @@ return SCPE_OK; /* return event service
static t_stat lp_attach (UNIT *uptr, CONST char *cptr)
{
t_stat result = SCPE_OK;
t_stat result;
result = attach_unit (uptr, cptr); /* attach the specified printer image file */
@ -2879,10 +2921,7 @@ if (result == SCPE_OK /* if the attach was suc
current_line = 1; /* reset the line counter to the top of the form */
if (sim_switches & SWMASK ('N')) /* if a new (empty) file was requested */
uptr->pos = 0; /* then position at the start of the file */
else if (fseek (uptr->fileref, 0, SEEK_END) == 0) /* otherwise append by seeking to the end of the file */
if (fseek (uptr->fileref, 0, SEEK_END) == 0) { /* append by seeking to the end of the file */
uptr->pos = (t_addr) ftell (uptr->fileref); /* and repositioning if the seek succeeded */
dprintf (lp_dev, DEB_CMD, "Printer paper loaded\n");
@ -2890,6 +2929,14 @@ if (result == SCPE_OK /* if the attach was suc
lp_set_locality (uptr, Online); /* set the printer online */
}
else { /* otherwise a host file system error occurred */
report_error (uptr->fileref); /* so report the error to the console */
lp_set_alarm (uptr); /* set an alarm condition */
result = SCPE_IOERR; /* and report that the attached failed */
}
}
paper_fault = FALSE; /* clear any existing paper fault */
if (lp_dev.flags & DEV_REALTIME) /* if the printer is in real-time mode */
@ -2904,10 +2951,10 @@ return result; /* return the result of
/* Detach the printer image file.
The specified file is detached from the indicated unit. This is the
simulation equivalent to unloading the paper from the printer or the printer
running out of paper. The out-of-paper condition cause a paper fault alarm,
and the printer goes offline. The transition from online to offline causes
an interrupt.
simulation equivalent of running out of paper or unloading the paper from the
printer. The out-of-paper condition cause a paper fault alarm, and the
printer goes offline. The transition from online to offline causes an
interrupt.
When the printer runs out of paper, it will not go offline until characters
present in the buffer are printed and paper motion stops. In addition, the
@ -2916,7 +2963,10 @@ return result; /* return the result of
In simulation, entering a DETACH LP command while the printer is busy will
defer the file detach until print operations reach the top of the next form
(2607) or until the current print operation completes (2613/17/18).
(2607) or until the current print operation completes (2613/17/18). An
immediate detach may be forced by adding the -F switch to the DETACH command.
This simulates physically removing the paper from the printer and succeeds
regardless of the current printer state.
Implementation notes:
@ -2943,10 +2993,16 @@ if (uptr->flags & UNIT_ATTABLE) /* if we're being called
if ((uptr->flags & UNIT_ATT) == 0) /* then if the unit is not currently attached */
return SCPE_UNATT; /* then report it */
else if ((print_props [model].fault_at_eol /* otherwise if the printer faults at the end of any line */
else {
if (sim_switches & (SWMASK ('F') | SIM_SW_SHUT)) { /* if this is a forced detach or shut down request */
current_line = 1; /* then reset the printer to TOF to enable detaching */
sim_cancel (uptr); /* and terminate */
device_command_out = FALSE; /* any print action in progress */
}
if ((print_props [model].fault_at_eol /* otherwise if the printer faults at the end of any line */
|| current_line == 1) /* or the printer is at the top of the form */
&& lp_set_alarm (uptr) /* and a paper alarm is accepted */
|| (sim_switches & SIM_SW_SHUT)) { /* or this is a shutdown call */
&& lp_set_alarm (uptr)) { /* and a paper alarm is accepted */
paper_fault = TRUE; /* then set the out-of-paper condition */
dprintf (lp_dev, DEB_CMD, "Printer is out of paper\n");
@ -2960,8 +3016,9 @@ if (uptr->flags & UNIT_ATTABLE) /* if we're being called
dprintf (lp_dev, DEB_CMD, "Paper out request deferred until print completes\n");
cputs ("Command deferred\n"); /* but the actual detach must be deferred */
return SCPE_OK; /* until the buffer prints */
cprintf ("%s\n", sim_error_text (SCPE_INCOMP)); /* report that the actual detach must be deferred */
return SCPE_OK; /* until the buffer has been printed */
}
}
else /* otherwise */
@ -3018,7 +3075,7 @@ switch ((DEVICE_MODES) value) { /* dispatch the mode to
break;
}
return SCPE_OK; /* the mode change succeeds */
return SCPE_OK; /* mode changes always succeed */
}
@ -3033,7 +3090,7 @@ return SCPE_OK; /* the mode change succe
static t_stat lp_set_model (UNIT *uptr, int32 value, CONST char *cptr, void *desc)
{
if (lp_dev.flags & DEV_REALTIME) /* if the printer is in real-time mode */
dlyptr = &real_times [GET_MODEL (uptr->flags)]; /* then use the times for the new model */
dlyptr = &real_times [GET_MODEL (value)]; /* then use the times for the new model */
return SCPE_OK; /* allow the reassignment to proceed */
}
@ -3044,26 +3101,29 @@ return SCPE_OK; /* allow the reassignmen
This validation routine is called to set the printer online or offline. The
"value" parameter is UNIT_OFFLINE if the printer is going offline and is zero
if the printer is going online. This simulates pressing the ON/OFFLINE
button on the printer.
button on the printer. The unit must be attached (i.e., paper must be
loaded), before the printer may be set online or offline.
If the printer is being taken offline, the buffer is checked to see if any
characters are present. If they are, or if the printer unit is currently
scheduled (i.e., executing a print operation), the offline request is
deferred until printing completes, and the routine prints "Command deferred"
to inform the user. Otherwise, the unit is set offline, DEMAND is denied,
and DEV END is asserted to indicate that the printer is not ready.
//
As a special case, a detach (out-of-paper condition) that has been deferred
until printing completes may be cancelled by setting the printer online.
deferred until printing completes, and the routine returns "Command not
complete" status to inform the user. Otherwise, the unit is set offline,
DEMAND is denied, and DEV END is asserted to indicate that the printer is not
ready.
If the printer is being put online, the unit must be attached (i.e., paper
must be loaded), or the command is rejected. If paper is present, the unit
is set online, and any tape fault present is cleared. If the sequencer
If the printer is being put online and paper is present, the unit is set
online, and any paper or tape fault present is cleared. If the sequencer
indicates an incomplete handshake, as would occur if paper ran out while
printing, the transfer service is called to complete the handshake by
asserting DEMAND. Otherwise, DEMAND is asserted explicitly, and DEV END is
denied.
As a special case, a detach (out-of-paper condition) or offline request that
has been deferred until printing completes may be cancelled by setting the
printer online. No other action is taken, because the printer has never
transitioned to the offline state.
Transitions between the offline and online state cause interrupts, and INTREQ
is asserted to the IOP if a transition occurred (but not, e.g., for a SET LP
OFFLINE command where the printer is already offline).
@ -3071,9 +3131,9 @@ return SCPE_OK; /* allow the reassignmen
Implementation notes:
1. Because a deferred offline request is not fatal, we return SCPE_OK to
allow command files to continue to execute, but we print a warning to the
user.
1. Although a deferred offline request is not fatal, we return SCPE_INCOMP
to prevent "set_cmd" from setting the UNIT_OFFLINE bit in the unit flags
before the printer actually goes offline.
*/
static t_stat lp_set_on_offline (UNIT *uptr, int32 value, CONST char *cptr, void *desc)
@ -3091,8 +3151,8 @@ else if (value == UNIT_ONLINE) /* otherwise if this is
lp_set_locality (uptr, Online); /* so set the printer online */
else if (lp_set_locality (uptr, Offline) == FALSE) { /* otherwise if it cannot be set offline now */
cputs ("Command deferred\n"); /* then let the user know */
dprintf (lp_dev, DEB_CMD, "Offline request deferred until print completes\n");
return SCPE_INCOMP; /* then let the user know */
}
return SCPE_OK; /* return operation success */
@ -3189,8 +3249,8 @@ static t_stat lp_show_vfu (FILE *st, UNIT *uptr, int32 value, CONST void *desc)
static const char header_1 [] = " Ch 1 Ch 2 Ch 3 Ch 4 Ch 5 Ch 6 Ch 7 Ch 8 Ch 9 Ch10 Ch11 Ch12";
static const char header_2 [] = " ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----";
const PRINTER_TYPE model = GET_MODEL (uptr->flags);
const uint32 channel_count = print_props [model].vfu_channels;
const PRINTER_TYPE model = GET_MODEL (uptr->flags); /* the printer model number */
const uint32 channel_count = print_props [model].vfu_channels; /* the count of VFU channels */
uint32 chan, line, current_channel;
if (value == 0) /* if we're called for a summary display */
@ -3328,8 +3388,8 @@ return NO_SIGNALS; /* no special control ac
This routine is called when an alarm condition exists. An alarm occurs when
paper is out (paper fault) or a VFU command addresses a channel that does not
contain a punch (tape fault). In response, the printer goes not ready and
offline.
contain a punch (tape fault). In response, the printer goes offline and,
for all models except the 2607, becomes not-ready.
On entry, the routine attempts to set the printer offline. If this succeeds,
the printer is set not-ready. If it fails (for reasons explained in the
@ -3430,9 +3490,8 @@ dprintf (lp_dev, DEB_CMD, "Printer set %s\n",
if (signals & INTREQ) /* if the transition caused an interrupt */
iop_assert_INTREQ (&lp_dib); /* then assert the INTREQ signal */
offline_pending = FALSE;
return TRUE;
offline_pending = FALSE; /* the operation completed */
return TRUE; /* successfully */
}
@ -3442,8 +3501,8 @@ return TRUE;
associated with the stream "vf" or with the standard 66-line tape if the
stream is NULL. The "uptr" parameter points to the printer unit.
The standard VFU tape (1535-2655 for the 8-channel HP 2607 and 2613-80001 for
the 12-channel HP 2613, 2617, and 2618) defines the channels as:
The standard VFU tape (02607-80024 for the 8-channel HP 2607 and 02613-80001
for the 12-channel HP 2613, 2617, and 2618) defines the channels as:
Chan Description
---- --------------
@ -3457,12 +3516,12 @@ return TRUE;
8 Sixth page
9 Bottom of form
...with channels 10-12 uncommitted. A custom tape must dedicate channel 1 to
the top-of-form, but the other channels may be defined as desired.
...with channels 10-12 uncommitted.
A custom tape file starts with a VFU definition line and then contains one
channel-definition line for each line of the form. The number of lines
establishes the form length.
establishes the form length. Channel 1 must be dedicated to the top-of-form,
but the other channels may be defined as desired.
A semicolon appearing anywhere on a line begins a comment, and the semicolon
and all following characters are ignored. Zero-length lines, including lines
@ -3542,7 +3601,7 @@ return TRUE;
static t_stat lp_load_vfu (UNIT *uptr, FILE *vf)
{
const PRINTER_TYPE model = GET_MODEL (uptr->flags); /* get the printer type */
const PRINTER_TYPE model = GET_MODEL (uptr->flags); /* the printer model number */
uint32 line, channel, vfu_status;
int32 len;
char buffer [LINE_SIZE], punch [LINE_SIZE], no_punch;
@ -3550,10 +3609,8 @@ char *bptr, *tptr;
uint16 tape [VFU_SIZE] = { 0 };
if (vf == NULL) { /* if the standard VFU is requested */
strcpy (vfu_title, "Standard VFU"); /* then set the title */
tape [ 1] = VFU_CHANNEL_1; /* punch channel 1 for the top of form */
tape [60] = VFU_CHANNEL_2 | VFU_CHANNEL_9; /* punch channels 2 and 9 for the bottom of form */
tape [ 1] = VFU_CHANNEL_1; /* then punch channel 1 for the top of form */
tape [60] = VFU_CHANNEL_2 | VFU_CHANNEL_9; /* and channels 2 and 9 for the bottom of form */
for (line = 1; line <= 60; line++) { /* load each of the 60 printable lines */
tape [line] |= VFU_CHANNEL_3 /* punch channel 3 for single space */
@ -3567,6 +3624,7 @@ if (vf == NULL) { /* if the standard VFU i
}
form_length = 66; /* set the form length */
strcpy (vfu_title, "Standard VFU"); /* and set the title */
}
else { /* otherwise load a custom VFU from the file */
@ -3690,11 +3748,8 @@ while (len == 0) {
if (feof (vf)) /* then if the end of file was seen */
return 0; /* then return an EOF indication */
else { /* otherwise report the error to the console */
cprintf ("%s simulator line printer I/O error: %s\n",
sim_name, strerror (errno));
clearerr (vf); /* clear the error */
else { /* otherwise */
report_error (vf); /* report the error to the console */
return -1; /* and return an error indication */
}

View file

@ -1,6 +1,6 @@
/* hp3000_ms.c: HP 3000 30215A Magnetic Tape Controller Interface simulator
Copyright (c) 2016, J. David Bryan
Copyright (c) 2016-2017, 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
@ -25,6 +25,7 @@
MS HP 30215A Magnetic Tape Controller Interface
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
12-Sep-16 JDB Changed DIB register macro usage from SRDATA to DIB_REG
09-Jun-16 JDB Added casts for ptrdiff_t to int32 values
08-Jun-16 JDB Corrected %d format to %u for unsigned values
@ -514,7 +515,7 @@ static REG ms_reg [] = {
{ FLDATA (UINTRP, unit_interrupt, 0) },
{ FLDATA (DEVEND, device_end, 0) },
{ FLDATA (XFRERR, xfer_error, 0) },
{ ORDATA (BUFWRD, buffer_word, 16), REG_A | REG_FIT | PV_RZRO },
{ ORDATA (BUFWRD, buffer_word, 16), REG_X | REG_FIT | PV_RZRO },
{ DRDATA (ATUNIT, attention_unit, 16), REG_FIT | PV_LEFT },
{ DRDATA (CLASS, command_class, 4), PV_LEFT },
{ YRDATA (FLAGS, flags, 8, PV_RZRO) },

View file

@ -1,6 +1,6 @@
SIMH/HP 3000 RELEASE NOTES
==========================
Last update: 2017-04-30
Last update: 2017-09-07
This file documents the release history of the Hewlett-Packard 3000 simulator.
@ -176,6 +176,107 @@ the MPE version used:
=====================
Release 6, 2017-09-07
=====================
This release of the HP 3000 simulator adds the following features:
- The new "-F" switch to the DETACH LP command forces an immediate detach,
regardless of the current paper position. This is the simulation equivalent
of physically removing the paper from the printer. Without the switch,
detaching is the equivalent of running out of paper, which permits printing
to continue to the end of the line (2613/17/18) or the page (2607) before the
printer goes offline.
- The HP 3000 Simulator User's Guide has been revised to add a new section
describing the simulator commands corresponding to hardware actions and to
rewrite the "Realistic, Calibrated, and Optimized Timing" section to describe
the three timing modes more clearly.
--------------------
Implementation Notes
--------------------
- The LP device's PCHR (punched channel character) and UPCHR (unpunched channel
character) registers have been renamed to PUNCHR and UNPCHR, respectively,
for compatibility with the HP 2100 simulator's LPT device.
- The manual clarifies that the display radix for shift counts, bit positions,
starting bits and counts, and the CIR values for the PAUS and HALT
instructions may be overridden with command-line switches.
----------
Bugs Fixed
----------
1. PROBLEM: Cancelling a deferred detach with ATTACH LP is rejected.
VERSION: Release 5.
OBSERVATION: The line printer "Unit Options" section of the HP 3000
Simulator User's Guide states that a DETACH LP command will be deferred if
there are characters in the print buffer. It further states that entering
ATTACH LP without specifying a filename will cancel the action. This does
not work. Entering ATTACH LP prints "Too few arguments" and does not alter
a pending detach.
CAUSE: The SCP routine "attach_cmd" checks for the presence of a filename
before calling the line printer simulator's "lp_attach" routine. If the
filename is omitted, "lp_attach" is never called to cancel the pending
detach.
RESOLUTION: Modify "lp_set_on_offline" (hp3000_lp.c) to cancel a deferred
detach, and modify the User's Guide to state that SET LP ONLINE is used to
cancel both the deferred offline and deferred detach actions.
STATUS: Fixed in Release 6.
2. PROBLEM: Changing printer models does not change the REALTIME delays.
VERSION: Release 5.
OBSERVATION: In REALTIME mode, the line printer simulator attempts to
model the print buffer load and print-and-space operation delays inherent
in the physical hardware. However, after setting a different model, the
buffer load, print, and paper advance times have not been changed.
CAUSE: The "lp_set_model" routine that is called in response to a "SET
LP <model>" command sets the realistic times to those of the current model
rather than those of the new model.
RESOLUTION: Modify "lp_set_model" (hp3000_lp.c) to use the new model value
to index into the realistic times array.
STATUS: Fixed in Release 6.
3. PROBLEM: Paper cannot be removed from a 2607 printer except at the TOF.
VERSION: Release 5.
OBSERVATION: Printing a few lines on a 2607 and then attempting to remove
the paper with the DETACH LP command displays "Command not completed" on
the simulation console. The file remains attached and therefore cannot be
manipulated externally.
CAUSE: The DETACH command simulates both running out of paper and removing
the paper from the printer. For the former, the 2607 continues to print
until the current form is complete (i.e., the top of what would be the next
form is reached). For the latter, the paper may be physically removed by
the operator while at any print position. The simulator incorrectly
forbids the latter operation unless the paper is positioned at the TOF.
RESOLUTION: Modify "lp_detach" (hp3000_lp.c) to add a "forced detach"
option ("DETACH -F LP") to detach the printer regardless of print position.
STATUS: Fixed in Release 6.
=====================
Release 5, 2017-04-30
=====================

View file

@ -1,6 +1,6 @@
/* hp3000_sel.c: HP 3000 30030C Selector Channel simulator
Copyright (c) 2016, J. David Bryan
Copyright (c) 2016-2017, 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
@ -25,6 +25,7 @@
SEL HP 3000 Series III Selector Channel
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
10-Oct-16 JDB Renumbered debug flags to start at 0
Added port_read_memory, port_write_memory macros
11-Jul-16 JDB Change "sel_unit" from a UNIT to an array of one UNIT
@ -458,8 +459,8 @@ static REG sel_reg [] = {
{ ORDATA (CNBUF, control_buffer, 16), REG_FIT },
{ ORDATA (ADDR, address_word, 16), REG_FIT },
{ ORDATA (ADBUF, address_buffer, 16), REG_FIT },
{ ORDATA (INBUF, input_buffer, 16), REG_A | REG_FIT },
{ ORDATA (OUTBUF, output_buffer, 16), REG_A | REG_FIT },
{ ORDATA (INBUF, input_buffer, 16), REG_X | REG_FIT },
{ ORDATA (OUTBUF, output_buffer, 16), REG_X | REG_FIT },
{ NULL }
};

View file

@ -23,6 +23,9 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the author.
05-Sep-17 JDB Removed the -B (binary display) option; use -2 instead
Rewrote "fprint_sym" for better coverage
11-May-17 JDB Corrected comment in "fprint_value"
28-Apr-17 JDB Added void cast to "fprint_instruction" call for left stackop
03-Mar-17 JDB Added an implementation note to the "parse_sym" routine
29-Dec-16 JDB Changed the switch for STA format from -S to -T;
@ -33,7 +36,7 @@
27-Sep-16 JDB Added COBOL firmware mnemonics
Modified "fprint_instruction" to handle two-word instructions
15-Sep-16 JDB Modified "one_time_init" to set aux_cmds "message" field
03-Sep-16 JDB Added the STOP_POWER and STOP_ARSINH messages
03-Sep-16 JDB Added the STOP_POWER and STOP_ARSINH status messages
01-Sep-16 JDB Moved the "hp_cold_cmd" routine to the CPU (as "cpu_cold_cmd")
Added the POWER command
03-Aug-16 JDB Improved "fmt_char" and "fmt_bitset" to allow multiple calls
@ -100,6 +103,26 @@ extern DEVICE ms_dev; /* 7970 Magnetic Tape */
#define SCPE_OK_3_WORDS ((t_stat) -2) /* three words produced or consumed */
/* Symbolic mode and format override switches */
#define A_SWITCH SWMASK ('A')
#define B_SWITCH SWMASK ('B')
#define C_SWITCH SWMASK ('C')
#define D_SWITCH SWMASK ('D')
#define E_SWITCH SWMASK ('E')
#define H_SWITCH SWMASK ('H')
#define I_SWITCH SWMASK ('I')
#define M_SWITCH SWMASK ('M')
#define O_SWITCH SWMASK ('O')
#define T_SWITCH SWMASK ('T')
#define MODE_SWITCHES (C_SWITCH | E_SWITCH | I_SWITCH | M_SWITCH | T_SWITCH)
#define FORMAT_SWITCHES (A_SWITCH | B_SWITCH | D_SWITCH | H_SWITCH | O_SWITCH)
#define SYMBOLIC_SWITCHES (MODE_SWITCHES | A_SWITCH) /* -A is both a mode and a format switch */
#define ALL_SWITCHES (MODE_SWITCHES | FORMAT_SWITCHES)
/* Address parsing configuration flags */
typedef enum {
@ -952,7 +975,7 @@ static t_stat hp_brk_cmd (int32 arg, CONST char *buf);
/* System interface local utility routines */
static void fprint_value (FILE *ofile, t_value val, uint32 radix, uint32 width, uint32 format);
static t_stat fprint_value (FILE *ofile, t_value val, uint32 radix, uint32 width, uint32 format);
static t_stat fprint_order (FILE *ofile, t_value *val, uint32 radix);
static t_stat fprint_subop (FILE *ofile, t_value *val, uint32 radix, t_addr addr, int32 switches);
static t_stat fprint_instruction (FILE *ofile, const OP_TABLE ops, t_value *val,
@ -1177,58 +1200,85 @@ return SCPE_ARG; /* return an error if ca
/* Print a value in symbolic format.
Print the data value in the format specified by the optional switches on the
output stream supplied. This routine is called to print:
This routine prints a data value in the format specified by the optional
switches on the output stream provided. On entry, "ofile" is the opened
output stream, and the other parameters depend on the reason the routine was
called, as follows:
- the next instruction mnemonic when the simulator stops
- the result of EXAMining a register marked with a user flag
- the result of EXAMining a memory address
- the result of EVALuating a symbol
* To print the next instruction mnemonic when the simulator stops:
- addr = the program counter
- val = a pointer to sim_eval [0]
- uptr = NULL
- sw = "-M" | SIM_SW_STOP
On entry, "ofile" is the opened output stream, "addr" is respectively the
program counter, register radix and flags, memory address, or symbol index,
"val" is a pointer to an array of t_values of depth "sim_emax" representing
the value to be printed, "uptr" is respectively NULL, NULL, a pointer to the
named unit, or a pointer to the default unit, and "sw" contains any switches
passed on the command line. "sw" also includes SIM_SW_STOP for a simulator
stop call or SIM_SW_REG for a register call.
* To print the result of EXAMining a register with REG_VMIO or a user flag:
- addr = the ORed register radix and user flags
- val = a pointer to a single t_value
- uptr = NULL
- sw = the command line switches | SIM_SW_REG
* To print the result of EXAMining a memory address:
- addr = the memory address
- val = a pointer to sim_eval [0]
- uptr = a pointer to the named unit
- sw = the command line switches
* To print the result of EVALuating a symbol:
- addr = the symbol index
- val = a pointer to sim_eval [addr]
- uptr = a pointer to the default unit (cpu_unit)
- sw = the command line switches
On exit, a status code is returned to the caller. If the format requested is
not supported, SCPE_ARG status is returned, which causes the caller to print
the value in numeric format. Otherwise, SCPE_OK status is returned if a
single-word value was consumed, or the negative number of extra words (beyond
the first) consumed in printing the symbol is returned. For example,
printing a two-word symbol would return SCPE_OK_2_WORDS (= -1).
the value in numeric format with the default radix. Otherwise, SCPE_OK
status is returned if a single-word value was consumed, or the negative
number of extra words (beyond the first) consumed in printing the symbol is
returned. For example, printing a two-word symbol would return
SCPE_OK_2_WORDS (= -1).
The following symbolic formats are supported by the listed switches:
The following symbolic modes are supported by including the indicated
switches on the command line:
Switch Interpretation
Switch Display Interpretation
------ --------------------------------------------------
-a a single character in the right-hand byte
-b a 16-bit binary value
-c a two-character packed string
-e an EDIT instruction subprogram mnemonic
-i an I/O program instruction mnemonic
-m a CPU instruction mnemonic
-s a CPU status mnemonic
-A a single character in the right-hand byte
-C a two-character packed string
-E an EDIT instruction subprogram mnemonic
-ER an EDIT mnemonic starting with the right-hand byte
-I an I/O program instruction mnemonic
-M a CPU instruction mnemonic
-T a CPU status mnemonic
-o override numeric output to octal
-d override numeric output to decimal
-h override numeric output to hex
-r begin EDIT interpretation with the right-hand byte
In the absence of a mode switch, the value is displayed in a numeric format.
Memory may be displayed in any format. All registers may be overridden to
display in octal, decimal, or hexadecimal numeric format. Only registers
marked with the REG_A flag may be displayed in any format. Registers marked
with REG_B may be displayed in binary format. Registers marked with REG_M
will default to CPU instruction mnemonic display. Registers marked with
REG_T will default to CPU status mnemonic display.
When displaying data in one of the mnemonic modes, an additional switch may
be specified to indicate the desired operand format, as follows:
When displaying mnemonics, operand values are displayed in a radix suitable
to the type of the value. Address values are displayed in the CPU's address
radix, which is octal, and data values are displayed in the CPU's data radix,
which defaults to octal but may be set to a different radix or overridden by
a switch on the command line.
Switch Operand Interpretation
------ --------------------------------------------------
-A a single character in the right-hand byte
-B a binary value
-O an octal value
-D a decimal value
-H a hexadecimal value
Except for -B, these switches may be used without a mode switch to display a
numeric value in the specified form. To summarize, the valid switch
combinations are:
-A
-C
-E [ -R ] [ -A | -B | -O | -D | -H ]
-I [ -A | -B | -O | -D | -H ]
-M [ -A | -B | -O | -D | -H ]
-T [ -A | -B | -O | -D | -H ]
When displaying mnemonics, operand values by default are displayed in a radix
suitable to the type of the value. Address values are displayed in the CPU's
address radix, which is octal, and data values are displayed in the CPU's
data radix, which defaults to octal but may be set to a different radix or
overridden by a switch on the command line.
Implementation notes:
@ -1241,76 +1291,116 @@ return SCPE_ARG; /* return an error if ca
2. Displaying a register having a symbolic default format (e.g., CIR) will
use the default unless the radix is overridden on the command line. For
example, "EXAMINE CIR" displays the CIR value as an instruction mnemonic,
whereas "EXAMINE -O CIR" displays the value as octal. Adding "-M" will
whereas "EXAMINE -D CIR" displays the value as decimal. Adding "-M" will
force mnemonic display and allow the radix switch to override the operand
display. For example, "EXAMINE -M -O CIR" displays the value as mnemonic
and overrides the operand radix to octal.
display. For example, "EXAMINE -M -D CIR" displays the value as mnemonic
and overrides the operand radix to decimal.
3. We return SCPE_INVSW when multiple modes or formats are specified, but
the callers do not act on this; they use the fallback formatter if any
status error is returned. We could work around this by printing "Invalid
switch" to the console and returning SCPE_OK, but this does not stop
IEXAMINE from prompting for the replacement value(s) or EXAMINE from
printing a range.
4. Radix switches and the -C switch are conceptually mutually exclusive.
However, if we return an error when "format" is non-zero, then -C will be
ignored, and the fallback formatter will use the radix switch. The other
choice is to process -C and ignore the radix switch; this is the option
implemented.
5. Because -A is both a mode and a format switch, we must check its presence
using SYMBOLIC_SWITCHES separately from the other modes to allow (e.g.)
both "EXAMINE -A" and "EXAMINE -M -A". If -A is added to MODE_SWITCHES,
the latter form would be rejected as having conflicting modes.
6. The penultimate condition of the multiway "if-else if" mode test checks
for no mode switches. This succeeds when -A is specified alone because
the earlier SYMBOLIC_SWITCHES test failed (so -A is present), but none of
the other mode switches are present.
*/
t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
{
const t_bool is_reg = (sw & SIM_SW_REG) != 0; /* TRUE if this is a register access */
uint32 radix_override;
int32 formats, modes;
uint32 radix;
if (sw & SWMASK ('A') && (!is_reg || addr & REG_A)) /* if ASCII character display is requested and permitted */
if (val [0] <= D8_SMAX) { /* then if the value is a single character */
fputs (fmt_char ((uint32) val [0]), ofile); /* then format and print it */
return SCPE_OK;
}
if ((sw & (SIM_SW_REG | ALL_SWITCHES)) == SIM_SW_REG) /* if we are formatting a register without overrides */
if (addr & REG_A) /* then if the default format is character */
sw |= A_SWITCH; /* then set the -A switch */
else /* otherwise */
return SCPE_ARG; /* report that it cannot be displayed */
else if (addr & REG_C) /* otherwise if the default mode is string */
sw |= C_SWITCH; /* then set the -C switch */
else if (sw & SWMASK ('C') && (!is_reg || addr & REG_A)) { /* if ASCII string display is requested and permitted */
fputs (fmt_char (UPPER_BYTE (val [0])), ofile); /* then format and print the upper byte */
fputc (',', ofile); /* followed by a separator */
fputs (fmt_char (LOWER_BYTE (val [0])), ofile); /* then format and print the lower byte */
return SCPE_OK;
}
else if (addr & REG_M) /* otherwise if the default mode is instruction mnemonic */
sw |= M_SWITCH; /* then set the -M switch */
else if (sw & SWMASK ('B') /* if binary display is requested */
&& (!is_reg || addr & (REG_A | REG_B))) { /* and is permitted */
fprint_val (ofile, val [0], 2, DV_WIDTH, PV_RZRO); /* then format and print the value */
return SCPE_OK;
}
else if (addr & REG_T) /* otherwise if the default mode is status */
sw |= T_SWITCH; /* then set the -T switch */
else { /* otherwise display as numeric or mnemonic */
if (sw & SWMASK ('O')) /* if an octal override is present */
radix_override = 8; /* then print the value in base 8 */
else if (sw & SWMASK ('D')) /* otherwise if a decimal override is present */
radix_override = 10; /* then print the value in base 10 */
else if (sw & SWMASK ('H')) /* otherwise if a hex override is present */
radix_override = 16; /* then print the value in base 16 */
else /* otherwise */
radix_override = 0; /* use the default radix setting */
if ((sw & SYMBOLIC_SWITCHES) == 0) /* if there are no symbolic mode overrides */
return SCPE_ARG; /* then return an error to use the standard formatter */
if (sw & SWMASK ('I') && !is_reg) /* if I/O channel order memory display is requested */
return fprint_order (ofile, val, radix_override); /* then format and print it */
else if (sw & SWMASK ('E') && !is_reg) /* otherwise if an EDIT subop memory display is requested */
return fprint_subop (ofile, val, radix_override, addr, sw);
formats = sw & FORMAT_SWITCHES; /* separate the format switches */
modes = sw & MODE_SWITCHES; /* from the mode switches */
else if (sw & SWMASK ('M') /* otherwise if CPU instruction display is requested */
&& (!is_reg || addr & (REG_A | REG_M)) /* and is permitted */
|| is_reg && addr & REG_M && radix_override == 0) /* or if displaying a register that defaults to mnemonic */
return fprint_cpu (ofile, val, radix_override, sw); /* then format and print it */
if (formats == A_SWITCH) /* if the -A switch is specified */
radix = 256; /* then override the radix to character */
else if (sw & SWMASK ('T') /* otherwise if status display is requested */
&& (!is_reg || addr & (REG_A | REG_T)) /* and is permitted */
|| is_reg && addr & REG_T && radix_override == 0) { /* or if displaying a register that defaults to status */
else if (formats == B_SWITCH) /* otherwise if the -B switch is specified */
radix = 2; /* then override the radix to binary */
else if (formats == D_SWITCH) /* otherwise if the -D switch is specified */
radix = 10; /* then override the radix to decimal */
else if (formats == H_SWITCH) /* otherwise if the -H switch is specified */
radix = 16; /* then override the radix to hexadecimal */
else if (formats == O_SWITCH) /* otherwise if the -O switch is specified */
radix = 8; /* then override the radix to octal */
else if (formats == 0) /* otherwise if no format switch is specified */
radix = 0; /* then indicate that the default radix is to be used */
else /* otherwise more than one format is specified */
return SCPE_INVSW; /* so return an error */
if (modes == M_SWITCH) /* if mnemonic mode is specified */
return fprint_cpu (ofile, val, radix, sw); /* then format and print the value in mnemonic format */
else if (modes == I_SWITCH) /* otherwise if I/O channel order mode is specified */
return fprint_order (ofile, val, radix); /* then format and print it */
else if (modes == E_SWITCH) /* otherwise if an EDIT subop memory display is requested */
return fprint_subop (ofile, val, radix, addr, sw); /* then format and print it */
else if (modes == T_SWITCH) { /* otherwise if status display is requested */
fputs (fmt_status ((uint32) val [0]), ofile); /* then format the status flags and condition code */
fputc (' ', ofile); /* and add a separator */
fprint_value (ofile, STATUS_CS (val [0]), /* print the code segment number */
(radix_override ? radix_override : cpu_dev.dradix),
STATUS_CS_WIDTH, PV_RZRO);
if (fprint_value (ofile, STATUS_CS (val [0]), /* if the code segment number */
(radix ? radix : cpu_dev.dradix), /* prints with the specified radix */
STATUS_CS_WIDTH, PV_RZRO) == SCPE_OK)
return SCPE_OK; /* then return success */
else /* otherwise print it */
return fprint_val (ofile, STATUS_CS (val [0]), /* in the CPU's default data radix */
cpu_dev.dradix, D8_WIDTH, PV_RZRO);
}
else if (modes == C_SWITCH) { /* otherwise if ASCII string mode is specified */
fputs (fmt_char (UPPER_BYTE (val [0])), ofile); /* then format and print the upper byte */
fputc (',', ofile); /* followed by a separator */
fputs (fmt_char (LOWER_BYTE (val [0])), ofile); /* followed by the lower byte */
return SCPE_OK;
}
else /* otherwise */
return SCPE_ARG; /* request that the value be printed numerically */
}
else if (modes == 0) /* otherwise if single-character mode was specified */
return fprint_value (ofile, val [0], radix, 0, 0); /* then format and print it */
else /* otherwise the modes conflict */
return SCPE_INVSW; /* so return an error */
}
@ -2025,11 +2115,11 @@ return formatted; /* return a pointer to t
/* Format a character for printing.
This routine formats single 8-bit character value into a printable string and
returns a pointer to that string. Printable characters retain their original
form but are enclosed in single quotes. Control characters are translated to
readable strings. Characters outside of the ASCII range are presented as
escaped octal values.
This routine formats a single 8-bit character value into a printable string
and returns a pointer to that string. Printable characters retain their
original form but are enclosed in single quotes. Control characters are
translated to readable strings. Characters outside of the ASCII range are
presented as escaped octal values.
Implementation notes:
@ -2914,24 +3004,39 @@ return status; /* return the handler st
/* System interface local utility routines */
/* Print a numeric value with a radix identifier.
/* Print a numeric value in a given radix with a radix identifier.
This routine prints a numeric value with a leading radix indicator if the
specified print radix is not the same as the current CPU data radix. It uses
the HP 3000 convention of a leading "%", "#", or "!" character to indicate
an octal, decimal, or hexadecimal number.
This routine prints a numeric value using the specified radix, width, and
output format. If the radix is 256, then the value is printed as a single
character. Otherwise, it is printed as a numeric value with a leading radix
indicator if the specified print radix is not the same as the current CPU
data radix. It uses the HP 3000 convention of a leading "%", "#", or "!"
character to indicate an octal, decimal, or hexadecimal number (there is no
binary convention, so a leading "@" is used arbitrarily).
On entry, the "ofile" parameter is the opened output stream, "val" is the
value to print, "radix" is the desired print radix, "width" is the number of
significant bits in the value, and "format" is a format specifier (PV_RZRO,
PV_RSPC, or PV_LEFT). On exit, the status of the print operation is
returned.
PV_RSPC, or PV_LEFT). On exit, the routine returns SCPE_OK if the value was
printed successfully, or SCPE_ARG if the value could not be printed.
*/
static void fprint_value (FILE *ofile, t_value val, uint32 radix, uint32 width, uint32 format)
static t_stat fprint_value (FILE *ofile, t_value val, uint32 radix, uint32 width, uint32 format)
{
if (radix != cpu_dev.dradix) /* if the requested radix is not the current data radix */
if (radix == 8) /* then if the requested radix is octal */
if (radix == 256) /* if ASCII character display is requested */
if (val <= D8_SMAX) { /* then if the value is a single character */
fputs (fmt_char ((uint32) val), ofile); /* then format and print it */
return SCPE_OK; /* and report success */
}
else /* otherwise */
return SCPE_ARG; /* report that it cannot be displayed */
else if (radix != cpu_dev.dradix) /* otherwise if the requested radix is not the current data radix */
if (radix == 2) /* then if the requested radix is binary */
fputc ('@', ofile); /* then print the binary indicator */
else if (radix == 8) /* otherwise if the requested radix is octal */
fputc ('%', ofile); /* then print the octal indicator */
else if (radix == 10) /* otherwise if it is decimal */
@ -2945,7 +3050,7 @@ if (radix != cpu_dev.dradix) /* if the requested radi
fprint_val (ofile, val, radix, width, format); /* print the value in the radix specified */
return;
return SCPE_OK; /* return success */
}
@ -2979,16 +3084,15 @@ return;
- Address values are printed in the CPU's address radix, which is octal.
- Counts are printed in decimal.
- Counts are printed by default in decimal.
- Control and status values are printed in the CPU's data radix, which
defaults to octal but may be set to a different radix with SET CPU
OCT|DEC|HEX.
defaults to octal.
The radix for operand values other than addresses may be overridden by a
switch on the command line. A value printed in a radix other than the
current data radix is preceded by a radix identifier ("%" for octal, "#" for
decimal, or "!" for hexadecimal).
current data radix is preceded by a radix identifier ("@" for binary, "%" for
octal, "#" for decimal, or "!" for hexadecimal).
The routine returns SCPE_OK_2_WORDS to indicate that two words were consumed.
@ -3031,7 +3135,7 @@ switch (order) { /* dispatch operand prin
case sioJUMP:
case sioJUMPC: /* print the jump target address */
fprint_value (ofile, ioaw, cpu_dev.aradix,
fprint_value (ofile, ioaw, cpu_dev.aradix, /* in the CPU's address radix */
LA_WIDTH, PV_RZRO);
break;
@ -3042,7 +3146,7 @@ switch (order) { /* dispatch operand prin
break;
case sioSBANK: /* print the bank address */
fprint_value (ofile, ioaw & BA_MASK,
fprint_value (ofile, ioaw & BA_MASK, /* in the CPU's address radix */
cpu_dev.aradix, BA_WIDTH, PV_RZRO);
break;
@ -3078,7 +3182,7 @@ switch (order) { /* dispatch operand prin
fputc (',', ofile);
fprint_value (ofile, ioaw, cpu_dev.aradix,
fprint_value (ofile, ioaw, cpu_dev.aradix, /* prnit the address in the CPU's address radix */
LA_WIDTH, PV_RZRO);
break;
}
@ -3562,7 +3666,6 @@ switch (ops [op_index].operand) { /* dispatch by the opera
prefix = " "; /* so just use a space to separate the value */
op_value = (op_value & ~op_mask [opS11]) >> EIS_SDEC_SHIFT; /* remove the flags from the S decrement value */
op_radix = (radix ? radix : cpu_dev.dradix); /* and set the print radix */
break;

View file

@ -1,6 +1,6 @@
/* hp_disclib.h: HP MAC/ICD disc controller simulator library declarations
Copyright (c) 2011-2016, J. David Bryan
Copyright (c) 2011-2017, J. David Bryan
Copyright (c) 2004-2011, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a copy
@ -24,6 +24,7 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the authors.
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
10-Oct-16 JDB Moved "hp3000_defs.h" inclusion to "hp_disclib.c"
13-May-16 JDB Modified for revised SCP API function parameter types
24-Mar-16 JDB Added the DL_BUFFER type to define the disc buffer array
@ -479,7 +480,7 @@ typedef CNTLR_VARS *CVPTR; /* pointer to a controller state
{ DRDATA (HEAD, (cntlr).head, 6), PV_LEFT }, \
{ DRDATA (SECTOR, (cntlr).sector, 8), PV_LEFT }, \
{ DRDATA (COUNT, (cntlr).count, 16), PV_LEFT }, \
{ BRDATA (SECBUF, (buffer), 8, 16, DL_BUFSIZE), REG_A }, \
{ BRDATA (SECBUF, (buffer), 8, 16, DL_BUFSIZE), REG_X }, \
{ DRDATA (INDEX, (cntlr).index, 8), PV_LEFT }, \
{ DRDATA (LENGTH, (cntlr).length, 8), PV_LEFT }, \
{ DRDATA (POLLU, (cntlr).poll_unit, 4), REG_HRO }, \

View file

@ -1,6 +1,6 @@
/* hp_tapelib.h: HP magnetic tape controller simulator library declarations
Copyright (c) 2013-2016, J. David Bryan
Copyright (c) 2013-2017, J. David Bryan
Copyright (c) 2004-2011, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a copy
@ -24,6 +24,7 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the authors.
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
10-Oct-16 JDB Moved "hp3000_defs.h" inclusion to "hp_tapelib.c"
13-May-16 JDB Modified for revised SCP API function parameter types
24-Mar-16 JDB Added the TL_BUFFER type to define the tape buffer array
@ -419,7 +420,7 @@ typedef CNTLR_VARS *CVPTR; /* a pointer to a controller sta
{ ORDATA (STATUS, (cntlr).status, 16), REG_RO }, \
{ DRDATA (USEL, (cntlr).unit_selected, 4), PV_LEFT | REG_RO }, \
{ YRDATA (UATTN, (cntlr).unit_attention, 4, PV_RZRO) }, \
{ BRDATA (RECBUF, (buffer), 8, 8, TL_BUFSIZE), REG_A }, \
{ BRDATA (RECBUF, (buffer), 8, 8, TL_BUFSIZE), REG_X }, \
{ DRDATA (LIBSTA, (cntlr).call_status, 16), PV_LEFT }, \
{ DRDATA (LENGTH, (cntlr).length, 24), PV_LEFT }, \
{ DRDATA (INDEX, (cntlr).index, 24), PV_LEFT }, \

Binary file not shown.