The source set has been extensively overhauled. For correct viewing, set Visual C++ or Emacs to have tab stops every 4 characters. 1. New Features 1.1 3.5-0 1.1.1 All Ethernet devices - Added Windows user-defined adapter names (from Timothe Litt) 1.1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors - Added support for SET <unit>n DISCONNECT 1.1.3 VAX - Added latent QDSS support - Revised autoconfigure to handle QDSS 1.1.4 PDP-11 - Revised autoconfigure to handle more cases 1.2 3.5-1 No new features 1.3 3.5-2 1.3.1 All ASCII terminals - Most ASCII terminal emulators have supported 7-bit and 8-bit operation; where required, they have also supported an upper- case only or KSR-emulation mode. This release adds a new mode, 7P, for 7-bit printing characters. In 7P mode, non-printing characters in the range 0-31 (decimal), and 127 (decimal), are automatically suppressed. This prevents printing of fill characters under Windows. The printable character set for ASCII code values 0-31 can be changed with the SET CONSOLE PCHAR command. Code value 127 (DELETE) is always suppressed. 1.3.2 VAX-11/780 - First release. The VAX-11/780 has successfully run VMS V7.2. The commercial instructions and compatability mode have not been extensively tested. The Ethernet controller is not working yet and is disabled. 2. Bugs Fixed 2.1 3.5-0 2.1.1 SCP and libraries - Trim trailing spaces on all input (for example, attach file names) - Fixed sim_sock spurious SIGPIPE error in Unix/Linux - Fixed sim_tape misallocation of TPC map array for 64b simulators 2.1.2 1401 - Fixed bug, CPU reset was clearing SSB through SSG 2.1.3 PDP-11 - Fixed bug in VH vector display routine - Fixed XU runt packet processing (found by Tim Chapman) 2.1.4 Interdata - Fixed bug in SHOW PAS CONN/STATS - Fixed potential integer overflow exception in divide 2.1.5 SDS - Fixed bug in SHOW MUX CONN/STATS 2.1.6 HP - Fixed bug in SHOW MUX CONN/STATS 2.1.7 PDP-8 - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.1.8 PDP-18b - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.1.9 Nova, Eclipse - Fixed potential integer overflow exception in divide 2.2 3.5-1 2.2.1 1401 - Changed character encodings to be compatible with Pierce 709X simulator - Added mode for old/new character encodings 2.2.2 1620 - Changed character encodings to be compatible with Pierce 709X simulator 2.2.3 PDP-10 - Changed MOVNI to eliminate GCC warning 2.2.4 VAX - Fixed bug in structure definitions with 32b compilation options - Fixed bug in autoconfiguration table 2.2.5 PDP-11 - Fixed bug in autoconfiguration table 2.3 3.5-2 2.3.1 PDP-10 - RP: fixed drive clear not to clear disk address 2.3.2 PDP-11 (VAX, VAX-11/780, for shared peripherals) - HK: fixed overlap seek interaction with drive select, drive clear, etc - RQ, TM, TQ, TS, TU: widened address display to 64b when USE_ADDR64 option selected - TU: changed default adapter from TM02 to TM03 (required by VMS) - RP: fixed drive clear not to clear disk address - RP, TU: fixed device enable/disable to enabled/disable Massbus adapter as well - XQ: fixed register access alignment bug (found by Doug Carman) 2.3.3 PDP-8 - RL: fixed IOT 61 decoding bug (found by David Gesswein) - DF, DT, RF: fixed register access alignment bug (found by Doug Carman) 2.3.4 VAX - Fixed CVTfi to trap on integer overflow if PSW<iv> is set - Fixed breakpoint detection when USE_ADDR64 option selected
461 lines
15 KiB
C
461 lines
15 KiB
C
/* pdp15_ttx.c: PDP-15 additional terminals simulator
|
|
|
|
Copyright (c) 1993-2005, Robert M Supnik
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Except as contained in this notice, the name of Robert M Supnik shall not be
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
in this Software without prior written authorization from Robert M Supnik.
|
|
|
|
ttix,ttox LT15/LT19 terminal input/output
|
|
|
|
22-Nov-05 RMS Revised for new terminal processing routines
|
|
29-Jun-05 RMS Added SET TTOXn DISCONNECT
|
|
21-Jun-05 RMS Fixed bug in SHOW CONN/STATS
|
|
14-Jan-04 RMS Cloned from pdp8_ttx.c
|
|
|
|
This module implements 16 individual serial interfaces similar in function
|
|
to the console. These interfaces are mapped to Telnet based connections as
|
|
though they were the four lines of a terminal multiplexor. The connection
|
|
polling mechanism is superimposed onto the keyboard of the first interface.
|
|
*/
|
|
|
|
#include "pdp18b_defs.h"
|
|
#include "sim_sock.h"
|
|
#include "sim_tmxr.h"
|
|
#include <ctype.h>
|
|
|
|
#if defined (PDP15)
|
|
#define TTX_MAXL 16 /* max number of lines */
|
|
#elif defined (PDP9)
|
|
#define TTX_MAXL 4
|
|
#else
|
|
#define TTX_MAXL 1
|
|
#endif
|
|
|
|
uint32 ttix_done = 0; /* input flags */
|
|
uint32 ttox_done = 0; /* output flags */
|
|
uint8 ttix_buf[TTX_MAXL] = { 0 }; /* input buffers */
|
|
uint8 ttox_buf[TTX_MAXL] = { 0 }; /* output buffers */
|
|
TMLN ttx_ldsc[TTX_MAXL] = { 0 }; /* line descriptors */
|
|
TMXR ttx_desc = { 1, 0, 0, ttx_ldsc }; /* mux descriptor */
|
|
#define ttx_lines ttx_desc.lines /* current number of lines */
|
|
|
|
extern int32 int_hwre[API_HLVL+1];
|
|
extern int32 tmxr_poll;
|
|
extern int32 stop_inst;
|
|
|
|
DEVICE ttix_dev, ttox_dev;
|
|
int32 ttix (int32 dev, int32 pulse, int32 dat);
|
|
int32 ttox (int32 dev, int32 pulse, int32 dat);
|
|
t_stat ttix_svc (UNIT *uptr);
|
|
t_bool ttix_test_done (int32 ln);
|
|
void ttix_set_done (int32 ln);
|
|
void ttix_clr_done (int32 ln);
|
|
t_stat ttox_svc (UNIT *uptr);
|
|
t_bool ttox_test_done (int32 ln);
|
|
void ttox_set_done (int32 ln);
|
|
void ttox_clr_done (int32 ln);
|
|
int32 ttx_getln (int32 dev, int32 pulse);
|
|
t_stat ttx_attach (UNIT *uptr, char *cptr);
|
|
t_stat ttx_detach (UNIT *uptr);
|
|
t_stat ttx_reset (DEVICE *dptr);
|
|
void ttx_reset_ln (int32 i);
|
|
t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc);
|
|
t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc);
|
|
t_stat ttx_vlines (UNIT *uptr, int32 val, char *cptr, void *desc);
|
|
|
|
/* TTIx data structures
|
|
|
|
ttix_dev TTIx device descriptor
|
|
ttix_unit TTIx unit descriptor
|
|
ttix_reg TTIx register list
|
|
ttix_mod TTIx modifiers list
|
|
*/
|
|
|
|
DIB ttix_dib = {
|
|
DEV_TTO1, 8, NULL,
|
|
{ &ttox, &ttix, &ttox, &ttix, &ttox, &ttix, &ttox, &ttix }
|
|
};
|
|
|
|
UNIT ttix_unit = { UDATA (&ttix_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
|
|
|
REG ttx_nlreg = { DRDATA (NLINES, ttx_lines, 4), PV_LEFT };
|
|
|
|
REG ttix_reg[] = {
|
|
{ BRDATA (BUF, ttix_buf, 8, 8, TTX_MAXL) },
|
|
{ ORDATA (DONE, ttix_done, TTX_MAXL) },
|
|
{ FLDATA (INT, int_hwre[API_TTI1], INT_V_TTI1) },
|
|
{ DRDATA (TIME, ttix_unit.wait, 24), REG_NZ + PV_LEFT },
|
|
{ ORDATA (DEVNUM, ttix_dib.dev, 6), REG_HRO },
|
|
{ NULL }
|
|
};
|
|
|
|
MTAB ttix_mod[] = {
|
|
{ MTAB_XTD | MTAB_VDV | MTAB_VAL, 0, "lines", "LINES",
|
|
&ttx_vlines, NULL, &ttx_nlreg },
|
|
{ UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &ttx_summ },
|
|
{ MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT",
|
|
&tmxr_dscln, NULL, &ttx_desc },
|
|
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL,
|
|
NULL, &ttx_show, NULL },
|
|
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL,
|
|
NULL, &ttx_show, NULL },
|
|
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
|
&set_devno, &show_devno, NULL },
|
|
{ 0 }
|
|
};
|
|
|
|
DEVICE tti1_dev = {
|
|
"TTIX", &ttix_unit, ttix_reg, ttix_mod,
|
|
1, 10, 31, 1, 8, 8,
|
|
&tmxr_ex, &tmxr_dep, &ttx_reset,
|
|
NULL, &ttx_attach, &ttx_detach,
|
|
&ttix_dib, DEV_NET | DEV_DISABLE
|
|
};
|
|
|
|
/* TTOx data structures
|
|
|
|
ttox_dev TTOx device descriptor
|
|
ttox_unit TTOx unit descriptor
|
|
ttox_reg TTOx register list
|
|
*/
|
|
|
|
UNIT ttox_unit[] = {
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT },
|
|
{ UDATA (&ttox_svc, TT_MODE_KSR+UNIT_DIS, 0), SERIAL_OUT_WAIT }
|
|
};
|
|
|
|
REG ttox_reg[] = {
|
|
{ BRDATA (BUF, ttox_buf, 8, 8, TTX_MAXL) },
|
|
{ ORDATA (DONE, ttox_done, TTX_MAXL) },
|
|
{ FLDATA (INT, int_hwre[API_TTO1], INT_V_TTO1) },
|
|
{ URDATA (TIME, ttox_unit[0].wait, 10, 24, 0,
|
|
TTX_MAXL, PV_LEFT) },
|
|
{ NULL }
|
|
};
|
|
|
|
MTAB ttox_mod[] = {
|
|
{ TT_MODE, TT_MODE_KSR, "KSR", "KSR", NULL },
|
|
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
|
|
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
|
|
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
|
|
{ MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT",
|
|
&tmxr_dscln, NULL, &ttx_desc },
|
|
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG",
|
|
&tmxr_set_log, &tmxr_show_log, &ttx_desc },
|
|
{ MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG",
|
|
&tmxr_set_nolog, NULL, &ttx_desc },
|
|
{ 0 }
|
|
};
|
|
|
|
DEVICE tto1_dev = {
|
|
"TTOX", ttox_unit, ttox_reg, ttox_mod,
|
|
TTX_MAXL, 10, 31, 1, 8, 8,
|
|
NULL, NULL, &ttx_reset,
|
|
NULL, NULL, NULL,
|
|
NULL, DEV_DISABLE
|
|
};
|
|
|
|
/* Terminal input: IOT routine */
|
|
|
|
int32 ttix (int32 dev, int32 pulse, int32 dat)
|
|
{
|
|
int32 ln = ttx_getln (dev, pulse); /* line # */
|
|
|
|
if (ln > ttx_lines) return dat;
|
|
if (pulse & 001) { /* KSF1 */
|
|
if (ttix_test_done (ln)) dat = dat | IOT_SKP;
|
|
}
|
|
if (pulse & 002) { /* KRB1 */
|
|
ttix_clr_done (ln); /* clear flag */
|
|
dat = dat | ttix_buf[ln]; /* return buffer */
|
|
}
|
|
return dat;
|
|
}
|
|
|
|
/* Unit service */
|
|
|
|
t_stat ttix_svc (UNIT *uptr)
|
|
{
|
|
int32 ln, c, temp;
|
|
|
|
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
|
|
sim_activate (uptr, tmxr_poll); /* continue poll */
|
|
ln = tmxr_poll_conn (&ttx_desc); /* look for connect */
|
|
if (ln >= 0) ttx_ldsc[ln].rcve = 1; /* got one? rcv enab */
|
|
tmxr_poll_rx (&ttx_desc); /* poll for input */
|
|
for (ln = 0; ln < TTX_MAXL; ln++) { /* loop thru lines */
|
|
if (ttx_ldsc[ln].conn) { /* connected? */
|
|
if (temp = tmxr_getc_ln (&ttx_ldsc[ln])) { /* get char */
|
|
if (temp & SCPE_BREAK) c = 0; /* break? */
|
|
else c = sim_tt_inpcvt (temp, TT_GET_MODE (ttox_unit[ln].flags));
|
|
ttix_buf[ln] = c;
|
|
ttix_set_done (ln);
|
|
}
|
|
}
|
|
}
|
|
return SCPE_OK;
|
|
}
|
|
|
|
/* Interrupt handling routines */
|
|
|
|
t_bool ttix_test_done (int32 ln)
|
|
{
|
|
if (ttix_done & (1 << ln)) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void ttix_set_done (int32 ln)
|
|
{
|
|
ttix_done = ttix_done | (1 << ln);
|
|
SET_INT (TTI1);
|
|
return;
|
|
}
|
|
|
|
void ttix_clr_done (int32 ln)
|
|
{
|
|
ttix_done = ttix_done & ~(1 << ln);
|
|
if (ttix_done) { SET_INT (TTI1); }
|
|
else {
|
|
CLR_INT (TTI1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* Terminal output: IOT routine */
|
|
|
|
int32 ttox (int32 dev, int32 pulse, int32 dat)
|
|
{
|
|
int32 ln = ttx_getln (dev, pulse); /* line # */
|
|
|
|
if (ln > ttx_lines) return dat;
|
|
if (pulse & 001) { /* TSF */
|
|
if (ttox_test_done (ln)) dat = dat | IOT_SKP;
|
|
}
|
|
if (pulse & 002) ttox_clr_done (ln); /* clear flag */
|
|
if (pulse & 004) { /* load buffer */
|
|
sim_activate (&ttox_unit[ln], ttox_unit[ln].wait); /* activate unit */
|
|
ttox_buf[ln] = dat & 0377; /* load buffer */
|
|
}
|
|
return dat;
|
|
}
|
|
|
|
/* Unit service */
|
|
|
|
t_stat ttox_svc (UNIT *uptr)
|
|
{
|
|
int32 c, ln = uptr - ttox_unit; /* line # */
|
|
|
|
if (ttx_ldsc[ln].conn) { /* connected? */
|
|
if (ttx_ldsc[ln].xmte) { /* tx enabled? */
|
|
TMLN *lp = &ttx_ldsc[ln]; /* get line */
|
|
c = sim_tt_outcvt (ttox_buf[ln], TT_GET_MODE (ttox_unit[ln].flags));
|
|
if (c >= 0) tmxr_putc_ln (lp, c); /* output char */
|
|
tmxr_poll_tx (&ttx_desc); /* poll xmt */
|
|
}
|
|
else {
|
|
tmxr_poll_tx (&ttx_desc); /* poll xmt */
|
|
sim_activate (uptr, ttox_unit[ln].wait); /* wait */
|
|
return SCPE_OK;
|
|
}
|
|
}
|
|
ttox_set_done (ln); /* set done */
|
|
return SCPE_OK;
|
|
}
|
|
|
|
/* Interrupt handling routines */
|
|
|
|
t_bool ttox_test_done (int32 ln)
|
|
{
|
|
if (ttox_done & (1 << ln)) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void ttox_set_done (int32 ln)
|
|
{
|
|
ttox_done = ttox_done | (1 << ln);
|
|
SET_INT (TTO1);
|
|
return;
|
|
}
|
|
|
|
void ttox_clr_done (int32 ln)
|
|
{
|
|
ttox_done = ttox_done & ~(1 << ln);
|
|
if (ttox_done) { SET_INT (TTO1); }
|
|
else { CLR_INT (TTO1); }
|
|
return;
|
|
}
|
|
|
|
/* Compute relative line number
|
|
|
|
This algorithm does not assign contiguous line numbers of ascending
|
|
LT19's. Rather, line numbers follow a simple progression based on
|
|
the relative IOT number and the subdevice select */
|
|
|
|
int32 ttx_getln (int32 dev, int32 pulse)
|
|
{
|
|
int32 rdno = ((dev - ttix_dib.dev) >> 1) & 3;
|
|
|
|
#if defined (PDP15) /* PDP-15? */
|
|
int32 sub = (pulse >> 4) & 3;
|
|
return (rdno * 4) + sub; /* use dev, subdev */
|
|
#else /* others */
|
|
return rdno; /* use dev only */
|
|
#endif
|
|
}
|
|
|
|
/* Reset routine */
|
|
|
|
t_stat ttx_reset (DEVICE *dptr)
|
|
{
|
|
int32 ln;
|
|
|
|
if (dptr->flags & DEV_DIS) { /* sync enables */
|
|
ttix_dev.flags = ttox_dev.flags | DEV_DIS;
|
|
ttox_dev.flags = ttox_dev.flags | DEV_DIS;
|
|
}
|
|
else {
|
|
ttix_dev.flags = ttix_dev.flags & ~DEV_DIS;
|
|
ttox_dev.flags = ttox_dev.flags & ~DEV_DIS;
|
|
}
|
|
if (ttix_unit.flags & UNIT_ATT) /* if attached, */
|
|
sim_activate (&ttix_unit, tmxr_poll); /* activate */
|
|
else sim_cancel (&ttix_unit); /* else stop */
|
|
for (ln = 0; ln < TTX_MAXL; ln++) ttx_reset_ln (ln); /* for all lines */
|
|
return SCPE_OK;
|
|
}
|
|
|
|
/* Reset line n */
|
|
|
|
void ttx_reset_ln (int32 ln)
|
|
{
|
|
ttix_buf[ln] = 0; /* clear buf, */
|
|
ttox_buf[ln] = 0;
|
|
ttix_clr_done (ln); /* clear done */
|
|
ttox_clr_done (ln);
|
|
sim_cancel (&ttox_unit[ln]); /* stop poll */
|
|
return;
|
|
}
|
|
|
|
/* Attach master unit */
|
|
|
|
t_stat ttx_attach (UNIT *uptr, char *cptr)
|
|
{
|
|
t_stat r;
|
|
|
|
r = tmxr_attach (&ttx_desc, uptr, cptr); /* attach */
|
|
if (r != SCPE_OK) return r; /* error */
|
|
sim_activate (uptr, tmxr_poll); /* start poll */
|
|
return SCPE_OK;
|
|
}
|
|
|
|
/* Detach master unit */
|
|
|
|
t_stat ttx_detach (UNIT *uptr)
|
|
{
|
|
int32 i;
|
|
t_stat r;
|
|
|
|
r = tmxr_detach (&ttx_desc, uptr); /* detach */
|
|
sim_cancel (uptr); /* stop poll */
|
|
for (i = 0; i < TTX_MAXL; i++) ttx_ldsc[i].rcve = 0; /* disable rcv */
|
|
return r;
|
|
}
|
|
|
|
/* Show summary processor */
|
|
|
|
t_stat ttx_summ (FILE *st, UNIT *uptr, int32 val, void *desc)
|
|
{
|
|
int32 i, t;
|
|
|
|
for (i = t = 0; i < TTX_MAXL; i++) t = t + (ttx_ldsc[i].conn != 0);
|
|
if (t == 1) fprintf (st, "1 connection");
|
|
else fprintf (st, "%d connections", t);
|
|
return SCPE_OK;
|
|
}
|
|
|
|
/* SHOW CONN/STAT processor */
|
|
|
|
t_stat ttx_show (FILE *st, UNIT *uptr, int32 val, void *desc)
|
|
{
|
|
int32 i, t;
|
|
|
|
for (i = t = 0; i < TTX_MAXL; i++) t = t + (ttx_ldsc[i].conn != 0);
|
|
if (t) {
|
|
for (i = 0; i < ttx_lines; i++) {
|
|
if (ttx_ldsc[i].conn) {
|
|
if (val) tmxr_fconns (st, &ttx_ldsc[i], i);
|
|
else tmxr_fstats (st, &ttx_ldsc[i], i);
|
|
}
|
|
}
|
|
}
|
|
else fprintf (st, "all disconnected\n");
|
|
return SCPE_OK;
|
|
}
|
|
|
|
/* Change number of lines */
|
|
|
|
t_stat ttx_vlines (UNIT *uptr, int32 val, char *cptr, void *desc)
|
|
{
|
|
int32 newln, i, t;
|
|
t_stat r;
|
|
|
|
if (cptr == NULL) return SCPE_ARG;
|
|
newln = get_uint (cptr, 10, TTX_MAXL, &r);
|
|
if ((r != SCPE_OK) || (newln == ttx_lines)) return r;
|
|
if (newln == 0) return SCPE_ARG;
|
|
if (newln < ttx_lines) {
|
|
for (i = newln, t = 0; i < ttx_lines; i++) t = t | ttx_ldsc[i].conn;
|
|
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
|
|
return SCPE_OK;
|
|
for (i = newln; i < ttx_lines; i++) {
|
|
if (ttx_ldsc[i].conn) {
|
|
tmxr_linemsg (&ttx_ldsc[i], "\r\nOperator disconnected line\r\n");
|
|
tmxr_reset_ln (&ttx_ldsc[i]); /* reset line */
|
|
}
|
|
ttox_unit[i].flags = ttox_unit[i].flags | UNIT_DIS;
|
|
ttx_reset_ln (i);
|
|
}
|
|
}
|
|
else {
|
|
for (i = ttx_lines; i < newln; i++) {
|
|
ttox_unit[i].flags = ttox_unit[i].flags & ~UNIT_DIS;
|
|
ttx_reset_ln (i);
|
|
}
|
|
}
|
|
ttx_lines = newln;
|
|
return SCPE_OK;
|
|
}
|
|
|
|
|