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 */ 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);
} }

View file

@ -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);
} }

View file

@ -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);

View file

@ -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)

View file

@ -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);
@ -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_show_tps (FILE *of, UNIT *uptr, int32 val, CONST void *desc);
t_stat rtc_register (uint32 tm, uint32 idx, UNIT *uptr); 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 */ 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);
} }

View file

@ -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);
} }

View file

@ -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);
} }
@ -296,4 +298,4 @@ st = attach_unit (uptr, cptr);
if ((uptr == &pt_unit[PTR]) && (st == SCPE_OK)) if ((uptr == &pt_unit[PTR]) && (st == SCPE_OK))
ptr_nzc = 0; ptr_nzc = 0;
return st; return st;
} }

View file

@ -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);
} }

View file

@ -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);
} }