A Commodore 64 chat client for MeshCore mesh radio networks. Connects to a MeshCore companion device via a SwiftLink cartridge and lets you send and receive messages over LoRa mesh.
- Channel messaging — Send and receive on up to 8 mesh channels
- Direct messages — Private 1:1 conversations with up to 32 contacts, each with a dedicated message buffer
- Delivery confirmation — DM messages turn from yellow (pending) to green when delivery is acknowledged
- @-mention cycling — Press Up/Down to cycle through senders in the current channel and auto-insert
@[name]mentions - Persistent config — Companion IP:port saved to disk (floppy or SD on device 8) so you only configure once
- Auto-reconnect — Detects connection loss and automatically redials
- NMI-driven serial — Interrupt-driven receive buffer prevents lost bytes during screen updates
- Commodore 64 (or emulator)
- SwiftLink RS-232 cartridge (directly, or via Ultimate 64 / 1541 Ultimate)
- Connection to a MeshCore companion device running the TCP serial bridge (
meshcore_py) - Optional: floppy drive or SD card on device 8 for config persistence
Requires the cc65 6502 C compiler toolchain.
# Install cc65 (macOS)
brew install cc65
# Build
makeThis produces build/meshcore64.prg.
The easiest way to test is with the VICE emulator and tcpser as a TCP-to-modem bridge.
# Install dependencies (macOS)
brew install vice tcpser
# Build and run (starts tcpser + VICE with SwiftLink emulation)
make runOr manually:
# 1. Start tcpser (bridges TCP to modem AT commands)
tcpser -v 25232 -s 9600 -l 4 &
# 2. Create a disk image for config persistence
c1541 -format "meshcore,mc" d64 build/meshcore64.d64
c1541 -attach build/meshcore64.d64 -write build/meshcore64.prg meshcore64
# 3. Launch VICE with SwiftLink cartridge
x64sc \
-acia1 -acia1base 56832 -acia1mode 1 -acia1irq 1 \
-myaciadev 2 \
-rsdev3 127.0.0.1:25232 -rsdev3baud 9600 -rsdev3ip232 \
-8 build/meshcore64.d64 \
-autostart build/meshcore64.prgIf you have an Ultimate 64 or 1541 Ultimate-II+, the built-in SwiftLink emulation can connect directly to your MeshCore companion over your local network — no physical cartridge or tcpser needed.
In the Ultimate configuration menu (F2 on Ultimate 64, or the cartridge button on Ultimate-II+):
- Enable Modem / ACIA emulation
- Set ACIA Base Address to
$DE00 - Set IRQ Mode to NMI
- Disable any cartridge or REU emulation that uses the IO1 ($DE00) address space
Copy build/meshcore64.d64 to a USB stick or transfer it via FTP to the Ultimate (port 21), then mount the D64 image and:
LOAD "MESHCORE64",8,1
RUN
On first launch, enter your companion device's IP:port (e.g., 192.168.2.145:5000). The Ultimate's modem emulation handles the ATDT dial command and opens a raw TCP socket to the companion.
On first launch you'll see a setup screen to enter your companion device's IP:port (e.g., 192.168.2.145:5000). This is saved to disk for subsequent launches.
| Key | Action |
|---|---|
| Return | Send message |
| Del | Backspace |
| F1 / F3 | Next / previous channel |
| F5 / F7 | Next / previous DM contact |
| Up / Down | Cycle @-mention target (channels only) |
| F2 | Settings (edit companion address) |
| Color | Meaning |
|---|---|
| Yellow (sender) | Your message, sent to radio |
| Green (sender) | Your DM, delivery confirmed |
| Light blue | @-mention of another user |
| Yellow (text) | @-mention of you |
src/
main.c Main loop, UI logic, mention cycling
meshcore.c MeshCore protocol (framing, commands, message parsing)
serial.c SwiftLink ACIA driver (polling + NMI modes)
screen.c 40-column display, per-channel message buffers
input.c Non-blocking keyboard handling
config.c Persistent config via CBM file I/O
nmi_acia.s NMI interrupt handler for serial receive
charset.h PETSCII / ASCII / screen code conversion
scripts/
run.sh Launch helper (tcpser + VICE)
Communicates with a MeshCore companion device using the binary TCP serial protocol defined in meshcore_py. The companion device handles all radio operations; this client sends commands and receives messages over the serial link at 9600 baud.
MIT
