MUX: Fix for connection establishment logic for virtual null modem connections.

Test case provided by Ed Marr using PDP11 DL devices.
This commit is contained in:
Mark Pizzolato 2015-08-18 09:52:49 -07:00
parent f602b132dd
commit 77152c6e20
2 changed files with 64 additions and 10 deletions

View file

@ -157,13 +157,34 @@ MTAB dli_mod[] = {
{ 0 } { 0 }
}; };
/* debugging bitmaps */
#define DBG_REG 0x0001 /* read/write registers */
#define DBG_INT 0x0002 /* interrupts */
#define DBG_TRC TMXR_DBG_TRC /* routine calls */
DEBTAB dl_debug[] = {
{ "REG", DBG_REG, "Register Activities" },
{ "INT", DBG_INT, "Interrupt Activities" },
{ "XMT", TMXR_DBG_XMT, "Transmit Data" },
{ "RCV", TMXR_DBG_RCV, "Received Data" },
{ "RET", TMXR_DBG_RET, "Returned Received Data" },
{ "MDM", TMXR_DBG_MDM, "Modem Signals" },
{ "CON", TMXR_DBG_CON, "Connection Activities" },
{ "ASY", TMXR_DBG_ASY, "Asynchronous Activities" },
{ "TRC", DBG_TRC, "trace routine calls" },
{ "EXP", TMXR_DBG_EXP, "Expect Activities" },
{ "SEND", TMXR_DBG_SEND, "Send Activities" },
{ 0 }
};
DEVICE dli_dev = { DEVICE dli_dev = {
"DLI", &dli_unit, dli_reg, dli_mod, "DLI", &dli_unit, dli_reg, dli_mod,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &dlx_reset, NULL, NULL, &dlx_reset,
NULL, &dlx_attach, &dlx_detach, NULL, &dlx_attach, &dlx_detach,
&dli_dib, DEV_UBUS | DEV_QBUS | DEV_DISABLE | DEV_DIS | DEV_MUX &dli_dib, DEV_UBUS | DEV_QBUS | DEV_DISABLE | DEV_DIS | DEV_MUX | DEV_DEBUG,
}; 0, dl_debug, NULL, NULL, NULL, NULL, NULL, NULL};
/* DLO data structures /* DLO data structures
@ -221,8 +242,12 @@ DEVICE dlo_dev = {
DLX_LINES, 10, 31, 1, 8, 8, DLX_LINES, 10, 31, 1, 8, 8,
NULL, NULL, &dlx_reset, NULL, NULL, &dlx_reset,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, DEV_UBUS | DEV_QBUS | DEV_DISABLE | DEV_DIS NULL, DEV_UBUS | DEV_QBUS | DEV_DISABLE | DEV_DIS | DEV_DEBUG,
}; 0, dl_debug, NULL, NULL, NULL, NULL, NULL, NULL };
/* Register names for Debug tracing */
static const char *dl_regs[] =
{"TTI CSR", "TTI BUF", "TTO CSR", "TTO BUF" };
/* Terminal input routines */ /* Terminal input routines */
@ -240,25 +265,30 @@ switch ((PA >> 1) & 03) { /* decode PA<2:1> */
((dlo_unit[ln].flags & DLX_MDM)? DLICSR_RD_M: DLICSR_RD); ((dlo_unit[ln].flags & DLX_MDM)? DLICSR_RD_M: DLICSR_RD);
dli_csr[ln] &= ~DLICSR_DSI; /* clr DSI flag */ dli_csr[ln] &= ~DLICSR_DSI; /* clr DSI flag */
dli_clr_int (ln, DLI_DSI); /* clr dset int req */ dli_clr_int (ln, DLI_DSI); /* clr dset int req */
return SCPE_OK; break;
case 01: /* tti buf */ case 01: /* tti buf */
*data = dli_buf[ln] & DLIBUF_RD; *data = dli_buf[ln] & DLIBUF_RD;
dli_csr[ln] &= ~CSR_DONE; /* clr rcv done */ dli_csr[ln] &= ~CSR_DONE; /* clr rcv done */
dli_clr_int (ln, DLI_RCI); /* clr rcv int req */ dli_clr_int (ln, DLI_RCI); /* clr rcv int req */
sim_activate_abs (&dli_unit, dli_unit.wait); sim_activate_abs (&dli_unit, dli_unit.wait);
return SCPE_OK; break;
case 02: /* tto csr */ case 02: /* tto csr */
*data = dlo_csr[ln] & DLOCSR_RD; *data = dlo_csr[ln] & DLOCSR_RD;
return SCPE_OK; break;
case 03: /* tto buf */ case 03: /* tto buf */
*data = dlo_buf[ln]; *data = dlo_buf[ln];
return SCPE_OK; break;
default:
return SCPE_NXM;
} /* end switch PA */ } /* end switch PA */
return SCPE_NXM; sim_debug(DBG_REG, &dli_dev, "dlx_rd(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, dl_regs[(PA >> 1) & 03], access, *data);
return SCPE_OK;
} }
t_stat dlx_wr (int32 data, int32 PA, int32 access) t_stat dlx_wr (int32 data, int32 PA, int32 access)
@ -269,6 +299,8 @@ TMLN *lp = &dlx_ldsc[ln];
if (ln > DLX_MAXMUX) /* validate line number */ if (ln > DLX_MAXMUX) /* validate line number */
return SCPE_IERR; return SCPE_IERR;
sim_debug(DBG_REG, &dli_dev, "dlx_wr(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, dl_regs[(PA >> 1) & 03], access, data);
switch ((PA >> 1) & 03) { /* decode PA<2:1> */ switch ((PA >> 1) & 03) { /* decode PA<2:1> */
case 00: /* tti csr */ case 00: /* tti csr */
@ -340,6 +372,8 @@ t_stat dli_svc (UNIT *uptr)
{ {
int32 ln, c, temp; int32 ln, c, temp;
sim_debug(DBG_TRC, &dli_dev, "dli_svc()\n");
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return SCPE_OK; return SCPE_OK;
sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */ sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */
@ -389,6 +423,8 @@ t_stat dlo_svc (UNIT *uptr)
int32 c; int32 c;
int32 ln = uptr - dlo_unit; /* line # */ int32 ln = uptr - dlo_unit; /* line # */
sim_debug(DBG_TRC, &dlo_dev, "dlo_svc()\n");
if (dlx_ldsc[ln].conn) { /* connected? */ if (dlx_ldsc[ln].conn) { /* connected? */
if (dlx_ldsc[ln].xmte) { /* tx enabled? */ if (dlx_ldsc[ln].xmte) { /* tx enabled? */
TMLN *lp = &dlx_ldsc[ln]; /* get line */ TMLN *lp = &dlx_ldsc[ln]; /* get line */
@ -413,6 +449,8 @@ return SCPE_OK;
void dli_clr_int (int32 ln, uint32 wd) void dli_clr_int (int32 ln, uint32 wd)
{ {
sim_debug(DBG_INT, &dli_dev, "dli_clr_int(dl=%d, wd=%d)\n", ln, wd);
dli_ireq[wd] &= ~(1 << ln); /* clr rcv/dset int */ dli_ireq[wd] &= ~(1 << ln); /* clr rcv/dset int */
if ((dli_ireq[DLI_RCI] | dli_ireq[DLI_DSI]) == 0) /* all clr? */ if ((dli_ireq[DLI_RCI] | dli_ireq[DLI_DSI]) == 0) /* all clr? */
CLR_INT (DLI); /* all clr? */ CLR_INT (DLI); /* all clr? */
@ -422,6 +460,8 @@ return;
void dli_set_int (int32 ln, uint32 wd) void dli_set_int (int32 ln, uint32 wd)
{ {
sim_debug(DBG_INT, &dli_dev, "dli_set_int(dl=%d, wd=%d)\n", ln, wd);
dli_ireq[wd] |= (1 << ln); /* set rcv/dset int */ dli_ireq[wd] |= (1 << ln); /* set rcv/dset int */
SET_INT (DLI); /* set master intr */ SET_INT (DLI); /* set master intr */
return; return;
@ -435,6 +475,7 @@ for (ln = 0; ln < DLX_LINES; ln++) { /* find 1st line */
if ((dli_ireq[DLI_RCI] | dli_ireq[DLI_DSI]) & (1 << ln)) { if ((dli_ireq[DLI_RCI] | dli_ireq[DLI_DSI]) & (1 << ln)) {
dli_clr_int (ln, DLI_RCI); /* clr both req */ dli_clr_int (ln, DLI_RCI); /* clr both req */
dli_clr_int (ln, DLI_DSI); dli_clr_int (ln, DLI_DSI);
sim_debug(DBG_INT, &dli_dev, "dli_iack(ln=%d)\n", ln);
return (dli_dib.vec + (ln * 010)); /* return vector */ return (dli_dib.vec + (ln * 010)); /* return vector */
} }
} }
@ -443,6 +484,8 @@ return 0;
void dlo_clr_int (int32 ln) void dlo_clr_int (int32 ln)
{ {
sim_debug(DBG_INT, &dlo_dev, "dlo_clr_int(dl=%d)\n", ln);
dlo_ireq &= ~(1 << ln); /* clr xmit int */ dlo_ireq &= ~(1 << ln); /* clr xmit int */
if (dlo_ireq == 0) /* all clr? */ if (dlo_ireq == 0) /* all clr? */
CLR_INT (DLO); CLR_INT (DLO);
@ -452,6 +495,8 @@ return;
void dlo_set_int (int32 ln) void dlo_set_int (int32 ln)
{ {
sim_debug(DBG_INT, &dlo_dev, "dlo_set_int(dl=%d)\n", ln);
dlo_ireq |= (1 << ln); /* set xmit int */ dlo_ireq |= (1 << ln); /* set xmit int */
SET_INT (DLO); /* set master intr */ SET_INT (DLO); /* set master intr */
return; return;
@ -464,6 +509,7 @@ int32 ln;
for (ln = 0; ln < DLX_LINES; ln++) { /* find 1st line */ for (ln = 0; ln < DLX_LINES; ln++) { /* find 1st line */
if (dlo_ireq & (1 << ln)) { if (dlo_ireq & (1 << ln)) {
dlo_clr_int (ln); /* clear intr */ dlo_clr_int (ln); /* clear intr */
sim_debug(DBG_INT, &dlo_dev, "dlo_iack(ln=%d)\n", ln);
return (dli_dib.vec + (ln * 010) + 4); /* return vector */ return (dli_dib.vec + (ln * 010) + 4); /* return vector */
} }
} }
@ -476,6 +522,8 @@ t_stat dlx_reset (DEVICE *dptr)
{ {
int32 ln; int32 ln;
sim_debug(DBG_TRC, dptr, "dlx_reset()\n");
dlx_enbdis (dptr->flags & DEV_DIS); /* sync enables */ dlx_enbdis (dptr->flags & DEV_DIS); /* sync enables */
sim_cancel (&dli_unit); /* assume stop */ sim_cancel (&dli_unit); /* assume stop */
if (dli_unit.flags & UNIT_ATT) /* if attached, */ if (dli_unit.flags & UNIT_ATT) /* if attached, */
@ -489,6 +537,8 @@ return auto_config (dli_dev.name, dlx_desc.lines); /* auto config */
void dlx_reset_ln (int32 ln) void dlx_reset_ln (int32 ln)
{ {
sim_debug(DBG_TRC, &dli_dev, "dlx_reset_ln(ln=%d)\n", ln);
dli_buf[ln] = 0; /* clear buf */ dli_buf[ln] = 0; /* clear buf */
if (dlo_unit[ln].flags & DLX_MDM) /* modem */ if (dlo_unit[ln].flags & DLX_MDM) /* modem */
dli_csr[ln] &= DLICSR_DTR; /* dont clr DTR */ dli_csr[ln] &= DLICSR_DTR; /* dont clr DTR */
@ -508,6 +558,8 @@ t_stat dlx_attach (UNIT *uptr, char *cptr)
{ {
t_stat r; t_stat r;
sim_debug(DBG_TRC, &dli_dev, "dlx_attach()\n");
r = tmxr_attach (&dlx_desc, uptr, cptr); /* attach */ r = tmxr_attach (&dlx_desc, uptr, cptr); /* attach */
if (r != SCPE_OK) /* error */ if (r != SCPE_OK) /* error */
return r; return r;
@ -522,6 +574,8 @@ t_stat dlx_detach (UNIT *uptr)
int32 i; int32 i;
t_stat r; t_stat r;
sim_debug(DBG_TRC, &dli_dev, "dlx_detach()\n");
r = tmxr_detach (&dlx_desc, uptr); /* detach */ r = tmxr_detach (&dlx_desc, uptr); /* detach */
for (i = 0; i < DLX_LINES; i++) /* all lines, */ for (i = 0; i < DLX_LINES; i++) /* all lines, */
dlx_ldsc[i].rcve = 0; /* disable rcv */ dlx_ldsc[i].rcve = 0; /* disable rcv */

View file

@ -1094,7 +1094,7 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
tmxr_debug_connect_line (lp, msg); tmxr_debug_connect_line (lp, msg);
free (sockname); free (sockname);
free (peername); free (peername);
break; return i;
case -1: /* failed connection */ case -1: /* failed connection */
sprintf (msg, "tmxr_poll_conn() - Outgoing Line Connection to %s failed", lp->destination); sprintf (msg, "tmxr_poll_conn() - Outgoing Line Connection to %s failed", lp->destination);
tmxr_debug_connect_line (lp, msg); tmxr_debug_connect_line (lp, msg);