Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Hayes modem emulation

Copperline provides an emulated Hayes-compatible AT command modem connected to the Amiga’s serial port. The modem bridges Amiga serial communication to TCP connections, enabling terminal programs (such as Term, NComm, or JR-Comm) and BBS software to dial Internet telnet BBSes or accept incoming connections.

The modem command interpreter supports standard Hayes AT commands as well as the AT* extension set popularized by the WiModem232.

Configuration

In the launcher:

  1. Navigate to I/O Ports -> Serial Port.

  2. Set Device / Mode to Modem.

  3. Optionally configure a Listen address (for incoming calls) and the Telnet NVT translation toggle.

In copperline.toml:

[serial]
mode = "modem"
# listen = "0.0.0.0:2323"   # Bind port for incoming calls (optional)
# telnet = true             # Enable Telnet NVT translation at power-on

From the command line:

copperline --model A1200 --serial modem KICK31.ROM

Dialing outbound connections

In your Amiga terminal software, use standard AT dialing commands:

[serial.phonebook]
"5551234" = "bbs.example.com:23"
"5555678" = "bbs2.example.com"

Result codes returned by the modem:

Outbound dialing performs DNS resolution and TCP connection synchronously on the emulation thread (with a five-second timeout once resolved), which causes a brief pause in emulation while the connection is established.

Handling incoming calls

To allow inbound connections, specify a listening address with listen = "0.0.0.0:2323" (or via the launcher).

Telnet NVT translation (AT*T1 / AT*T0)

Raw TCP connections pass 8-bit byte streams directly. For compatibility with telnet servers requiring RFC 854 option negotiation:

WiModem232 command extensions

CommandDescription
AT*B<baud>Set reported baud rate string returned in CONNECT responses
AT*T0 / AT*T1Disable / enable Telnet NVT translation mode
AT*L<port>Rebind inbound listener to a new port on the current interface
AT*P<port>Set default destination port for hostname-only dials
AT*NList simulated wireless networks
AT*NS<n>,<pass>Simulated network join command
AT*REBOOTReset modem state machine (equivalent to ATZ)

Settings modified via AT commands can be saved to persistent NVRAM using AT&W and recalled with ATZ. Factory defaults can be restored with AT&F.

S-registers

RegisterFunctionDefault
S0Rings before auto-answer (0 = disabled)0
S1Ring counter0
S2Escape character code (+)43
S3Command-line carriage return character13
S4Linefeed character10
S9Connect delay in tenths of a second (WiModem compatibility)0
S12Escape sequence guard time in 1/50th seconds50 (1.0s)

Unimplemented S-registers read as 0 and ignore writes.

RS-232 control lines

Scripted session replay

For deterministic automated testing, CI, or demo playback, network calls can be replaced with scripted session recordings:

[serial]
mode = "modem"
session = "session.txt"

Directives in a session file:

# Session script example
accept
delay 0.5
send \r\nWelcome to the BBS\r\n
expect BYE\r
send \r\nNO CARRIER\r\n
close
DirectiveDescription
acceptThe next ATD succeeds (CONNECT)
refuse [busy|unreachable]The next ATD fails with BUSY or NO CARRIER
delay SECSWait specified emulated seconds before next action
send TEXTTransmit text to guest (\r, \n, \t supported)
expect TEXTWait for expected guest text (mismatch drops connection)
closeRemote hangup