Skip to content
FreeDOSHow-To Published Updated 8 min readViews unavailable

How to Build a Reliable FreeDOS Serial Link for Retro Hardware

Build a reliable FreeDOS serial link by validating UART settings, null-modem wiring, flow control, terminal configuration, and file checksums.

Reliable serial communication is a chain: a compatible electrical interface, correct cable topology, matching framing, a sender and receiver that can keep up, and (for files) a transfer protocol understood by both programs. Diagnose those layers in order. Changing baud rate cannot repair a crossed handshake wire; installing a null-modem cable cannot correct mismatched parity; and a terminal displaying characters is not proof that a binary file has been transferred intact.

1. Identify the ports and electrical interfaces

First establish what each connector actually exposes. A PC COM port normally presents EIA/TIA-232 (commonly called RS-232) electrical signaling. A microcontroller header may instead expose logic-level UART pins. They share the idea of asynchronous serial data but not necessarily voltage levels or polarity. Never connect a PC serial output directly to a 3.3 V or 5 V UART header: use a transceiver designed for the two interfaces, and verify its supply, pinout, and signal direction from its datasheet. A MAX232-family device is one example of a line driver/receiver, not a universal adapter for every voltage or connector.

On a real machine, identify the COM port address and interrupt resources using the machine’s firmware/setup documentation or a trusted hardware inventory utility. Do not assume COM1 exists merely because an application defaults to it. USB-to-serial adapters can appear as host-side serial ports but may not be visible to FreeDOS unless the adapter is supported by a DOS driver; a working adapter on another OS does not prove the DOS guest can access it. In a virtual machine, check that the emulator has actually attached its virtual COM port to the intended host endpoint (file, socket, pipe, or physical port) and that the endpoint is open on both ends.

2. Choose a straight-through or null-modem cable

The terms describe signal routing, not connector shape. A traditional DTE computer port and a DCE modem port use complementary transmit/receive assignments, so a straight-through cable is normally used between them. Connecting two DTE ports directly usually requires a null-modem arrangement that crosses transmit and receive. A minimal three-wire link uses transmit, receive, and signal ground; it is only sufficient when both applications and devices can operate without hardware handshaking. Some terminals require RTS/CTS or other modem-control signals. In that case use a cable explicitly wired for the required handshake scheme: null-modem cables are not all wired alike.

For a conventional PC DTE DE-9 connector, pins 2 and 3 are receive and transmit respectively, while on a conventional PC DTE DB-25 connector pin 2 is transmit and pin 3 is receive. Adapters must map signal names, not blindly preserve pin numbers. These conventions describe common PC serial ports; equipment wired as DCE or with a nonstandard connector can differ. Before connecting expensive or irreplaceable equipment, use the device manual, a continuity tester, and (if available) a breakout box to verify the actual path. Do not hot-plug an unknown cable into vintage equipment simply because the shells fit.

3. Set framing with FreeDOS MODE, then inspect it

Asynchronous serial framing consists of baud rate, data bits, parity, and stop bits. Both ends must agree. 9600,N,8,1 means 9600 symbols per second, no parity, eight data bits, and one stop bit; it is a starting profile, not a guarantee that either application or cable supports it. FreeDOS MODE documents serial configuration and a status display:

MODE COM1 /STATUS
MODE COM1:9600,N,8,1
MODE COM1 /STATUS

The exact supported options depend on the installed MODE build and the serial device. FreeDOS documentation lists an optional retry field but says it is ignored; that field is not hardware flow control. MODE does not make two applications agree automatically, nor does it necessarily configure a terminal’s own protocol settings. Set the same framing in the terminal program, device firmware, or emulator. MODE COM1 /STATUS is useful for inspecting the DOS-visible configuration, but it cannot prove the cable wiring, remote settings, electrical levels, or that the receiving program has opened the port.

Flow control is a separate agreement. With RTS/CTS, the transmitter obeys the receiver’s readiness signal; the cable must carry those signals and both endpoint configurations must enable compatible behavior. XON/XOFF uses in-band control characters, which means arbitrary binary data and software that consumes these characters need special care. If the endpoints disagree, a transfer may work briefly and then stall or lose data when buffers fill. Do not select “hardware” or “software” flow control just because it appears in a menu: confirm what the remote endpoint and cable implement. If no flow control is available, use a pace and workload that the receiving program can handle, then verify with repeated transfers.

Open a terminal program on both ends, configure matching framing, select the correct COM ports, and disable local echo for the initial test if it would make locally typed characters look like remote replies. Type a short sequence in one direction, then in the other. Seeing your own keystrokes only proves the terminal’s local echo; seeing characters arrive at the other endpoint proves more, but still does not establish file-transfer integrity. Try distinct characters, line endings, and a sustained stream long enough to expose buffering or handshake problems.

If nothing arrives, verify in this order: the COM port is available and selected; both terminals opened it; cable transmit/receive/ground paths are correct; framing matches; flow-control settings and wires agree; and neither side is waiting for a modem-control signal. If characters are consistently garbled, first compare baud, data bits, parity, and stop bits rather than raising or lowering one setting at random. If characters are correct initially but disappear in long bursts, investigate flow control, receiver buffering, interrupt handling, CPU load, and adapter limitations. Record the exact setup before changing it so you can revert one variable at a time.

5. Select a protocol both transfer programs implement

Terminal capture is suitable for text diagnostics, not as a dependable binary-file transfer method. Choose a protocol by its exact variant and confirm both applications support that variant: “XMODEM” may refer to checksum or CRC mode, XMODEM-1K uses a different block size, YMODEM adds batch/file metadata conventions, and ZMODEM is a distinct protocol family. A sender and receiver can use similar names while still negotiating incompatible modes. XMODEM’s classic form uses 128-byte blocks and a one-byte checksum; CRC variants use a stronger check, but neither a link-layer check nor a successful completion message substitutes for comparing the destination bytes with an independently calculated digest.

Start the receiver in receive mode, then initiate the sender as the program documentation directs. Use a disposable test file first. After the protocol reports completion, confirm that the received file exists, has the expected byte length, and opens or parses correctly. Where hashing tools are available, compute a SHA-256 digest at both ends and compare the resulting hex strings. The reference digest should come from the original file or a trusted source; copying a digest from an untrusted transfer alongside the file only detects accidental mismatch, not malicious substitution. DOS builds may lack a modern hashing utility, so moving the file to a maintained host for comparison can be the practical verification step.

6. Understand UART buffering without treating folklore as a limit

UARTs differ in their receive/transmit buffers, FIFO behavior, clocking, interrupt logic, and driver support. A 16550-class UART such as TI’s TL16C550C has configurable 16-byte FIFOs, but that does not establish a universal maximum baud rate for an entire PC. A FIFO reduces the frequency with which software must service individual bytes; it cannot repair a bad cable, a mismatched clock, an interrupt conflict, a flow-control mismatch, or an application that reads too slowly. Conversely, older hardware may still work reliably at a given rate when its driver and workload keep pace. Avoid blanket rules such as “anything above 9600 requires a 16550.”

Increase speed only after the lower-rate baseline passes repeated bidirectional and file-integrity checks. Change one variable at a time. For every candidate rate, repeat the same test file several times, inspect protocol retries/errors, compare byte counts and hashes, and test a sustained transfer rather than a short greeting. If a higher rate fails, revert to the last verified profile and investigate which layer changed. Document actual results per machine, cable, adapter, and software combination instead of presenting one machine’s successful rate as a property of all FreeDOS systems.

Write down endpoint identities, physical connector and adapter details, cable wiring or part number, electrical interface, COM port, framing, flow-control mode, terminal versions, transfer-protocol variant, file size, retry count, and digest result. Note whether the endpoint is real hardware, a USB adapter, or an emulator and include relevant virtual-machine settings. This record makes later troubleshooting far faster and prevents a successful profile from being accidentally replaced with a merely plausible one.

Consider the link proven only when the intended application can exchange data both ways, sustained transfers complete without unexplained retries, and representative files pass length and digest checks. If testing an industrial controller, firmware loader, or archival device, also confirm the device-specific manual’s voltage, cable, handshake, and command requirements before sending any bytes: random terminal input may be interpreted as an action rather than harmless text.

Related:

Sources:

Comments