536 lines
21 KiB
Text
536 lines
21 KiB
Text
== Serial (Optional Add-On)
|
|
|
|
Declared in `<joey/serial.h>`.
|
|
|
|
[IMPORTANT]
|
|
====
|
|
This header is *not* pulled in by `<joey/joey.h>`. Include it explicitly:
|
|
|
|
[source,c]
|
|
----
|
|
#include <joey/joey.h>
|
|
#include <joey/serial.h>
|
|
----
|
|
|
|
A program that never references `jlSerial*` pays nothing -- the linker drops
|
|
the module entirely.
|
|
====
|
|
|
|
One byte-stream API spans every port while the HAL hides very different
|
|
hardware: the IIgs drives a Zilog 8530 SCC directly or a 6551 card in a slot;
|
|
DOS uses an interrupt-driven 8250/16550 UART; the Amiga uses `serial.device`;
|
|
the ST goes through the BIOS Aux channel; the X68000 transmits through IOCS
|
|
and receives on its own SCC interrupt; DVX goes through DVX's serial library,
|
|
which owns the COM ports for every program on the desktop (a port another
|
|
program has open cannot be opened); Win32 and Win16 go through Windows' own
|
|
communications calls, whose driver owns the ports the same way; SDL3 on Linux,
|
|
macOS, Haiku, and BeOS open the port as a terminal device through termios. The web and
|
|
the PSP have no serial port: `jlSerialOpen` fails there.
|
|
|
|
The model is *non-blocking and buffered*. Received bytes accumulate in a
|
|
background ring -- a hardware interrupt on DOS, the X68000, and the IIgs, the
|
|
OS on Amiga, ST, DVX, Windows, Linux, Haiku, and BeOS -- and reads never
|
|
block. Call `jlSerialPoll`
|
|
once per frame.
|
|
|
|
On the IIgs a Super Serial Card only interrupts with its interrupt switch
|
|
(SW2-6) on; with it off the card still works, drained by `jlSerialPoll`, but
|
|
loses what arrives while the program is busy.
|
|
|
|
On the Amiga the port is `serial.device`, which AmigaOS loads from `DEVS:`:
|
|
every Workbench installation has it, but Kickstart 3.1 on its own does not, so
|
|
a program booted without Workbench cannot open the port. `joey-run` puts the
|
|
installer's copy (component `amigaSerial`) on the boot drive; a game shipped
|
|
to boot on its own must do the same.
|
|
|
|
A failed `jlSerialOpen` is non-fatal: it returns `false` and every other call
|
|
becomes a safe no-op, exactly like a failed audio init.
|
|
|
|
=== What Can Lose Received Bytes
|
|
|
|
Every port receives into a small hardware buffer that an interrupt empties
|
|
into the ring. A byte is lost when that buffer fills before the interrupt
|
|
runs: when something keeps interrupts off, or keeps the CPU away from the
|
|
handler, for longer than the buffer lasts. A byte takes about 1 ms to arrive
|
|
at 9600 baud, so:
|
|
|
|
[cols="3,2,2", options="header"]
|
|
|===
|
|
|Port |Receive buffer |Lasts at 9600 baud
|
|
|IIgs modem and printer ports (Zilog 8530) |3 bytes |~3 ms
|
|
|IIgs Super Serial Card (6551) |1 byte |~1 ms
|
|
|DOS, 16550A UART |16 bytes, interrupt at 14 |~2 ms from the interrupt
|
|
|DOS, 8250 or 16450 UART |1 byte |~1 ms
|
|
|DVX |as DOS: DVX's library drives the same UARTs |as DOS
|
|
|Win32, Win16 |the UART's; Windows' driver empties it into a 4 KB queue |as DOS
|
|
|Amiga (Paula) |1 byte |~1 ms
|
|
|Atari ST (68901 MFP) |1 byte |~1 ms
|
|
|X68000 (Zilog 8530) |3 bytes |~3 ms
|
|
|===
|
|
|
|
At 19200 baud each lasts half as long, and so on.
|
|
|
|
A byte that arrives with a framing, parity, or overrun error is delivered as
|
|
it came on the IIgs, DOS, the X68000, Linux, Haiku, and BeOS (the port does
|
|
not ask the driver to check parity); on the other ports the system's driver
|
|
decides.
|
|
|
|
JoeyLib's own work is safe while a port is open, with one exception on the
|
|
X68000 (below). On the IIgs, where the
|
|
display and sound code masks interrupts for long stretches, opening a port
|
|
makes JoeyLib cut them into pieces of at most ~1.7 ms: the present and the
|
|
full-surface clear, the joystick read (~2.8 ms otherwise, with the stick at
|
|
full deflection), and the sound-effect calls into the NinjaTrackerPlus
|
|
replayer (~2.4 ms to start an effect, and a refill interrupt that tops up
|
|
every streaming effect that is due at once). A full-screen present gets about
|
|
5% slower; a joystick read costs about what it does with no port open, up to
|
|
~0.8 ms more with the stick in a corner, and can read one count different
|
|
from the same stick with no port open. With no port open all of these run as
|
|
before. The other ports mask interrupts only across a few register writes.
|
|
|
|
These can still lose bytes, and are the program's to schedule around:
|
|
|
|
* *Disk access.* On the IIgs, GS/OS holds interrupts off while it reads or
|
|
writes a 3.5-inch floppy: 65 to 220 ms at a time, measured. That is every
|
|
file call -- `jlFile*`, `jlSave*`, loading assets and sprite banks, and
|
|
`jlInit` unless `jlConfigT.noAudio` is set, since starting audio loads the
|
|
replayer from disk. The other ports' disk
|
|
access goes through the operating system and has not been measured; treat
|
|
it as a risk there too.
|
|
* *Starting a song on the IIgs.* `jlAudioPlayMod` loads the song's
|
|
instruments into the sound chip with interrupts off, roughly 12 ms per KB of
|
|
samples.
|
|
* *Music playing on the IIgs.* The replayer's tick runs as an interrupt
|
|
handler, and has not been measured with a port open.
|
|
* *A Super Serial Card above 2400 baud.* The IIgs's own interrupt handling can
|
|
outlast the 6551's single byte, so the card runs loss-free at 2400 and above
|
|
that relies on the protocol to recover. The built-in modem and printer ports
|
|
stay loss-free at 9600 through full-screen presents, clears, joystick reads,
|
|
and sound effects.
|
|
* *The IIgs's built-in ports above 9600 baud.* At 19200 the present's ~1.7 ms
|
|
stretches outlast the chip's 3 bytes, and a stream received through
|
|
full-screen presents loses about one byte in 70. From 38400 up a steady
|
|
stream keeps the 65816 in its interrupt handler until it ends, even with
|
|
nothing drawn: the program gets no time until then, and the 512-byte receive
|
|
buffer keeps the first 511 bytes. Those rates suit bursts that fit the
|
|
buffer, a protocol that paces its blocks (XMODEM's acknowledgements do), and
|
|
sending, which they do at full speed.
|
|
* *Per-scanline palettes on the X68000.* The port reloads its one hardware
|
|
palette as the beam scans, and a run of palette changes on consecutive lines
|
|
holds serial receive off for the whole run, about 32 microseconds a line.
|
|
Receive stays loss-free while such runs are under about 90 lines at 9600
|
|
baud, 40 at 19200, and 15 at 38400; palette changes three or more lines apart
|
|
release it between bands.
|
|
* *The program's own code*, wherever it masks interrupts.
|
|
|
|
Ways to live with them:
|
|
|
|
* Keep file access and `jlAudioPlayMod` out of the middle of a transfer: do
|
|
them between messages, or while the other end is waiting for a reply.
|
|
* Ask the other end to pause first. With hardware flow control, drop RTS with
|
|
`jlSerialSetRts(false)`, allow a few character times for bytes already on
|
|
the way, do the slow operation, then raise RTS again. With software flow
|
|
control, send XOFF and later XON.
|
|
* For data that must arrive intact, use a protocol with checksums and
|
|
retransmission; XMODEM and its descendants exist for exactly this.
|
|
|
|
=== Flow Control
|
|
|
|
`flow` in `jlSerialConfigT` picks the handshake, and every port with a serial
|
|
port honors it:
|
|
|
|
* `JL_SERIAL_FLOW_RTSCTS`: transmit waits while the peer holds CTS down, and
|
|
the port drops RTS when its receive buffer is three quarters full, raising
|
|
it again once reads have it down to a quarter.
|
|
* `JL_SERIAL_FLOW_XONXOFF`: the peer's XOFF and XON (0x13 and 0x11) pause and
|
|
resume transmit and never reach `jlSerialRead`, and the port sends XOFF
|
|
when its receive buffer is three quarters full and XON at a quarter.
|
|
|
|
The receive buffer, which also decides how long a program may go without
|
|
reading when there is no flow control:
|
|
|
|
[cols="3,2,2", options="header"]
|
|
|===
|
|
|Port |Receive buffer |Lasts at 9600 baud
|
|
|IIgs |512 bytes |~0.5 s
|
|
|DOS, DVX |2 KB |~2 s
|
|
|Amiga (`serial.device`) |4 KB |~4 s
|
|
|Atari ST (TOS's, enlarged while the port is open) |4 KB |~4 s
|
|
|X68000 |4 KB |~4 s
|
|
|Win32, Win16 (Windows' driver) |4 KB |~4 s
|
|
|===
|
|
|
|
Where they differ:
|
|
|
|
* The IIgs modem and printer ports' connector (mini-DIN-8) has no RTS line:
|
|
its one handshake output is DTR. RTS/CTS there makes transmit wait for CTS,
|
|
but nothing can tell the peer to pause, so receive needs XON/XOFF or a
|
|
protocol that paces itself. A Super Serial Card has RTS, and its 6551 also
|
|
stops its own transmitter while RTS is down.
|
|
* On the ST, the Amiga, Win32, and Win16 the operating system's driver does
|
|
the handshaking, and under RTS/CTS it may change RTS after
|
|
`jlSerialSetRts` did. DVX's library holds the peer off at four fifths full
|
|
and lets it go at a fifth.
|
|
* The X68000 drops RTS from its receive interrupt, but sends XOFF and XON
|
|
from `jlSerialPoll`, `jlSerialRead`, and `jlSerialWrite`: under XON/XOFF, a
|
|
program that calls none of them for longer than the last quarter of the
|
|
buffer lasts (about a second at 9600 baud) can still lose bytes.
|
|
|
|
=== Types
|
|
|
|
[source,c]
|
|
----
|
|
typedef enum {
|
|
JL_SERIAL_DEFAULT = 0, // the platform's natural RS-232 port
|
|
JL_SERIAL_MODEM, // IIgs modem port (SCC channel B)
|
|
JL_SERIAL_PRINTER, // IIgs printer port (SCC channel A)
|
|
JL_SERIAL_SLOT // card/port selected by config->unit
|
|
} jlSerialDeviceE;
|
|
|
|
typedef enum {
|
|
JL_SERIAL_PARITY_NONE = 0, JL_SERIAL_PARITY_ODD, JL_SERIAL_PARITY_EVEN
|
|
} jlSerialParityE;
|
|
|
|
typedef enum {
|
|
JL_SERIAL_FLOW_NONE = 0, // no handshaking
|
|
JL_SERIAL_FLOW_RTSCTS, // hardware RTS/CTS
|
|
JL_SERIAL_FLOW_XONXOFF // software XON/XOFF
|
|
} jlSerialFlowE;
|
|
|
|
typedef struct {
|
|
uint32_t baud; // 300 .. 115200; each port runs its nearest
|
|
uint8_t dataBits; // 5 .. 8
|
|
uint8_t stopBits; // 1 or 2
|
|
jlSerialParityE parity;
|
|
jlSerialFlowE flow;
|
|
uint8_t unit; // JL_SERIAL_SLOT only
|
|
} jlSerialConfigT;
|
|
----
|
|
|
|
A field left 0 takes a default: `baud` 9600, `dataBits` 8, and `stopBits` 1.
|
|
`jlSerialOpen` fails for `dataBits` outside 5 to 8, `stopBits` other than 1 or
|
|
2, or a `parity` or `flow` the enumerations do not name.
|
|
|
|
`baud` is the rate asked for. Each port runs at the nearest rate it has:
|
|
|
|
[cols="2,5", options="header"]
|
|
|===
|
|
|Port |Rates
|
|
|
|
|IIgs modem and printer ports
|
|
|115200 divided by a whole number: 115200 itself straight from the ports'
|
|
crystal, the rest from the SCC's baud rate generator. A rate between two of
|
|
those runs at the one above it, and anything faster at 115200.
|
|
|
|
|IIgs Super Serial Card
|
|
|The 6551's fifteen rates, 50 to 19200; any other runs at the fastest one
|
|
below it.
|
|
|
|
|DOS
|
|
|115200 divided by a whole number, up to 115200; a rate between two of those
|
|
runs at the one above it.
|
|
|
|
|DVX
|
|
|DVX's library's rates, 50 to 115200; any other runs at the fastest one below
|
|
it.
|
|
|
|
|Amiga
|
|
|The rate as asked, handed to `serial.device`.
|
|
|
|
|Atari ST
|
|
|The MFP's sixteen rates, 50 to 19200; any other runs at the fastest one below
|
|
it.
|
|
|
|
|X68000
|
|
|75 to 38400, each double the last (38400 is really 39062); any other runs at
|
|
the fastest one below it.
|
|
|
|
|Win32
|
|
|The rate as asked, handed to Windows' driver.
|
|
|
|
|Win16
|
|
|The rate as asked up to 57600; above that, see below.
|
|
|
|
|SDL3 (Linux), Haiku, BeOS
|
|
|The nearest of 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, and
|
|
115200, handed to the system's driver.
|
|
|===
|
|
|
|
The IIgs is the machine with three device choices; elsewhere `JL_SERIAL_MODEM`
|
|
and `JL_SERIAL_PRINTER` both mean the default port. `JL_SERIAL_DEFAULT` selects
|
|
the IIgs modem port; COM1 on DOS, DVX, Win32, and Win16; the ST Modem port;
|
|
Amiga unit 0; the X68000's RS-232C port; on Linux `/dev/ttyS0`; or on Haiku and
|
|
BeOS the first entry of `/dev/ports`. On Linux, Haiku, and BeOS the
|
|
`JOEYLIB_SERIAL` environment variable names another device for the default
|
|
(and the modem and printer) port: a USB adapter, `JOEYLIB_SERIAL=/dev/ttyUSB0`.
|
|
Haiku's and BeOS's drivers take 7 or 8 data bits only, so 5 or 6 fail the
|
|
open there.
|
|
|
|
On Win16 a `baud` above 57600 runs at 115200 through KPCOMM.DRV, the
|
|
communications driver JoeyLib's Windows runs with in place of Windows 3.1's
|
|
own (the `kpcomm` installer component, built from the mscomm project). On a
|
|
Windows with its own COMM.DRV, which has no 115200, it runs at 57600.
|
|
|
|
On the X68000 the serial add-on *requires* Human68k's RS-232C driver,
|
|
RSDRV.SYS. Every Human68k system disk has it and the stock CONFIG.SYS loads
|
|
it (`DEVICE = \SYS\RSDRV.SYS`), as do JoeyLib's own X68000 boot disks; a
|
|
game shipped to boot on its own must keep it. Without it `jlSerialOpen`
|
|
returns `false` and `jlLastError` says the driver is missing. With it the
|
|
port runs at 75 to 38400 bps. 38400 is really 39062 bps, 1.7% fast, within
|
|
the usual tolerance of a UART at the far end.
|
|
|
|
`unit` disambiguates `JL_SERIAL_SLOT` and is ignored otherwise: an IIgs Super
|
|
Serial Card slot 1..7, a DOS or DVX COM number 1..4, a Win16 COM number
|
|
1..9, a Win32 COM number 1..255, an Amiga `serial.device` unit, or on Linux
|
|
`/dev/ttyS<unit - 1>` and on Haiku and BeOS the unit'th entry of `/dev/ports`
|
|
in name order. On the ST family it is a port in TOS's Bconmap order: 1 the
|
|
Modem port, and on a Mega STe, TT, or Falcon 2 and up its other ports (a
|
|
Mega STe's SCC channel B, Modem 2, is 2 and its LAN port 3; a TT adds its
|
|
second MFP's port as 3 and has the LAN port at 4). The open maps TOS's AUX
|
|
device to that port and the close maps it back; a plain ST has unit 1 only.
|
|
The other devices open AUX wherever TOS has it, the Modem port unless the
|
|
user mapped it elsewhere. The X68000 has one port, and opens it for every
|
|
device, `JL_SERIAL_SLOT` included.
|
|
|
|
=== jlSerialOpen
|
|
|
|
[source,c]
|
|
----
|
|
bool jlSerialOpen(jlSerialDeviceE device, const jlSerialConfigT *config);
|
|
----
|
|
|
|
Opens and configures the port. Only one port may be open at a time; a second
|
|
open without an intervening close fails.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`device` |`jlSerialDeviceE` |Which interface.
|
|
|`config` |`const jlSerialConfigT *` |Line configuration.
|
|
|===
|
|
|
|
*Returns:* `true` on success. `false` if the port cannot be opened or the
|
|
platform has no serial support -- and then every other call no-ops. It is
|
|
also `false`, with `jlLastError` saying why, when no UART answers at the DOS
|
|
COM port, when no Super Serial Card answers in the IIgs slot, and when
|
|
RSDRV.SYS is not loaded on the X68000.
|
|
|
|
=== jlSerialClose
|
|
|
|
[source,c]
|
|
----
|
|
void jlSerialClose(void);
|
|
----
|
|
|
|
Closes the port and releases its resources. Safe when not open. A port still
|
|
open when the program exits is closed then: the first successful
|
|
`jlSerialOpen` registers an `atexit` handler, because on DOS, the X68000, and
|
|
the IIgs the port's receive interrupt vector points into the program until it
|
|
is closed. Bytes `jlSerialWrite` accepted are still sent, so a program can
|
|
write a farewell and close straight away. DOS, the ST, the X68000, Linux,
|
|
Haiku, and BeOS put back the speed and framing the port had before the open
|
|
(Linux, Haiku, and BeOS with HUPCL off, so the system's own last close keeps
|
|
DTR up); the IIgs (whose serial chip's settings cannot be read back) and DVX
|
|
leave it as JoeyLib set it.
|
|
|
|
Closing does *not* hang up: `jlSerialClose` leaves DTR exactly as it is, so
|
|
a modem call or a BBS caller survives the program handing the line back: a
|
|
door returning to its BBS, or a terminal program exiting while the call stays
|
|
up. RTS is not part of that promise; on the Amiga, `serial.device` puts back
|
|
whatever RTS was before the open.
|
|
|
|
Win32 cannot make the promise: the close gives the port back to Windows'
|
|
driver, which has no call that keeps DTR up past it, so a Win32 program that
|
|
must not hang up the line keeps the port open. Win16 keeps it through
|
|
KPCOMM.DRV, the communications driver JoeyLib's Windows runs with; with
|
|
Windows 3.1's own COMM.DRV it drops too.
|
|
|
|
To hang up, drop DTR first: call `jlSerialSetDtr(false)`, wait longer than
|
|
the modem needs to notice (a Hayes modem's S25 setting, 50 ms by default),
|
|
then close. The line stays down.
|
|
|
|
[NOTE]
|
|
====
|
|
Two ports cannot keep the line perfectly steady, though neither gap is long
|
|
enough to hang up a modem (a Hayes modem ignores DTR drops shorter than its
|
|
S25 setting, 50 ms by default):
|
|
|
|
* On the Amiga, when another program had the port open first, the last close
|
|
can drop DTR (`serial.device` puts back the lines as that program found
|
|
them), and JoeyLib raises it again straight away: the line is off for under
|
|
a millisecond. Otherwise JoeyLib raises DTR before its own open, so the
|
|
close keeps it up with no gap.
|
|
* On the IIgs, opening a port resets its channel, which drops DTR briefly
|
|
even if it was already up: about a quarter of a millisecond on the modem
|
|
and printer ports, about a millisecond on a Super Serial Card.
|
|
====
|
|
|
|
*Parameters:* none. *Returns:* nothing.
|
|
|
|
=== jlSerialPoll
|
|
|
|
[source,c]
|
|
----
|
|
void jlSerialPoll(void);
|
|
----
|
|
|
|
Pumps the receive and transmit buffers. Call once per game frame. Where an
|
|
interrupt fills the ring this does next to nothing; it is the drain for a port
|
|
that cannot interrupt.
|
|
|
|
*Parameters:* none. *Returns:* nothing.
|
|
|
|
=== jlSerialAvailable
|
|
|
|
[source,c]
|
|
----
|
|
uint16_t jlSerialAvailable(void);
|
|
----
|
|
|
|
*Parameters:* none.
|
|
|
|
*Returns:* the number of bytes waiting in the receive buffer, readable now
|
|
without blocking.
|
|
|
|
=== jlSerialRead
|
|
|
|
[source,c]
|
|
----
|
|
uint16_t jlSerialRead(uint8_t *buf, uint16_t max);
|
|
----
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`buf` |`uint8_t *` |Destination buffer.
|
|
|`max` |`uint16_t` |Buffer capacity.
|
|
|===
|
|
|
|
*Returns:* the number of bytes copied, 0 to `max`. Never blocks.
|
|
|
|
=== jlSerialWrite
|
|
|
|
[source,c]
|
|
----
|
|
uint16_t jlSerialWrite(const uint8_t *buf, uint16_t len);
|
|
----
|
|
|
|
Sends bytes without waiting long. Most ports feed the bytes to the line as it
|
|
takes them, and give up once it has taken none for 100 ms (a peer holding
|
|
transmit off, say). The Amiga queues them in two 1 KB buffers it sends from in
|
|
the background, DVX in its serial library's 2 KB ring, and Win16 in Windows'
|
|
driver's queue, so those never wait at all.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`buf` |`const uint8_t *` |Data to send.
|
|
|`len` |`uint16_t` |Byte count.
|
|
|===
|
|
|
|
*Returns:* the number of bytes accepted, which may be fewer than `len` if a
|
|
flow-controlled peer or a full transmit path stalls.
|
|
|
|
=== jlSerialWriteByte / jlSerialReadByte
|
|
|
|
[source,c]
|
|
----
|
|
bool jlSerialWriteByte(uint8_t b);
|
|
int16_t jlSerialReadByte(void);
|
|
----
|
|
|
|
Single-byte convenience calls.
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`b` |`uint8_t` |Byte to send.
|
|
|===
|
|
|
|
*Returns:* `jlSerialWriteByte` returns `true` if the byte was accepted.
|
|
`jlSerialReadByte` returns the byte, or `-1` when none is ready.
|
|
|
|
=== jlSerialFlush
|
|
|
|
[source,c]
|
|
----
|
|
void jlSerialFlush(void);
|
|
----
|
|
|
|
Discards any buffered received bytes.
|
|
|
|
*Parameters:* none. *Returns:* nothing.
|
|
|
|
=== jlSerialSetDtr
|
|
|
|
[source,c]
|
|
----
|
|
void jlSerialSetDtr(bool on);
|
|
----
|
|
|
|
Raises or drops DTR. `jlSerialOpen` raises DTR and `jlSerialClose` leaves it
|
|
as it is, so this is how a program hangs up:
|
|
|
|
[source,c]
|
|
----
|
|
jlSerialSetDtr(false); // hang up
|
|
// ...wait longer than the modem's DTR-drop detection time (Hayes S25,
|
|
// 50 ms by default)...
|
|
jlSerialClose(); // DTR stays down
|
|
----
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`on` |`bool` |`true` raises DTR, `false` drops it.
|
|
|===
|
|
|
|
*Returns:* nothing. A closed port no-ops, so this can be driven
|
|
unconditionally.
|
|
|
|
Two ports tie DTR to more than the line:
|
|
|
|
* On an IIgs Super Serial Card the 6551 has no DTR that is only a line:
|
|
dropping DTR also stops the card's receiver until DTR is raised again.
|
|
* On the X68000 the line setup in the ROM and in RSDRV.SYS raises DTR
|
|
whenever it runs, so the next `jlSerialOpen` -- or another program setting
|
|
the line -- raises it again.
|
|
|
|
On a Mega STe's, TT's, or Falcon's ports other than the Modem port (a
|
|
`JL_SERIAL_SLOT` open, or AUX mapped there) DTR stays as TOS set it: TOS has
|
|
no call for those ports' lines, and JoeyLib does not reach past its driver to
|
|
the SCC.
|
|
|
|
Closing after a hang-up keeps DTR down, but on two ports it rises briefly on
|
|
the way: on the Amiga for under a millisecond (`serial.device` puts back the
|
|
lines as they were at its open) and on the X68000 for about 0.2 ms (close puts
|
|
back the line settings, which raises DTR), before JoeyLib drops it again. A
|
|
modem that has hung up ignores that.
|
|
|
|
=== jlSerialSetRts
|
|
|
|
[source,c]
|
|
----
|
|
void jlSerialSetRts(bool on);
|
|
----
|
|
|
|
Asserts or drops RTS, for a caller doing its own receive-side flow control.
|
|
|
|
`JL_SERIAL_FLOW_RTSCTS` asks the *port* to handshake; this is the other half --
|
|
the application saying "my buffer is nearly full, stop sending", and later "go
|
|
ahead". That is what a client with a small ring and a peer that can be told to
|
|
pause actually needs. Under `JL_SERIAL_FLOW_RTSCTS` on DOS, the X68000, and a
|
|
IIgs Super Serial Card, RTS is up only while both the port's handshake and
|
|
this call want it; elsewhere the driver may change it again (see Flow
|
|
Control). The IIgs modem and printer ports have no RTS line on their
|
|
connector, so nothing reaches the peer there, and a Mega STe's, TT's, or
|
|
Falcon's ports other than the Modem port keep RTS as TOS sets it (as DTR).
|
|
|
|
[cols="1,1,4", options="header"]
|
|
|===
|
|
|Parameter |Type |Description
|
|
|`on` |`bool` |`true` asserts RTS, meaning ready to receive.
|
|
|===
|
|
|
|
*Returns:* nothing. A port with no controllable RTS line no-ops, and a closed
|
|
port no-ops; neither is an error, so this can be driven unconditionally.
|