150 lines
6.5 KiB
QBasic
150 lines
6.5 KiB
QBasic
' The MIT License (MIT)
|
|
'
|
|
' Copyright (C) 2026 Scott Duensing
|
|
'
|
|
' 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 THE
|
|
' AUTHORS OR COPYRIGHT HOLDERS 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.
|
|
|
|
' comm.bas -- Serial Communications Library for DVX BASIC
|
|
'
|
|
' Three tiers of serial communication:
|
|
'
|
|
' 1. Raw serial (SerXxx) -- direct UART I/O with ISR-driven ring
|
|
' buffers. No framing or error correction. Use this for talking
|
|
' to existing BBSs, modems, and other plain serial devices.
|
|
'
|
|
' 2. Packet serial (CommXxx) -- adds HDLC framing, CRC-16 checksums,
|
|
' and Go-Back-N ARQ for reliable delivery. Data is split into
|
|
' packets and retransmitted on error. Requires both sides to
|
|
' speak the same protocol.
|
|
'
|
|
' 3. Encrypted serial (CommHandshake + encrypt flag) -- adds DH key
|
|
' exchange and XTEA-CTR encryption on top of packets. Use
|
|
' CommSend with encrypt=True after CommHandshake.
|
|
'
|
|
' Usage: Add this file to your project.
|
|
|
|
' UART types (returned by SerGetUart)
|
|
CONST SER_UART_NONE = 0
|
|
CONST SER_UART_8250 = 1
|
|
CONST SER_UART_16450 = 2
|
|
CONST SER_UART_16550 = 3
|
|
CONST SER_UART_16550A = 4
|
|
|
|
' Handshake modes (for SerOpen / CommOpen)
|
|
CONST SER_HANDSHAKE_NONE = 0
|
|
CONST SER_HANDSHAKE_XONXOFF = 1
|
|
CONST SER_HANDSHAKE_RTSCTS = 2
|
|
CONST SER_HANDSHAKE_DTRDSR = 3
|
|
|
|
DECLARE LIBRARY "basrt"
|
|
|
|
' =========================================================
|
|
' UART Detection and Configuration
|
|
' =========================================================
|
|
|
|
' Detect the UART type for a COM port (1-4) WITHOUT opening it.
|
|
DECLARE FUNCTION SerGetUart(BYVAL com AS INTEGER) AS INTEGER
|
|
|
|
' Set the I/O base address for a COM port before opening.
|
|
' Default bases: COM1=&H3F8, COM2=&H2F8, COM3=&H3E8, COM4=&H2E8
|
|
DECLARE SUB SerSetBase(BYVAL com AS INTEGER, BYVAL base AS INTEGER)
|
|
|
|
' Set the IRQ for a COM port before opening.
|
|
' Default IRQs: COM1=4, COM2=3, COM3=4, COM4=3
|
|
DECLARE SUB SerSetIrq(BYVAL com AS INTEGER, BYVAL irq AS INTEGER)
|
|
|
|
' Get the I/O base address for a COM port.
|
|
DECLARE FUNCTION SerGetBase(BYVAL com AS INTEGER) AS INTEGER
|
|
|
|
' Get the IRQ for a COM port.
|
|
DECLARE FUNCTION SerGetIrq(BYVAL com AS INTEGER) AS INTEGER
|
|
|
|
' =========================================================
|
|
' Raw Serial I/O (no framing, no error correction)
|
|
' =========================================================
|
|
|
|
' Open a raw serial port. Returns True on success.
|
|
DECLARE FUNCTION SerOpen(BYVAL com AS INTEGER, BYVAL baud AS LONG, BYVAL dataBits AS INTEGER, BYVAL parity AS STRING, BYVAL stopBits AS INTEGER, BYVAL handshake AS INTEGER) AS INTEGER
|
|
|
|
' Close a raw serial port.
|
|
DECLARE SUB SerClose(BYVAL com AS INTEGER)
|
|
|
|
' Write a string to the serial port. Returns True on success.
|
|
DECLARE FUNCTION SerWrite(BYVAL com AS INTEGER, BYVAL data AS STRING) AS INTEGER
|
|
|
|
' Read pending data from the serial port. Returns "" if none available.
|
|
DECLARE FUNCTION SerRead$(BYVAL com AS INTEGER) AS STRING
|
|
|
|
' Return the number of bytes waiting in the receive buffer.
|
|
DECLARE FUNCTION SerAvailable(BYVAL com AS INTEGER) AS INTEGER
|
|
|
|
' Clear the receive buffer.
|
|
DECLARE SUB SerFlush(BYVAL com AS INTEGER)
|
|
|
|
' Attach a raw serial port to a Terminal widget.
|
|
DECLARE SUB SerAttach(BYVAL com AS INTEGER, BYVAL termCtrlName AS STRING)
|
|
|
|
' Detach a raw serial port from a Terminal widget.
|
|
DECLARE SUB SerDetach(BYVAL com AS INTEGER)
|
|
|
|
' =========================================================
|
|
' Packet Serial (reliable delivery + channel multiplexing)
|
|
' =========================================================
|
|
|
|
' Open a packet serial link. Returns a handle (>0), or 0 on failure.
|
|
DECLARE FUNCTION CommOpen(BYVAL com AS INTEGER, BYVAL baud AS LONG, BYVAL dataBits AS INTEGER, BYVAL parity AS STRING, BYVAL stopBits AS INTEGER, BYVAL handshake AS INTEGER) AS INTEGER
|
|
|
|
' Close a packet serial link.
|
|
DECLARE SUB CommClose(BYVAL handle AS INTEGER)
|
|
|
|
' Send data on a logical channel (0-127).
|
|
' encrypt: True to encrypt (requires CommHandshake first).
|
|
DECLARE FUNCTION CommSend(BYVAL handle AS INTEGER, BYVAL data AS STRING, BYVAL channel AS INTEGER, BYVAL encrypt AS INTEGER) AS INTEGER
|
|
|
|
' Receive pending data from a specific channel. Returns "" if none.
|
|
DECLARE FUNCTION CommRecv$(BYVAL handle AS INTEGER, BYVAL channel AS INTEGER) AS STRING
|
|
|
|
' Poll for incoming packets. Call periodically if not using CommAttach.
|
|
DECLARE FUNCTION CommPoll(BYVAL handle AS INTEGER) AS INTEGER
|
|
|
|
' Return the number of unacknowledged packets in the transmit window.
|
|
DECLARE FUNCTION CommPending(BYVAL handle AS INTEGER) AS INTEGER
|
|
|
|
' =========================================================
|
|
' Encryption (DH key exchange + XTEA-CTR)
|
|
' =========================================================
|
|
|
|
' Perform Diffie-Hellman key exchange. Blocks until both sides
|
|
' complete. After this, CommSend with encrypt=True will encrypt.
|
|
DECLARE FUNCTION CommHandshake(BYVAL handle AS INTEGER) AS INTEGER
|
|
|
|
' Check if the key exchange is complete.
|
|
DECLARE FUNCTION CommIsReady(BYVAL handle AS INTEGER) AS INTEGER
|
|
|
|
' =========================================================
|
|
' Terminal Widget Integration
|
|
' =========================================================
|
|
|
|
' Attach a packet link to a Terminal widget on a given channel.
|
|
' encrypt: True to encrypt terminal traffic.
|
|
DECLARE SUB CommAttach(BYVAL handle AS INTEGER, BYVAL termCtrlName AS STRING, BYVAL channel AS INTEGER, BYVAL encrypt AS INTEGER)
|
|
|
|
' Detach a packet link from a Terminal widget.
|
|
DECLARE SUB CommDetach(BYVAL handle AS INTEGER)
|
|
END DECLARE
|