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 */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = mux_tio_status (); /* get status */
|
*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 */
|
muxc_cmd = MUXC_INIT; /* start dev thread */
|
||||||
sim_activate (&mux_unit[MUXC], chan_ctl_time);
|
sim_activate (&mux_unit[MUXC], chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,9 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = dk_tio_status (un); /* get status */
|
*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 */
|
dk_cmd = DKS_INIT; /* start dev thread */
|
||||||
sim_activate (&dk_unit[un], chan_ctl_time);
|
sim_activate (&dk_unit[un], chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,16 @@
|
||||||
one for timing asynchronous seek completions. The controller will not
|
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
|
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 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"
|
#include "sigma_io_defs.h"
|
||||||
|
@ -589,6 +599,18 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = dp_tio_status (cidx, un); /* get status */
|
*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? */
|
if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */
|
||||||
uptr->UCMD = DPS_INIT; /* start dev thread */
|
uptr->UCMD = DPS_INIT; /* start dev thread */
|
||||||
sim_activate (uptr, chan_ctl_time);
|
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;
|
CC |= CC1|CC2;
|
||||||
return 0;
|
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 */
|
st = chan[ch].disp[dev] (OP_SIO, ad, &dvst); /* start I/O */
|
||||||
CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */
|
CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */
|
||||||
if (CC & cpu_tab[cpu_model].iocc) /* error? */
|
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;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set device interrupt */
|
/* Set, check device interrupt */
|
||||||
|
|
||||||
void chan_set_dvi (uint32 dva)
|
void chan_set_dvi (uint32 dva)
|
||||||
{
|
{
|
||||||
|
@ -817,6 +812,16 @@ chan[ch].chf[dev] |= CHF_INP; /* int pending */
|
||||||
return;
|
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 */
|
/* Called by device reset to reset channel registers */
|
||||||
|
|
||||||
t_stat chan_reset_dev (uint32 dva)
|
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);
|
void chan_set_dvi (uint32 dva);
|
||||||
int32 chan_clr_chi (uint32 dva);
|
int32 chan_clr_chi (uint32 dva);
|
||||||
int32 chan_chk_chi (uint32 dva);
|
int32 chan_chk_chi (uint32 dva);
|
||||||
|
t_bool chan_chk_dvi (uint32 dva);
|
||||||
uint32 chan_end (uint32 dva);
|
uint32 chan_end (uint32 dva);
|
||||||
uint32 chan_uen (uint32 dva);
|
uint32 chan_uen (uint32 dva);
|
||||||
uint32 chan_RdMemB (uint32 dva, uint32 *dat);
|
uint32 chan_RdMemB (uint32 dva, uint32 *dat);
|
||||||
|
|
|
@ -180,7 +180,9 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = lp_tio_status (); /* get status */
|
*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 */
|
lp_cmd = LPS_INIT; /* start dev thread */
|
||||||
sim_activate (&lp_unit, chan_ctl_time);
|
sim_activate (&lp_unit, chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,9 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = mt_tio_status (un); /* get status */
|
*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 */
|
uptr->UCMD = MCM_INIT; /* start dev thread */
|
||||||
sim_activate (uptr, chan_ctl_time);
|
sim_activate (uptr, chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,9 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = pt_tio_status (); /* get status */
|
*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 */
|
pt_cmd = PTS_INIT; /* start dev thread */
|
||||||
sim_activate (&pt_unit[PTR], chan_ctl_time);
|
sim_activate (&pt_unit[PTR], chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,9 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = rad_tio_status (un); /* get status */
|
*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 */
|
rad_cmd = RADS_INIT; /* start dev thread */
|
||||||
sim_activate (&rad_unit[un], chan_ctl_time);
|
sim_activate (&rad_unit[un], chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,9 @@ switch (op) { /* case on op */
|
||||||
|
|
||||||
case OP_SIO: /* start I/O */
|
case OP_SIO: /* start I/O */
|
||||||
*dvst = tt_tio_status (); /* get status */
|
*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 */
|
tt_cmd = TTS_INIT; /* start dev thread */
|
||||||
sim_activate (&tt_unit[TTO], chan_ctl_time);
|
sim_activate (&tt_unit[TTO], chan_ctl_time);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue