HP3000: Update to early Release 8 which is still simh V4.x API compatible

Dave Bryan has migrated support for this simulator to http://simh.trailing-edge.com/hp
This commit is contained in:
Mark Pizzolato 2020-02-16 22:24:16 -08:00
parent 254e173fc1
commit 6bbbc19e01
19 changed files with 394 additions and 129 deletions

View file

@ -1,6 +1,6 @@
/* hp3000_atc.c: HP 3000 30032B Asynchronous Terminal Controller simulator
Copyright (c) 2014-2017, J. David Bryan
Copyright (c) 2014-2018, 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
30-Apr-18 JDB Corrected typo in "store" routine comment
18-Dec-17 JDB Return event time instead of status from "activate_unit"
11-Dec-17 JDB Reschedule "line_service" if receive buffer has data
26-Oct-17 JDB Call "tmxr_poll_tx" if transmit buffer is full

View file

@ -693,7 +693,7 @@ while (working_set) {
case DRESETINT:
dibptr->interrupt_active = CLEAR; /* clear the Interrupt Active flip-flop */
dibptr->interrupt_active = CLEAR; /* clear the Interrupt Active flip-flop */
if ((limit_irq == SET || lost_tick_irq == SET) /* if the limit or lost tick flip-flops are set */
&& control_word & CN_IRQ_ENABLE) /* and interrupts are enabled */

View file

@ -1,6 +1,6 @@
/* hp3000_cpu.c: HP 3000 Central Processing Unit simulator
Copyright (c) 2016-2017, J. David Bryan
Copyright (c) 2016-2019, 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,11 @@
CPU HP 3000 Series III Central Processing Unit
21-Feb-19 JDB Resuming into PAUS with pending IRQ now sets P correctly
Moved "debug_save" from global to "sim_instr" local
12-Feb-19 JDB Worked around idle problem (SIMH issue 622)
06-Feb-19 JDB Corrected trace report for simulation stop
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
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
@ -718,6 +723,13 @@
Both implementations were mocked up and timing measurements made. The
results were that copying values is much faster than mapping via array
index values, so this is the implementation chosen.
4. Idling with 4.x simulator framework versions after June 14, 2018 (git
commit ID d3986466) loses system clock ticks. This causes the MPE clock
to run slowly, losing about one second per minute. A workaround is to
prevent "sim_interval" from going negative on return from "sim_idle".
Issue 622 on the SIMH site describes the same problem with the HP 2100
simulator.
*/
@ -730,6 +742,17 @@
/* Lost time workaround */
#if (SIM_MAJOR >= 4)
#define sim_idle(timer,decrement) \
if (sim_idle (timer, decrement) == TRUE /* [workaround] idle the simulator; if idling occurred */ \
&& sim_interval < 0) /* [workaround] and the time interval is negative */ \
sim_interval = 0 /* [workaround] then reset it to zero */
#endif
/* Program constants */
#define PCLK_PERIOD mS (1) /* 1 millisecond process clock period */
@ -869,7 +892,6 @@ static uint32 sim_stops = 0; /* the current simulation stop f
static uint32 cpu_speed = 1; /* the CPU speed, expressed as a multiplier of a real machine */
static uint32 pclk_increment = 1; /* the process clock increment per event service */
static uint32 dump_control = 0002006u; /* the cold dump control word (default CNTL = 4, DEVNO = 6 */
static uint32 debug_save = 0; /* the current debug trace flag settings */
static HP_WORD exec_mask = 0; /* the current instruction execution trace mask */
static HP_WORD exec_match = D16_UMAX; /* the current instruction execution trace matching value */
@ -1095,11 +1117,11 @@ static MTAB cpu_mod [] = {
{ UNIT_CIS, UNIT_CIS, "CIS", "CIS", &set_option, NULL, NULL },
{ UNIT_CIS, 0, "no CIS", "NOCIS", NULL, NULL, NULL },
{ UNIT_PFARS, UNIT_PFARS, "auto-restart", "ARS", &set_pfars, NULL, NULL },
{ UNIT_PFARS, 0, "no auto-restart", "NOARS", &set_pfars, NULL, NULL },
{ UNIT_PFARS, UNIT_PFARS, "auto-restart", "ARS", &set_pfars, NULL, NULL },
{ UNIT_PFARS, 0, "no auto-restart", "NOARS", &set_pfars, NULL, NULL },
{ UNIT_CALTIME, UNIT_CALTIME, "calibrated timing", "CALTIME", NULL, NULL, NULL },
{ UNIT_CALTIME, 0, "realistic timing", "REALTIME", NULL, NULL, NULL },
{ UNIT_CALTIME, 0, "realistic timing", "REALTIME", NULL, NULL, NULL },
/* Entry Flags Value Print String Match String Validation Display Descriptor */
/* ------------------- ----------- ------------ ------------ ------------- -------------- ---------- */
@ -1402,6 +1424,7 @@ int abortval;
HP_WORD label, parameter;
TRAP_CLASS trap;
t_bool exec_test;
volatile uint32 debug_save;
volatile HP_WORD device;
volatile t_stat status = SCPE_OK;
@ -1465,13 +1488,13 @@ if (abortval) { /* if a microcode abort
if (STT_SEGMENT (parameter) <= ISR_SEGMENT) /* if the trap occurred in segment 1 */
MICRO_ABORT (trap_SysHalt_CSTV_1); /* then the failure is fatal */
/* fall into the next trap handler */
/* fall through into the next trap handler */
case trap_STT_Violation:
if (STT_SEGMENT (parameter) <= ISR_SEGMENT) /* if the trap occurred in segment 1 */
MICRO_ABORT (trap_SysHalt_STTV_1); /* then the failure is fatal */
/* fall into the next trap handler */
/* fall through into the next trap handler */
case trap_Unimplemented:
case trap_DST_Violation:
@ -1480,13 +1503,13 @@ if (abortval) { /* if a microcode abort
case trap_Bounds_Violation:
parameter = label; /* the label is the parameter for these traps */
/* fall into the next trap handler */
/* fall through into the next trap handler */
case trap_DS_Absent:
cpu_flush (); /* flush the TOS registers to memory */
cpu_mark_stack (); /* and then write a stack marker */
/* fall into the next trap handler */
/* fall through into the next trap handler */
case trap_Uncallable:
break; /* set up the trap handler */
@ -1524,7 +1547,7 @@ if (abortval) { /* if a microcode abort
case trap_Cold_Load: /* this trap executes on the ICS */
status = STOP_CLOAD; /* report that the cold load is complete */
/* fall into trap_Stack_Overflow */
/* fall through into trap_Stack_Overflow */
case trap_Stack_Overflow: /* this trap executes on the ICS */
if (CPX1 & cpx1_ICSFLAG) /* so if the trap occurred while on the ICS */
@ -1708,7 +1731,9 @@ if (cpu_power_state == power_failing /* if power is failing *
cpu_power_state = power_off; /* then power will be off when we return */
dprintf (cpu_dev, cpu_dev.dctrl, BOV_FORMAT "simulation stop: %s\n",
PBANK, P, STA, sim_error_text (status));
PBANK, P, STA,
status >= SCPE_BASE ? sim_error_text (status)
: sim_stop_messages [status]);
return status; /* return the reason for the stop */
}
@ -1964,20 +1989,47 @@ return status; /* return the operation
If an interrupt occurs while PAUS is executing, the interrupt handler
will return to the instruction following the PAUS, as though HALT and RUN
had been pressed. This occurs because P normally points two instructions
beyond the current instruction, so stacking the value P - 1 during the
interrupt will return to the next instruction to be executed. When
resuming the PAUS instruction from a simulation stop with an interrupt
pending, though, P is set so that P - 1 points to the PAUS instruction,
which is (correctly) the next instruction to execute on resumption.
Stacking the usual P - 1 value, therefore, will cause the interrupt
handler to return to the PAUS instruction instead of to the instruction
following, as would have occurred had a simulation stop not been
involved.
had been pressed. This occurs because the P register normally points two
instructions past the instruction currently executing. When an interrupt
occurs, P is decremented to point at the instruction after the current
instruction, which is the correct point of return after the interrupt
service routine completes.
Therefore, this case is detected when a PAUS instruction is in the CIR
but the micromachine state is "running" instead of "paused", and P is
incremented so that the return will be to the instruction following PAUS.
When the simulator is stopped, P is backed up to point at the next
instruction to execute. In the case of a PAUS instruction, the "next
instruction" is the same PAUS instruction. When simulation resumes, the
PAUS instruction is fetched into the NIR, and P is incremented. If no
interrupt is pending, the main instruction execution loop copies the NIR
into the CIR, prefetches the instruction following the PAUS into the NIR,
and increments P again, so that it points two instructions beyond the
current instruction. At this point, everything is set up properly as
before the simulation stop.
However, if an interrupt is pending when simulation resumes, this routine
is called before the NIR-to-CIR operation is performed, so P still points
one instruction beyond the PAUS. Stacking the usual P - 1 value would
cause the interrupt handler to return to the PAUS instruction instead of
to the instruction following, as would have occurred had a simulation
stop not been involved.
Therefore, when resuming from a simulator stop, the SS_PAUSE_RESUMED flag
is set in the "cpu_stop_flags" variable by the "halt_mode_interrupt"
routine if a PAUS instruction is in the NIR after reloading. If an
interrupt is pending, this routine will be entered with the flag set, and
we then increment P so that it is correctly set to point two instructions
beyond the PAUS before handling the interrupt. If an interrupt is not
pending on resumption, the P adjustment is performed as described above,
and P will be set properly when the next interrupt occurs.
A special case occurs when resuming into a PAUS from a simulator stop if
a higher-priority interrupt occurs immediately after handling a pending
lower-priority interrupt. In this case, this routine will be entered a
second time before the instruction execution loop performs the NIR-to-CIR
operation. Although the PAUS is still in the CIR, we must not increment
P a second time, because the instruction now being interrupted is not the
PAUS but is the first instruction of the lower-priority interrupt routine
that never had a chance to execute. Wo do this by clearing the
SS_PAUSE_RESUMED flag after the first increment.
*/
void cpu_run_mode_interrupt (HP_WORD device_number)
@ -1985,11 +2037,12 @@ void cpu_run_mode_interrupt (HP_WORD device_number)
HP_WORD request_set, request_count, parameter;
IRQ_CLASS class;
if (cpu_micro_state == running /* if we are resuming from a sim stop */
&& (CIR & PAUS_MASK) == PAUS) /* into a PAUS instruction */
P = P + 1 & R_MASK; /* then return is to the instruction following */
else /* otherwise the micromachine may be paused */
cpu_micro_state = running; /* but is no longer */
if (cpu_stop_flags & SS_PAUSE_RESUMED) { /* if we are resuming into a PAUS instruction */
P = P + 1 & R_MASK; /* then set the return to the instruction following */
cpu_stop_flags &= ~SS_PAUSE_RESUMED; /* and clear the flag in case of back-to-back interrupts */
}
cpu_micro_state = running; /* the micromachine may be paused but is no longer */
request_set = CPX1 & CPX1_IRQ_SET; /* get the set of active interrupt requests */
@ -2845,7 +2898,7 @@ void cpu_setup_ics_irq (IRQ_CLASS class, TRAP_CLASS trap)
{
HP_WORD delta_q, stack_db;
if (class != irq_Trap /* if this is not */
if (class != irq_Trap /* if this is not */
|| trap != trap_Cold_Load && trap != trap_Power_On) { /* a cold load or power on trap entry */
cpu_flush (); /* then flush the TOS registers to memory */
cpu_mark_stack (); /* and write a four-word stack marker */
@ -3294,9 +3347,8 @@ return;
examined from the SCP command prompt.
The simulation console is normally hosted by, and therefore polled by, the
ATC on channel 0. If the console is not hosted by the ATC, due either to a
SET ATC NOCONSOLE or a SET ATC DISABLED command, the process clock assumes
polling control over the console.
ATC on channel 0. If the console is not hosted by the ATC, due to a SET ATC
DISABLED command, the process clock assumes polling control over the console.
Implementation notes:
@ -3962,10 +4014,10 @@ return SCPE_OK; /* and report success
Implementation notes:
1. After RUN switch processing and return to the instruction loop, if no
interrupt is present, and the R-bit in the status register is clear, then
CIR will be set from NIR, and NIR will be reloaded. If the R-bit is set,
then CIR and NIR will not be changed, i.e., the NEXT action will be
1. After processing the RUN switch and returning to the instruction loop, if
no interrupt is present, and the R-bit in the status register is clear,
then CIR will be set from NIR, and NIR will be reloaded. If the R-bit is
set, then CIR and NIR will not be changed, i.e., the NEXT action will be
skipped, so we perform it here. If an interrupt is pending, then the
interrupt will be processed using the old value of the CIR, and the
instruction in the NIR will become the first instruction executed after
@ -4004,6 +4056,9 @@ if (CPX2 & cpx2_RUNSWCH) { /* if the RUN switch is
cpu_read_memory (fetch, P, &NIR); /* load the next instruction to execute */
P = P + 1 & R_MASK; /* and point to the following instruction */
if ((NIR & PAUS_MASK) == PAUS) /* if resuming into a PAUS instruction */
cpu_stop_flags |= SS_PAUSE_RESUMED; /* then defer any interrupt until after PAUS is executed */
if ((NIR & SUBOP_MASK) != 0) /* if the instruction is not a stack instruction */
STA &= ~STATUS_R; /* then clear the R-bit in case it had been set */

View file

@ -1,6 +1,6 @@
/* hp3000_cpu.h: HP 3000 CPU declarations
Copyright (c) 2016, J. David Bryan
Copyright (c) 2016-2019, 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
@ -23,6 +23,8 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the author.
18-Feb-19 JDB Added SS_PAUSE_RESUMED simulation stop condition
25-Jul-18 JDB Fixed typo in "cpu_setup_code_segment" declaration
07-Nov-16 JDB Added SETR and SETR_X for SETR executor use;
renamed cpu_byte_to_word_ea to cpu_byte_ea
03-Nov-16 JDB Added LABEL_LOCAL for PARC/XBR/ENDP executor use
@ -105,6 +107,8 @@
#define SS_PAUSE (1u << 1) /* stop on PAUS instruction */
#define SS_UNDEF (1u << 2) /* stop on undefined instruction */
#define SS_UNIMPL (1u << 3) /* stop on unimplemented instruction */
#define SS_PAUSE_RESUMED (1u << 30) /* stop resumes into a PAUS instruction */
#define SS_BYPASSED (1u << 31) /* stops are bypassed for this instruction */
@ -1092,7 +1096,7 @@ extern uint32 cpu_byte_ea (ACCESS_CLASS class, uint32 byte_offset, uint32 block_
extern void cpu_setup_irq_handler (IRQ_CLASS class, HP_WORD parameter);
extern void cpu_setup_ics_irq (IRQ_CLASS class, TRAP_CLASS trap);
extern void cpu_run_mode_interrupt (HP_WORD device_number);
extern void cpu_setup_code_segment (HP_WORD label, HP_WORD* status, HP_WORD *entry_0);
extern void cpu_setup_code_segment (HP_WORD label, HP_WORD *status, HP_WORD *entry_0);
extern void cpu_setup_data_segment (HP_WORD segment_number, HP_WORD *bank, HP_WORD *address);
extern void cpu_call_procedure (HP_WORD label, HP_WORD offset);
extern void cpu_exit_procedure (HP_WORD new_q, HP_WORD new_sm, HP_WORD parameter);

View file

@ -1,6 +1,6 @@
/* hp3000_cpu_base.c: HP 3000 CPU base set instruction simulator
Copyright (c) 2016-2017, J. David Bryan
Copyright (c) 2016-2018, 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
@ -23,6 +23,7 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the author.
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
08-Jan-17 JDB Fixed bug in SCAL 0/PCAL 0 if a stack overflow occurs
07-Nov-16 JDB SETR doesn't set cpu_base_changed if no register change;
renamed cpu_byte_to_word_ea to cpu_byte_ea
@ -3335,7 +3336,7 @@ switch (operation) { /* dispatch the move or
break;
}
/* fall into the LOCK executor */
/* fall through into the LOCK executor */
case 001: /* LOCK (none; MODE) */
if (UNIT_CPU_MODEL == UNIT_SERIES_II) { /* if the CPU is a Series II */
@ -3358,7 +3359,7 @@ switch (operation) { /* dispatch the move or
break;
}
/* fall into the PCN executor */
/* fall through into the PCN executor */
case 002: /* PCN (none; STOV, MODE) */
cpu_push (); /* push the stack down */
@ -3382,7 +3383,7 @@ switch (operation) { /* dispatch the move or
break;
} /* otherwise fall into the UNLK executor */
/* fall into the UNLK executor */
/* fall through into the UNLK executor */
case 003: /* UNLK (none; MODE) */
if (UNIT_CPU_MODEL == UNIT_SERIES_II) { /* if the CPU is a Series II */
@ -3712,7 +3713,7 @@ switch (operation) { /* dispatch the I/O or c
break;
}
/* fall into the PSDB executor */
/* fall through into the PSDB executor */
case 001: /* PSDB (none; MODE) */
cpu_read_memory (absolute, ICS_Q, /* read the ICS stack marker pointer value */
@ -3737,7 +3738,7 @@ switch (operation) { /* dispatch the I/O or c
break;
}
/* fall into the DISP executor */
/* fall through into the DISP executor */
case 002: /* DISP (CCx; MODE, CSTV, TRACE, ABS CST, BNDV) */
cpu_read_memory (absolute, ICS_Q, /* read the stack marker initial value */
@ -3771,7 +3772,7 @@ switch (operation) { /* dispatch the I/O or c
break;
}
/* fall into the PSEB executor */
/* fall through into the PSEB executor */
case 003: /* PSEB (CCx; MODE, CSTV, TRACE, ABS CST, BNDV) */
cpu_read_memory (absolute, ICS_Q, /* read the stack marker initial value */

View file

@ -157,7 +157,7 @@
numbers with an even number of digits will not use the upper four bits of the
first byte. Digits are represented by four-bit values from 0-9 (i.e., in
Binary-Coded Decimal or BCD), with the most-significant digit first and the
least-significant digit last. The sign is given by one of these encodings:
least-significant digit last. The sign is given by one of these encodings:
1100 - the number is positive
1101 - the number is negative

View file

@ -1,6 +1,6 @@
/* hp3000_ds.c: HP 3000 30229B Cartridge Disc Interface simulator
Copyright (c) 2016-2017, J. David Bryan
Copyright (c) 2016-2018, 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
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
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
@ -1314,7 +1315,7 @@ do { /* call the controller p
break; /* and try again */
}
/* otherwise, request an interrupt */
/* fall into the STINT case */
/* fall through into the STINT case */
case STINT: /* Set Interrupt */
flags &= ~XFRNG; /* clear the transfer error flag */

View file

@ -1,6 +1,6 @@
/* hp3000_io.h: HP 3000 device-to-IOP/MPX/SEL interface declarations
Copyright (c) 2016, J. David Bryan
Copyright (c) 2016-2018, 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
@ -23,6 +23,7 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the author.
30-Sep-18 JDB Corrected typo in I/O macro comments
12-Sep-16 JDB Added the DIB_REGS macro
02-Sep-16 JDB Added the iop_assert_PFWARN routine
11-Jun-16 JDB Bit mask constants are now unsigned
@ -187,7 +188,7 @@ typedef uint32 SIGNALS_DATA; /* a combined outbound signal se
A priority set is an unsigned value, where each bit represents an assertion
of some nature (e.g., I/O signals, interrupt requests, etc.), and the
position of the bit represents its priority, which increases from LSB to MSB.
position of the bit represents its priority, which decreases from LSB to MSB.
The IOPRIORITY macro isolates the highest-priority bit from the set. It does
this by ANDing the value with its two's complement; only the lowest-order bit
will differ. For example (bits are numbered here from the LSB):

View file

@ -1,6 +1,6 @@
/* hp3000_iop.c: HP 3000 30003B I/O Processor simulator
Copyright (c) 2016, J. David Bryan
Copyright (c) 2016-2019, 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 @@
IOP HP 3000 Series III I/O Processor
18-Feb-19 JDB Continue iop_poll if first interface returns INTPOLLOUT
10-Oct-16 JDB Renumbered debug flags to start at bit 0
03-Sep-16 JDB Added "iop_assert_PFWARN" to warn devices of power loss
01-Aug-16 JDB Added "iop_reset" to initialize the IOP
@ -496,7 +497,8 @@ return IOA;
However, if some condition has occurred between the time of the original
request and this poll, the interface will assert INTPOLLOUT. In response,
the IOP will clear IOA and the associated bit in the poll set to cancel the
request.
request. If any other interfaces are asserting INTREQ, the poll continues
with the next-highest-priority interface in the chain.
In either case, the associated bit in the request set is cleared.
@ -507,6 +509,12 @@ return IOA;
This prevents a second interrupt from changing IOA until the microcode
signals its readiness by clearing EXTINT. In simulation, entry with
cpx1_EXTINTR set returns IOA in lieu of conducting a poll.
2. An interface that asserted INTREQ should respond to an INTPOLL by
asserting either INTACK or INTPOLLOUT. If it does neither, then the
interface is inhibiting lower-priority interrupts but not performing an
interrupt itself. We simulate this by clearing the request set bit but
not the poll set bit.
*/
uint32 iop_poll (void)
@ -518,38 +526,54 @@ uint32 ipn, priority_mask, request_granted;
if (CPX1 & cpx1_EXTINTR) /* if an external interrupt has been requested */
return IOA; /* then return the device number in lieu of polling */
priority_mask = IOPRIORITY (interrupt_poll_set); /* calculate the priority mask */
request_granted = priority_mask & iop_interrupt_request_set; /* and determine the request to grant */
else do { /* otherwise poll for an interrupt request */
priority_mask = IOPRIORITY (interrupt_poll_set); /* calculate the priority mask */
request_granted = priority_mask & iop_interrupt_request_set; /* and determine the request to grant */
if (request_granted == 0) /* if no request has been granted */
return 0; /* then return */
if (request_granted == 0) /* if no request was granted */
return 0; /* then return */
else /* otherwise */
iop_interrupt_request_set &= ~priority_mask; /* clear the request */
for (ipn = 0; !(request_granted & 1); ipn++) /* determine the interrupt priority number */
request_granted = request_granted >> 1; /* by counting the bits until the set bit is reached */
for (ipn = 0; !(request_granted & 1); ipn++) /* determine the interrupt priority number */
request_granted = request_granted >> 1; /* by counting the bits until the set bit is reached */
dibptr = irqs [ipn]; /* get the DIB pointer for the request */
dibptr = irqs [ipn]; /* get the DIB pointer for the request */
outbound = dibptr->io_interface (dibptr, INTPOLLIN, 0); /* poll the interface that requested the interrupt */
outbound = dibptr->io_interface (dibptr, INTPOLLIN, 0); /* poll the interface that requested the interrupt */
if (outbound & INTACK) { /* if the interface acknowledged the interrupt */
IOA = IODATA (outbound); /* then save the returned device number */
CPX1 |= cpx1_EXTINTR; /* and tell the CPU */
if (outbound & INTACK) { /* if the interface acknowledged the interrupt */
IOA = IODATA (outbound); /* then save the returned device number */
CPX1 |= cpx1_EXTINTR; /* and tell the CPU */
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
"Device number %u acknowledged interrupt request at priority %u\n",
dibptr->device_number, ipn);
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
"Device number %u acknowledged interrupt request at priority %u\n",
dibptr->device_number, ipn);
break; /* stop the poll at this interface */
}
else if (outbound & INTPOLLOUT) { /* otherwise if the interface cancelled the request */
IOA = 0; /* then clear the device number */
interrupt_poll_set &= ~priority_mask; /* and the associated bit in the poll set */
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
"Device number %u canceled interrupt request at priority %u\n",
dibptr->device_number, ipn);
}
else { /* otherwise the interface inhibited the poll */
IOA = 0; /* so clear the device number */
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
"Device number %u inhibited INTPOLLIN at priority %u\n",
dibptr->device_number, ipn);
break; /* stop the poll at this interface */
}
}
else if (outbound & INTPOLLOUT) { /* otherwise if the interface cancelled the request */
IOA = 0; /* then clear the device number */
interrupt_poll_set &= ~priority_mask; /* and the associated bit in the poll set */
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
"Device number %u canceled interrupt request at priority %u\n",
dibptr->device_number, ipn);
}
iop_interrupt_request_set &= ~priority_mask; /* clear the request */
while (iop_interrupt_request_set != 0); /* continue polling while requests remain */
return IOA; /* return the interrupting device number */
}

View file

@ -1,6 +1,6 @@
/* hp3000_lp.c: HP 3000 30209A Line Printer Interface simulator
Copyright (c) 2016-2017, J. David Bryan
Copyright (c) 2016-2018, 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 @@
LP HP 30209A Line Printer Interface
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
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
@ -1437,7 +1438,7 @@ while (working_set) {
if (! J2W1_INSTALLED) /* if W1 (SR set by Device Status) is not installed */
device_sr = SET; /* then set the device service request flip-flop */
/* fall into the DCONTSTB case */
/* fall through into the DCONTSTB case */
case DCONTSTB:
dprintf (lp_dev, DEB_CSRW,

View file

@ -25,6 +25,7 @@
MEM HP 3000 Series III Main Memory
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
21-May-18 JDB Changed "access" to "mem_access" to avoid clashing
10-Oct-16 JDB Created
@ -549,7 +550,7 @@ else { /* otherwise the access
if (offset > SM && offset <= SM + SR && bank == SBANK) /* if the offset is within the TOS */
TR [SM + SR - offset] = value; /* then write the value to a TOS register */
/* fall into checked cases */
/* fall through into checked cases */
case data_checked:
if (DL <= offset && offset <= SM + SR || PRIV) /* if the offset is within bounds or is privileged */

View file

@ -363,7 +363,6 @@ extern DEVICE iop_dev; /* I/O Processor */
state RAM" command.
3. State "parity" is 1 for an illegal state and 0 for a valid state.
*/
#define INTRF_COUNT (SRNO_MAX + 1) /* count of interfaces handled by the multiplexer channel */

View file

@ -1,6 +1,6 @@
/* hp3000_ms.c: HP 3000 30215A Magnetic Tape Controller Interface simulator
Copyright (c) 2016-2017, J. David Bryan
Copyright (c) 2016-2018, 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
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
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
@ -1315,7 +1316,7 @@ while (command_set) { /* process the set of re
unit_interrupt = SET; /* set the unit interrupt flip-flop */
attention_unit = TLIBUS (result); /* and save the number of the requesting unit */
/* fall into the STINT case */
/* fall through into the STINT case */
case STINT: /* Set Interrupt */
flags = NO_FLAGS; /* clear the interface transfer flags and INTOK */

View file

@ -1,6 +1,6 @@
SIMH/HP 3000 RELEASE NOTES
==========================
Last update: 2018-01-12
Last update: 2019-02-21
This file documents the release history of the Hewlett-Packard 3000 simulator.
@ -13,11 +13,17 @@ simulator code base is available at:
...and may be downloaded at any time. A code snapshot is identified by the "git
commit ID" that is displayed in the simulator welcome banner.
Therefore, HP 3000 releases are simply documentation checkpoints that describe
the changes that have occurred since the last checkpoint. Generally, a release
is written when one or more major changes have been incorporated. Minor bug
fixes will be available immediately from the repository but only noted as part
of the next release document.
An HP 3000 "release" replaces the HP portion of the SIMH code base and is made
when one or more major changes have been incorporated. Each release is
documented below and describes the changes (new features and corrected errors)
that have occurred since the prior release. A revised "HP 3000 Simulator User's
Guide" accompanies every release where user-visible changes were made.
A "release update" is made to fix minor errors that do not affect normal user
operation. Examples of updates might be expansion or correction of source file
comments, minor algorithm improvements, or rewording of error messages. Updates
are not documented here, although every change is reported in the change logs
that appear at the beginning of all HP 3000 source files.
@ -104,9 +110,9 @@ the MPE version used:
- After a cold load from tape (COLDSTART/RELOAD/UPDATE), if a non-HP terminal
such as the simulation console is used as the system console, MPE prints DATE
(M/D/Y)? and then WED, NOV 1, 1972, 12:00 AM, as though RETURN had been
entered, but it wasn't. If an HP terminal emulator is used instead, MPE
waits for the user to enter the date before proceeding.
(M/D/Y)? and then WED, NOV 1, 1972, 12:00 AM, as though the RETURN key had
been pressed. If an HP terminal emulator is used instead, MPE waits for the
user to enter the date before proceeding.
The problem is incorrect coding in the SPEEDSENSE procedure in module
INITIAL. As a result, the console baud rate is set to an invalid value, so
@ -118,11 +124,16 @@ the MPE version used:
does not seem to have survived. A simple workaround is to set local ENQ/ACK
processing on ATC channel 0 (SET ATCD0 LOCALACK) when the system console is
not an HP terminal. This is the default setting, so the bug only manifests
itself when SET ATCD0 REMOTEACK is done before booting. An alternate
workaround that does not depend on the ATC setting is to set memory location
01.112247 to octal value 021360. This changes the "LOAD P+22,I,X"
instruction at that location to "LDI 360" to set the detected speed to 2400
baud unconditionally.
itself when SET ATCD0 REMOTEACK is done before booting.
An alternate workaround that does not depend on the ATC configuration is to
set memory location 01.112247 to octal value 021360 after cold loading is
complete. This changes the "LOAD P+22,I,X" instruction at that location to
"LDI 360" to set the detected speed to 2400 baud unconditionally. This
workaround is present in the "mpe-1-reload.sim" simulator command file
provided with the MPE-V/R Operating System Software Kit mentioned above.
However, the correction is applied only to the in-memory copy of MPE; the
disc and tape images supplied in the kit are unaltered.
- If a SHUTDOWN is performed while a logon read is pending on the system
@ -134,7 +145,7 @@ the MPE version used:
SHUTDOWN command or because the read timed out, the message is printed
normally.
The problem is that while the message is being send to the ATC character-by-
The problem is that while the message is being sent to the ATC character-by-
character, the I/O abort issued to cancel the logon read also cancels the
message write. The timing is such that only the first few characters of the
message are printed before the rest of the output is cancelled.
@ -156,8 +167,9 @@ the MPE version used:
(LOAD ERR 33)" error. This is because MPE defaults to an 8K code segment
size limit, and DPAN4 has three segments between 8K and 12K in size. If the
limit is subsequently raised via a SYSDUMP and COLDSTART reconfiguration,
running DPAN4 produces a "FILE IS NOT A VALID PROGRAM FILE" error. However,
if the reconfiguration is done before running DPAN4, it will run properly
running DPAN4 produces a "FILE IS NOT A VALID PROGRAM FILE" error, which
will persist until DPAN4.PUB.SYS is restored from the FOS tape. However, if
the reconfiguration is done before running DPAN4, it will run properly
thereafter.
The problem is that MPE incorrectly modifies the executable file's Segment
@ -170,9 +182,151 @@ the MPE version used:
No SSB KPR has been located, but a later MPE version ensures that code
segment size aborts occur before any of the STTs are modified, so the program
file remains internally consistent. A memory patch is impossible, but
workarounds are to increase the code segment limit before running DPAN4 and
to restore DPAN4.PUB.SYS from the FOS tape if it has been damaged.
file remains internally consistent. A memory patch is impossible, but a
workaround is to increase the code segment limit before running DPAN4. This
is done by the "mpe-3-sysdump.sim" simulator command file provided with the
MPE-V/R Operating System Software Kit mentioned above, and the supplied disc
image contains the increased limit.
=====================
Release 8, 2019-02-19
=====================
This release of the HP 3000 simulator does not add any new features.
--------------------
Implementation Notes
--------------------
- Comments marking the locations where "switch" statement executions fall
through from one case label to the following case now comply with the
requirements of the GNU C compiler to avoid warnings when the compiler option
"-Wimplicit-fallthrough" is used.
- A workaround for the MPE system clock losing time with simulator framework
versions after June 14, 2018 (git commit ID d3986466) has been implemented.
It will be removed when the framework issue has been corrected.
----------
Bugs Fixed
----------
1. PROBLEM: Simulation stops are reported improperly in CPU traces.
VERSION: Release 7.
OBSERVATION: A simulation stop that occurs while CPU tracing is enabled
reports the cause of the stop in the trace log. However, stop reasons
specific to the HP simulator are not reported properly. For example,
tracing a halt instruction reports "simulation stop: Error 5" instead of
"simulation stop: Programmed halt".
CAUSE: The "sim_error_text" routine called to obtain the error translation
does not return simulator-specific messages. Instead, the routine returns
the generic message, "Error <n>", where <n> is the value of the simulator-
specific stop code.
RESOLUTION: Modify the simulation stop trace at the end of the instruction
postlude in "sim_instr" (hp2100_cpu.c) to call "sim_error_text" for SCP
errors and to obtain HP-specific messages from the "sim_stop_messages"
array.
STATUS: Fixed in Release 8.
2. PROBLEM: "Non-configured device" error when mounting a magnetic tape.
VERSION: Release 7.
OBSERVATION: Occasionally, resuming simulation after mounting a magnetic
tape produces this message on the system console:
18:05/3/Interrupt received for non-configured device on DRT 6. Check I/O
configuration.
...instead of the expected:
17:59/10/Vol (unlabelled) mounted on LDEV# 7
However, the I/O map produced as part of a system reload shows that all
four magnetic tape units are configured properly.
Tracing CPU execution after resumption shows that the error occurs when the
mag tape controller interrupt (a result of the offline-to-online transition
when the tape is mounted) is immediately followed by a system clock
interrupt. The wrong return address is stacked by the second interrupt, so
the first instruction of the mag tape interrupt service routine (a TIO
instruction for DRT 6) is skipped when the clock interrupt routine exits.
As a result, the stack alignment is wrong, so the test for a configured
device fails, resulting in the error message observed.
CAUSE: MPE executes a PAUS instruction to wait for an interrupt while
idle. The mag tape interrupt stacks a return address that points to the
instruction after the PAUS, which is correct. But before the mag tape
interrupt handler can execute its first instruction, the higher-priority
clock interrupt occurs. This should stack a return address that points to
the first instruction of the mag tape interrupt handler, which has not yet
been executed. But instead, the return address points to the second
instruction. Consequently, the first instruction will be skipped when the
clock handler completes.
The problem occurs because the "cpu_run_mode_interrupt" routine in
"hp3000_cpu.c" must adjust the program counter (P register) when resuming
from a simulation stop that occurred while a PAUS instruction was
executing.
Because of the Series III's two-stage instruction pipeline, the P register
normally points two instructions past the instruction currently executing.
When an interrupt occurs, P is decremented to point at the instruction
after the current instruction, which is the correct point of return after
the interrupt service routine completes.
When the simulator is stopped, P is backed up to point at the next
instruction to execute. In the case of a PAUS instruction, the "next
instruction" is the same PAUS instruction. When simulation resumes, the
PAUS instruction is fetched into the NIR (Next Instruction Register), and P
is incremented. If no interrupt is pending, the main instruction execution
loop copies the NIR into the CIR (Current Instruction Register), prefetches
the instruction following the PAUS into the NIR, and increments P again, so
that it points two instructions beyond the current instruction. At this
point, everything is set up properly as before the simulation stop.
However, in the error case, the tape controller has requested an interrupt
that is pending when simulation is resumed. Interrupts are checked before
each instruction executes, so when the interrupt is acknowledged, P is
still pointing to the next instruction instead of two instructions ahead.
For things to work as expected, P needs to be advanced one more instruction
before the interrupt is serviced. So, in the special case of a PAUS
instruction present in the CIR after resuming a simulator stop with an
interrupt pending, the "cpu_run_mode_interrupt" routine increments P again
before stacking the return address.
That code does just what it is supposed to...except in the case of a higher
priority device that immediately interrupts a lower priority device while a
PAUS instruction is in the CIR. In this case, the second interrupt causes
a second entry into the "cpu_run_mode_interrupt" routine, and because it
still sees the PAUS instruction in the CIR, P is incremented again. This
is wrong, because the instruction now being interrupted is not the PAUS but
is the first instruction of the lower-priority interrupt routine, which
never had a chance to execute. The result is that when the lower-priority
routine is resumed, the first instruction of that routine is skipped
because P was incremented a second time.
The problem does not occur if the higher-priority interrupt is delayed by
one instruction, or if the higher-priority interrupt occurs before the
lower-priority interrupt, or if the CPU is executing something other than a
PAUS instruction when it was stopped.
RESOLUTION: Modify "cpu_run_mode_interrupt" (hp3000_cpu.c) to test a flag
that is set in "halt_mode_interrupt" when resuming into a PAUS instruction.
If the flag is set, increment P and clear it, so that a second entry will
not increment P twice.
STATUS: Fixed in Release 8.
@ -394,7 +548,7 @@ Bugs Fixed
VERSION: Release 4.
OBSERVATION: The EDIT instruction is interruptible between operations. If
OBSERVATION: The EDIT instruction is interruptible between operations. If
an interrupt is detected, two words are pushed onto the stack before the
interrupt handler is called. These words hold the current significance
trigger, loop count, float character, and fill character. This allows the

View file

@ -1,6 +1,6 @@
/* hp3000_sel.c: HP 3000 30030C Selector Channel simulator
Copyright (c) 2016-2017, J. David Bryan
Copyright (c) 2016-2018, 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
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
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
@ -1005,7 +1006,7 @@ while (sel_request && cycles > 0) { /* execute as long as a
sequencer = Transfer_Sequence; /* continue with the transfer sequence */
/* fall into the Transfer_Sequence */
/* fall through into the Transfer_Sequence */
case Transfer_Sequence:

View file

@ -23,6 +23,8 @@
in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from the author.
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
29-May-18 JDB Added a check for the "alternate" flag to "fmt_bitset"
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"
@ -80,6 +82,14 @@
/* Global release string */
const char *sim_vm_release = "8"; /* HP 3000 simulator release number */
const char *sim_vm_release_message =
"This is the last version of this simulator which is API compatible\n"
"with the 4.x version of the simh framework. A supported version of\n"
"this simulator can be found at: http://simh.trailing-edge.com/hp\n";
/* External I/O data structures */
extern DEVICE iop_dev; /* I/O Processor */
@ -1072,7 +1082,7 @@ char sim_name [] = "HP 3000"; /* the simulator name */
int32 sim_emax = 2; /* the maximum number of words in any instruction */
WEAK void (*sim_vm_init) (void) = &one_time_init; /* a pointer to the one-time initializer */
void (*sim_vm_init) (void) = &one_time_init; /* a pointer to the one-time initializer */
DEVICE *sim_devices [] = { /* an array of pointers to the simulated devices */
&cpu_dev, /* CPU (must be first) */
@ -1958,7 +1968,7 @@ switch (opcode) { /* dispatch by the exten
else /* otherwise */
operand = NEG8 (operand); /* negate the operand for display */
/* fall into the BRIS case */
/* fall through into the BRIS case */
case 011: /* BRIS - branch if significance */
if (operand & D8_SIGN) { /* if the displacement is negative */
@ -3490,7 +3500,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
index = (instruction & X_FLAG) != 0; /* save the index condition */
indirect = (instruction & I_FLAG_BIT_5) != 0; /* and the indirect condition */
/* fall into the P-relative displacement case */
/* fall through into the P-relative displacement case */
/* P +/- displacement range 0-255 */
@ -3597,7 +3607,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
break;
}
/* otherwise the displacement is not P-relative, so fall into the data-relative handler */
/* otherwise the displacement is not P-relative, so fall through into the data-relative handler */
/* DB+/Q+/Q-/S- displacements, indirect bit 5, index bit 4 */
@ -3624,7 +3634,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
indirect = (instruction & I_FLAG_BIT_5) != 0; /* save the indirect condition */
/* fall into the index case */
/* fall through into the index case */
/* index bit 4 */
@ -3639,7 +3649,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
index = (instruction & X_FLAG) != 0; /* save the index condition */
op_value = op_value & DISPL_63_MASK; /* and mask to the operand value */
/* fall into the unsigned value case */
/* fall through into the unsigned value case */
/* unsigned value range 0-63 */
@ -3686,7 +3696,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
case opSU2:
op_value = op_value >> EIS_SDEC_SHIFT; /* align the S decrement value */
/* fall into the unsigned operand case */
/* fall through into the unsigned operand case */
/* unsigned value range 0-1 */
/* unsigned value range 0-255 */

View file

@ -1,6 +1,6 @@
/* hp_disclib.c: HP MAC/ICD disc controller simulator library
Copyright (c) 2011-2017, J. David Bryan
Copyright (c) 2011-2018, 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 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the authors.
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
22-Apr-17 JDB A failed sim_fseek call now causes a drive fault
10-Oct-16 JDB Moved "hp3000_defs.h" inclusion from "hp_disclib.h"
03-Aug-16 JDB "fmt_bitset" now allows multiple concurrent calls
@ -1816,12 +1817,12 @@ else { /* otherwise the command
cvptr->verify = FALSE; /* do not verify until a track is crossed */
inbound_data &= ~CM_SPD_MASK; /* clear the SPD bits to avoid changing the state */
/* fall into the Initialize case */
/* fall through into the Initialize case */
case Initialize:
cvptr->spd_unit |= CM_SPD (inbound_data); /* merge the SPD flags with the unit */
/* fall into the read/write cases */
/* fall through into the read/write cases */
case Read:
case Read_Full_Sector:
@ -2268,7 +2269,7 @@ switch (phase) { /* dispatch the phase */
case Cold_Load_Read:
cvptr->file_mask = CM_SPARE_EN; /* enable sparing in surface mode without auto-seek */
/* fall into the default case */
/* fall through into the default case */
default: /* a command was waiting on seek completion */
set_rotation (cvptr, uptr); /* so set up the rotation phase and latency */

View file

@ -1,6 +1,6 @@
/* hp_tapelib.c: HP magnetic tape controller simulator library
Copyright (c) 2013-2017, J. David Bryan
Copyright (c) 2013-2018, 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 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the authors.
27-Dec-18 JDB Revised fall through comments to comply with gcc 7
22-Apr-17 JDB Corrected status_name array element count
10-Oct-16 JDB Moved "hp3000_defs.h" inclusion from "hp_tapelib.h"
01-Jul-16 JDB Changed tl_attach to reset the event delay times pointer
@ -2146,7 +2147,7 @@ switch (phase) { /* dispatch the phase */
case Write_Record_without_Parity:
outbound = RQSRV; /* request the first data word from the channel */
/* fall into the Write_File_Mark case */
/* fall through into the Write_File_Mark case */
case Write_File_Mark:
if ((cvptr->device->flags & DEV_REALTIME) == 0 /* if fast timing is enabled */
@ -2156,7 +2157,7 @@ switch (phase) { /* dispatch the phase */
break;
} /* otherwise an initial gap is needed */
/* fall into the Write_Gap case */
/* fall through into the Write_Gap case */
case Write_Gap:
outbound |= /* erase the gap */
@ -2214,7 +2215,7 @@ switch (phase) { /* dispatch the phase */
case Rewind_Offline:
uptr->flags |= UNIT_OFFLINE; /* set the unit offline immediately */
/* fall into the Rewind case */
/* fall through into the Rewind case */
case Rewind:
outbound = end_command (cvptr, uptr); /* release the controller */
@ -2469,7 +2470,7 @@ switch (phase) { /* dispatch the phase */
break; /* after the motion stops */
}
/* otherwise fall into the Backspace_File case */
/* otherwise fall through into the Backspace_File case */
case Backspace_File:
uptr->PHASE = Start_Phase; /* set up to space over the next record */
@ -2550,7 +2551,7 @@ switch (phase) { /* dispatch the phase */
&& cvptr->length & 1) /* and the record length is odd */
cvptr->status |= CST_ODDLEN; /* then set the corresponding status */
/* fall into the Write_File_Mark case */
/* fall through into the Write_File_Mark case */
case Write_File_Mark:
case Write_Gap:
@ -2842,7 +2843,7 @@ switch (cvptr->call_status) { /* dispatch on the call
case MTSE_RECE: /* record data in error */
cvptr->status |= CST_DATAERR; /* report as a data error */
/* fall into the MTSE_OK case */
/* fall through into the MTSE_OK case */
case MTSE_OK: /* operation succeeded */
if (cvptr->length > 0) /* if data is present */
@ -2854,7 +2855,7 @@ switch (cvptr->call_status) { /* dispatch on the call
case MTSE_TMK: /* tape mark encountered */
cvptr->gaplen -= sizeof (t_mtrlnt); /* reduce the gap length by the metadata marker size */
/* fall into the MTSE_EOM case */
/* fall through into the MTSE_EOM case */
case MTSE_EOM: /* end of medium encountered */
cvptr->status |= CST_EOF; /* set the EOF status */
@ -2862,7 +2863,7 @@ switch (cvptr->call_status) { /* dispatch on the call
if (cvptr->type == HP_13181) /* the HP 1000 NRZI controller */
cvptr->status |= CST_ODDLEN; /* also sets odd length status for a tape mark */
/* fall into the MTSE_BOT case */
/* fall through into the MTSE_BOT case */
case MTSE_BOT: /* beginning of tape encountered */
cvptr->state = End_State; /* indicate a device end condition */

View file

@ -1,6 +1,6 @@
/* hp_tapelib.h: HP magnetic tape controller simulator library declarations
Copyright (c) 2013-2017, J. David Bryan
Copyright (c) 2013-2019, 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.
01-Feb-19 JDB Remap sim_tape_attach to avoid unwanted debug output
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
@ -44,6 +45,14 @@
/* Remap tape attach in 4.x to avoid unwanted debug output */
#if (SIM_MAJOR >= 4)
#define sim_tape_attach(a,b) sim_tape_attach_ex (a, b, 0, 0)
#endif
/* Architectural constants.
The type of the tape buffer element is defined. This must be an 8-bit array