PDP11, VAX: Add RQ device option for variable number of drives

This commit is contained in:
Mark Pizzolato 2019-06-23 23:47:12 -07:00
parent b3fa1f9fe8
commit 9c2c621278

View file

@ -148,7 +148,8 @@ extern int32 MMR2;
#define RQ_SVER 3 /* software version */ #define RQ_SVER 3 /* software version */
#define RQ_DHTMO 60 /* def host timeout */ #define RQ_DHTMO 60 /* def host timeout */
#define RQ_DCTMO 120 /* def ctrl timeout */ #define RQ_DCTMO 120 /* def ctrl timeout */
#define RQ_NUMDR 4 /* # drives */ #define RQ_NUMDR 4 /* def # drives */
#define RQ_MAXDR 254 /* max # drives */
#define RQ_NUMBY 512 /* bytes per block */ #define RQ_NUMBY 512 /* bytes per block */
#define RQ_MAXFR (1 << 16) /* max xfer */ #define RQ_MAXFR (1 << 16) /* max xfer */
#define RQ_MAPXFER (1u << 31) /* mapped xfer */ #define RQ_MAPXFER (1u << 31) /* mapped xfer */
@ -193,8 +194,8 @@ extern int32 MMR2;
#define ERR 0 /* must be SCPE_OK! */ #define ERR 0 /* must be SCPE_OK! */
#define OK 1 #define OK 1
#define RQ_TIMER (RQ_NUMDR) #define RQ_TIMER (RQ_MAXDR)
#define RQ_QUEUE (RQ_TIMER + 1) #define RQ_QUEUE (RQ_MAXDR + 1)
/* Internal packet management. The real RQDX3 manages its packets as true /* Internal packet management. The real RQDX3 manages its packets as true
linked lists. However, use of actual addresses in structures won't work linked lists. However, use of actual addresses in structures won't work
@ -879,6 +880,7 @@ t_stat rq_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat rq_set_ctype (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat rq_set_ctype (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat rq_set_plug (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat rq_set_plug (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat rq_show_plug (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat rq_show_plug (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat rq_set_drives (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat rq_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat rq_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat rq_show_ctype (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat rq_show_ctype (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat rq_show_wlk (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat rq_show_wlk (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
@ -946,7 +948,7 @@ DIB rq_dib = {
1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ 1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ
}; };
UNIT rq_unit[] = { UNIT rq_unit[RQ_MAXDR + 2] = {
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
@ -955,8 +957,6 @@ UNIT rq_unit[] = {
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RX50_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RX50)) }, (RX50_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RX50)) },
{ UDATA (&rq_tmrsvc, UNIT_IDLE|UNIT_DIS, 0) },
{ UDATA (&rq_quesvc, UNIT_DIS, 0) }
}; };
REG rq_reg[] = { REG rq_reg[] = {
@ -1084,6 +1084,8 @@ MTAB rq_mod[] = {
NULL, &rq_show_type, NULL, "Display device type" }, NULL, &rq_show_type, NULL, "Display device type" },
{ MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "UNIT", "UNIT=val (0-65534)", { MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "UNIT", "UNIT=val (0-65534)",
&rq_set_plug, &rq_show_plug, NULL, "Set/Display Unit plug value" }, &rq_set_plug, &rq_show_plug, NULL, "Set/Display Unit plug value" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "DRIVES=val (4-254)",
&rq_set_drives, NULL, NULL, "Set Number of Drives" },
{ UNIT_NOAUTO, UNIT_NOAUTO, "noautosize", "NOAUTOSIZE", NULL, NULL, NULL, "Disables disk autosize on attach" }, { UNIT_NOAUTO, UNIT_NOAUTO, "noautosize", "NOAUTOSIZE", NULL, NULL, NULL, "Disables disk autosize on attach" },
{ UNIT_NOAUTO, 0, "autosize", "AUTOSIZE", NULL, NULL, NULL, "Enables disk autosize on attach" }, { UNIT_NOAUTO, 0, "autosize", "AUTOSIZE", NULL, NULL, NULL, "Enables disk autosize on attach" },
{ MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "FORMAT", "FORMAT={SIMH|VHD|RAW}", { MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "FORMAT", "FORMAT={SIMH|VHD|RAW}",
@ -1106,7 +1108,7 @@ MTAB rq_mod[] = {
DEVICE rq_dev = { DEVICE rq_dev = {
"RQ", rq_unit, rq_reg, rq_mod, "RQ", rq_unit, rq_reg, rq_mod,
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_MAXDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &rq_boot, &rq_attach, &rq_detach,
&rq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS, &rq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
@ -1129,7 +1131,7 @@ DIB rqb_dib = {
1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ 1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ
}; };
UNIT rqb_unit[] = { UNIT rqb_unit[RQ_MAXDR + 2] = {
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
@ -1138,8 +1140,6 @@ UNIT rqb_unit[] = {
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_tmrsvc, UNIT_IDLE|UNIT_DIS, 0) },
{ UDATA (&rq_quesvc, UNIT_DIS, 0) }
}; };
REG rqb_reg[] = { REG rqb_reg[] = {
@ -1181,7 +1181,7 @@ REG rqb_reg[] = {
DEVICE rqb_dev = { DEVICE rqb_dev = {
"RQB", rqb_unit, rqb_reg, rq_mod, "RQB", rqb_unit, rqb_reg, rq_mod,
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_MAXDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &rq_boot, &rq_attach, &rq_detach,
&rqb_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS, &rqb_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
@ -1204,7 +1204,7 @@ DIB rqc_dib = {
1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ 1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ
}; };
UNIT rqc_unit[] = { UNIT rqc_unit[RQ_MAXDR + 2] = {
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
@ -1213,8 +1213,6 @@ UNIT rqc_unit[] = {
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_tmrsvc, UNIT_IDLE|UNIT_DIS, 0) },
{ UDATA (&rq_quesvc, UNIT_DIS, 0) }
}; };
REG rqc_reg[] = { REG rqc_reg[] = {
@ -1256,7 +1254,7 @@ REG rqc_reg[] = {
DEVICE rqc_dev = { DEVICE rqc_dev = {
"RQC", rqc_unit, rqc_reg, rq_mod, "RQC", rqc_unit, rqc_reg, rq_mod,
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_MAXDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &rq_boot, &rq_attach, &rq_detach,
&rqc_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS, &rqc_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
@ -1279,7 +1277,7 @@ DIB rqd_dib = {
1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ 1, IVCL (RQ), 0, { &rq_inta }, IOLN_RQ
}; };
UNIT rqd_unit[] = { UNIT rqd_unit[RQ_MAXDR + 2] = {
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
@ -1288,8 +1286,6 @@ UNIT rqd_unit[] = {
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+ { UDATA (&rq_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_ROABLE+
(RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) }, (RD54_DTYPE << UNIT_V_DTYPE), RQ_SIZE (RD54)) },
{ UDATA (&rq_tmrsvc, UNIT_IDLE|UNIT_DIS, 0) },
{ UDATA (&rq_quesvc, UNIT_DIS, 0) }
}; };
REG rqd_reg[] = { REG rqd_reg[] = {
@ -1331,7 +1327,7 @@ REG rqd_reg[] = {
DEVICE rqd_dev = { DEVICE rqd_dev = {
"RQD", rqd_unit, rqd_reg, rq_mod, "RQD", rqd_unit, rqd_reg, rq_mod,
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_MAXDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &rq_boot, &rq_attach, &rq_detach,
&rqd_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS, &rqd_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
@ -2866,6 +2862,43 @@ uptr->unit_plug = plug;
return SCPE_OK; return SCPE_OK;
} }
/* Set number of drives */
t_stat rq_set_drives (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 new_drives;
uint32 i;
t_stat r;
DEVICE *dptr = find_dev_from_unit (uptr);
uint32 old_drives = 0;
if ((cptr == NULL) || (*cptr == '\0'))
return sim_messagef (SCPE_ARG, "Must specify DRIVES=value\n");
for (i=0; i < dptr->numunits; i++) {
if (dptr->units[i].flags & UNIT_DISABLE)
++old_drives;
}
new_drives = (int32) get_uint (cptr, 10, RQ_MAXDR, &r);
if ((r != SCPE_OK) || (new_drives > RQ_MAXDR) || (new_drives < RQ_NUMDR))
return sim_messagef (SCPE_ARG, "Invalid Number of Drives: %s\n", cptr);
if (old_drives == new_drives)
return SCPE_OK; /* Nothing to do */
for (i=new_drives; i < old_drives; i++) {
if (dptr->units[i].flags & UNIT_ATT)
return sim_messagef (SCPE_ALATT, "Can't change number of drives on %s with %s attached to %s.\n",
dptr->name, sim_uname (&dptr->units[i]), dptr->units[i].filename);
}
for (i=old_drives; i < new_drives; i++) {
dptr->units[i].flags &= ~UNIT_DIS;
dptr->units[i].flags |= UNIT_DISABLE;
}
for (i=new_drives; i < old_drives; i++) {
dptr->units[i].flags |= UNIT_DIS;
dptr->units[i].flags &= ~UNIT_DISABLE;
}
return SCPE_OK;
}
/* Show unit type */ /* Show unit type */
t_stat rq_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc) t_stat rq_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
@ -2952,13 +2985,22 @@ if (!plugs_inited ) {
uint32 d, u = 0; uint32 d, u = 0;
char uname[16]; char uname[16];
sprintf (uname, "%s-TIMER", dptr->name);
sim_set_uname (&dptr->units[4], uname);
sprintf (uname, "%s-QUESVC", dptr->name);
sim_set_uname (&dptr->units[5], uname);
plugs_inited = TRUE; plugs_inited = TRUE;
dptr->units[RQ_TIMER].action = &rq_tmrsvc;
dptr->units[RQ_TIMER].flags = UNIT_IDLE|UNIT_DIS;
sprintf (uname, "%s-TIMER", dptr->name);
sim_set_uname (&dptr->units[RQ_TIMER], uname);
dptr->units[RQ_QUEUE].action = &rq_quesvc;
dptr->units[RQ_QUEUE].flags = UNIT_DIS;
sprintf (uname, "%s-QUESVC", dptr->name);
sim_set_uname (&dptr->units[RQ_QUEUE], uname);
for (i = 0; i < RQ_NUMCT; i++) { for (i = 0; i < RQ_NUMCT; i++) {
for (d = 0; d < rq_devmap[i]->numunits - 2; d++) { for (d = 0; d < rq_devmap[i]->numunits - 2; d++) {
if (d >= RQ_NUMDR) {
rq_devmap[i]->units[d] = rq_devmap[i]->units[0];
rq_devmap[i]->units[d].flags |= UNIT_DIS;
rq_devmap[i]->units[d].flags &= ~UNIT_DISABLE;
}
rq_devmap[i]->units[d].unit_plug = rq_devmap[i]->units[d].unit_plug =
#if defined (VM_VAX) #if defined (VM_VAX)
d; /* VAX default units */ d; /* VAX default units */
@ -3008,7 +3050,7 @@ for (i = 0; i < (RQ_NUMDR + 2); i++) { /* init units */
return SCPE_MEM; return SCPE_MEM;
} }
for (i=cp->max_plug=0; i<RQ_NUMDR; i++) for (i=cp->max_plug=0; i<RQ_NUMDR; i++)
if (dptr->units[i].unit_plug > cp->max_plug) if ((0 == (dptr->units[i].flags & UNIT_DIS)) && (dptr->units[i].unit_plug > cp->max_plug))
cp->max_plug = (uint16)dptr->units[i].unit_plug; cp->max_plug = (uint16)dptr->units[i].unit_plug;
return auto_config (0, 0); /* run autoconfig */ return auto_config (0, 0); /* run autoconfig */
} }
@ -3197,7 +3239,8 @@ t_stat rq_show_ctrl (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{ {
MSC *cp = rq_ctxmap[uptr->cnum]; MSC *cp = rq_ctxmap[uptr->cnum];
DEVICE *dptr = rq_devmap[uptr->cnum]; DEVICE *dptr = rq_devmap[uptr->cnum];
int32 i, pkt; uint32 i;
int32 pkt;
if (cp->csta != CST_UP) { if (cp->csta != CST_UP) {
fprintf (st, "Controller is not initialized\n"); fprintf (st, "Controller is not initialized\n");
@ -3235,8 +3278,9 @@ if (val & RQ_SH_RS) {
else fprintf (st, "Response queue is empty\n"); else fprintf (st, "Response queue is empty\n");
} }
if (val & RQ_SH_UN) { if (val & RQ_SH_UN) {
for (i = 0; i < RQ_NUMDR; i++) for (i = 0; i < (dptr->numunits - 2); i++)
rq_show_unitq (st, dptr->units + i, 0, desc); if (0 == (dptr->units[i].flags & UNIT_DIS))
rq_show_unitq (st, &dptr->units[i], 0, desc);
} }
return SCPE_OK; return SCPE_OK;
} }