PDP11, VAX8600, VAX780, VAX750: Fix to auto configure Massbus adapters

When a mix of Massbus devices are configured with some enabled and
others disabled, the MBA's need to be allocated and properly configured
in the desired preferred order (RP, TU, RS).  On the PDP11, this interacts
with auto-configure since the RH devices are visible in the Unibus I/O
page.  On the PDP11 the second Massbus device can only be configured
if the TM device is disabled since the auto-configure assigned vectors
overlap for RHB and TM.

Problem originally reported in #301.
This commit is contained in:
Mark Pizzolato 2016-05-07 15:17:24 -07:00
parent 820d77ef69
commit 1af590d806
10 changed files with 184 additions and 60 deletions

View file

@ -788,9 +788,7 @@ typedef struct pdp_dib DIB;
/* Massbus definitions */ /* Massbus definitions */
#define MBA_NUM 3 /* number of MBA's */ #define MBA_NUM 3 /* number of MBA's */
#define MBA_RP 0 /* MBA for RP */ #define MBA_AUTO (uint32)0xFFFFFFFF /* Unassigned MBA */
#define MBA_TU 1 /* MBA for TU */
#define MBA_RS 2 /* MBA for RS */
#define MBA_RMASK 037 /* max 32 reg */ #define MBA_RMASK 037 /* max 32 reg */
#define MBE_NXD 1 /* nx drive */ #define MBE_NXD 1 /* nx drive */
#define MBE_NXR 2 /* nx reg */ #define MBE_NXR 2 /* nx reg */
@ -820,9 +818,11 @@ int32 mba_get_csr (uint32 mbus);
void mba_upd_ata (uint32 mbus, uint32 val); void mba_upd_ata (uint32 mbus, uint32 val);
void mba_set_exc (uint32 mbus); void mba_set_exc (uint32 mbus);
void mba_set_don (uint32 mbus); void mba_set_don (uint32 mbus);
void mba_set_enbdis (uint32 mb, t_bool dis); void mba_set_enbdis (DEVICE *dptr);
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat build_dib_tab (void);
void cpu_set_boot (int32 pc); void cpu_set_boot (int32 pc);
#include "pdp11_io_lib.h" #include "pdp11_io_lib.h"

View file

@ -68,6 +68,7 @@ int32 calc_ints (int32 nipl, int32 trq);
extern t_stat cpu_build_dib (void); extern t_stat cpu_build_dib (void);
extern void init_mbus_tab (void); extern void init_mbus_tab (void);
extern t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp); extern t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp);
extern void fixup_mbus_tab (void);
/* I/O data structures */ /* I/O data structures */
@ -433,5 +434,6 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
} }
} /* end if enabled */ } /* end if enabled */
} /* end for */ } /* end for */
fixup_mbus_tab ();
return SCPE_OK; return SCPE_OK;
} }

View file

@ -23,7 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
rha, rhb RH11/RH70 Massbus adapter rha, rhb, rhc RH11/RH70 Massbus adapter
02-Sep-13 RMS Added third Massbus adapter, debug printouts 02-Sep-13 RMS Added third Massbus adapter, debug printouts
19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato) 19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato)
@ -190,6 +190,8 @@ static t_stat (*mbregR[MBA_NUM])(int32 *dat, int32 ad, int32 md);
static t_stat (*mbregW[MBA_NUM])(int32 dat, int32 ad, int32 md); static t_stat (*mbregW[MBA_NUM])(int32 dat, int32 ad, int32 md);
static int32 (*mbabort[MBA_NUM])(void); static int32 (*mbabort[MBA_NUM])(void);
static int32 mba_active = 0; /* Number of active MBA's */
/* Unibus to register offset map */ /* Unibus to register offset map */
static int32 mba_mapofs[(MBA_OFSMASK + 1) >> 1] = { static int32 mba_mapofs[(MBA_OFSMASK + 1) >> 1] = {
@ -317,7 +319,7 @@ DEVICE mba_dev[] = {
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
NULL, NULL, &mba_reset, NULL, NULL, &mba_reset,
NULL, NULL, NULL, NULL, NULL, NULL,
&mba0_dib, DEV_DEBUG | DEV_DISABLE | DEV_UBUS | DEV_QBUS, 0, &mba0_dib, DEV_DEBUG | DEV_UBUS | DEV_QBUS, 0,
NULL, NULL, NULL, &rh_help, NULL, NULL, NULL, NULL, NULL, &rh_help, NULL, NULL,
&rh_description &rh_description
}, },
@ -326,7 +328,7 @@ DEVICE mba_dev[] = {
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
NULL, NULL, &mba_reset, NULL, NULL, &mba_reset,
NULL, NULL, NULL, NULL, NULL, NULL,
&mba1_dib, DEV_DEBUG | DEV_DISABLE | DEV_UBUS | DEV_QBUS, 0, &mba1_dib, DEV_DEBUG | DEV_UBUS | DEV_QBUS, 0,
NULL, NULL, NULL, &rh_help, NULL, NULL, NULL, NULL, NULL, &rh_help, NULL, NULL,
&rh_description &rh_description
}, },
@ -335,7 +337,7 @@ DEVICE mba_dev[] = {
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
NULL, NULL, &mba_reset, NULL, NULL, &mba_reset,
NULL, NULL, NULL, NULL, NULL, NULL,
&mba2_dib, DEV_DEBUG | DEV_DISABLE | DEV_UBUS | DEV_QBUS, 0, &mba2_dib, DEV_DEBUG | DEV_UBUS | DEV_QBUS, 0,
NULL, NULL, NULL, &rh_help, NULL, NULL, NULL, NULL, NULL, &rh_help, NULL, NULL,
&rh_description &rh_description
} }
@ -827,7 +829,6 @@ return -1;
t_stat mba_reset (DEVICE *dptr) t_stat mba_reset (DEVICE *dptr)
{ {
uint32 mb; uint32 mb;
mb = dptr - mba_dev; mb = dptr - mba_dev;
if (mb >= MBA_NUM) if (mb >= MBA_NUM)
return SCPE_NOFNC; return SCPE_NOFNC;
@ -842,23 +843,34 @@ massbus[mb].iff = 0;
mba_clr_int (mb); mba_clr_int (mb);
if (mbabort[mb]) if (mbabort[mb])
mbabort[mb] (); mbabort[mb] ();
return auto_config (0, 0); return build_dib_tab();
} }
/* Enable/disable Massbus adapter */ /* Enable/disable Massbus adapter */
void mba_set_enbdis (uint32 mb, t_bool dis) void mba_set_enbdis (DEVICE *dptr)
{ {
t_bool orig; DIB *dibp = (DIB *)dptr->ctxt;
if (mb >= MBA_NUM) /* valid MBA? */
if (((dptr->flags & DEV_DIS) && /* Already Disabled */
(dibp->ba == MBA_AUTO)) || /* OR */
(!(dptr->flags & DEV_DIS) && /* Already Enabled */
(dibp->ba != MBA_AUTO)))
return; return;
orig = mba_dev[mb].flags & DEV_DIS; if (dptr->flags & DEV_DIS) { /* Disabling? */
if (dis) uint32 mb = dibp->ba;
mba_dev[mb].flags |= DEV_DIS;
else mba_dev[mb].flags &= ~DEV_DIS; dibp->ba = MBA_AUTO; /* Flag unassigned */
if (orig ^ dis) mba_reset (&mba_dev[mb]); /* reset prior MBA */
mba_reset (&mba_dev[mb]); /* reset on change */ mba_dev[mb].flags |= DEV_DIS; /* disable prior MBA */
return; }
build_dib_tab();
if (!(dptr->flags & DEV_DIS)) { /* Enabling? */
uint32 mb = dibp->ba;
mba_dev[mb].flags &= ~DEV_DIS; /* enable assigned MBA */
mba_reset (&mba_dev[dibp->ba]); /* reset new MBA */
}
} }
/* Show Massbus adapter number */ /* Show Massbus adapter number */
@ -882,13 +894,27 @@ return SCPE_OK;
void init_mbus_tab (void) void init_mbus_tab (void)
{ {
uint32 i; uint32 i;
static t_bool initialized = FALSE;
if (!initialized) { /* Force MBA devices to reflect initial state */
DEVICE *dptr; /* of potentially attached devices */
int mba_devs;
for (i = mba_devs = 0; (dptr = sim_devices[i]) != NULL; i++) {
if (dptr->flags & DEV_MBUS) {
mba_dev[mba_devs].flags &= ~DEV_DIS;
mba_dev[mba_devs].flags |= (dptr->flags & DEV_DIS);
mba_devs++;
}
}
initialized = TRUE;
}
for (i = 0; i < MBA_NUM; i++) { for (i = 0; i < MBA_NUM; i++) {
mbregR[i] = NULL; mbregR[i] = NULL;
mbregW[i] = NULL; mbregW[i] = NULL;
mbabort[i] = NULL; mbabort[i] = NULL;
} }
return; mba_active = 0;
} }
/* Build dispatch tables */ /* Build dispatch tables */
@ -899,7 +925,8 @@ uint32 idx;
if ((dptr == NULL) || (dibp == NULL)) /* validate args */ if ((dptr == NULL) || (dibp == NULL)) /* validate args */
return SCPE_IERR; return SCPE_IERR;
idx = dibp->ba; /* Mbus # */ idx = mba_active++;
dibp->ba = idx; /* Mbus # */
if (idx >= MBA_NUM) if (idx >= MBA_NUM)
return SCPE_STOP; return SCPE_STOP;
if ((mbregR[idx] && dibp->rd && /* conflict? */ if ((mbregR[idx] && dibp->rd && /* conflict? */
@ -918,7 +945,49 @@ if (dibp->wr) /* set wr dispatch */
mbregW[idx] = dibp->wr; mbregW[idx] = dibp->wr;
if (dibp->ack[0]) /* set abort dispatch */ if (dibp->ack[0]) /* set abort dispatch */
mbabort[idx] = dibp->ack[0]; mbabort[idx] = dibp->ack[0];
return SCPE_OK; return build_ubus_tab (&mba_dev[idx], (DIB *)mba_dev[idx].ctxt);
}
void fixup_mbus_tab (void)
{
uint32 idx, idy, active;
DEVICE *dptr;
DIB *dibp;
static const char *mbus_devs[MBA_NUM+1] = {"RP", "TU", "RS", NULL};
for (idx = active = 0; idx < MBA_NUM; idx++) {
dptr = find_dev (mbus_devs[idx]);
if (!dptr)
break;
if (dptr->flags & DEV_DIS)
continue;
dibp = (DIB *)dptr->ctxt;
if (dibp->ba != active) {
t_stat (*TmbregR)(int32 *dat, int32 ad, int32 md) = mbregR[active];
t_stat (*TmbregW)(int32 dat, int32 ad, int32 md) = mbregW[active];
int32 (*Tmbabort)(void) = mbabort[active];
mbregR[active] = mbregR[dibp->ba];
mbregW[active] = mbregW[dibp->ba];
mbabort[active] = mbabort[dibp->ba];;
mbregR[dibp->ba] = TmbregR;
mbregW[dibp->ba] = TmbregW;
mbabort[dibp->ba] = Tmbabort;;
for (idy = 1; idy < MBA_NUM; idy++) {
DEVICE *ydptr = find_dev (mbus_devs[idy]);
DIB *ydibp = (DIB *)ydptr->ctxt;
if (ydibp->ba != active)
continue;
ydibp->ba = dibp->ba;
dibp->ba = active;
break;
}
}
++active;
}
} }
t_stat rh_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) t_stat rh_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
@ -947,11 +1016,22 @@ return SCPE_OK;
const char *rh_description (DEVICE *dptr) const char *rh_description (DEVICE *dptr)
{ {
if (dptr == &mba_dev[0]) static char buf[64];
return "RH70/RH11 Massbus adapter (for RP)"; uint32 mb = dptr - mba_dev;
else
if (dptr == &mba_dev[1]) if (dptr->flags & DEV_DIS)
return "RH70/RH11 Massbus adapter (for TU)"; dptr = NULL;
else else {
return "RH70/RH11 Massbus adapter (for RS)"; int i;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devs */
if (!(dptr->flags & DEV_DIS) &&
(dptr->flags & DEV_MBUS) &&
((DIB *)dptr->ctxt)->ba == mb)
break;
}
}
sprintf (buf, "RH70/RH11 Massbus adapter%s%s%s",
dptr ? " (for " : "", dptr ? dptr->name : "", dptr ? ")" : "");
return buf;
} }

View file

@ -595,7 +595,7 @@ const char *rp_description (DEVICE *dptr);
rp_mod RP modifier list rp_mod RP modifier list
*/ */
DIB rp_dib = { MBA_RP, 0, &rp_mbrd, &rp_mbwr, 0, 0, 0, { &rp_abort } }; DIB rp_dib = { MBA_AUTO, 0, &rp_mbrd, &rp_mbwr, 0, 0, 0, { &rp_abort } };
UNIT rp_unit[] = { UNIT rp_unit[] = {
{ UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+ { UDATA (&rp_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_AUTO+
@ -648,6 +648,8 @@ MTAB rp_mod[] = {
NULL, NULL, NULL, "Write lock disk drive" }, NULL, NULL, NULL, "Write lock disk drive" },
{ UNIT_DUMMY, 0, NULL, "BADBLOCK", { UNIT_DUMMY, 0, NULL, "BADBLOCK",
&rp_set_bad, NULL, NULL, "write bad block table on last track" }, &rp_set_bad, NULL, NULL, "write bad block table on last track" },
{ MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "FORMAT", "FORMAT={SIMH|VHD|RAW}",
&sim_disk_set_fmt, &sim_disk_show_fmt, NULL, "Display disk format" },
{ (UNIT_DTYPE+UNIT_ATT), (RM03_DTYPE << UNIT_V_DTYPE) + UNIT_ATT, { (UNIT_DTYPE+UNIT_ATT), (RM03_DTYPE << UNIT_V_DTYPE) + UNIT_ATT,
"RM03", NULL, NULL }, "RM03", NULL, NULL },
{ (UNIT_DTYPE+UNIT_ATT), (RP04_DTYPE << UNIT_V_DTYPE) + UNIT_ATT, { (UNIT_DTYPE+UNIT_ATT), (RP04_DTYPE << UNIT_V_DTYPE) + UNIT_ATT,
@ -1334,7 +1336,7 @@ UNIT *uptr;
sim_debug(DBG_TRC, dptr, "rp_reset()\n"); sim_debug(DBG_TRC, dptr, "rp_reset()\n");
mba_set_enbdis (MBA_RP, dptr->flags & DEV_DIS); mba_set_enbdis (dptr);
for (i = 0; i < RP_NUMDR; i++) { for (i = 0; i < RP_NUMDR; i++) {
uptr = dptr->units + i; uptr = dptr->units + i;
sim_cancel (uptr); sim_cancel (uptr);

View file

@ -197,7 +197,7 @@ const char *rs_description (DEVICE *dptr);
rs_mod RS modifier list rs_mod RS modifier list
*/ */
DIB rs_dib = { MBA_RS, 0, &rs_mbrd, &rs_mbwr, 0, 0, 0, { &rs_abort } }; DIB rs_dib = { MBA_AUTO, 0, &rs_mbrd, &rs_mbwr, 0, 0, 0, { &rs_abort } };
UNIT rs_unit[] = { UNIT rs_unit[] = {
{ UDATA (&rs_svc, UNIT_FIX|UNIT_ATTABLE|UNIT_DISABLE|UNIT_AUTO| { UDATA (&rs_svc, UNIT_FIX|UNIT_ATTABLE|UNIT_DISABLE|UNIT_AUTO|
@ -580,7 +580,7 @@ t_stat rs_reset (DEVICE *dptr)
int32 i; int32 i;
UNIT *uptr; UNIT *uptr;
mba_set_enbdis (MBA_RS, rs_dev.flags & DEV_DIS); mba_set_enbdis (dptr);
for (i = 0; i < RS_NUMDR; i++) { for (i = 0; i < RS_NUMDR; i++) {
uptr = rs_dev.units + i; uptr = rs_dev.units + i;
sim_cancel (uptr); sim_cancel (uptr);

View file

@ -266,7 +266,7 @@ t_stat tu_map_err (int32 drv, t_stat st, t_bool qdt);
tu_mod TU modifier list tu_mod TU modifier list
*/ */
DIB tu_dib = { MBA_TU, 0, &tu_mbrd, &tu_mbwr,0, 0, 0, { &tu_abort } }; DIB tu_dib = { MBA_AUTO, 0, &tu_mbrd, &tu_mbwr,0, 0, 0, { &tu_abort } };
UNIT tu_unit[] = { UNIT tu_unit[] = {
{ UDATA (&tu_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) }, { UDATA (&tu_svc, UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE, 0) },
@ -920,7 +920,7 @@ t_stat tu_reset (DEVICE *dptr)
int32 u; int32 u;
UNIT *uptr; UNIT *uptr;
mba_set_enbdis (MBA_TU, tu_dev.flags & DEV_DIS); mba_set_enbdis (dptr);
tucs1 = 0; tucs1 = 0;
tufc = 0; tufc = 0;
tuer = 0; tuer = 0;

View file

@ -398,9 +398,8 @@ extern int32 int_req[IPL_HLVL]; /* intr, IPL 14-17 */
/* Massbus definitions */ /* Massbus definitions */
#define MBA_RP (TR_MBA0 - TR_MBA0) /* MBA for RP */
#define MBA_TU (TR_MBA1 - TR_MBA0) /* MBA for TU */
#define MBA_RMASK 0x1F /* max 32 reg */ #define MBA_RMASK 0x1F /* max 32 reg */
#define MBA_AUTO (uint32)0xFFFFFFFF /* Unassigned MBA */
#define MBE_NXD 1 /* nx drive */ #define MBE_NXD 1 /* nx drive */
#define MBE_NXR 2 /* nx reg */ #define MBE_NXR 2 /* nx reg */
#define MBE_GOE 3 /* err on GO */ #define MBE_GOE 3 /* err on GO */
@ -428,7 +427,7 @@ int32 mba_get_bc (uint32 mbus);
void mba_upd_ata (uint32 mbus, uint32 val); void mba_upd_ata (uint32 mbus, uint32 val);
void mba_set_exc (uint32 mbus); void mba_set_exc (uint32 mbus);
void mba_set_don (uint32 mbus); void mba_set_don (uint32 mbus);
void mba_set_enbdis (uint32 mbus, t_bool dis); void mba_set_enbdis (DEVICE *dptr);
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);

View file

@ -411,9 +411,8 @@ extern int32 int_req[IPL_HLVL]; /* intr, IPL 14-17 */
/* Massbus definitions */ /* Massbus definitions */
#define MBA_RP (TR_MBA0 - TR_MBA0) /* MBA for RP */
#define MBA_TU (TR_MBA1 - TR_MBA0) /* MBA for TU */
#define MBA_RMASK 0x1F /* max 32 reg */ #define MBA_RMASK 0x1F /* max 32 reg */
#define MBA_AUTO (uint32)0xFFFFFFFF /* Unassigned MBA */
#define MBE_NXD 1 /* nx drive */ #define MBE_NXD 1 /* nx drive */
#define MBE_NXR 2 /* nx reg */ #define MBE_NXR 2 /* nx reg */
#define MBE_GOE 3 /* err on GO */ #define MBE_GOE 3 /* err on GO */
@ -440,7 +439,7 @@ int32 mba_get_bc (uint32 mbus);
void mba_upd_ata (uint32 mbus, uint32 val); void mba_upd_ata (uint32 mbus, uint32 val);
void mba_set_exc (uint32 mbus); void mba_set_exc (uint32 mbus);
void mba_set_don (uint32 mbus); void mba_set_don (uint32 mbus);
void mba_set_enbdis (uint32 mbus, t_bool dis); void mba_set_enbdis (DEVICE *dptr);
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);

View file

@ -270,6 +270,8 @@ static t_stat (*mbregR[MBA_NUM])(int32 *dat, int32 ad, int32 md);
static t_stat (*mbregW[MBA_NUM])(int32 dat, int32 ad, int32 md); static t_stat (*mbregW[MBA_NUM])(int32 dat, int32 ad, int32 md);
static int32 (*mbabort[MBA_NUM])(void); static int32 (*mbabort[MBA_NUM])(void);
static int32 mba_active = 0; /* Number of active MBA's */
/* Massbus adapter data structures /* Massbus adapter data structures
mba_dev MBA device descriptors mba_dev MBA device descriptors
@ -838,14 +840,11 @@ return;
t_stat mba_reset (DEVICE *dptr) t_stat mba_reset (DEVICE *dptr)
{ {
int32 i, mb; int32 i, mb;
DIB *dibp; DIB *dibp = (DIB *)dptr->ctxt;
dibp = (DIB *) dptr->ctxt;
if (dibp == NULL) if (dibp == NULL)
return SCPE_IERR; return SCPE_IERR;
mb = dibp->ba - TR_MBA0; mb = dptr - mba_dev;
if ((mb < 0) || (mb >= MBA_NUM))
return SCPE_IERR;
mba_cnf[mb] = 0; mba_cnf[mb] = 0;
mba_cr[mb] &= MBACR_MNT; mba_cr[mb] &= MBACR_MNT;
mba_sr[mb] = 0; mba_sr[mb] = 0;
@ -859,7 +858,7 @@ if (sim_switches & SWMASK ('P')) {
} }
if (mbabort[mb]) /* reset device */ if (mbabort[mb]) /* reset device */
mbabort[mb] (); mbabort[mb] ();
return SCPE_OK; return build_dib_tab();
} }
t_stat mba_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) t_stat mba_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
@ -876,8 +875,22 @@ return SCPE_OK;
const char *mba_description (DEVICE *dptr) const char *mba_description (DEVICE *dptr)
{ {
static char buf[64]; static char buf[64];
uint32 mb = dptr - mba_dev;
sprintf (buf, "Massbus adapter %d", (int)(dptr-mba_dev)); if (dptr->flags & DEV_DIS)
dptr = NULL;
else {
int i;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru devs */
if (!(dptr->flags & DEV_DIS) &&
(dptr->flags & DEV_MBUS) &&
((DIB *)dptr->ctxt)->ba == mb)
break;
}
}
sprintf (buf, "Massbus adapter %d", mb,
dptr ? " (for " : "", dptr ? dptr->name : "", dptr ? ")" : "");
return buf; return buf;
} }
@ -899,14 +912,29 @@ return SCPE_OK;
/* Enable/disable Massbus adapter */ /* Enable/disable Massbus adapter */
void mba_set_enbdis (uint32 mb, t_bool dis) void mba_set_enbdis (DEVICE *dptr)
{ {
if (mb >= MBA_NUM) /* valid MBA? */ DIB *dibp = (DIB *)dptr->ctxt;
if (((dptr->flags & DEV_DIS) && /* Already Disabled */
(dibp->ba == MBA_AUTO)) || /* OR */
(!(dptr->flags & DEV_DIS) && /* Already Enabled */
(dibp->ba != MBA_AUTO)))
return; return;
if (dis) if (dptr->flags & DEV_DIS) { /* Disabling? */
mba_dev[mb].flags |= DEV_DIS; uint32 mb = dibp->ba;
else mba_dev[mb].flags &= ~DEV_DIS;
return; dibp->ba = MBA_AUTO; /* Flag unassigned */
mba_reset (&mba_dev[mb]); /* reset prior MBA */
mba_dev[mb].flags |= DEV_DIS; /* disable prior MBA */
}
build_dib_tab();
if (!(dptr->flags & DEV_DIS)) { /* Enabling? */
uint32 mb = dibp->ba;
mba_dev[mb].flags &= ~DEV_DIS; /* enable assigned MBA */
mba_reset (&mba_dev[dibp->ba]); /* reset new MBA */
}
} }
/* Init Mbus tables */ /* Init Mbus tables */
@ -914,13 +942,27 @@ return;
void init_mbus_tab (void) void init_mbus_tab (void)
{ {
uint32 i; uint32 i;
static t_bool initialized = FALSE;
if (!initialized) { /* Force MBA devices to reflect initial state */
DEVICE *dptr; /* of potentially attached devices */
int mba_devs;
for (i = mba_devs = 0; (dptr = sim_devices[i]) != NULL; i++) {
if (dptr->flags & DEV_MBUS) {
mba_dev[mba_devs].flags &= ~DEV_DIS;
mba_dev[mba_devs].flags |= (dptr->flags & DEV_DIS);
mba_devs++;
}
}
initialized = TRUE;
}
for (i = 0; i < MBA_NUM; i++) { for (i = 0; i < MBA_NUM; i++) {
mbregR[i] = NULL; mbregR[i] = NULL;
mbregW[i] = NULL; mbregW[i] = NULL;
mbabort[i] = NULL; mbabort[i] = NULL;
} }
return; mba_active = 0;
} }
/* Build dispatch tables */ /* Build dispatch tables */
@ -931,7 +973,8 @@ uint32 idx;
if ((dptr == NULL) || (dibp == NULL)) /* validate args */ if ((dptr == NULL) || (dibp == NULL)) /* validate args */
return SCPE_IERR; return SCPE_IERR;
idx = dibp->ba; /* Mbus # */ idx = mba_active++;
dibp->ba = idx; /* Mbus # */
if (idx >= MBA_NUM) if (idx >= MBA_NUM)
return SCPE_STOP; return SCPE_STOP;
if ((mbregR[idx] && dibp->rd && /* conflict? */ if ((mbregR[idx] && dibp->rd && /* conflict? */

View file

@ -441,9 +441,8 @@ extern int32 int_req[IPL_HLVL]; /* intr, IPL 14-17 */
/* Massbus definitions */ /* Massbus definitions */
#define MBA_RP (TR_MBA0 - TR_MBA0) /* MBA for RP */
#define MBA_TU (TR_MBA1 - TR_MBA0) /* MBA for TU */
#define MBA_RMASK 0x1F /* max 32 reg */ #define MBA_RMASK 0x1F /* max 32 reg */
#define MBA_AUTO (uint32)0xFFFFFFFF /* Unassigned MBA */
#define MBE_NXD 1 /* nx drive */ #define MBE_NXD 1 /* nx drive */
#define MBE_NXR 2 /* nx reg */ #define MBE_NXR 2 /* nx reg */
#define MBE_GOE 3 /* err on GO */ #define MBE_GOE 3 /* err on GO */
@ -470,7 +469,7 @@ int32 mba_get_bc (uint32 mbus);
void mba_upd_ata (uint32 mbus, uint32 val); void mba_upd_ata (uint32 mbus, uint32 val);
void mba_set_exc (uint32 mbus); void mba_set_exc (uint32 mbus);
void mba_set_don (uint32 mbus); void mba_set_don (uint32 mbus);
void mba_set_enbdis (uint32 mbus, t_bool dis); void mba_set_enbdis (DEVICE *dptr);
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);