PDP11, VAX: Add settable unit numbers for TQ drives

This commit is contained in:
Mark Pizzolato 2018-04-12 13:15:48 -07:00
parent bd621f50bf
commit 5a9263c0cf
2 changed files with 61 additions and 10 deletions

View file

@ -2817,6 +2817,8 @@ uint32 i;
t_stat r;
DEVICE *dptr = find_dev_from_unit (uptr);
if (cptr == NULL)
return sim_messagef (SCPE_ARG, "Must specify UNIT=value\n");
plug = (int32) get_uint (cptr, 10, 0xFFFFFFFF, &r);
if ((r != SCPE_OK) || (plug > 65534))
return sim_messagef (SCPE_ARG, "Invalid Unit Plug Number: %s\n", cptr);
@ -3052,7 +3054,7 @@ UNIT *uptr = &dptr->units[unitno];
for (i = 0; i < BOOT_LEN; i++)
M[(BOOT_START >> 1) + i] = boot_rom[i];
M[BOOT_UNIT >> 1] = uptr->unit_plug;
M[BOOT_UNIT >> 1] = (uint16)uptr->unit_plug;
M[BOOT_CSR >> 1] = dibp->ba & DMASK;
cpu_set_boot (BOOT_ENTRY);
return SCPE_OK;

View file

@ -121,6 +121,7 @@
#define pktq us10 /* packet queue */
#define uf buf /* settable unit flags */
#define objp wait /* object position */
#define unit_plug u4 /* drive unit plug value */
#define io_status u5 /* io status from callback */
#define io_complete u6 /* io completion flag */
#define TQ_WPH(u) ((sim_tape_wrp (u))? UF_WPH: 0)
@ -353,6 +354,8 @@ t_stat tq_show_ctrl (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat tq_show_unitq (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat tq_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat tq_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat tq_set_plug (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat tq_show_plug (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
static t_stat tq_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *tq_description (DEVICE *dptr);
@ -461,6 +464,7 @@ REG tq_reg[] = {
{ DRDATAD (XTIME, tq_xtime, 24, "response time for data transfers"), PV_LEFT + REG_NZ },
{ DRDATAD (RWTIME, tq_rwtime, 32, "rewind time 2 sec (adjusted later)"), PV_LEFT + REG_NZ },
{ BRDATAD (PKTS, tq_pkt, DEV_RDX, 16, TQ_NPKTS * (TQ_PKT_SIZE_W + 1), "packet buffers, 33W each, 32 entries") },
{ URDATAD (PLUG, tq_unit[0].unit_plug, 10, T_ADDR_W, 0, TQ_NUMDR, PV_LEFT | REG_RO, "unit plug value, units 0 to 3") },
{ DRDATA (DEVTYPE, tq_typ, 2), REG_HRO },
{ DRDATA (DEVCAP, drv_tab[TQU_TYPE].cap, T_ADDR_W), PV_LEFT | REG_HRO },
{ GRDATA (DEVADDR, tq_dib.ba, DEV_RDX, 32, 0), REG_HRO },
@ -483,6 +487,8 @@ MTAB tq_mod[] = {
&tq_set_type, NULL, NULL, "Set TKUSER=size Device Type" },
{ MTAB_XTD|MTAB_VDV, 0, "TYPE", NULL,
NULL, &tq_show_type, NULL, "Display device type" },
{ MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "UNIT", "UNIT=val (0-65534)",
&tq_set_plug, &tq_show_plug, NULL, "Set/Display Unit plug value" },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, TQ_SH_RI, "RINGS", NULL,
NULL, &tq_show_ctrl, NULL, "Display command and response rings" },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, TQ_SH_FR, "FREEQ", NULL,
@ -1013,7 +1019,7 @@ UNIT *uptr;
sim_debug(DBG_TRC, &tq_dev, "tq_gus\n");
if (tq_pkt[pkt].d[CMD_MOD] & MD_NXU) { /* next unit? */
if (lu >= TQ_NUMDR) { /* end of range? */
if (lu == 65535) { /* end of range? */
lu = 0; /* reset to 0 */
tq_pkt[pkt].d[RSP_UN] = (uint16)lu;
}
@ -1726,7 +1732,7 @@ uint16 lu;
if (!tq_deqf (&pkt)) /* get log pkt */
return ERR;
lu = (uint16) (uptr - tq_dev.units); /* get unit */
lu = (uint16) (uptr->unit_plug); /* get unit */
tq_pkt[pkt].d[RSP_REFL] = tq_pkt[pkt].d[RSP_REFH] = 0; /* ref = 0 */
tq_pkt[pkt].d[RSP_UN] = lu;
tq_pkt[pkt].d[RSP_RSV] = 0;
@ -1906,14 +1912,16 @@ return OK;
UNIT *tq_getucb (uint16 lu)
{
uint32 i;
UNIT *uptr;
if (lu >= TQ_NUMDR)
return NULL;
uptr = tq_dev.units + lu;
if (uptr->flags & UNIT_DIS)
return NULL;
return uptr;
for (i = 0; i < tq_dev.numunits - 2; i++) {
uptr = &tq_dev.units[i];
if ((lu == uptr->unit_plug) &&
!(uptr->flags & UNIT_DIS))
return uptr;
}
return NULL;
}
/* Hack unit flags */
@ -2058,6 +2066,15 @@ t_stat tq_reset (DEVICE *dptr)
{
int32 i, j;
UNIT *uptr;
static t_bool plugs_inited = FALSE;
if (!plugs_inited ) {
uint32 d;
plugs_inited = TRUE;
for (d = 0; d < tq_dev.numunits - 2; d++)
tq_unit[d].unit_plug = d;
}
tq_csta = CST_S1; /* init stage 1 */
tq_s1dat = 0; /* no S1 data */
@ -2211,10 +2228,11 @@ static const uint16 boot_rom[] = {
t_stat tq_boot (int32 unitno, DEVICE *dptr)
{
size_t i;
UNIT *uptr = &dptr->units[unitno];
for (i = 0; i < BOOT_LEN; i++)
M[(BOOT_START >> 1) + i] = boot_rom[i];
M[BOOT_UNIT >> 1] = unitno & 3;
M[BOOT_UNIT >> 1] = (uint16)uptr->unit_plug;
M[BOOT_CSR >> 1] = tq_dib.ba & DMASK;
cpu_set_boot (BOOT_ENTRY);
return SCPE_OK;
@ -2388,6 +2406,37 @@ fprintf (st, "%s (%dMB)", drv_tab[tq_typ].name, (uint32) (drv_tab[tq_typ].cap >>
return SCPE_OK;
}
/* Show unit plug */
t_stat tq_show_plug (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf (st, "UNIT=%d", uptr->unit_plug);
return SCPE_OK;
}
/* Set unit plug */
t_stat tq_set_plug (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
int32 plug;
uint32 i;
t_stat r;
DEVICE *dptr = find_dev_from_unit (uptr);
if (cptr == NULL)
return sim_messagef (SCPE_ARG, "Must specify UNIT=value\n");
plug = (int32) get_uint (cptr, 10, 0xFFFFFFFF, &r);
if ((r != SCPE_OK) || (plug > 65534))
return sim_messagef (SCPE_ARG, "Invalid Unit Plug Number: %s\n", cptr);
if (uptr->unit_plug == plug)
return SCPE_OK;
for (i=0; i < dptr->numunits - 2; i++)
if (dptr->units[i].unit_plug == plug)
return sim_messagef (SCPE_ARG, "Unit Plug %d Already In Use on %s\n", plug, sim_uname (&dptr->units[i]));
uptr->unit_plug = plug;
return SCPE_OK;
}
static t_stat tq_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
const char *devtype = UNIBUS ? "TUK50" : "TQK50";