sigma: Correct recognition of pending DP seek interrupt.

This corrects an error that caused SIO reject when SIO occured before
a pending seek interrupt on a different device.
 - Move the interrupt pending test from sigma_io.c into each device.
 - Make the sigma_dp.c test a special case that looks for pending
   seek interrupts.
This commit is contained in:
ken rector 2023-03-21 17:11:56 -07:00 committed by Paul Koning
parent 4b8a6f8d2c
commit 869dc0fe4a
10 changed files with 57 additions and 15 deletions

View file

@ -277,7 +277,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = mux_tio_status (); /* get status */
if ((*dvst & DVS_CST) == 0) { /* ctrl idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & DVS_CST) == 0) { /* ctrl idle? */
muxc_cmd = MUXC_INIT; /* start dev thread */
sim_activate (&mux_unit[MUXC], chan_ctl_time);
}

View file

@ -170,7 +170,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = dk_tio_status (un); /* get status */
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
dk_cmd = DKS_INIT; /* start dev thread */
sim_activate (&dk_unit[un], chan_ctl_time);
}

View file

@ -47,6 +47,16 @@
one for timing asynchronous seek completions. The controller will not
start a new operation is it is busy (any of the main units active) or if
the target device is busy (its seek unit is active).
The DP's seek interrupt has a unique feature: it comes and goes, lasting only
a sector's time; and it gets "knocked down" by any SIO to a different unit.
Therefore, the SIO interrupt check is complicated.
1. If there's a controller interrupt, the SIO fails.
2. If there's a seek interrupt on the selected unit, the SIO fails.
3. All other seek interrupts are "knocked down" and rescheduled for
some time "in the future."
4. The SIO completes normally.
*/
#include "sigma_io_defs.h"
@ -589,6 +599,18 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = dp_tio_status (cidx, un); /* get status */
if ((chan_chk_chi (dva) >= 0) || /* channel int pending? */
(dp_ctx[cidx].dp_ski & (1u << un))) { /* seek int on sel unit? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
break;
}
for (i = 0; i < DP_NUMDR; i++) { /* knock down other seek ints */
if (dp_ctx[cidx].dp_ski & (1u << i)) { /* seek int on unit? */
dp_clr_ski (cidx, i); /* knock it down */
sim_activate (&dp_unit[i + DP_SEEK], chan_ctl_time * 10);
dp_unit[i + DP_SEEK].UCMD = DSC_SEEKW; /* resched interrupt */
}
}
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
uptr->UCMD = DPS_INIT; /* start dev thread */
sim_activate (uptr, chan_ctl_time);

View file

@ -353,11 +353,6 @@ if (!io_init_inst (rn, ad, ch, dev, R[0])) { /* valid inst? */
CC |= CC1|CC2;
return 0;
}
if (chan[ch].chf[dev] & CHF_INP) { /* int pending? */
chan[ch].disp[dev] (OP_TIO, ad, &dvst); /* get status */
CC |= (CC2 | io_set_status (rn, ch, dev, dvst, 0)); /* set status */
return 0;
}
st = chan[ch].disp[dev] (OP_SIO, ad, &dvst); /* start I/O */
CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */
if (CC & cpu_tab[cpu_model].iocc) /* error? */
@ -806,7 +801,7 @@ if (chan[ch].chi[dev] & CHI_CTL) /* ctl int pending? */
else return -1;
}
/* Set device interrupt */
/* Set, check device interrupt */
void chan_set_dvi (uint32 dva)
{
@ -817,6 +812,16 @@ chan[ch].chf[dev] |= CHF_INP; /* int pending */
return;
}
t_bool chan_chk_dvi (uint32 dva)
{
uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */
uint32 dev = DVA_GETDEV (dva);
if ((chan[ch].chf[dev] & CHF_INP) != 0)
return TRUE;
return FALSE;
}
/* Called by device reset to reset channel registers */
t_stat chan_reset_dev (uint32 dva)

View file

@ -252,6 +252,7 @@ void chan_set_chi (uint32 dva, uint32 fl);
void chan_set_dvi (uint32 dva);
int32 chan_clr_chi (uint32 dva);
int32 chan_chk_chi (uint32 dva);
t_bool chan_chk_dvi (uint32 dva);
uint32 chan_end (uint32 dva);
uint32 chan_uen (uint32 dva);
uint32 chan_RdMemB (uint32 dva, uint32 *dat);
@ -275,4 +276,4 @@ t_stat rtc_set_tps (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat rtc_show_tps (FILE *of, UNIT *uptr, int32 val, CONST void *desc);
t_stat rtc_register (uint32 tm, uint32 idx, UNIT *uptr);
#endif
#endif

View file

@ -180,7 +180,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = lp_tio_status (); /* get status */
if ((*dvst & DVS_DST) == 0) { /* idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & DVS_DST) == 0) { /* idle? */
lp_cmd = LPS_INIT; /* start dev thread */
sim_activate (&lp_unit, chan_ctl_time);
}

View file

@ -237,7 +237,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = mt_tio_status (un); /* get status */
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
uptr->UCMD = MCM_INIT; /* start dev thread */
sim_activate (uptr, chan_ctl_time);
}

View file

@ -119,7 +119,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = pt_tio_status (); /* get status */
if ((*dvst & DVS_DST) == 0) { /* idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & DVS_DST) == 0) { /* idle? */
pt_cmd = PTS_INIT; /* start dev thread */
sim_activate (&pt_unit[PTR], chan_ctl_time);
}
@ -296,4 +298,4 @@ st = attach_unit (uptr, cptr);
if ((uptr == &pt_unit[PTR]) && (st == SCPE_OK))
ptr_nzc = 0;
return st;
}
}

View file

@ -211,7 +211,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = rad_tio_status (un); /* get status */
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
rad_cmd = RADS_INIT; /* start dev thread */
sim_activate (&rad_unit[un], chan_ctl_time);
}

View file

@ -134,7 +134,9 @@ switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = tt_tio_status (); /* get status */
if ((*dvst & DVS_DST) == 0) { /* idle? */
if (chan_chk_dvi (dva)) /* int pending? */
*dvst |= (CC2 << DVT_V_CC); /* SIO fails */
else if ((*dvst & DVS_DST) == 0) { /* idle? */
tt_cmd = TTS_INIT; /* start dev thread */
sim_activate (&tt_unit[TTO], chan_ctl_time);
}