From: Svjatoslav Agejenko Date: Mon, 4 Aug 2025 20:13:22 +0000 (+0300) Subject: Document TSR communication driver X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=56d9b67c34be35bec69f3325e2d0f1ce88046d91;p=qbasicapps.git Document TSR communication driver --- diff --git a/Networking/LPT communication driver/diagram.png b/Networking/LPT communication driver/diagram.png new file mode 100644 index 0000000..baf5bee Binary files /dev/null and b/Networking/LPT communication driver/diagram.png differ diff --git a/Networking/LPT communication driver/index.html b/Networking/LPT communication driver/index.html new file mode 100644 index 0000000..cf57632 --- /dev/null +++ b/Networking/LPT communication driver/index.html @@ -0,0 +1,606 @@ + + + + + + + +LPT Communication Driver + + + + + + +
+

LPT Communication Driver

+ + +
+

1. Overview

+
+

+This is weird networking solution. It allows to send data using +parallel LPT port serially(!) by bit-banging between two connected +computers :) +

+ +

+Out of 25 physical wires in LPT port, only 3 are used: +

+ +
+
Pin 14
Carries a synchronization signal which uses a periodic +pattern (e.g., 010101…) to maintain timing alignment between the +communicating computers.
+ +
Pin 17
Functions as the bidirectional data line, responsible for +transmitting and receiving data between the connected computers.
+ +
Pin 18
Acts as the ground connection, providing a common +reference for electrical signals to ensure consistency in +communication.
+
+ + +
+

diagram.png +

+
+ +

+By utilizing only three wires and software controlled bit-banging +algorithm, custom, comparatively simple, cheap and long cable can be +built to connect 2 computers in a DIY network setup. +

+
+
+ +
+

2. LPT Communication Driver

+
+
+
+

2.1. Overview

+
+

+The LPT Communication Driver is a Terminate and Stay Resident (TSR) +driver designed to facilitate communication between computers using +parallel printer ports (LPT). This driver uses bit-banging to send and +receive data serially over the LPT port, utilizing only three wires +for communication. +

+ +

+Driver hooks into the system's IRQ 0 to ensure that system timer +always keeps executing it in the background. While operating as a +background process, it periodically monitors LPT port to detect +incoming transmission. When transmission is detected, driver receives, +decodes and stores it into preallocated 5000 byte receive buffer. +

+ +

+Applications can then communicate with the driver on their own +schedule using INT 63h to poll for and retrieve received messages, if +any. Applications can also send outgoing messages into 5000 byte +driver outbox memory buffer. Thereafter driver will transmit those +messages in background mode over the wire. +

+ +

+The driver is half-duplex: it prioritizes receiving over sending and +does not transmit while receiving. +

+ +

+During active transmission/reception, the driver can consume 100% CPU +due to busy-wait loops in the IRQ handler, potentially causing random +temporary hiccups for application running in the +foreground. Unsuitable for real-time systems. +

+ +

+Download: +

+ +
+
+ +
+

2.2. Data transmission implementation details

+
+

+When there is incoming data transmission, the TSR driver detects it +during its periodic execution in the IRQ 0 (timer) handler, which runs +approximately every 55ms. +

+ +

+Driver checks for possible transmission comparatively rarely (every 55 +ms) and for this reason it is important to have quite long +transmission start indicator/header before actual data is sent. This +allows long enough time for recipient computer communication driver to +detect that transmission line is active and start listening to it now +in exclusive busy-wait loop. So, the TSR driver steals 100% of the CPU +for the duration of transmission. +

+ +

+The start of transmission is detected by reading the port (37Ah) +value, and checking if bit 3 of the raw input is high. It then enters +a "skip header" loop. Once bit 1 goes low, bit reception begins. The +end is detected via a timeout: during bit reception, a counter +increments on each poll. If there is no change in the port value for +30 consecutive polls (indicating no new bit transition), it assumes +the transmission is complete, appends a 2-byte length to the receive +buffer, and exits the routine. +

+ +

+So, both receive and send routines execute within the IRQ 0 handler +using busy-wait polling loops (for receive) or timed output loops (for +send). These can hold the CPU for the full duration of a transmission, +as the handler does not yield until complete. +

+ +

+It bit-bangs data by treating the LPT control port (37Ah) as both +output and input, using bit 3 (pin 17, data line) for the serial data +bit and bit 1 (pin 14, sync line) for a clock that alternates (low on +even bit indices, high on odd) to signal transitions. +

+ +

+For sending: the port is first set to 0xFF (all bits high) as a +header, held for ~110ms (2 timer ticks). +

+ +

+For receiving: after start detection, it polls the port for value +changes (transitions). On each change, it reads the port again (to +ensure that synchronization bit did not arrive ahead data bit over the +separate physical wire), extracts bit 3 as the data bit, shifts it +into a byte accumulator, and resets the timeout counter. Once a full +byte is accumulated, it stores it in the receive buffer. No ACK or +error checking. +

+ +

+Driver can receive multiple transmissions into its 5000-byte receive +buffer before the client program reads it out. Each incoming +transmission appends its data bytes followed by a 2-byte length word +directly to the end of the buffer (updating dbufsiz to the new total +used). As long as the cumulative size doesn't exceed 5000 bytes, +multiple can queue up. The buffer acts as a FIFO for concatenated +packets; overflows are not handled (it would corrupt without +checks). The client retrieves the entire buffer contents at once when +polling. +

+ +

+When the client program reads received data from the TSR (via INT 63h +AH=2), the driver copies the full buffer contents (up to dbufsiz +bytes) to the client's specified ES:DI pointer, returns the byte count +in AX, and immediately resets dbufsiz to 0, clearing the buffer. This +ensures the data is not served again on subsequent reads, as the +buffer is emptied after each retrieval. If no data is available, AX=0 +is returned. +

+
+
+ +
+

2.3. Driver API

+
+

+The driver uses INT 63h for its API, with functions selected via the +AH register. It maintains two internal buffers: +

+ +
    +
  • Download Buffer: 5000 bytes for incoming (received) data. Multiple +transmissions can be queued here, each appended with a 2-byte length +footer.
  • +
  • Upload Buffer: 5000 bytes for outgoing (to-be-sent) data. Data is +copied here and transmitted when the line is free.
  • +
+ + +

+Communication is polling-based for applications; the driver handles +transmission/reception in the background. +

+ +

+No error checking, acknowledgments, or flow control; it's a simple, +unidirectional-per-turn protocol. +

+ +

+To use the driver: +

+
    +
  • Load the TSR (e.g., run lptdrv.com).
  • +
  • Activate it via the API.
  • +
  • Poll for received data or queue sends as needed.
  • +
  • Deactivate when done.
  • +
+ +

+API overview: +

+ + + +++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AH registerAPI function
0Deactivate the driver
1Activate the driver
2Retrieve downloaded data from the driver's input buffer
3Upload data to the driver's output buffer for transmission
+
+ +
+

2.3.1. Deactivate the driver

+
+

+Disables the driver, stopping background monitoring and +transmission. The LPT port is reset (set to 0). +

+ +
    +
  • AH: 0
  • +
  • Parameters: None
  • +
  • Returns: None
  • +
  • Side Effects: Clears the enabled flag.
  • +
  • Usage Notes: Call this before unloading the TSR or when +communication is no longer needed to free system resources.
  • +
+
+
+ +
+

2.3.2. Activate the driver

+
+

+Enables the driver, starting background LPT port monitoring for +incoming data. The LPT port is reset (set to 0) upon activation. +

+ +
    +
  • AH: 1
  • +
  • Parameters: None
  • +
  • Returns: None
  • +
  • Side Effects: Sets the enabled flag. Existing buffer contents are +preserved.
  • +
  • Usage Notes: Must be called after loading the TSR and before any +send/receive operations. Can be called multiple times; redundant +activations are harmless.
  • +
+
+
+ +
+

2.3.3. Retrieve downloaded data from the driver's input buffer

+
+

+Copies all accumulated received data from the driver's download buffer +to the caller's memory location and clears the buffer. +

+ +
    +
  • AH : 2
  • +
  • Parameters : +
      +
    • ES:DI : Pointer to the buffer where received data should be +copied (must be large enough to hold up to 5000 bytes).
    • +
  • +
  • Returns : +
      +
    • AX : Number of bytes copied (0 if no data available).
    • +
  • +
  • Side Effects : Resets the download buffer size to 0, preventing +re-retrieval of the same data.
  • +
  • Usage Notes : +
      +
    • Data is retrieved as a concatenated stream of all queued +transmissions.
    • +
    • Each transmission in the buffer ends with a 2-byte length word +(little-endian) indicating its payload size (excluding the length +itself).
    • +
    • Poll this function periodically in a loop to check for new data.
    • +
    • If AX=0, no copy occurs.
    • +
    • Example: In assembly, set ES:DI to your receive buffer and call +INT 63h; then process AX bytes if >0.
    • +
  • +
+
+
+ +
+

2.3.4. Upload data to the driver's output buffer for transmission

+
+

+Copies the specified data to the driver's upload buffer for background +transmission. Transmission occurs when the line is free (no incoming +data). +

+ +
    +
  • AH : 3
  • +
  • Parameters : +
      +
    • DS:SI : Pointer to the data to upload.
    • +
    • CX : Number of bytes to upload (must not exceed remaining upload +buffer space; no checks performed).
    • +
  • +
  • Returns : None
  • +
  • Side Effects : Appends data to the upload buffer and updates its +size. Transmission is asynchronous.
  • +
  • Usage Notes : +
      +
    • Data is sent as a single transmission (no automatic framing; +caller can add headers if needed).
    • +
    • If the buffer is full (total >5000 bytes), behavior is undefined +(overflow).
    • +
    • Multiple calls can queue data sequentially in the buffer.
    • +
    • Transmission starts in the next IRQ 0 tick if the line is idle.
    • +
    • The driver adds no footer; the receiver sees exactly the sent bytes.
    • +
    • Example: Load DS:SI with your message, CX with length, call INT +63h; the driver handles sending.
    • +
  • +
+
+
+
+
+
+
+

Created: 2025-08-04 ma 02:12

+

Validate

+
+ + diff --git a/Networking/LPT communication driver/index.org b/Networking/LPT communication driver/index.org index 5ba91f0..cb82b14 100755 --- a/Networking/LPT communication driver/index.org +++ b/Networking/LPT communication driver/index.org @@ -26,6 +26,7 @@ Out of [[https://en.wikipedia.org/wiki/Parallel_port][25 physical wires in LPT p reference for electrical signals to ensure consistency in communication. +[[file:diagram.png]] By utilizing only three wires and software controlled bit-banging algorithm, custom, comparatively simple, cheap and long cable can be @@ -33,6 +34,7 @@ built to connect 2 computers in a DIY network setup. * LPT Communication Driver +** Overview The LPT Communication Driver is a Terminate and Stay Resident (TSR) driver designed to facilitate communication between computers using @@ -52,40 +54,195 @@ any. Applications can also send outgoing messages into 5000 byte driver outbox memory buffer. Thereafter driver will transmit those messages in background mode over the wire. +The driver is half-duplex: it prioritizes receiving over sending and +does not transmit while receiving. + +During active transmission/reception, the driver can consume 100% CPU +due to busy-wait loops in the IRQ handler, potentially causing random +temporary hiccups for application running in the +foreground. Unsuitable for real-time systems. + Download: - Source code: [[file:lptdrv.asm][lptdrv.asm]] - Compiled binary: [[file:lptdrv.com][lptdrv.com]] +** Data transmission implementation details + +When there is incoming data transmission, the TSR driver detects it +during its periodic execution in the IRQ 0 (timer) handler, which runs +approximately every 55ms. + +Driver checks for possible transmission comparatively rarely (every 55 +ms) and for this reason it is important to have quite long +transmission start indicator/header before actual data is sent. This +allows long enough time for recipient computer communication driver to +detect that transmission line is active and start listening to it now +in exclusive busy-wait loop. So, the TSR driver steals 100% of the CPU +for the duration of transmission. + +The start of transmission is detected by reading the port (37Ah) +value, and checking if bit 3 of the raw input is high. It then enters +a "skip header" loop. Once bit 1 goes low, bit reception begins. The +end is detected via a timeout: during bit reception, a counter +increments on each poll. If there is no change in the port value for +30 consecutive polls (indicating no new bit transition), it assumes +the transmission is complete, appends a 2-byte length to the receive +buffer, and exits the routine. + +So, both receive and send routines execute within the IRQ 0 handler +using busy-wait polling loops (for receive) or timed output loops (for +send). These can hold the CPU for the full duration of a transmission, +as the handler does not yield until complete. + +It bit-bangs data by treating the LPT control port (37Ah) as both +output and input, using bit 3 (pin 17, data line) for the serial data +bit and bit 1 (pin 14, sync line) for a clock that alternates (low on +even bit indices, high on odd) to signal transitions. + +For sending: the port is first set to 0xFF (all bits high) as a +header, held for ~110ms (2 timer ticks). + +For receiving: after start detection, it polls the port for value +changes (transitions). On each change, it reads the port again (to +ensure that synchronization bit did not arrive ahead data bit over the +separate physical wire), extracts bit 3 as the data bit, shifts it +into a byte accumulator, and resets the timeout counter. Once a full +byte is accumulated, it stores it in the receive buffer. No ACK or +error checking. + +Driver can receive multiple transmissions into its 5000-byte receive +buffer before the client program reads it out. Each incoming +transmission appends its data bytes followed by a 2-byte length word +directly to the end of the buffer (updating dbufsiz to the new total +used). As long as the cumulative size doesn't exceed 5000 bytes, +multiple can queue up. The buffer acts as a FIFO for concatenated +packets; overflows are not handled (it would corrupt without +checks). The client retrieves the entire buffer contents at once when +polling. + +When the client program reads received data from the TSR (via INT 63h +AH=2), the driver copies the full buffer contents (up to dbufsiz +bytes) to the client's specified ES:DI pointer, returns the byte count +in AX, and immediately resets dbufsiz to 0, clearing the buffer. This +ensures the data is not served again on subsequent reads, as the +buffer is emptied after each retrieval. If no data is available, AX=0 +is returned. ** Driver API -*** Deactivate the driver -*Parameters*: -: AH = 0 +The driver uses INT 63h for its API, with functions selected via the +AH register. It maintains two internal buffers: -*Returns*: None +- Download Buffer: 5000 bytes for incoming (received) data. Multiple + transmissions can be queued here, each appended with a 2-byte length + footer. +- Upload Buffer: 5000 bytes for outgoing (to-be-sent) data. Data is + copied here and transmitted when the line is free. -*** Activates the driver -*Parameters*: -: AH = 1 +Communication is polling-based for applications; the driver handles +transmission/reception in the background. -*Returns*: None - -*** Retrieve downloaded data from the driver's input buffer +No error checking, acknowledgments, or flow control; it's a simple, +unidirectional-per-turn protocol. -*Parameters*: -: AH = 2 -: ES:DI = Pointer to the location where downloaded data should be placed +To use the driver: +- Load the TSR (e.g., run lptdrv.com). +- Activate it via the API. +- Poll for received data or queue sends as needed. +- Deactivate when done. -*Returns*: -: AX : Number of bytes downloaded +API overview: +| AH register | API function | +|-------------+---------------------------------------------------------| +| 0 | [[id:a7aaa0e6-92de-467c-bcd4-b3d3216b15d4][Deactivate the driver]] | +| 1 | [[id:944be7b6-d3ba-486a-98bd-1a66cfffe6e5][Activate the driver]] | +| 2 | [[id:49350196-55b9-4d50-b672-b3c6d6d55e53][Retrieve downloaded data from the driver's input buffer]] | +| 3 | [[id:53fd0c68-4057-4e9e-b908-87fab6eab5c8][Upload data to the driver's output buffer for transmission]] | -*** Upload data to the driver's output buffer for transmission +*** Deactivate the driver +:PROPERTIES: +:ID: a7aaa0e6-92de-467c-bcd4-b3d3216b15d4 +:END: + +Disables the driver, stopping background monitoring and +transmission. The LPT port is reset (set to 0). + +- AH: 0 +- Parameters: None +- Returns: None +- Side Effects: Clears the enabled flag. +- Usage Notes: Call this before unloading the TSR or when + communication is no longer needed to free system resources. + +*** Activate the driver +:PROPERTIES: +:ID: 944be7b6-d3ba-486a-98bd-1a66cfffe6e5 +:END: + +Enables the driver, starting background LPT port monitoring for +incoming data. The LPT port is reset (set to 0) upon activation. + +- AH: 1 +- Parameters: None +- Returns: None +- Side Effects: Sets the enabled flag. Existing buffer contents are + preserved. +- Usage Notes: Must be called after loading the TSR and before any + send/receive operations. Can be called multiple times; redundant + activations are harmless. -*Parameters*: -: AH = 3 -: DS:SI: Pointer to the data to be uploaded -: CX: Number of bytes to upload +*** Retrieve downloaded data from the driver's input buffer +:PROPERTIES: +:ID: 49350196-55b9-4d50-b672-b3c6d6d55e53 +:END: + +Copies all accumulated received data from the driver's download buffer +to the caller's memory location and clears the buffer. + +- *AH* : 2 +- *Parameters* : + - *ES:DI* : Pointer to the buffer where received data should be + copied (must be large enough to hold up to 5000 bytes). +- *Returns* : + - *AX* : Number of bytes copied (0 if no data available). +- *Side Effects* : Resets the download buffer size to 0, preventing + re-retrieval of the same data. +- *Usage Notes* : + - Data is retrieved as a concatenated stream of all queued + transmissions. + - Each transmission in the buffer ends with a 2-byte length word + (little-endian) indicating its payload size (excluding the length + itself). + - Poll this function periodically in a loop to check for new data. + - If AX=0, no copy occurs. + - Example: In assembly, set ES:DI to your receive buffer and call + INT 63h; then process AX bytes if >0. -*Returns*: None +*** Upload data to the driver's output buffer for transmission +:PROPERTIES: +:ID: 53fd0c68-4057-4e9e-b908-87fab6eab5c8 +:END: + +Copies the specified data to the driver's upload buffer for background +transmission. Transmission occurs when the line is free (no incoming +data). + +- *AH* : 3 +- *Parameters* : + - *DS:SI* : Pointer to the data to upload. + - *CX* : Number of bytes to upload (must not exceed remaining upload + buffer space; no checks performed). +- *Returns* : None +- *Side Effects* : Appends data to the upload buffer and updates its + size. Transmission is asynchronous. +- *Usage Notes* : + - Data is sent as a single transmission (no automatic framing; + caller can add headers if needed). + - If the buffer is full (total >5000 bytes), behavior is undefined + (overflow). + - Multiple calls can queue data sequentially in the buffer. + - Transmission starts in the next IRQ 0 tick if the line is idle. + - The driver adds no footer; the receiver sees exactly the sent bytes. + - Example: Load DS:SI with your message, CX with length, call INT + 63h; the driver handles sending. diff --git a/Tools/Update web site b/Tools/Update web site index acd87ee..f162ed4 100755 --- a/Tools/Update web site +++ b/Tools/Update web site @@ -43,6 +43,7 @@ export_org_to_html "Math/Truth table" export_org_to_html "Miscellaneous/Mouse driver" export_org_to_html "Networking/Digital data over analog audio" +export_org_to_html "Networking/LPT communication driver" # Upload project homepage to the server. rsync -avz --delete -e 'ssh -p 10006' ./ \ diff --git a/index.org b/index.org index 59e8acf..ae99e95 100644 --- a/index.org +++ b/index.org @@ -888,6 +888,12 @@ How It Works: Download source code: [[file:Networking/LPT%20to%20COM%20port%20data%20transfer.bas][LPT to COM port data transfer.bas]] +** LPT communication driver + +TSR driver that allows 2 computers to communicate over parallel port serially. + +[[file:Networking/LPT%20communication%20driver/index.html][Read more]] + ** Data over analog audio CODEC Utilities to encode digital data to sound file and back.