Hardware Reference · Telephony · POTS to SIP
Phone lines and modems: from copper to VoIP
RS-232 / UART Hayes AT V.34 → V.90 The local loop, the serial stack between computer and modem, the modulation standards that got from 300bps to 56k, and why a modern fiber "landline" quietly breaks all of it.
The local loop
What a "phone line" physically is: a twisted copper pair running from a demarcation point at the building back to a central office, carrying a nominal -48V DC feed for on-hook power and a ringing voltage around 90V AC when a call comes in. Everything about how a modem behaves, the tones it can produce, the impedance it expects to see, was engineered against that specific electrical environment: a real, continuous, circuit-switched analog path with no packets, no jitter, and one predictable source of noise, the line itself.
Inside every analog modem sits a DAA, the circuit that isolates the modem's low-voltage logic from the phone line's much higher voltages, detects ring signals, and goes off-hook. This is the part a fiber ONT's voice port replaces with something electrically similar but architecturally very different, more on that below.
RS-232 and the UART
- The computer talks to the modem over RS-232, a point-to-point serial link with the computer as DTE and the modem as DCE. This distinction is why a straight-through cable, not a null-modem cable, connects a PC to a real modem.
- On the PC side, a UART chip handles the actual bit-level serial framing. The original IBM PC/XT shipped the 8250; the AT moved to the pin-compatible, faster 16450. Both share one fatal flaw for high-speed use: a single-byte buffer, meaning the CPU takes an interrupt for every single character.
- The 16550, introduced by National Semiconductor in 1987, added 16-byte FIFO buffers on both transmit and receive with a programmable interrupt trigger (1/4/8/14 bytes). Above roughly 9600 baud, a 1-byte UART reliably drops characters under any real multitasking load; the 16550's buffer is what makes higher speeds and BBS-era multitasking (DESQview, FOSSIL drivers servicing multiple things at once) actually reliable.
- Hardware flow control (RTS/CTS) matters specifically because the DTE-DCE serial link runs faster than the modem's actual over-the-wire rate, to leave headroom for the modem's own data compression. Without RTS/CTS, that gap silently drops bytes.
The Hayes AT command set
Dale Heatherington and Dennis Hayes wrote the original command language for the 1981 Hayes Smartmodem, and it became the de facto universal modem control protocol simply because everyone else copied it wholesale, registers and all. It splits into three tiers by prefix: basic commands (a letter straight after AT, like ATD to dial or ATA to answer), extended commands (an ampersand prefix, AT&K3 for flow control), and vendor-proprietary commands using whatever prefix character a manufacturer picked, backslash for Microcom, percent for others.
Settings live in S-registers, roughly two dozen numbered memory slots (S0 through S27 in practice) queried with ATSn? and set with ATSn=value, covering things like rings-before-auto-answer (S0) and various timers. Hayes patented the "guard time" behind the +++ escape sequence and enforced it commercially in the late 1980s. The ITU eventually standardized the core of all this as V.25ter in 1995, renamed V.250 in 1998, formally requiring specific commands and specific S-register semantics for compliance.
Modulation standards: 300bps to 56k
| standard | speed | note |
|---|---|---|
| Bell 103 | 300 bps | the original US standard, FSK |
| Bell 212A / V.22 | 1200 bps | first widely deployed PSK modem speed |
| V.22bis | 2400 bps | QAM, doubled throughput in the same bandwidth |
| V.32 | 9600 bps | trellis-coded modulation, needs echo cancellation for full duplex on one frequency band |
| V.32bis | 14400 bps | the fax-modem workhorse of the early-mid 90s |
| V.34 | 28800–33600 bps | the practical ceiling for a fully analog, symmetric connection |
| V.90 | 56000/33600 bps | asymmetric — downstream only, requires a digitally-attached far end |
| V.92 | 56000/48000 bps | improved upstream via PCM, plus modem-on-hold for call waiting |
V.32 and later full-duplex standards need real echo cancellation because both modems transmit in the same frequency band simultaneously, each has to null out its own reflected signal to hear the other side. This is exactly the function that a VoIP ATA's speech-tuned echo canceller gets wrong for modem tones, see below.
The 56k trick, and why it rarely delivers 56k
The core rule: V.90/X2/K56flex only work with a single analog-to-digital conversion between the two ends. Downstream data is encoded directly as PCM samples on a digital trunk from the ISP straight to the phone company's line card, hitting only one D/A conversion, the one at your local loop, so it avoids the quantization noise that otherwise caps a connection near 33.6k. Upstream still has to cross an A/D conversion at your end, so it stays capped at V.34 rates regardless.
The practical consequence for a residential caller-to-caller connection, like a dial-up BBS: since both ends are ordinary analog lines, there's no digital backhaul on either side, so the call negotiates down to V.34, around 33.6k, not 56k. This isn't a fault condition, it's the standard behaving exactly as specified. 56k was always an ISP-and-you technology, not a you-and-your-friend technology. USRobotics (X2) and Rockwell/Lucent (K56flex) fought a standards war over the asymmetric trick before the ITU unified both into V.90 in 1998.
FOSSIL drivers and the BBS comms stack
- FOSSIL (Fido/Opus/SEAdog Standard Interface Layer) is the DOS-era abstraction between BBS software and the raw UART, since DOS's own BIOS serial support was too primitive for anything beyond trivial use.
- X00 and BNU were the two dominant real-hardware DOS FOSSIL drivers, talking directly to a physical UART on a physical COM port.
- RLFOSSIL is the one that matters for getting a genuine DOS BBS onto the modern internet: a FOSSIL driver plus a Hayes modem emulator built on a packet driver, presenting incoming Telnet/rlogin connections as virtual "calls" complete with AT-command handshaking, explicitly designed to run alongside X00/BNU so a real modem and a telnet line can coexist as separate nodes on the same box.
- NetFoss does the same job but for Windows-hosted DOS BBS setups (NTVDM), not real-mode DOS on bare hardware.
Modern nuance: what VoIP does to a modem tone
A modem signal is not speech. It's a precisely shaped, phase- and amplitude-modulated carrier that both ends demodulate assuming a continuous, low-noise analog path. VoIP breaks every one of those assumptions in a different way:
Codec compression: speech codecs like G.729 and G.723 are lossy, and they're lossy specifically in ways tuned to how the human ear parses vowels and consonants, not how a modem's constellation encodes bits. Running modem tones through one is not "lower quality," it's actively destructive, the compressed signal often can't be demodulated at all. Even an uncompressed G.711 codec doesn't fully solve this.
Packet behavior: loss, jitter, and reordering are invisible to a phone call (the ear tolerates tiny gaps) and catastrophic to a modem, which needs a continuous, precisely timed sample stream to hold its carrier lock. Clock skew between the two ends' independent sample clocks compounds this over the length of a call.
Echo cancellation: full-duplex modem standards from V.32 onward rely on precise self-echo cancellation to separate their own transmission from the far end's. A VoIP ATA's echo canceller is tuned for speech and will actively distort or cancel legitimate modem signal, mistaking it for echo.
The purpose-built fix is T.38 for fax and the much less commonly implemented V.150.1 for general modem relay, both of which demodulate at the VoIP edge and carry the data as data, not as compressed audio. Most consumer VoIP equipment supports neither by default.
Diagnostic quick reference
| symptom | likely cause |
|---|---|
| connects only at 14.4–28.8k, or fails to connect at all | compressed VoIP codec (G.729/G.723) somewhere in the path |
| connects, then random garbage / frequent retrains | packet loss or jitter on the VoIP leg, or clock skew between ATAs |
| connects fine but caps around 33.6k both directions | expected — both ends are analog, this is V.34, not a fault |
| characters dropped during file transfer at high baud | no hardware flow control, or a non-16550 UART |
| works but zmodem/file transfer stalls at 0% | telnet-bridge escape sequence handling, common on early Zimodem/ESP-based bridges |