From 0a46da5aa0fb1a90d1d3fbd52f9cdf7e8e7ad0e1 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 17 Oct 2012 14:17:14 -0700 Subject: [PATCH] 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. --- PDP11/pdp11_dz.c | 99 +++++++++++++++++++++++++++++++++++++----------- sim_tmxr.c | 47 ++++++++++++++++++++++- sim_tmxr.h | 1 + 3 files changed, 123 insertions(+), 24 deletions(-) diff --git a/PDP11/pdp11_dz.c b/PDP11/pdp11_dz.c index 3067e18c..1e15dc84 100644 --- a/PDP11/pdp11_dz.c +++ b/PDP11/pdp11_dz.c @@ -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> 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); } diff --git a/sim_tmxr.c b/sim_tmxr.c index 283f9aac..eac088dc 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -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; ilines; ++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; } diff --git a/sim_tmxr.h b/sim_tmxr.h index 6283402a..3d105768 100644 --- a/sim_tmxr.h +++ b/sim_tmxr.h @@ -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);