104 lines
4.3 KiB
C
104 lines
4.3 KiB
C
// Serial communications add-on -- portable RS-232 byte streams.
|
|
//
|
|
// OPTIONAL add-on: this header is NOT pulled in by <joey/joey.h>. Include it
|
|
// explicitly. An app that never references jlSerial* pays nothing -- the
|
|
// linker drops the module (archive granularity / IIgs dead-strip).
|
|
//
|
|
// One byte-stream API spans every port; the per-port HAL hides the very
|
|
// different hardware:
|
|
// Apple IIgs -- direct Zilog 8530 SCC (modem/printer ports) or a 6551
|
|
// Super Serial Card in a slot; polled, drained on
|
|
// jlSerialPoll().
|
|
// DOS -- 8250/16550 UART on a COM port; interrupt-driven RX ring.
|
|
// Amiga -- serial.device (async exec IO); the OS buffers RX.
|
|
// Atari ST -- BIOS Aux (Modem port) via XBIOS Rsconf; TOS buffers RX.
|
|
//
|
|
// Model: non-blocking + buffered. Received bytes accumulate in a background
|
|
// ring (a hardware IRQ on DOS, the OS on Amiga/ST, or jlSerialPoll() on the
|
|
// IIgs); jlSerialRead / jlSerialAvailable never block. Call jlSerialPoll()
|
|
// once per game frame -- it is a no-op where the IRQ/OS already fills the
|
|
// ring, and the hardware drain where it does not, so calling it every frame is
|
|
// always correct. Transmit is a bounded poll.
|
|
//
|
|
// A failed jlSerialOpen is non-fatal: it returns false and every other call is
|
|
// a safe no-op (Available 0, Read 0), exactly like a failed audio init.
|
|
|
|
#ifndef JOEYLIB_SERIAL_H
|
|
#define JOEYLIB_SERIAL_H
|
|
|
|
#include "platform.h"
|
|
#include "types.h"
|
|
|
|
// Which physical interface to open. The IIgs is the oddball with three:
|
|
// JL_SERIAL_MODEM -- IIgs modem port (SCC channel A). Elsewhere == DEFAULT.
|
|
// JL_SERIAL_PRINTER -- IIgs printer port (SCC channel B). Only the IIgs has
|
|
// a second built-in port; elsewhere == DEFAULT.
|
|
// JL_SERIAL_SLOT -- a card/port selected by jlSerialConfigT.unit: IIgs
|
|
// Super Serial Card slot (1..7); DOS COM number (1..4);
|
|
// Amiga serial.device unit.
|
|
// JL_SERIAL_DEFAULT -- the platform's natural RS-232 port (IIgs modem, DOS
|
|
// COM1, ST Modem port, Amiga unit 0).
|
|
typedef enum {
|
|
JL_SERIAL_DEFAULT = 0,
|
|
JL_SERIAL_MODEM,
|
|
JL_SERIAL_PRINTER,
|
|
JL_SERIAL_SLOT
|
|
} 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;
|
|
|
|
// Line configuration. `unit` disambiguates JL_SERIAL_SLOT (see jlSerialDeviceE)
|
|
// and is ignored for the other devices.
|
|
typedef struct {
|
|
uint32_t baud; // 300 .. 115200 (each port clamps to what it supports)
|
|
uint8_t dataBits; // 5 .. 8
|
|
uint8_t stopBits; // 1 or 2
|
|
jlSerialParityE parity;
|
|
jlSerialFlowE flow;
|
|
uint8_t unit; // JL_SERIAL_SLOT: IIgs slot 1..7 / DOS COM 1..4 / Amiga unit
|
|
} jlSerialConfigT;
|
|
|
|
// Open + configure the port. Only one port is open at a time; a second
|
|
// jlSerialOpen without a jlSerialClose fails. Returns false (non-fatal) if the
|
|
// port cannot be opened or the platform has no serial support -- every other
|
|
// call then no-ops.
|
|
bool jlSerialOpen(jlSerialDeviceE device, const jlSerialConfigT *config);
|
|
|
|
// Close the open port and release its resources. Safe to call when not open.
|
|
void jlSerialClose(void);
|
|
|
|
// Pump the RX/TX buffers. Call once per game frame. No-op where a hardware IRQ
|
|
// or the OS already services the port (DOS/Amiga/ST); drains the hardware FIFO
|
|
// into the RX ring where it does not (IIgs). Calling it every frame is always
|
|
// correct.
|
|
void jlSerialPoll(void);
|
|
|
|
// Bytes waiting in the RX buffer, readable now without blocking.
|
|
uint16_t jlSerialAvailable(void);
|
|
|
|
// Copy up to `max` received bytes into `buf`; returns the count copied
|
|
// (0 .. max). Never blocks.
|
|
uint16_t jlSerialRead(uint8_t *buf, uint16_t max);
|
|
|
|
// Send `len` bytes; returns the count accepted (may be < len if a flow-
|
|
// controlled peer or a full transmit path stalls). Transmit is a bounded poll.
|
|
uint16_t jlSerialWrite(const uint8_t *buf, uint16_t len);
|
|
|
|
// Single-byte convenience. jlSerialReadByte returns -1 when none is ready.
|
|
bool jlSerialWriteByte(uint8_t b);
|
|
int16_t jlSerialReadByte(void);
|
|
|
|
// Discard any buffered received bytes.
|
|
void jlSerialFlush(void);
|
|
|
|
#endif
|