1
0
mirror of https://github.com/simh/simh.git synced 2026-02-10 02:01:05 +00:00

Change to support serial ports on multiplexer devices without any changes to existing multiplexer device emulation code.

Added support for per line tcp listen ports.
Added support for per line outgoing tcp/telnet connections.

Removed DEV_NET from pdp11_dz and pdp11_vh emulators to allow proper restore of
This commit is contained in:
Mark Pizzolato
2012-10-17 08:40:01 -07:00
parent 24696892fd
commit 02cb620c9b
21 changed files with 2360 additions and 1405 deletions

View File

@@ -29,8 +29,6 @@
28-Mar-11 JDB Tidied up signal handling
26-Oct-10 JDB Changed I/O signal handler for revised signal model
25-Nov-08 JDB Revised for new multiplexer library SHOW routines
19-Nov-08 JDB [serial] Removed DEV_NET to allow restoration of listening port
17-Oct-08 JDB [serial] Added serial port support
11-Sep-08 JDB Fixed STC,C losing interrupt request on BREAK
07-Sep-08 JDB Fixed IN_LOOPBACK conflict with netinet/in.h
Changed Telnet poll to connect immediately after reset or attach
@@ -80,13 +78,13 @@
an "external rate" that is equivalent to 9600 baud, as most terminals were
set to their maximum speeds.
We support the 12966A connected to an HP terminal emulator via Telnet or a
serial port. Internally, we model the BACI as a terminal multiplexer with
one line. The simulation is complicated by the half-duplex nature of the
card (there is only one FIFO, used selectively either for transmission or
reception) and the double-buffered UART (a Western Digital TR1863A), which
has holding registers as well as a shift registers for transmission and
reception. We model both sets of device registers.
We support the 12966A connected to an HP terminal emulator via Telnet.
Internally, we model the BACI as a terminal multiplexer with one line. The
simulation is complicated by the half-duplex nature of the card (there is
only one FIFO, used selectively either for transmission or reception) and the
double-buffered UART (a Western Digital TR1863A), which has holding registers
as well as a shift registers for transmission and reception. We model both
sets of device registers.
During an output operation, the first character output to the card passes
through the FIFO and into the transmitter holding register. Subsequent
@@ -115,12 +113,12 @@
as an "optimized (fast) timing" option. Optimization makes three
improvements:
1. On output, characters in the FIFO are emptied into the line buffer as a
1. On output, characters in the FIFO are emptied into the Telnet buffer as a
block, rather than one character per service call, and on input, all of
the characters available in the line buffer are loaded into the FIFO as a
block.
the characters available in the Telnet buffer are loaded into the FIFO as
a block.
2. The ENQ/ACK handshake is done locally, without involving the terminal
2. The ENQ/ACK handshake is done locally, without involving the Telnet
client.
3. Input occurring during an output operation is delayed until the second or
@@ -320,7 +318,7 @@
/* Unit references */
#define baci_term baci_unit[0] /* terminal I/O unit */
#define baci_poll baci_unit[1] /* line polling unit */
#define baci_poll baci_unit[1] /* Telnet polling unit */
/* BACI state variables */
@@ -393,11 +391,11 @@ t_stat baci_detach (UNIT *uptr);
baci_deb BACI debug list
baci_dev BACI device descriptor
Two units are used: one to handle character I/O via the multiplexer library,
and another to poll for connections and input. The character I/O service
routine runs only when there are characters to read or write. It operates at
the approximate baud rate of the terminal (in CPU instructions per second) in
order to be compatible with the OS drivers. The line poll must run
Two units are used: one to handle character I/O via the Telnet library, and
another to poll for connections and input. The character I/O service routine
runs only when there are characters to read or write. It operates at the
approximate baud rate of the terminal (in CPU instructions per second) in
order to be compatible with the OS drivers. The Telnet poll must run
continuously, but it can operate much more slowly, as the only requirement is
that it must not present a perceptible lag to human input. To be compatible
with CPU idling, it is co-scheduled with the master poll timer, which uses a
@@ -406,14 +404,14 @@ t_stat baci_detach (UNIT *uptr);
DEVICE baci_dev;
TMLN baci_ldsc = { 0 }; /* line descriptor */
TMXR baci_desc = { 1, 0, 0, &baci_ldsc, NULL, &baci_dev }; /* device descriptor */
TMLN baci_ldsc = { 0 }; /* line descriptor */
TMXR baci_desc = { 1, 0, 0, &baci_ldsc }; /* device descriptor */
DIB baci_dib = { &baci_io, BACI, 0 };
UNIT baci_unit[] = {
{ UDATA (&baci_term_svc, UNIT_ATTABLE | UNIT_FASTTIME, 0) }, /* terminal I/O unit */
{ UDATA (&baci_poll_svc, UNIT_DIS, POLL_FIRST) } /* line poll unit */
{ UDATA (&baci_poll_svc, UNIT_DIS, POLL_FIRST) } /* Telnet poll unit */
};
REG baci_reg[] = {
@@ -771,7 +769,7 @@ return stat_data;
The terminal service routine is used to transmit and receive characters.
In terminal mode, it is started when a character is ready for output or when
the line poll routine determines that there are characters ready for input
the Telnet poll routine determines that there are characters ready for input
and stopped when there are no more characters to output or input. When the
terminal is quiescent, this routine does not run.
@@ -811,11 +809,11 @@ return stat_data;
first character after an ENQ is not an ACK.
Finally, fast timing enables buffer combining. For output, all characters
present in the FIFO are unloaded into the line buffer before initiating a
packet send. For input, all characters present in the line buffer are loaded
into the FIFO. This reduces network traffic and decreases simulator overhead
(there is only one service routine entry per block, rather than one per
character).
present in the FIFO are unloaded into the Telnet buffer before initiating a
packet send. For input, all characters present in the Telnet buffer are
loaded into the FIFO. This reduces network traffic and decreases simulator
overhead (there is only one service routine entry per block, rather than one
per character).
In fast output mode, it is imperative that not less than 1500 instructions
elapse between the first character load to the FIFO and the initiation of
@@ -978,11 +976,12 @@ return status;
}
/* BACI line poll service.
/* BACI Telnet poll service.
This service routine is used to poll for connections and incoming characters.
If characters are available, the terminal I/O service routine is scheduled.
It starts when the line is attached and stops when the line is detached.
This service routine is used to poll for Telnet connections and incoming
characters. If characters are available, the terminal I/O service routine is
scheduled. It starts when the socket is attached and stops when the socket
is detached.
As there is only one line, we only poll for a new connection when the line is
disconnected.
@@ -1029,57 +1028,42 @@ baci_term.wait = service_time (baci_icw); /* set terminal I/O time
if (baci_term.flags & UNIT_ATT) { /* device attached? */
baci_poll.wait = POLL_FIRST; /* set up poll */
sim_activate (&baci_poll, baci_poll.wait); /* start line poll immediately */
sim_activate (&baci_poll, baci_poll.wait); /* start Telnet poll immediately */
}
else
sim_cancel (&baci_poll); /* else stop line poll */
sim_cancel (&baci_poll); /* else stop Telnet poll */
return SCPE_OK;
}
/* Attach line */
/* Attach controller */
t_stat baci_attach (UNIT *uptr, char *cptr)
{
t_stat status = SCPE_OK;
if (uptr->flags & UNIT_DIS) /* unit disabled? */
return SCPE_UDIS; /* report it */
status = tmxr_attach (&baci_desc, uptr, cptr); /* attach to socket */
status = tmxr_attach (&baci_desc, uptr, cptr); /* try to attach to socket */
if (status == SCPE_ARG) /* invalid numeric port supplied? */
status = tmxr_attach_line (uptr, 0, cptr, &baci_desc); /* try to attach to serial port */
if (status == SCPE_OK) { /* attach successful? */
baci_poll.wait = POLL_FIRST; /* set up poll */
sim_activate (&baci_poll, baci_poll.wait); /* start line poll immediately */
if (status == SCPE_OK) {
baci_poll.wait = POLL_FIRST; /* set up poll */
sim_activate (&baci_poll, baci_poll.wait); /* start Telnet poll immediately */
}
return status;
}
/* Detach line */
/* Detach controller */
t_stat baci_detach (UNIT *uptr)
{
t_stat status;
if (uptr->flags & UNIT_DIS) /* unit disabled? */
return SCPE_UDIS; /* report it */
status = tmxr_detach_line (uptr, 0, NULL, &baci_desc); /* attempt to detach serial line */
if (status == SCPE_UNATT) /* not attached to serial? */
status = tmxr_detach (&baci_desc, uptr); /* attempt to detach listening socket */
status = tmxr_detach (&baci_desc, uptr); /* detach socket */
baci_ldsc.rcve = 0; /* disable line reception */
sim_cancel (&baci_poll); /* stop line poll */
sim_cancel (&baci_poll); /* stop Telnet poll */
return status;
}
/* Local routines */

View File

@@ -32,7 +32,6 @@
27-Oct-10 JDB Revised I/O signal enum values for concurrent signals
Revised I/O macros for new signal handling
09-Oct-10 JDB Added DA and DC device select code assignments
21-Oct-08 JDB [serial] Added "sim_unit_ref" external
07-Sep-08 JDB Added POLL_FIRST to indicate immediate connection attempt
15-Jul-08 JDB Rearranged declarations with hp2100_cpu.h
26-Jun-08 JDB Rewrote device I/O to model backplane signals
@@ -457,11 +456,10 @@ extern uint32 dev_prl [2], dev_irq [2], dev_srq [2]; /* I/O signal vectors */
/* Simulator state */
extern FILE *sim_deb;
extern FILE *sim_log;
extern int32 sim_step;
extern int32 sim_switches;
extern UNITREF sim_unit_ref;
extern FILE *sim_deb;
extern FILE *sim_log;
extern int32 sim_step;
extern int32 sim_switches;
/* CPU functions */

View File

@@ -29,9 +29,7 @@
28-Mar-11 JDB Tidied up signal handling
26-Oct-10 JDB Changed I/O signal handler for revised signal model
25-Nov-08 JDB Revised for new multiplexer library SHOW routines
19-Nov-08 JDB [serial] Removed DEV_NET to allow restoration of listening port
14-Nov-08 JDB Cleaned up VC++ size mismatch warnings for zero assignments
20-Oct-08 JDB [serial] Added serial port support
03-Oct-08 JDB Fixed logic for ENQ/XOFF transmit wait
07-Sep-08 JDB Changed Telnet poll to connect immediately after reset or attach
10-Aug-08 JDB Added REG_FIT to register variables < 32-bit size
@@ -59,8 +57,8 @@
character editing, echoing, ENQ/ACK handshaking, and read terminator
detection, substantially reducing the load on the CPU over the earlier 12920
multiplexer. It was supported by HP under RTE-MIII, RTE-IVB, and RTE-6/VM.
Under simulation, it connects with HP terminal emulators via Telnet or serial
ports.
Under simulation, it connects with HP terminal emulators via Telnet to a
user-specified port.
The single interface card contained a Z80 CPU, DMA controller, CTC, four
two-channel SIO UARTs, 16K of RAM, 8K of ROM, and I/O backplane latches and
@@ -201,7 +199,7 @@
#define MPX_CNTLS 2 /* number of control units */
#define mpx_cntl (mpx_unit [MPX_PORTS + 0]) /* controller unit */
#define mpx_poll (mpx_unit [MPX_PORTS + 1]) /* polling unit */
#define mpx_poll (mpx_unit [MPX_PORTS + 1]) /* Telnet polling unit */
/* Character constants */
@@ -613,16 +611,16 @@ t_stat mpx_show_frev (FILE *st, UNIT *uptr, int32 val, void *desc);
mpx_dev MPX device descriptor
The first eight units correspond to the eight multiplexer line ports. These
handle character I/O via the multiplexer library. A ninth unit acts as the
card controller, executing commands and transferring data to and from the I/O
buffers. A tenth unit is responsible for polling for connections and line
I/O. It also holds the master socket for Telnet connections.
handle character I/O via the Telnet library. A ninth unit acts as the card
controller, executing commands and transferring data to and from the I/O
buffers. A tenth unit is responsible for polling for connections and socket
I/O. It also holds the master socket.
The character I/O service routines run only when there are characters to read
or write. They operate at the approximate baud rates of the terminals (in
CPU instructions per second) in order to be compatible with the OS drivers.
The controller service routine runs only when a command is executing or a
data transfer to or from the CPU is in progress. The poll service must run
data transfer to or from the CPU is in progress. The Telnet poll must run
continuously, but it may operate much more slowly, as the only requirement is
that it must not present a perceptible lag to human input. To be compatible
with CPU idling, it is co-scheduled with the master poll timer, which uses a
@@ -634,9 +632,9 @@ t_stat mpx_show_frev (FILE *st, UNIT *uptr, int32 val, void *desc);
DEVICE mpx_dev;
int32 mpx_order [MPX_PORTS] = { -1 }; /* connection order */
TMLN mpx_ldsc [MPX_PORTS] = { { 0 } }; /* line descriptors */
TMXR mpx_desc = { MPX_PORTS, 0, 0, mpx_ldsc, mpx_order, &mpx_dev }; /* device descriptor */
int32 mpx_order [MPX_PORTS] = { -1 }; /* connection order */
TMLN mpx_ldsc [MPX_PORTS] = { { 0 } }; /* line descriptors */
TMXR mpx_desc = { MPX_PORTS, 0, 0, mpx_ldsc, mpx_order }; /* device descriptor */
DIB mpx_dib = { &mpx_io, MPX };
@@ -650,7 +648,7 @@ UNIT mpx_unit [] = {
{ UDATA (&mpx_line_svc, UNIT_FASTTIME, 0) }, /* terminal I/O line 6 */
{ UDATA (&mpx_line_svc, UNIT_FASTTIME, 0) }, /* terminal I/O line 7 */
{ UDATA (&mpx_cntl_svc, UNIT_DIS, 0) }, /* controller unit */
{ UDATA (&mpx_poll_svc, UNIT_ATTABLE | UNIT_DIS, POLL_FIRST) } /* line poll unit */
{ UDATA (&mpx_poll_svc, UNIT_ATTABLE | UNIT_DIS, POLL_FIRST) } /* Telnet poll unit */
};
REG mpx_reg [] = {
@@ -1604,20 +1602,21 @@ return SCPE_OK;
/* Multiplexer line service.
The line service routine is used to transmit and receive characters. It is
started when a buffer is ready for output or when the poll service routine
started when a buffer is ready for output or when the Telnet poll routine
determines that there are characters ready for input, and it is stopped when
there are no more characters to output or input. When a line is quiescent,
this routine does not run. Service times are selected to approximate the
baud rate setting of the multiplexer port.
"Fast timing" mode enables three optimizations. First, buffered characters
are transferred in blocks, rather than a character at a time; this reduces
line traffic and decreases simulator overhead (there is only one service
routine entry per block, rather than one per character). Second, ENQ/ACK
handshaking is done locally, without involving the client. Third, when
editing and echo is enabled, entering BS echoes a backspace, a space, and a
backspace, and entering DEL echoes a backslash, a carriage return, and a line
feed, providing better compatibility with prior RTE terminal drivers.
are transferred via Telnet in blocks, rather than a character at a time; this
reduces network traffic and decreases simulator overhead (there is only one
service routine entry per block, rather than one per character). Second,
ENQ/ACK handshaking is done locally, without involving the Telnet client.
Third, when editing and echo is enabled, entering BS echoes a backspace, a
space, and a backspace, and entering DEL echoes a backslash, a carriage
return, and a line feed, providing better compatibility with prior RTE
terminal drivers.
Each read and write buffer begins with a reserved header byte that stores
per-buffer information, such as whether handshaking should be suppressed
@@ -1631,7 +1630,7 @@ return SCPE_OK;
write buffer is freed, and a UI check is made if the controller is idle, in
case a write buffer request is pending.
For input, the character is retrieved from the line buffer. If a BREAK was
For input, the character is retrieved from the Telnet buffer. If a BREAK was
received, break status is set, and the character is discarded (the current
multiplexer library implementation always returns a NUL with a BREAK
indication). If the character is an XOFF, and XON/XOFF pacing is enabled, a
@@ -1940,11 +1939,11 @@ return SCPE_OK;
}
/* Poll service.
/* Telnet poll service.
This service routine is used to poll for connections and incoming characters.
It is started when the listening socket or a serial line is attached and is
stopped when the socket and all lines are detached.
This service routine is used to poll for Telnet connections and incoming
characters. It starts when the socket is attached and stops when the socket
is detached.
Each line is then checked for a pending ENQ/ACK handshake. If one is
pending, the ACK counter is incremented, and if it times out, another ENQ is
@@ -2008,10 +2007,10 @@ return SCPE_OK;
1. Under simulation, we also clear the input buffer register, even though
the hardware doesn't.
2. We set up the first poll for connections to occur "immediately" upon
execution, so that clients will be connected before execution begins.
Otherwise, a fast program may access the multiplexer before the poll
service routine activates.
2. We set up the first poll for Telnet connections to occur "immediately"
upon execution, so that clients will be connected before execution
begins. Otherwise, a fast program may access the multiplexer before the
poll service routine activates.
3. We must set the "emptying_flags" and "filling_flags" values here, because
they cannot be initialized statically, even though the values are
@@ -2031,129 +2030,83 @@ IOPRESET (&mpx_dib); /* PRESET device (does n
mpx_ibuf = 0; /* clear input buffer */
if (tmxr_mux_free (&mpx_desc)) /* any lines attached? */
sim_cancel (&mpx_poll); /* no, so stop poll */
else { /* attached or listening */
if (mpx_poll.flags & UNIT_ATT) { /* network attached? */
mpx_poll.wait = POLL_FIRST; /* set up poll */
sim_activate (&mpx_poll, mpx_poll.wait); /* start poll immediately */
sim_activate (&mpx_poll, mpx_poll.wait); /* start Telnet poll immediately */
}
else
sim_cancel (&mpx_poll); /* else stop Telnet poll */
return SCPE_OK;
}
/* Attach the multiplexer or a line.
/* Attach the multiplexer to a Telnet port.
We are called by the ATTACH MPX <port> command to attach the multiplexer to
the listening port indicated by <port> and by ATTACH MPX<n> <ser> to attach
line <n> to serial port <ser>. Logically, it is the multiplexer device that
is attached; however, SIMH only allows units to be attached. This makes
sense for devices such as tape drives, where the attached media is a property
of a specific drive. In our case, though, the listening port is a property
of the multiplexer card, not of any given serial line.
the listening port indicated by <port>. Logically, it is the multiplexer
device that is attached; however, SIMH only allows units to be attached.
This makes sense for devices such as tape drives, where the attached media is
a property of a specific drive. In our case, though, the listening port is a
property of the multiplexer card, not of any given serial line. As ATTACH
MPX is equivalent to ATTACH MPX0, the port would, by default, be attached to
the first serial line and be reported there in a SHOW MPX command.
To preserve the logical picture, we attach the listening port to the poll
unit (unit 9), which is normally disabled to inhibit its display. Serial
ports are attached to line units 0-7 normally. Attachment is reported by the
"mpx_status" routine below.
To preserve the logical picture, we attach the port to the Telnet poll unit,
which is normally disabled to inhibit its display. Attaching to a disabled
unit is not allowed, so we first enable the unit, then attach it, then
disable it again. Attachment is reported by the "mpx_status" routine below.
The connection poll service routine is synchronized with the other input
polling devices in the simulator to facilitate idling.
Implementation notes:
1. ATTACH MPX will pass a pointer unit 0. This is because the common
simulator code treats ATTACH MPX as equivalent to ATTACH MPX0. We
differentiate these cases by examining the "sim_unit_ref" global to see
if a device was referenced.
2. Directly attempting to attach to units 8 (controller) or 9 (poll) will be
rejected.
3. If we are being called as part of RESTORE processing, we may see a
request to attach the poll unit (unit 9). This will occur if unit 9 was
attached when the SAVE was done. In this case, the SIM_SW_REST flag will
be set in "sim_switches", and we will allow the call to succeed.
4. If the poll unit is attached, it will be enabled as part of RESTORE
processing. We always unilaterally disable this unit to ensure that it
remains hidden.
The Telnet poll service routine is synchronized with the other input polling
devices in the simulator to facilitate idling.
*/
t_stat mpx_attach (UNIT *uptr, char *cptr)
{
t_stat status = SCPE_OK;
if ((uptr == &mpx_cntl) || /* attaching controller? */
(uptr == &mpx_poll) && !(sim_switches & SIM_SW_REST)) /* or poll unit directly? */
return SCPE_NOATT; /* disallow */
if (uptr != mpx_unit) /* not unit 0? */
return SCPE_NOATT; /* can't attach */
if (sim_unit_ref == ref_dev || (uptr == &mpx_poll)) { /* device attach or poll restore request? */
status = tmxr_attach (&mpx_desc, &mpx_poll, cptr); /* attach to socket */
mpx_poll.flags = mpx_poll.flags | UNIT_DIS; /* disable unit */
}
else /* line attach request */
status = tmxr_attach_line (uptr, 0, cptr, &mpx_desc); /* attach line */
mpx_poll.flags = mpx_poll.flags & ~UNIT_DIS; /* enable unit */
status = tmxr_attach (&mpx_desc, &mpx_poll, cptr); /* attach to socket */
mpx_poll.flags = mpx_poll.flags | UNIT_DIS; /* disable unit */
if (status == SCPE_OK) {
mpx_poll.wait = POLL_FIRST; /* set up poll */
sim_activate (&mpx_poll, mpx_poll.wait); /* start poll immediately */
mpx_poll.wait = POLL_FIRST; /* set up poll */
sim_activate (&mpx_poll, mpx_poll.wait); /* start poll immediately */
}
return status;
}
/* Detach the multiplexer or a line.
/* Detach the multiplexer.
We are called by the DETACH MPX command to detach the listening port and all
Telnet sessions and by the DETACH MPX<n> to detach a serial port from line
<n>. We will also be called by DETACH ALL, RESTORE, and during simulator
shutdown. For DETACH ALL and RESTORE, we must not fail the call, or
processing of other units will cease.
Implementation notes:
Normally, we are called by the DETACH MPX command, which is equivalent to
DETACH MPX0. However, we may be called with other units in two cases.
1. Because DETACH MPX will pass unit 0, we check the "sim_unit_ref" global
to see if MPX or MPX0 was specified in the command.
2. Directly attempting to detach unit 8 (controller) will be rejected. We
cannot fail a direct DETACH MPX9 (poll unit), because we cannot tell that
case apart from a DETACH ALL (a RESTORE will have the SIM_SW_REST flag
set in "sim_switches").
3. During simulator shutdown, we will be called for units 0-8 (detach_all in
scp.c calls the detach routines of all units that do NOT have
UNIT_ATTABLE), as well as for unit 9 if it is attached.
A DETACH ALL command will call us for unit 9 (the poll unit) if it is
attached. Also, during simulator shutdown, we will be called for units 0-8
(detach_all in scp.c calls the detach routines of all units that do NOT have
UNIT_ATTABLE), as well as for unit 9 if it is attached. In both cases, it is
imperative that we return SCPE_OK, otherwise any remaining device detaches
will not be performed.
*/
t_stat mpx_detach (UNIT *uptr)
{
uint32 ln;
t_stat status;
t_bool mux_free = TRUE;
t_stat status = SCPE_OK;
int32 i;
if (uptr == &mpx_cntl) /* detaching controller directly? */
return SCPE_NOATT; /* disallow */
if ((uptr == mpx_unit) || (uptr == &mpx_poll)) { /* base unit or poll unit? */
status = tmxr_detach (&mpx_desc, &mpx_poll); /* detach socket */
if (sim_unit_ref == ref_dev || uptr == &mpx_poll) /* device detach or detach all request? */
status = tmxr_detach (&mpx_desc, &mpx_poll); /* detach socket */
for (i = 0; i < MPX_PORTS; i++) {
mpx_ldsc [i].rcve = 0; /* disable line reception */
sim_cancel (&mpx_unit [i]); /* cancel any scheduled I/O */
}
else /* line detach request */
status = tmxr_detach_line (uptr, 0, NULL, &mpx_desc); /* detach line */
if (status == SCPE_OK) {
for (ln = 0; ln < MPX_PORTS; ln++) /* loop through lines */
if (tmxr_line_free (&mpx_ldsc[ln])) { /* is line free? */
mpx_ldsc[ln].rcve = 0; /* disable rcv as line was reset */
sim_cancel (&mpx_unit [ln]); /* cancel any scheduled I/O */
}
else
mux_free = FALSE; /* mux isn't free if line is in use */
if (mux_free && !(mpx_poll.flags & UNIT_ATT)) /* all lines free and not listening? */
sim_cancel (&mpx_poll); /* stop poll */
sim_cancel (&mpx_poll); /* stop Telnet poll */
}
return status;
@@ -2214,7 +2167,7 @@ return SCPE_OK;
/* Local routines */
/* Poll for new connections */
/* Poll for new Telnet connections */
static void poll_connection (void)
{

View File

@@ -29,8 +29,6 @@
28-Mar-11 JDB Tidied up signal handling
26-Oct-10 JDB Changed I/O signal handler for revised signal model
25-Nov-08 JDB Revised for new multiplexer library SHOW routines
19-Nov-08 JDB [serial] Removed DEV_NET to allow restoration of listening port
20-Oct-08 JDB [serial] Added serial port support
09-Oct-08 JDB "muxl_unit" defined one too many units (17 instead of 16)
10-Sep-08 JDB SHOW MUX CONN/STAT with SET MUX DIAG is no longer disallowed
07-Sep-08 JDB Changed Telnet poll to connect immediately after reset or attach
@@ -329,7 +327,6 @@ t_stat muxo_svc (UNIT *uptr);
t_stat muxc_reset (DEVICE *dptr);
t_stat mux_attach (UNIT *uptr, char *cptr);
t_stat mux_detach (UNIT *uptr);
t_stat muxl_detach (UNIT *uptr);
t_stat mux_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc);
@@ -433,8 +430,8 @@ DEVICE muxl_dev = {
NULL, /* deposit routine */
&muxc_reset, /* reset routine */
NULL, /* boot routine */
&mux_attach, /* attach routine */
&muxl_detach, /* detach routine */
NULL, /* attach routine */
NULL, /* detach routine */
&muxl_dib, /* device information block */
DEV_DISABLE, /* device flags */
0, /* debug control flags */
@@ -459,9 +456,9 @@ DEVICE muxl_dev = {
DEVICE muxu_dev;
int32 mux_order [MUX_LINES] = { -1 }; /* connection order */
TMLN mux_ldsc [MUX_LINES] = { { 0 } }; /* line descriptors */
TMXR mux_desc = { MUX_LINES, 0, 0, mux_ldsc, mux_order, &muxu_dev }; /* device descriptor */
int32 mux_order [MUX_LINES] = { -1 }; /* connection order */
TMLN mux_ldsc [MUX_LINES] = { { 0 } }; /* line descriptors */
TMXR mux_desc = { MUX_LINES, 0, 0, mux_ldsc, mux_order }; /* device descriptor */
UNIT muxu_unit = { UDATA (&muxi_svc, UNIT_ATTABLE, 0), POLL_FIRST };
@@ -923,7 +920,7 @@ while (working_set) {
(old & DTR) && /* DTR drop? */
!(muxc_ota[ln] & DTR)) {
tmxr_linemsg (&mux_ldsc[ln], "\r\nLine hangup\r\n");
tmxr_clear_ln (&mux_desc, &mux_ldsc[ln]); /* disconnect line */
tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */
muxc_lia[ln] = 0; /* dataset off */
}
} /* end update */
@@ -1308,12 +1305,12 @@ IOPRESET (dibptr); /* PRESET device (does n
muxc_chan = muxc_scan = 0; /* init modem scan */
if (tmxr_mux_free (&mux_desc)) /* any lines attached? */
sim_cancel (&muxu_unit); /* no, so stop poll */
else { /* attached or listening */
if (muxu_unit.flags & UNIT_ATT) { /* master att? */
muxu_unit.wait = POLL_FIRST; /* set up poll */
sim_activate (&muxu_unit, muxu_unit.wait); /* start poll immediately */
sim_activate (&muxu_unit, muxu_unit.wait); /* start Telnet poll immediately */
}
else
sim_cancel (&muxu_unit); /* else stop */
for (i = 0; i < MUX_LINES; i++)
mux_reset_ln (i); /* reset lines 0-15 */
@@ -1325,23 +1322,20 @@ return SCPE_OK;
}
/* Attach master unit or line */
/* Attach master unit */
t_stat mux_attach (UNIT *uptr, char *cptr)
{
t_stat status = SCPE_OK;
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
return SCPE_NOFNC; /* command not allowed */
if (muxu_unit.flags & UNIT_DIAG) /* diag mode? */
return SCPE_NOFNC; /* command not allowed */
if (uptr == &muxu_unit) /* master unit? */
status = tmxr_attach (&mux_desc, uptr, cptr); /* attach socket */
else
status = tmxr_attach_line (uptr, 0, cptr, &mux_desc); /* attach line */
status = tmxr_attach (&mux_desc, uptr, cptr); /* attach */
if (status == SCPE_OK) { /* attach successful? */
muxu_unit.wait = POLL_FIRST; /* set up poll */
sim_activate (&muxu_unit, muxu_unit.wait); /* start poll immediately */
if (status == SCPE_OK) {
muxu_unit.wait = POLL_FIRST; /* set up poll */
sim_activate (&muxu_unit, muxu_unit.wait); /* start Telnet poll immediately */
}
return status;
@@ -1352,45 +1346,13 @@ return status;
t_stat mux_detach (UNIT *uptr)
{
uint32 ln;
t_stat status;
t_bool free = TRUE;
int32 i;
t_stat r;
status = tmxr_detach (&mux_desc, uptr); /* detach unit */
if (status == SCPE_OK) {
for (ln = 0; ln < MUX_LINES; ln++) /* loop through lines */
if (tmxr_line_free (&mux_ldsc[ln])) /* is line free? */
mux_ldsc[ln].rcve = 0; /* yes, so disable rcv as line was reset */
else
free = FALSE; /* mux isn't free if line is in use */
if (free) /* all lines free? */
sim_cancel (uptr); /* stop poll */
}
return status;
}
/* Detach line */
t_stat muxl_detach (UNIT *uptr)
{
uint32 ln;
t_stat status;
status = tmxr_detach_line (uptr, 0, NULL, &mux_desc); /* detach line */
if (status == SCPE_OK) {
ln = uptr - muxl_unit; /* determine line number */
mux_ldsc[ln].rcve = 0; /* disable line reception */
if (tmxr_mux_free (&mux_desc)) /* all lines free and not listening? */
sim_cancel (&muxu_unit); /* stop poll */
}
return status;
r = tmxr_detach (&mux_desc, uptr); /* detach */
for (i = 0; i < MUX_LINES; i++) mux_ldsc[i].rcve = 0; /* disable rcv */
sim_cancel (uptr); /* stop poll */
return r;
}
@@ -1405,7 +1367,7 @@ return status;
for normal character transfers, which is undesirable.
Therefore, to enable diagnostic mode, we must force a disconnect of the
master socket and all Telnet and serial lines, which clears the connection
master socket and any connected Telnet lines, which clears the connection
flags on all lines. Then we set the "transmission enabled" flags on all
lines to enable output character processing for the diagnostic. (Normally,
all of the flags are set when the multiplexer is first attached. Until then,
@@ -1418,12 +1380,9 @@ t_stat mux_setdiag (UNIT *uptr, int32 val, char *cptr, void *desc)
int32 ln;
if (val) { /* set diag? */
mux_detach (uptr); /* detach Telnet lines */
for (ln = 0; ln < MUX_LINES; ln++) {
muxl_detach (&muxl_unit[ln]); /* detach all serial lines */
mux_ldsc[ln].xmte = 1; /* enable transmission on all lines */
}
mux_detach (uptr); /* detach lines */
for (ln = 0; ln < MUX_LINES; ln++) /* enable transmission */
mux_ldsc[ln].xmte = 1; /* on all lines */
}
else { /* set term */
for (ln = 0; ln < MUX_LINES; ln++) /* clear connections */