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:
parent
254e173fc1
commit
6bbbc19e01
19 changed files with 394 additions and 129 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_atc.c: HP 3000 30032B Asynchronous Terminal Controller simulator
|
/* 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
|
Copyright (c) 2002-2012, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
ATCD,ATCC HP 30032B Asynchronous Terminal Controller
|
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"
|
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
|
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
|
26-Oct-17 JDB Call "tmxr_poll_tx" if transmit buffer is full
|
||||||
|
|
|
@ -693,7 +693,7 @@ while (working_set) {
|
||||||
|
|
||||||
|
|
||||||
case DRESETINT:
|
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 */
|
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 */
|
&& control_word & CN_IRQ_ENABLE) /* and interrupts are enabled */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_cpu.c: HP 3000 Central Processing Unit simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
CPU HP 3000 Series III Central Processing Unit
|
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
|
05-Sep-17 JDB Removed the -B (binary display) option; use -2 instead
|
||||||
Changed REG_A (permit any symbolic override) to REG_X
|
Changed REG_A (permit any symbolic override) to REG_X
|
||||||
19-Jan-17 JDB Added comments describing the OPND and EXEC trace options
|
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
|
Both implementations were mocked up and timing measurements made. The
|
||||||
results were that copying values is much faster than mapping via array
|
results were that copying values is much faster than mapping via array
|
||||||
index values, so this is the implementation chosen.
|
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 */
|
/* Program constants */
|
||||||
|
|
||||||
#define PCLK_PERIOD mS (1) /* 1 millisecond process clock period */
|
#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 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 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 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_mask = 0; /* the current instruction execution trace mask */
|
||||||
static HP_WORD exec_match = D16_UMAX; /* the current instruction execution trace matching value */
|
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, UNIT_CIS, "CIS", "CIS", &set_option, NULL, NULL },
|
||||||
{ UNIT_CIS, 0, "no CIS", "NOCIS", NULL, NULL, NULL },
|
{ UNIT_CIS, 0, "no CIS", "NOCIS", NULL, NULL, NULL },
|
||||||
|
|
||||||
{ UNIT_PFARS, UNIT_PFARS, "auto-restart", "ARS", &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_PFARS, 0, "no auto-restart", "NOARS", &set_pfars, NULL, NULL },
|
||||||
|
|
||||||
{ UNIT_CALTIME, UNIT_CALTIME, "calibrated timing", "CALTIME", NULL, 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 */
|
/* Entry Flags Value Print String Match String Validation Display Descriptor */
|
||||||
/* ------------------- ----------- ------------ ------------ ------------- -------------- ---------- */
|
/* ------------------- ----------- ------------ ------------ ------------- -------------- ---------- */
|
||||||
|
@ -1402,6 +1424,7 @@ int abortval;
|
||||||
HP_WORD label, parameter;
|
HP_WORD label, parameter;
|
||||||
TRAP_CLASS trap;
|
TRAP_CLASS trap;
|
||||||
t_bool exec_test;
|
t_bool exec_test;
|
||||||
|
volatile uint32 debug_save;
|
||||||
volatile HP_WORD device;
|
volatile HP_WORD device;
|
||||||
volatile t_stat status = SCPE_OK;
|
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 */
|
if (STT_SEGMENT (parameter) <= ISR_SEGMENT) /* if the trap occurred in segment 1 */
|
||||||
MICRO_ABORT (trap_SysHalt_CSTV_1); /* then the failure is fatal */
|
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:
|
case trap_STT_Violation:
|
||||||
if (STT_SEGMENT (parameter) <= ISR_SEGMENT) /* if the trap occurred in segment 1 */
|
if (STT_SEGMENT (parameter) <= ISR_SEGMENT) /* if the trap occurred in segment 1 */
|
||||||
MICRO_ABORT (trap_SysHalt_STTV_1); /* then the failure is fatal */
|
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_Unimplemented:
|
||||||
case trap_DST_Violation:
|
case trap_DST_Violation:
|
||||||
|
@ -1480,13 +1503,13 @@ if (abortval) { /* if a microcode abort
|
||||||
case trap_Bounds_Violation:
|
case trap_Bounds_Violation:
|
||||||
parameter = label; /* the label is the parameter for these traps */
|
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:
|
case trap_DS_Absent:
|
||||||
cpu_flush (); /* flush the TOS registers to memory */
|
cpu_flush (); /* flush the TOS registers to memory */
|
||||||
cpu_mark_stack (); /* and then write a stack marker */
|
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:
|
case trap_Uncallable:
|
||||||
break; /* set up the trap handler */
|
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 */
|
case trap_Cold_Load: /* this trap executes on the ICS */
|
||||||
status = STOP_CLOAD; /* report that the cold load is complete */
|
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 */
|
case trap_Stack_Overflow: /* this trap executes on the ICS */
|
||||||
if (CPX1 & cpx1_ICSFLAG) /* so if the trap occurred while 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 */
|
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",
|
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 */
|
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
|
If an interrupt occurs while PAUS is executing, the interrupt handler
|
||||||
will return to the instruction following the PAUS, as though HALT and RUN
|
will return to the instruction following the PAUS, as though HALT and RUN
|
||||||
had been pressed. This occurs because P normally points two instructions
|
had been pressed. This occurs because the P register normally points two
|
||||||
beyond the current instruction, so stacking the value P - 1 during the
|
instructions past the instruction currently executing. When an interrupt
|
||||||
interrupt will return to the next instruction to be executed. When
|
occurs, P is decremented to point at the instruction after the current
|
||||||
resuming the PAUS instruction from a simulation stop with an interrupt
|
instruction, which is the correct point of return after the interrupt
|
||||||
pending, though, P is set so that P - 1 points to the PAUS instruction,
|
service routine completes.
|
||||||
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.
|
|
||||||
|
|
||||||
Therefore, this case is detected when a PAUS instruction is in the CIR
|
When the simulator is stopped, P is backed up to point at the next
|
||||||
but the micromachine state is "running" instead of "paused", and P is
|
instruction to execute. In the case of a PAUS instruction, the "next
|
||||||
incremented so that the return will be to the instruction following PAUS.
|
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)
|
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;
|
HP_WORD request_set, request_count, parameter;
|
||||||
IRQ_CLASS class;
|
IRQ_CLASS class;
|
||||||
|
|
||||||
if (cpu_micro_state == running /* if we are resuming from a sim stop */
|
if (cpu_stop_flags & SS_PAUSE_RESUMED) { /* if we are resuming into a PAUS instruction */
|
||||||
&& (CIR & PAUS_MASK) == PAUS) /* into a PAUS instruction */
|
P = P + 1 & R_MASK; /* then set the return to the instruction following */
|
||||||
P = P + 1 & R_MASK; /* then return is to the instruction following */
|
cpu_stop_flags &= ~SS_PAUSE_RESUMED; /* and clear the flag in case of back-to-back interrupts */
|
||||||
else /* otherwise the micromachine may be paused */
|
}
|
||||||
cpu_micro_state = running; /* but is no longer */
|
|
||||||
|
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 */
|
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;
|
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 */
|
|| 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_flush (); /* then flush the TOS registers to memory */
|
||||||
cpu_mark_stack (); /* and write a four-word stack marker */
|
cpu_mark_stack (); /* and write a four-word stack marker */
|
||||||
|
@ -3294,9 +3347,8 @@ return;
|
||||||
examined from the SCP command prompt.
|
examined from the SCP command prompt.
|
||||||
|
|
||||||
The simulation console is normally hosted by, and therefore polled by, the
|
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
|
ATC on channel 0. If the console is not hosted by the ATC, due to a SET ATC
|
||||||
SET ATC NOCONSOLE or a SET ATC DISABLED command, the process clock assumes
|
DISABLED command, the process clock assumes polling control over the console.
|
||||||
polling control over the console.
|
|
||||||
|
|
||||||
|
|
||||||
Implementation notes:
|
Implementation notes:
|
||||||
|
@ -3962,10 +4014,10 @@ return SCPE_OK; /* and report success
|
||||||
|
|
||||||
Implementation notes:
|
Implementation notes:
|
||||||
|
|
||||||
1. After RUN switch processing and return to the instruction loop, if no
|
1. After processing the RUN switch and returning to the instruction loop, if
|
||||||
interrupt is present, and the R-bit in the status register is clear, then
|
no interrupt is present, and the R-bit in the status register is clear,
|
||||||
CIR will be set from NIR, and NIR will be reloaded. If the R-bit is set,
|
then CIR will be set from NIR, and NIR will be reloaded. If the R-bit is
|
||||||
then CIR and NIR will not be changed, i.e., the NEXT action will be
|
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
|
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
|
interrupt will be processed using the old value of the CIR, and the
|
||||||
instruction in the NIR will become the first instruction executed after
|
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 */
|
cpu_read_memory (fetch, P, &NIR); /* load the next instruction to execute */
|
||||||
P = P + 1 & R_MASK; /* and point to the following instruction */
|
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 */
|
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 */
|
STA &= ~STATUS_R; /* then clear the R-bit in case it had been set */
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_cpu.h: HP 3000 CPU declarations
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
in advertising or otherwise to promote the sale, use or other dealings in
|
||||||
this Software without prior written authorization from the author.
|
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;
|
07-Nov-16 JDB Added SETR and SETR_X for SETR executor use;
|
||||||
renamed cpu_byte_to_word_ea to cpu_byte_ea
|
renamed cpu_byte_to_word_ea to cpu_byte_ea
|
||||||
03-Nov-16 JDB Added LABEL_LOCAL for PARC/XBR/ENDP executor use
|
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_PAUSE (1u << 1) /* stop on PAUS instruction */
|
||||||
#define SS_UNDEF (1u << 2) /* stop on undefined instruction */
|
#define SS_UNDEF (1u << 2) /* stop on undefined instruction */
|
||||||
#define SS_UNIMPL (1u << 3) /* stop on unimplemented 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 */
|
#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_irq_handler (IRQ_CLASS class, HP_WORD parameter);
|
||||||
extern void cpu_setup_ics_irq (IRQ_CLASS class, TRAP_CLASS trap);
|
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_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_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_call_procedure (HP_WORD label, HP_WORD offset);
|
||||||
extern void cpu_exit_procedure (HP_WORD new_q, HP_WORD new_sm, HP_WORD parameter);
|
extern void cpu_exit_procedure (HP_WORD new_q, HP_WORD new_sm, HP_WORD parameter);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_cpu_base.c: HP 3000 CPU base set instruction simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
in advertising or otherwise to promote the sale, use or other dealings in
|
||||||
this Software without prior written authorization from the author.
|
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
|
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;
|
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
|
renamed cpu_byte_to_word_ea to cpu_byte_ea
|
||||||
|
@ -3335,7 +3336,7 @@ switch (operation) { /* dispatch the move or
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall into the LOCK executor */
|
/* fall through into the LOCK executor */
|
||||||
|
|
||||||
case 001: /* LOCK (none; MODE) */
|
case 001: /* LOCK (none; MODE) */
|
||||||
if (UNIT_CPU_MODEL == UNIT_SERIES_II) { /* if the CPU is a Series II */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall into the PCN executor */
|
/* fall through into the PCN executor */
|
||||||
|
|
||||||
case 002: /* PCN (none; STOV, MODE) */
|
case 002: /* PCN (none; STOV, MODE) */
|
||||||
cpu_push (); /* push the stack down */
|
cpu_push (); /* push the stack down */
|
||||||
|
@ -3382,7 +3383,7 @@ switch (operation) { /* dispatch the move or
|
||||||
break;
|
break;
|
||||||
} /* otherwise fall into the UNLK executor */
|
} /* otherwise fall into the UNLK executor */
|
||||||
|
|
||||||
/* fall into the UNLK executor */
|
/* fall through into the UNLK executor */
|
||||||
|
|
||||||
case 003: /* UNLK (none; MODE) */
|
case 003: /* UNLK (none; MODE) */
|
||||||
if (UNIT_CPU_MODEL == UNIT_SERIES_II) { /* if the CPU is a Series II */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall into the PSDB executor */
|
/* fall through into the PSDB executor */
|
||||||
|
|
||||||
case 001: /* PSDB (none; MODE) */
|
case 001: /* PSDB (none; MODE) */
|
||||||
cpu_read_memory (absolute, ICS_Q, /* read the ICS stack marker pointer value */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall into the DISP executor */
|
/* fall through into the DISP executor */
|
||||||
|
|
||||||
case 002: /* DISP (CCx; MODE, CSTV, TRACE, ABS CST, BNDV) */
|
case 002: /* DISP (CCx; MODE, CSTV, TRACE, ABS CST, BNDV) */
|
||||||
cpu_read_memory (absolute, ICS_Q, /* read the stack marker initial value */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall into the PSEB executor */
|
/* fall through into the PSEB executor */
|
||||||
|
|
||||||
case 003: /* PSEB (CCx; MODE, CSTV, TRACE, ABS CST, BNDV) */
|
case 003: /* PSEB (CCx; MODE, CSTV, TRACE, ABS CST, BNDV) */
|
||||||
cpu_read_memory (absolute, ICS_Q, /* read the stack marker initial value */
|
cpu_read_memory (absolute, ICS_Q, /* read the stack marker initial value */
|
||||||
|
|
|
@ -157,7 +157,7 @@
|
||||||
numbers with an even number of digits will not use the upper four bits of the
|
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
|
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
|
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
|
1100 - the number is positive
|
||||||
1101 - the number is negative
|
1101 - the number is negative
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_ds.c: HP 3000 30229B Cartridge Disc Interface simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
DS HP 30229B Cartridge Disc Interface
|
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
|
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
|
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
|
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 */
|
break; /* and try again */
|
||||||
}
|
}
|
||||||
/* otherwise, request an interrupt */
|
/* otherwise, request an interrupt */
|
||||||
/* fall into the STINT case */
|
/* fall through into the STINT case */
|
||||||
|
|
||||||
case STINT: /* Set Interrupt */
|
case STINT: /* Set Interrupt */
|
||||||
flags &= ~XFRNG; /* clear the transfer error flag */
|
flags &= ~XFRNG; /* clear the transfer error flag */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_io.h: HP 3000 device-to-IOP/MPX/SEL interface declarations
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
in advertising or otherwise to promote the sale, use or other dealings in
|
||||||
this Software without prior written authorization from the author.
|
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
|
12-Sep-16 JDB Added the DIB_REGS macro
|
||||||
02-Sep-16 JDB Added the iop_assert_PFWARN routine
|
02-Sep-16 JDB Added the iop_assert_PFWARN routine
|
||||||
11-Jun-16 JDB Bit mask constants are now unsigned
|
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
|
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
|
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
|
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
|
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):
|
will differ. For example (bits are numbered here from the LSB):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_iop.c: HP 3000 30003B I/O Processor simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
IOP HP 3000 Series III I/O Processor
|
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
|
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
|
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
|
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
|
However, if some condition has occurred between the time of the original
|
||||||
request and this poll, the interface will assert INTPOLLOUT. In response,
|
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
|
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.
|
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
|
This prevents a second interrupt from changing IOA until the microcode
|
||||||
signals its readiness by clearing EXTINT. In simulation, entry with
|
signals its readiness by clearing EXTINT. In simulation, entry with
|
||||||
cpx1_EXTINTR set returns IOA in lieu of conducting a poll.
|
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)
|
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 */
|
if (CPX1 & cpx1_EXTINTR) /* if an external interrupt has been requested */
|
||||||
return IOA; /* then return the device number in lieu of polling */
|
return IOA; /* then return the device number in lieu of polling */
|
||||||
|
|
||||||
priority_mask = IOPRIORITY (interrupt_poll_set); /* calculate the priority mask */
|
else do { /* otherwise poll for an interrupt request */
|
||||||
request_granted = priority_mask & iop_interrupt_request_set; /* and determine the request to grant */
|
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 */
|
if (request_granted == 0) /* if no request was granted */
|
||||||
return 0; /* then return */
|
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 */
|
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 */
|
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 */
|
if (outbound & INTACK) { /* if the interface acknowledged the interrupt */
|
||||||
IOA = IODATA (outbound); /* then save the returned device number */
|
IOA = IODATA (outbound); /* then save the returned device number */
|
||||||
CPX1 |= cpx1_EXTINTR; /* and tell the CPU */
|
CPX1 |= cpx1_EXTINTR; /* and tell the CPU */
|
||||||
|
|
||||||
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
|
dprintf (iop_dev, FILTER (dibptr->device_number) ? DEB_IRQ : 0,
|
||||||
"Device number %u acknowledged interrupt request at priority %u\n",
|
"Device number %u acknowledged interrupt request at priority %u\n",
|
||||||
dibptr->device_number, ipn);
|
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 */
|
while (iop_interrupt_request_set != 0); /* continue polling while requests remain */
|
||||||
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 */
|
|
||||||
|
|
||||||
return IOA; /* return the interrupting device number */
|
return IOA; /* return the interrupting device number */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_lp.c: HP 3000 30209A Line Printer Interface simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
LP HP 30209A Line Printer Interface
|
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
|
07-Sep-17 JDB Changed PCHR and UPCHR registers to PUNCHR and UNPCHR
|
||||||
Changed PRTBUF, OVPCHR, PUNCHR, and UNPCHR to REG_A
|
Changed PRTBUF, OVPCHR, PUNCHR, and UNPCHR to REG_A
|
||||||
05-Sep-17 JDB Changed REG_A (permit any symbolic override) to REG_X
|
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 */
|
if (! J2W1_INSTALLED) /* if W1 (SR set by Device Status) is not installed */
|
||||||
device_sr = SET; /* then set the device service request flip-flop */
|
device_sr = SET; /* then set the device service request flip-flop */
|
||||||
|
|
||||||
/* fall into the DCONTSTB case */
|
/* fall through into the DCONTSTB case */
|
||||||
|
|
||||||
case DCONTSTB:
|
case DCONTSTB:
|
||||||
dprintf (lp_dev, DEB_CSRW,
|
dprintf (lp_dev, DEB_CSRW,
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
MEM HP 3000 Series III Main Memory
|
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
|
21-May-18 JDB Changed "access" to "mem_access" to avoid clashing
|
||||||
10-Oct-16 JDB Created
|
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 */
|
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 */
|
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:
|
case data_checked:
|
||||||
if (DL <= offset && offset <= SM + SR || PRIV) /* if the offset is within bounds or is privileged */
|
if (DL <= offset && offset <= SM + SR || PRIV) /* if the offset is within bounds or is privileged */
|
||||||
|
|
|
@ -363,7 +363,6 @@ extern DEVICE iop_dev; /* I/O Processor */
|
||||||
state RAM" command.
|
state RAM" command.
|
||||||
|
|
||||||
3. State "parity" is 1 for an illegal state and 0 for a valid state.
|
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 */
|
#define INTRF_COUNT (SRNO_MAX + 1) /* count of interfaces handled by the multiplexer channel */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_ms.c: HP 3000 30215A Magnetic Tape Controller Interface simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
MS HP 30215A Magnetic Tape Controller Interface
|
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
|
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
|
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
|
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 */
|
unit_interrupt = SET; /* set the unit interrupt flip-flop */
|
||||||
attention_unit = TLIBUS (result); /* and save the number of the requesting unit */
|
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 */
|
case STINT: /* Set Interrupt */
|
||||||
flags = NO_FLAGS; /* clear the interface transfer flags and INTOK */
|
flags = NO_FLAGS; /* clear the interface transfer flags and INTOK */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
SIMH/HP 3000 RELEASE NOTES
|
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.
|
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
|
...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.
|
commit ID" that is displayed in the simulator welcome banner.
|
||||||
|
|
||||||
Therefore, HP 3000 releases are simply documentation checkpoints that describe
|
An HP 3000 "release" replaces the HP portion of the SIMH code base and is made
|
||||||
the changes that have occurred since the last checkpoint. Generally, a release
|
when one or more major changes have been incorporated. Each release is
|
||||||
is written when one or more major changes have been incorporated. Minor bug
|
documented below and describes the changes (new features and corrected errors)
|
||||||
fixes will be available immediately from the repository but only noted as part
|
that have occurred since the prior release. A revised "HP 3000 Simulator User's
|
||||||
of the next release document.
|
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
|
- 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
|
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
|
(M/D/Y)? and then WED, NOV 1, 1972, 12:00 AM, as though the RETURN key had
|
||||||
entered, but it wasn't. If an HP terminal emulator is used instead, MPE
|
been pressed. If an HP terminal emulator is used instead, MPE waits for the
|
||||||
waits for the user to enter the date before proceeding.
|
user to enter the date before proceeding.
|
||||||
|
|
||||||
The problem is incorrect coding in the SPEEDSENSE procedure in module
|
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
|
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
|
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
|
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
|
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
|
itself when SET ATCD0 REMOTEACK is done before booting.
|
||||||
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"
|
An alternate workaround that does not depend on the ATC configuration is to
|
||||||
instruction at that location to "LDI 360" to set the detected speed to 2400
|
set memory location 01.112247 to octal value 021360 after cold loading is
|
||||||
baud unconditionally.
|
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
|
- 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
|
SHUTDOWN command or because the read timed out, the message is printed
|
||||||
normally.
|
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
|
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 write. The timing is such that only the first few characters of the
|
||||||
message are printed before the rest of the output is cancelled.
|
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
|
(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
|
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,
|
limit is subsequently raised via a SYSDUMP and COLDSTART reconfiguration,
|
||||||
running DPAN4 produces a "FILE IS NOT A VALID PROGRAM FILE" error. However,
|
running DPAN4 produces a "FILE IS NOT A VALID PROGRAM FILE" error, which
|
||||||
if the reconfiguration is done before running DPAN4, it will run properly
|
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.
|
thereafter.
|
||||||
|
|
||||||
The problem is that MPE incorrectly modifies the executable file's Segment
|
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
|
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
|
segment size aborts occur before any of the STTs are modified, so the program
|
||||||
file remains internally consistent. A memory patch is impossible, but
|
file remains internally consistent. A memory patch is impossible, but a
|
||||||
workarounds are to increase the code segment limit before running DPAN4 and
|
workaround is to increase the code segment limit before running DPAN4. This
|
||||||
to restore DPAN4.PUB.SYS from the FOS tape if it has been damaged.
|
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.
|
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
|
an interrupt is detected, two words are pushed onto the stack before the
|
||||||
interrupt handler is called. These words hold the current significance
|
interrupt handler is called. These words hold the current significance
|
||||||
trigger, loop count, float character, and fill character. This allows the
|
trigger, loop count, float character, and fill character. This allows the
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp3000_sel.c: HP 3000 30030C Selector Channel simulator
|
/* 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
SEL HP 3000 Series III Selector Channel
|
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
|
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
|
10-Oct-16 JDB Renumbered debug flags to start at 0
|
||||||
Added port_read_memory, port_write_memory macros
|
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 */
|
sequencer = Transfer_Sequence; /* continue with the transfer sequence */
|
||||||
|
|
||||||
/* fall into the Transfer_Sequence */
|
/* fall through into the Transfer_Sequence */
|
||||||
|
|
||||||
|
|
||||||
case Transfer_Sequence:
|
case Transfer_Sequence:
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
in advertising or otherwise to promote the sale, use or other dealings in
|
in advertising or otherwise to promote the sale, use or other dealings in
|
||||||
this Software without prior written authorization from the author.
|
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
|
05-Sep-17 JDB Removed the -B (binary display) option; use -2 instead
|
||||||
Rewrote "fprint_sym" for better coverage
|
Rewrote "fprint_sym" for better coverage
|
||||||
11-May-17 JDB Corrected comment in "fprint_value"
|
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 */
|
/* External I/O data structures */
|
||||||
|
|
||||||
extern DEVICE iop_dev; /* I/O Processor */
|
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 */
|
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 */
|
DEVICE *sim_devices [] = { /* an array of pointers to the simulated devices */
|
||||||
&cpu_dev, /* CPU (must be first) */
|
&cpu_dev, /* CPU (must be first) */
|
||||||
|
@ -1958,7 +1968,7 @@ switch (opcode) { /* dispatch by the exten
|
||||||
else /* otherwise */
|
else /* otherwise */
|
||||||
operand = NEG8 (operand); /* negate the operand for display */
|
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 */
|
case 011: /* BRIS - branch if significance */
|
||||||
if (operand & D8_SIGN) { /* if the displacement is negative */
|
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 */
|
index = (instruction & X_FLAG) != 0; /* save the index condition */
|
||||||
indirect = (instruction & I_FLAG_BIT_5) != 0; /* and the indirect 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 */
|
/* P +/- displacement range 0-255 */
|
||||||
|
|
||||||
|
@ -3597,7 +3607,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
|
||||||
break;
|
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 */
|
/* 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 */
|
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 */
|
/* 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 */
|
index = (instruction & X_FLAG) != 0; /* save the index condition */
|
||||||
op_value = op_value & DISPL_63_MASK; /* and mask to the operand value */
|
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 */
|
/* unsigned value range 0-63 */
|
||||||
|
|
||||||
|
@ -3686,7 +3696,7 @@ switch (ops [op_index].operand) { /* dispatch by the opera
|
||||||
case opSU2:
|
case opSU2:
|
||||||
op_value = op_value >> EIS_SDEC_SHIFT; /* align the S decrement value */
|
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-1 */
|
||||||
/* unsigned value range 0-255 */
|
/* unsigned value range 0-255 */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp_disclib.c: HP MAC/ICD disc controller simulator library
|
/* 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
|
Copyright (c) 2004-2011, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
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
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from the authors.
|
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
|
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"
|
10-Oct-16 JDB Moved "hp3000_defs.h" inclusion from "hp_disclib.h"
|
||||||
03-Aug-16 JDB "fmt_bitset" now allows multiple concurrent calls
|
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 */
|
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 */
|
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:
|
case Initialize:
|
||||||
cvptr->spd_unit |= CM_SPD (inbound_data); /* merge the SPD flags with the unit */
|
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:
|
||||||
case Read_Full_Sector:
|
case Read_Full_Sector:
|
||||||
|
@ -2268,7 +2269,7 @@ switch (phase) { /* dispatch the phase */
|
||||||
case Cold_Load_Read:
|
case Cold_Load_Read:
|
||||||
cvptr->file_mask = CM_SPARE_EN; /* enable sparing in surface mode without auto-seek */
|
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 */
|
default: /* a command was waiting on seek completion */
|
||||||
set_rotation (cvptr, uptr); /* so set up the rotation phase and latency */
|
set_rotation (cvptr, uptr); /* so set up the rotation phase and latency */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp_tapelib.c: HP magnetic tape controller simulator library
|
/* 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
|
Copyright (c) 2004-2011, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
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
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from the authors.
|
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
|
22-Apr-17 JDB Corrected status_name array element count
|
||||||
10-Oct-16 JDB Moved "hp3000_defs.h" inclusion from "hp_tapelib.h"
|
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
|
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:
|
case Write_Record_without_Parity:
|
||||||
outbound = RQSRV; /* request the first data word from the channel */
|
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:
|
case Write_File_Mark:
|
||||||
if ((cvptr->device->flags & DEV_REALTIME) == 0 /* if fast timing is enabled */
|
if ((cvptr->device->flags & DEV_REALTIME) == 0 /* if fast timing is enabled */
|
||||||
|
@ -2156,7 +2157,7 @@ switch (phase) { /* dispatch the phase */
|
||||||
break;
|
break;
|
||||||
} /* otherwise an initial gap is needed */
|
} /* otherwise an initial gap is needed */
|
||||||
|
|
||||||
/* fall into the Write_Gap case */
|
/* fall through into the Write_Gap case */
|
||||||
|
|
||||||
case Write_Gap:
|
case Write_Gap:
|
||||||
outbound |= /* erase the gap */
|
outbound |= /* erase the gap */
|
||||||
|
@ -2214,7 +2215,7 @@ switch (phase) { /* dispatch the phase */
|
||||||
case Rewind_Offline:
|
case Rewind_Offline:
|
||||||
uptr->flags |= UNIT_OFFLINE; /* set the unit offline immediately */
|
uptr->flags |= UNIT_OFFLINE; /* set the unit offline immediately */
|
||||||
|
|
||||||
/* fall into the Rewind case */
|
/* fall through into the Rewind case */
|
||||||
|
|
||||||
case Rewind:
|
case Rewind:
|
||||||
outbound = end_command (cvptr, uptr); /* release the controller */
|
outbound = end_command (cvptr, uptr); /* release the controller */
|
||||||
|
@ -2469,7 +2470,7 @@ switch (phase) { /* dispatch the phase */
|
||||||
break; /* after the motion stops */
|
break; /* after the motion stops */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* otherwise fall into the Backspace_File case */
|
/* otherwise fall through into the Backspace_File case */
|
||||||
|
|
||||||
case Backspace_File:
|
case Backspace_File:
|
||||||
uptr->PHASE = Start_Phase; /* set up to space over the next record */
|
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->length & 1) /* and the record length is odd */
|
||||||
cvptr->status |= CST_ODDLEN; /* then set the corresponding status */
|
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_File_Mark:
|
||||||
case Write_Gap:
|
case Write_Gap:
|
||||||
|
@ -2842,7 +2843,7 @@ switch (cvptr->call_status) { /* dispatch on the call
|
||||||
case MTSE_RECE: /* record data in error */
|
case MTSE_RECE: /* record data in error */
|
||||||
cvptr->status |= CST_DATAERR; /* report as a data 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 */
|
case MTSE_OK: /* operation succeeded */
|
||||||
if (cvptr->length > 0) /* if data is present */
|
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 */
|
case MTSE_TMK: /* tape mark encountered */
|
||||||
cvptr->gaplen -= sizeof (t_mtrlnt); /* reduce the gap length by the metadata marker size */
|
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 */
|
case MTSE_EOM: /* end of medium encountered */
|
||||||
cvptr->status |= CST_EOF; /* set the EOF status */
|
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 */
|
if (cvptr->type == HP_13181) /* the HP 1000 NRZI controller */
|
||||||
cvptr->status |= CST_ODDLEN; /* also sets odd length status for a tape mark */
|
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 */
|
case MTSE_BOT: /* beginning of tape encountered */
|
||||||
cvptr->state = End_State; /* indicate a device end condition */
|
cvptr->state = End_State; /* indicate a device end condition */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* hp_tapelib.h: HP magnetic tape controller simulator library declarations
|
/* 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
|
Copyright (c) 2004-2011, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
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
|
in advertising or otherwise to promote the sale, use or other dealings in
|
||||||
this Software without prior written authorization from the authors.
|
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
|
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"
|
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
|
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.
|
/* Architectural constants.
|
||||||
|
|
||||||
The type of the tape buffer element is defined. This must be an 8-bit array
|
The type of the tape buffer element is defined. This must be an 8-bit array
|
||||||
|
|
Loading…
Add table
Reference in a new issue