Fix three kinds of error in I/O modules. Discovered while getting standalone System Exerciser to run.

IO: DVT_NOTDEV macro incorrect, Device mapping algorithm creates false dispatch points.
This mapped Multi Unit Controller and Single Unit Controller to same device.
DP, DP, MT, RAD:  Test for non-existent device returns wrong status.
DP, DK, MT: TIO status should return non-operational for unattached device.
This commit is contained in:
ken rector 2024-02-20 18:20:13 -08:00 committed by Paul Koning
parent e444c674f6
commit ffe537a621
6 changed files with 103 additions and 40 deletions

View file

@ -131,6 +131,19 @@
124. IO, all devices: moved SIO reject-on-interrupt test to devices.
125. DP: SIO will knock down pending device interrupts and allow operation to proceed.
126. MT: AIO must mask unit number before calling TDV status.
127. IO: location 20/21 set incorrectly in the even, non-zero register case.
128. CPU: WAIT must be implemented for correct operation of CP-V.
129. DP: On 10 byte models, SENSE length errors can't happen. On 16 byte models,
SENSE length errors only occur if length == 0 || length > 16.
130. IO: DVT_NOTDEV macro incorrect.
131. DP: Test for non-existent device returns wrong status.
132. DK: Test for non-existent device returns wrong status.
133. MT: Test for non-existent device returns wrong status.
134. RAD: Test for non-existent device returns wrong status.
135. DP: TIO status should return non-operational for unattached device.
136. DK: TIO status should return non-operational for unattached device.
137. NT: TIO status should return non-operational for unattached device.
138. IO: Device mapping algorithm creates false dispatch points.
Diagnostic Notes
----------------

View file

@ -1,6 +1,6 @@
/* sigma_dk.c: 7250/7251-7252 cartridge disk simulator
Copyright (c) 2007-2022, Robert M Supnik
Copyright (c) 2007-2024, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,6 +25,9 @@
dk 7250/7251-7252 cartridge disk
11-Feb-24 RMS Report non-operational if not attached (Ken Rector)
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
15-Dec-22 RMS Moved SIO interrupt test to devices
02-Jul-22 RMS Fixed bugs in multi-unit operation
Transfers are always done a sector at a time.
@ -164,8 +167,10 @@ int32 iu;
UNIT *uptr;
if ((un >= DK_NUMDR) || /* inv unit num? */
(dk_unit[un].flags & UNIT_DIS)) /* disabled unit? */
return DVT_NODEV;
(dk_unit[un].flags & UNIT_DIS)) { /* disabled unit? */
*dvst = DVT_NODEV;
return 0;
}
switch (op) { /* case on op */
case OP_SIO: /* start I/O */
@ -412,12 +417,17 @@ return FALSE; /* cmd done */
uint32 dk_tio_status (uint32 un)
{
uint32 i;
uint32 i, st;
st = DVS_AUTO; /* flags */
if (sim_is_active (&dk_unit[un])) /* active => busy */
st |= DVS_DBUSY;
else if ((dk_unit[un].flags & UNIT_ATT) == 0) /* not att => offl */
st |= DVS_DOFFL;
for (i = 0; i < DK_NUMDR; i++) { /* loop thru units */
if (sim_is_active (&dk_unit[i])) /* active? */
return (DVS_AUTO | DVS_CBUSY | (CC2 << DVT_V_CC) |
((i == un)? DVS_DBUSY: 0));
st |= (DVS_CBUSY | (CC2 << DVT_V_CC)); /* ctrl is busy */
return st;
}
return DVS_AUTO;
}

View file

@ -1,6 +1,6 @@
/* sigma_dp.c: moving head disk pack controller
Copyright (c) 2008-2022, Robert M Supnik
Copyright (c) 2008-2024, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,13 +25,18 @@
dp moving head disk pack controller
11-Feb-24 RMS Report non-operational if not attached (Ken Rector)
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
03-Jun-23 RMS Fixed SENSE length error detection (Ken Rector)
06-Mar-23 RMS SIO can start despite outstanding seek interrupt (Ken Rector)
15-Dec-22 RMS Moved SIO interrupt test to devices
09-Dec-22 RMS Invalid address must set a TDV-visible error flag (Ken Rector)
23-Jul-22 RMS SEEK(I), RECAL(I) should be fast operations (Ken Rector)
02-Jul-22 RMS Fixed bugs in multi-unit operation
29-Jun-22 RMS Fixed initialization errors in ctrl, seek units (Ken Rector)
28-Jun-22 RMS Fixed off-by-1 error in DP_SEEK definition (Ken Rector)
07-Jun-22 RMS Removed unused variables (V4)
06-Jun-22 RMS Fixed incorrect return in TIO status (Ken Rector)
06-Jun-22 RMS Fixed missing loop increment in TDV (Ken Rector)
13-Mar-17 RMS Fixed bug in selecting 3281 unit F (COVERITY)
Transfers are always done a sector at a time.
@ -586,14 +591,19 @@ int32 iu;
uint32 i;
DP_CTX *ctx;
if (cidx >= DP_NUMCTL) /* inv ctrl num? */
return DVT_NODEV;
if (cidx >= DP_NUMCTL) { /* inv ctrl num? */
*dvst = DVT_NODEV;
return 0;
}
ctx = &dp_ctx[cidx];
if (((un < DP_NUMDR) && /* un valid and */
((dp_unit[un].flags & UNIT_DIS) == 0)) || /* not disabled OR */
((un == 0xF) && (ctx->dp_ctype == DP_C3281))) /* 3281 unit F? */
uptr = dp_unit + un; /* un exists */
else return DVT_NODEV;
else {
*dvst = DVT_NODEV;
return 0;
}
switch (op) { /* case on op */
@ -995,21 +1005,23 @@ return FALSE; /* cmd done */
uint32 dp_tio_status (uint32 cidx, uint32 un)
{
uint32 i;
uint32 i, st;
DP_CTX *ctx = &dp_ctx[cidx];
UNIT *dp_unit = dp_dev[cidx].units;
uint32 stat = DVS_AUTO;
st = DVS_AUTO;
if (sim_is_active (&dp_unit[un]) ||
sim_is_active (&dp_unit[un + DP_SEEK]))
st |= (DVS_DBUSY | (CC2 << DVT_V_CC));
else if ((un != 0xF) && ((dp_unit[un].flags & UNIT_ATT) == 0))
st |= DVS_DOFFL;
for (i = 0; i < DP_NUMDR; i++) {
if (sim_is_active (&dp_unit[i])) {
stat |= (DVS_CBUSY | (CC2 << DVT_V_CC));
st |= (DVS_CBUSY | (CC2 << DVT_V_CC));
break;
}
}
if (sim_is_active (&dp_unit[un]) ||
sim_is_active (&dp_unit[un + DP_SEEK]))
stat |= (DVS_DBUSY | (CC2 << DVT_V_CC));
return stat;
return st;
}
uint32 dp_tdv_status (uint32 cidx, uint32 un)

25
sigma/sigma_io.c Executable file → Normal file
View file

@ -1,6 +1,6 @@
/* sigma_io.c: XDS Sigma IO simulator
/* sigma_io.c: XDS Sigma IO simulator
Copyright (c) 2007-2022, Robert M Supnik
Copyright (c) 2007-2024, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -23,6 +23,9 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
11-Feb-2024 RMS Fixed false dispatch bug (Ken Rector)
04-May-2023 RMS Fixed location 21 usage in even register case (Ken Rector)
15-Dec-2022 RMS Moved SIO interrupt test to devices
23-Jul-2022 RMS Made chan_ctl_time accessible as a register
21-Jul-2022 RMS Added numeric channel numbers to SET/SHOW
07-Jul-2022 RMS Fixed dangling else in read/write direct (Ken Rector)
@ -473,14 +476,27 @@ CC |= CC1|CC2; /* no recognition */
return 0;
}
/* Initiate I/O instruction */
/* Initiate I/O instruction
False dispatch problem. Although device numbers are not permitted to overlap,
there is nothing to stop programs from issuing IO instructions to a multi-
unit device address using its single-unit counterpart, or vice-versa.
For example, an IO address of 0x00 will map to the dispatch used for
0x80, and vice versa. This routine must detect that the device
address actually agrees with the type of device in that dispatch slot.
*/
t_bool io_init_inst (uint32 rn, uint32 ad, uint32 ch, uint32 dev, uint32 r0)
{
uint32 loc20;
t_bool ch_mu, dva_mu;
if (ch >= chan_num) /* bad chan? */
if ((dev >= CHAN_N_DEV) || (ch >= chan_num)) /* bad dev or chan? */
return FALSE;
ch_mu = (chan[ch].chsf[dev] & CHSF_MU) != 0; /* does chan think MU? */
dva_mu = (ad & DVA_MU) != 0; /* is dva MU? */
if (ch_mu != dva_mu) /* not the same? */
return FALSE; /* dev not there */
loc20 = ((ad & 0xFF) << 24) | /* <0:7> = dev ad */
((rn & 1) | (rn? 3: 0) << 22) | /* <8:9> = reg ind */
(r0 & (cpu_tab[cpu_model].pamask >> 1)); /* <14/16:31> = r0 */
@ -493,7 +509,6 @@ return (chan[ch].disp[dev] != NULL)? TRUE: FALSE;
uint32 io_set_status (uint32 rn, uint32 ch, uint32 dev, uint32 dvst, t_bool tdv)
{
uint32 mrgst;
uint32 odd = rn & 1;
if ((rn != 0) && !(dvst & DVT_NOST)) { /* return status? */
if (tdv)

View file

@ -149,7 +149,7 @@ typedef struct {
#define DVT_GETCC(x) (((x) >> DVT_V_CC) & DVT_M_CC)
#define DVT_GETDVS(x) (((x) >> DVT_V_DVS) & DVT_M_DVS)
#define DVT_NOST (CC1 << DVT_V_CC) /* no status */
#define DVT_NODEV ((CC1|CC2) < DVT_V_CC) /* no device */
#define DVT_NODEV ((CC1|CC2) << DVT_V_CC) /* no device */
/* Read and write direct address format */

View file

@ -1,6 +1,6 @@
/* sigma_mt.c: Sigma 732X 9-track magnetic tape
Copyright (c) 2007-2022, Robert M. Supnik
Copyright (c) 2007-2024, Robert M. Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@ -25,11 +25,18 @@
mt 7320 and 7322/7323 magnetic tape
11-Feb-24 RMS Report non-operational if not attached (Ken Rector)
01-Feb-24 RMS Fixed nx unit test (Ken Rector)
01-Nov-23 RMS Fixed reset not to clear BOT
31-Mar-23 RMS Mask unit flag before calling status in AIO (Ken Rector)
07-Feb-23 RMS Silenced Mac compiler warnings (Ken Rector)
15-Dec-22 RMS Moved SIO interrupt test to devices
20-Jul-22 RMS Space record must set EOF flag on tape mark (Ken Rector)
03-Jul-22 RMS Fixed error in handling of channel errors (Ken Rector)
02-Jul-22 RMS Fixed bugs in multi-unit operation
07-Jun-22 RMS Removed unused variables (V4)
26-Mar-22 RMS Added extra case points for new MTSE definitions
23-Mar-20 RMS Unload should call sim_tape_detach (Mark Pizzolato)
13-Mar-17 RMS Annotated fall through in switch
Magnetic tapes are represented as a series of variable records
@ -194,10 +201,8 @@ REG mt_reg[] = {
};
MTAB mt_mod[] = {
{ MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED",
&set_writelock, &show_writelock, NULL, "Write enable tape drive" },
{ MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED",
&set_writelock, NULL, NULL, "Write lock tape drive" },
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
@ -231,13 +236,15 @@ uint32 un = DVA_GETUNIT (dva);
UNIT *uptr = &mt_unit[un];
if ((un >= MT_NUMDR) || /* inv unit num? */
(uptr-> flags & UNIT_DIS)) /* disabled unit? */
return DVT_NODEV;
(uptr-> flags & UNIT_DIS)) { /* disabled unit? */
*dvst = DVT_NODEV;
return 0;
}
switch (op) { /* case on op */
case OP_SIO: /* start I/O */
*dvst = mt_tio_status (un); /* get status */
if (chan_chk_dvi (dva)) /* int pending? */
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 */
@ -480,7 +487,7 @@ switch (cmd) { /* case on command */
sim_activate (uptr, mt_time); /* continue thread */
return SCPE_OK;
}
if ((r = mt_flush_buf (uptr))) { /* flush buffer */
if ((r = mt_flush_buf (uptr)) != 0) { /* flush buffer */
st = mt_map_err (uptr, r); /* map error */
if (CHS_IFERR (st)) /* chan or SCP err? */
return mt_chan_err (dva, st); /* uend and stop */
@ -516,6 +523,7 @@ return sim_tape_wrrecf (uptr, mt_xb, mt_blim); /* write, err? */
t_stat mt_map_err (UNIT *uptr, t_stat st)
{
uint32 un = uptr - mt_unit;
uint32 dva = mt_dib.dva | un;
@ -563,10 +571,12 @@ uint32 mt_tio_status (uint32 un)
uint32 i, st;
UNIT *uptr = &mt_unit[un];
st = (uptr->flags & UNIT_ATT)? DVS_AUTO: 0; /* AUTO */
st = DVS_AUTO; /* flags */
if (sim_is_active (uptr) || /* unit busy */
sim_is_active (uptr + MT_REW)) /* or rewinding? */
st |= DVS_DBUSY;
else if ((uptr -> flags & UNIT_ATT) == 0) /* not att => offl */
st |= DVS_DOFFL;
for (i = 0; i < MT_NUMDR; i++) { /* loop thru units */
if (sim_is_active (&mt_unit[i])) { /* active? */
st |= (DVS_CBUSY | (CC2 << DVT_V_CC)); /* ctrl is busy */
@ -654,7 +664,9 @@ uint32 i;
for (i = 0; i < MT_NUMDR; i++) {
sim_cancel (&mt_unit[i]); /* stop unit */
sim_cancel (&mt_unit[i + MT_REW]); /* stop rewind */
mt_unit[i].UST = 0;
if (mt_unit[i].flags & UNIT_ATT) /* attached? */
mt_unit[i].UST &= MTDV_BOT; /* clr sta exc BOT */
else mt_unit[i].UST = 0;
mt_unit[i].UCMD = 0;
}
mt_rwi = 0;
@ -673,7 +685,8 @@ t_stat mt_attach (UNIT *uptr, CONST char *cptr)
t_stat r;
r = sim_tape_attach (uptr, cptr);
if (r != SCPE_OK) return r;
if (r != SCPE_OK)
return r;
uptr->UST = MTDV_BOT;
return r;
}