From 869dc0fe4ac9124b688460e9b4a143e54c7e8c88 Mon Sep 17 00:00:00 2001 From: ken rector Date: Tue, 21 Mar 2023 17:11:56 -0700 Subject: [PATCH] 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. --- sigma/sigma_coc.c | 4 +++- sigma/sigma_dk.c | 4 +++- sigma/sigma_dp.c | 22 ++++++++++++++++++++++ sigma/sigma_io.c | 17 +++++++++++------ sigma/sigma_io_defs.h | 3 ++- sigma/sigma_lp.c | 4 +++- sigma/sigma_mt.c | 4 +++- sigma/sigma_pt.c | 6 ++++-- sigma/sigma_rad.c | 4 +++- sigma/sigma_tt.c | 4 +++- 10 files changed, 57 insertions(+), 15 deletions(-) diff --git a/sigma/sigma_coc.c b/sigma/sigma_coc.c index d0bca54e..e93aad6d 100755 --- a/sigma/sigma_coc.c +++ b/sigma/sigma_coc.c @@ -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); } diff --git a/sigma/sigma_dk.c b/sigma/sigma_dk.c index 0e6795a7..08c2a00b 100644 --- a/sigma/sigma_dk.c +++ b/sigma/sigma_dk.c @@ -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); } diff --git a/sigma/sigma_dp.c b/sigma/sigma_dp.c index 4c9e1e4f..2c58e7de 100644 --- a/sigma/sigma_dp.c +++ b/sigma/sigma_dp.c @@ -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); diff --git a/sigma/sigma_io.c b/sigma/sigma_io.c index c9085c6c..be0b8ed6 100644 --- a/sigma/sigma_io.c +++ b/sigma/sigma_io.c @@ -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) diff --git a/sigma/sigma_io_defs.h b/sigma/sigma_io_defs.h index 921c6f3a..4f9aa0f0 100644 --- a/sigma/sigma_io_defs.h +++ b/sigma/sigma_io_defs.h @@ -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 \ No newline at end of file +#endif diff --git a/sigma/sigma_lp.c b/sigma/sigma_lp.c index 5a25633f..9a2106fc 100644 --- a/sigma/sigma_lp.c +++ b/sigma/sigma_lp.c @@ -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); } diff --git a/sigma/sigma_mt.c b/sigma/sigma_mt.c index 7c7d3f7e..0194e83b 100644 --- a/sigma/sigma_mt.c +++ b/sigma/sigma_mt.c @@ -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); } diff --git a/sigma/sigma_pt.c b/sigma/sigma_pt.c index cbda3052..3551115d 100644 --- a/sigma/sigma_pt.c +++ b/sigma/sigma_pt.c @@ -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; -} \ No newline at end of file +} diff --git a/sigma/sigma_rad.c b/sigma/sigma_rad.c index 845abbdb..4892a47e 100644 --- a/sigma/sigma_rad.c +++ b/sigma/sigma_rad.c @@ -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); } diff --git a/sigma/sigma_tt.c b/sigma/sigma_tt.c index 1c357d2a..ed605c13 100644 --- a/sigma/sigma_tt.c +++ b/sigma/sigma_tt.c @@ -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); }