Changed pdp11_dz to leverage the tmxr library's pass thru modem control capabilities.

Fixed reporting of DCD for dz lines beyond the first 4.
This commit is contained in:
Mark Pizzolato 2012-10-17 14:17:14 -07:00
parent 02cb620c9b
commit 0a46da5aa0
3 changed files with 123 additions and 24 deletions

View file

@ -119,9 +119,26 @@ extern int32 int_req[IPL_HLVL];
#define RBUF_VALID 0100000 /* rcv valid */
#define RBUF_MBZ 0004000
char *dz_charsizes[] = {"5", "6", "7", "8"};
char *dz_baudrates[] = {"50", "75", "110", "134.5", "150", "300", "600", "1200",
"1800", "2000", "2400", "3600", "4800", "7200", "9600", "19200"};
char *dz_parity[] = {"N", "E", "N", "O"};
char *dz_stopbits[] = {"1", "2", "1", "1.5"};
/* DZLPR - 160102 - line parameter register, write only, word access only */
#define LPR_V_LINE 0 /* line */
#define LPR_V_SPEED 8 /* speed code */
#define LPR_M_SPEED 0007400 /* speed code mask */
#define LPR_V_CHARSIZE 3 /* char size code */
#define LPR_M_CHARSIZE 0000030 /* char size code mask */
#define LPR_V_STOPBITS 5 /* stop bits code */
#define LPR_V_PARENB 6 /* parity enable */
#define LPR_V_PARODD 7 /* parity odd */
#define LPR_GETSPD(x) dz_baudrates[((x) & LPR_M_SPEED) >> LPR_V_SPEED]
#define LPR_GETCHARSIZE(x) dz_charsizes[((x) & LPR_M_CHARSIZE) >> LPR_V_CHARSIZE]
#define LPR_GETPARITY(x) dz_parity[(((x) >> LPR_V_PARENB) & 1) | (((x) >> (LPR_V_PARODD-1)) & 2)]
#define LPR_GETSTOPBITS(x) dz_stopbits[(((x) >> LPR_V_STOPBITS) & 1) + (((((x) & LPR_M_CHARSIZE) >> LPR_V_CHARSIZE) == 5) ? 2 : 0)]
#define LPR_LPAR 0007770 /* line pars - NI */
#define LPR_RCVE 0010000 /* receive enb */
#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LNOMASK)
@ -281,6 +298,7 @@ static char *dz_wr_regs[] =
t_stat dz_rd (int32 *data, int32 PA, int32 access)
{
int i;
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
@ -310,6 +328,20 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
break;
case 03: /* MSR */
if (dz_mctl)
for (i=0; i<DZ_LINES; ++i) { /* Gather line status bits for each line */
int line;
int32 modem_bits;
TMLN *lp;
line = (dz * DZ_LINES) + i;
lp = &dz_ldsc[line]; /* get line desc */
tmxr_set_get_modem_bits (lp, 0, 0, &modem_bits);
dz_msr[dz] &= ~((1 << (MSR_V_RI + i)) | (1 << (MSR_V_CD + i)));
dz_msr[dz] |= ((modem_bits&TMXR_MDM_RNG) ? (1 << (MSR_V_RI + i)) : 0) |
((modem_bits&TMXR_MDM_DCD) ? (1 << (MSR_V_CD + i)) : 0);
}
*data = dz_msr[dz];
break;
}
@ -323,6 +355,7 @@ t_stat dz_wr (int32 data, int32 PA, int32 access)
{
int32 dz = ((PA - dz_dib.ba) >> 3) & DZ_MNOMASK; /* get mux num */
int32 i, c, line;
char lineconfig[16];
TMLN *lp;
sim_debug(DBG_REG, &dz_dev, "dz_wr(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, dz_wr_regs[(PA >> 1) & 03], access, data);
@ -358,6 +391,11 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
if (dz_lpr[dz] & LPR_RCVE) /* rcv enb? on */
lp->rcve = 1;
else lp->rcve = 0; /* else line off */
if (dz_mctl) {
sprintf(lineconfig, "%s-%s%s%s", LPR_GETSPD(data), LPR_GETCHARSIZE(data), LPR_GETPARITY(data), LPR_GETSTOPBITS(data));
if (!lp->serconfig || (0 != strcmp(lp->serconfig, lineconfig))) /* config changed? */
tmxr_set_config_line (lp, lineconfig); /* set it */
}
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* update rx intr */
break;
@ -367,23 +405,20 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
(dz_tcr[dz] & 0377) | (data << 8):
(dz_tcr[dz] & ~0377) | data;
if (dz_mctl) { /* modem ctl? */
dz_msr[dz] |= ((data & 0177400) & /* dcd |= dtr & ring */
((dz_msr[dz] & DZ_LMASK) << MSR_V_CD));
dz_msr[dz] &= ~(data >> TCR_V_DTR); /* ring &= ~dtr */
if (dz_auto) { /* auto disconnect? */
int32 drop;
drop = (dz_tcr[dz] & ~data) >> TCR_V_DTR; /* drop = dtr & ~data */
for (i = 0; i < DZ_LINES; i++) { /* drop hangups */
line = (dz * DZ_LINES) + i; /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
if (lp->conn && (drop & (1 << i))) {
tmxr_linemsg (lp, "\r\nLine hangup\r\n");
tmxr_reset_ln (lp); /* reset line, cdet */
dz_msr[dz] &= ~(1 << (i + MSR_V_CD));
} /* end if drop */
} /* end for */
} /* end if auto */
} /* end if modem */
int32 changed = data ^ dz_tcr[dz];
for (i = 0; i < DZ_LINES; i++) {
if (0 == (changed & (1 << (TCR_V_DTR + i))))
continue; /* line unchanged skip */
line = (dz * DZ_LINES) + i; /* get line num */
lp = &dz_ldsc[line]; /* get line desc */
if (data & (1 << (TCR_V_DTR + i)))
tmxr_set_get_modem_bits (lp, TMXR_MDM_DTR|TMXR_MDM_RTS, 0, NULL);
else
if (dz_auto)
tmxr_set_get_modem_bits (lp, 0, TMXR_MDM_DTR|TMXR_MDM_RTS, NULL);
}
}
dz_tcr[dz] = data;
tmxr_poll_tx (&dz_desc); /* poll output */
dz_update_xmti (); /* update int */
@ -423,7 +458,7 @@ return SCPE_OK;
t_stat dz_svc (UNIT *uptr)
{
int32 dz, t, newln;
int32 dz, t, newln, muxln;
for (dz = t = 0; dz < DZ_MUXES; dz++) /* check enabled */
t = t | (dz_csr[dz] & CSR_MSE);
@ -431,9 +466,10 @@ if (t) { /* any enabled? */
newln = tmxr_poll_conn (&dz_desc); /* poll connect */
if ((newln >= 0) && dz_mctl) { /* got a live one? */
dz = newln / DZ_LINES; /* get mux num */
if (dz_tcr[dz] & (1 << (newln + TCR_V_DTR))) /* DTR set? */
dz_msr[dz] |= (1 << (newln + MSR_V_CD)); /* set cdet */
else dz_msr[dz] |= (1 << newln); /* set ring */
muxln = newln % DZ_LINES; /* get line in mux */
if (dz_tcr[dz] & (1 << (muxln + TCR_V_DTR))) /* DTR set? */
dz_msr[dz] |= (1 << (muxln + MSR_V_CD)); /* set cdet */
else dz_msr[dz] |= (1 << (muxln + MSR_V_RI)); /* set ring */
}
tmxr_poll_rx (&dz_desc); /* poll input */
dz_update_rcvi (); /* upd rcv intr */
@ -627,13 +663,17 @@ return auto_config (dptr->name, ndev); /* auto config */
t_stat dz_attach (UNIT *uptr, char *cptr)
{
int32 dz, muxln;
t_stat r;
extern int32 sim_switches;
dz_mctl = dz_auto = 0; /* modem ctl off */
if (sim_switches & SWMASK ('M')) /* modem control? */
tmxr_set_modem_control_passthru (&dz_desc);
r = tmxr_attach (&dz_desc, uptr, cptr); /* attach mux */
if (r != SCPE_OK) /* error? */
if (r != SCPE_OK) { /* error? */
tmxr_clear_modem_control_passthru (&dz_desc);
return r;
}
if (sim_switches & SWMASK ('M')) { /* modem control? */
dz_mctl = 1;
printf ("Modem control activated\n");
@ -646,6 +686,18 @@ if (sim_switches & SWMASK ('M')) { /* modem control? */
fprintf (sim_log, "Auto disconnect activated\n");
}
}
for (dz = 0; dz < DZ_MUXES; dz++) {
if (!dz_mctl || (0 == (dz_csr[dz] & CSR_MSE))) /* enabled? */
continue;
for (muxln = 0; muxln < DZ_LINES; muxln++) {
if (dz_tcr[dz] & (1 << (muxln + TCR_V_DTR))) {
TMLN *lp = &dz_ldsc[(dz * DZ_LINES) + muxln];
tmxr_set_get_modem_bits (lp, TMXR_MDM_DTR|TMXR_MDM_RTS, 0, NULL);
}
}
}
return SCPE_OK;
}
@ -653,6 +705,7 @@ return SCPE_OK;
t_stat dz_detach (UNIT *uptr)
{
dz_mctl = dz_auto = 0; /* modem ctl off */
return tmxr_detach (&dz_desc, uptr);
}

View file

@ -71,6 +71,7 @@
tmxr_poll_tx - poll transmit
tmxr_send_buffered_data - transmit buffered data
tmxr_set_modem_control_passthru - enable modem control on a multiplexer
tmxr_clear_modem_control_passthru - disable modem control on a multiplexer
tmxr_set_get_modem_bits - set and/or get a line modem bits
tmxr_set_config_line - set port speed, character size, parity and stop bits
tmxr_open_master - open master connection
@ -867,7 +868,6 @@ return SCPE_OK;
2 Calling this API enables the tmxr_set_get_modem_bits and
tmxr_set_config_line APIs.
*/
t_stat tmxr_set_modem_control_passthru (TMXR *mp)
{
@ -875,6 +875,49 @@ mp->modem_control = TRUE;
return SCPE_OK;
}
/* Disable modem control pass thru
Inputs:
none
Output:
none
Implementation note:
1 Calling this API enables this library's direct manipulation
of DTR (&RTS) on serial ports.
2 Calling this API disables the tmxr_set_get_modem_bits and
tmxr_set_config_line APIs.
3 This API will only change the state of the modem control processing
of this library if there are no listening ports, serial ports or
outgoing connecctions associated with the specified multiplexer
*/
t_stat tmxr_clear_modem_control_passthru (TMXR *mp)
{
int i;
if (!mp->modem_control)
return SCPE_OK;
if (mp->master)
return SCPE_ALATT;
for (i=0; i<mp->lines; ++i) {
TMLN *lp;
lp = mp->ldsc + i;
if ((lp->master) ||
(lp->conn) ||
(lp->connecting) ||
(lp->serport))
return SCPE_ALATT;
}
mp->modem_control = FALSE;
return SCPE_OK;
}
/* Manipulate the modem control bits of a specific line
Inputs:
@ -2116,6 +2159,7 @@ if (lp->txlog == NULL) { /* error? */
free (lp->txlogname); /* free buffer */
return SCPE_OPENERR;
}
lp->mp->uptr->filename = _mux_attach_string (lp->mp->uptr->filename, lp->mp);
return SCPE_OK;
}
@ -2138,6 +2182,7 @@ if (lp->txlog) { /* logging? */
lp->txlog = NULL;
lp->txlogname = NULL;
}
lp->mp->uptr->filename = _mux_attach_string (lp->mp->uptr->filename, lp->mp);
return SCPE_OK;
}

View file

@ -150,6 +150,7 @@ t_stat tmxr_close_master (TMXR *mp);
t_stat tmxr_attach (TMXR *mp, UNIT *uptr, char *cptr);
t_stat tmxr_detach (TMXR *mp, UNIT *uptr);
t_stat tmxr_set_modem_control_passthru (TMXR *mp);
t_stat tmxr_clear_modem_control_passthru (TMXR *mp);
t_stat tmxr_set_get_modem_bits (TMLN *lp, int32 bits_to_set, int32 bits_to_clear, int32 *incoming_bits);
t_stat tmxr_set_config_line (TMLN *lp, char *config);
t_stat tmxr_set_line_unit (TMXR *mp, int line, UNIT *uptr_poll);