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:
parent
4b8a6f8d2c
commit
869dc0fe4a
10 changed files with 57 additions and 15 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue