The Diamond Rio PMP300, released in 1998, was one of the first commercially successful portable MP3 players and a landmark device in digital audio history. However, the PMP300 communicates exclusively through a parallel port (DB-25) interface—a connection type that has been absent from consumer computers for over two decades.
This project provides a complete solution for bridging that gap. By utilizing an Arduino microcontroller as a USB-to-parallel-port adapter, combined with a purpose-built command-line interface, you can manage your PMP300 on any modern computer with a USB port. The Arduino handles the precise timing and signal translation required by the PMP300's parallel protocol, while the CLI provides intuitive commands for uploading music, managing files, and configuring the device.
Whether you're preserving vintage hardware, exploring retro computing, or simply want to use your original PMP300 with contemporary systems, this tool makes it possible.
- Hardware Setup: Connect Arduino to PMP300 (see Wiring Guide)
- Flash Firmware:
pmp300 flash(requires arduino-cli) - Test:
pmp300 test - Use:
pmp300 list,pmp300 upload song.mp3, etc.
See QUICKSTART.md for detailed 5-minute setup guide.
- Upload MP3 files to device
- Download files from device
- Delete individual files or all files
- List files with metadata (size, timestamp)
- View device information (capacity, free space)
- Change playback order of songs
- Format/initialize device
- Bad block detection
- Switch between internal flash and external SmartMedia card
- Firmware updates (no public protocol exists)
pmp300 test # Test Arduino and PMP300 connection
pmp300 flash # Flash Arduino with firmware
pmp300 list # List all files
pmp300 list --external # List files on SmartMedia card
pmp300 info # Show device information
pmp300 upload song.mp3 # Upload file(s)
pmp300 upload --external song.mp3 # Upload to SmartMedia card
pmp300 download song.mp3 # Download file
pmp300 delete song.mp3 # Delete file(s)
pmp300 move 3 1 # Rearrange playback order
pmp300 format # Format device
pmp300 storage list # Show available storage (internal/external)
pmp300 version # Show versionSee CLI_README.md for complete command reference.
- Model: Diamond Rio PMP300
- Storage: 32MB internal flash (64MB on SE models)
- Interface: Parallel Port (LPT)
- Block Size: 32KB (32,768 bytes)
- Total Blocks: 1024 (32MB) or 2048 (64MB SE)
Recommended: Arduino USB Bridge
- Arduino Mega 2560 or Uno
- DB-25 female connector
- 15 signal wires + ground
- Cost: ~$30-50 total
See arduino/ directory for:
- Complete firmware (auto-detects Mega/Uno)
- Wiring diagrams
- Protocol documentation
- Hardware test sketch
DB-25 female connector (PC side):
Data Pins (8 signals, bidirectional):
- Pins 2-9: Data 0-7
Control Pins (2 signals used, output):
- Pin 16: nInitialize
- Pin 17: nSelect-In
Status Pins (5 signals, input):
- Pin 15: nError
- Pin 13: Select
- Pin 12: Paper-Out
- Pin 10: nAck
- Pin 11: Busy
Ground:
- Pins 18-25: Ground (connect all)
See arduino/WIRING.md for complete wiring diagrams.
- 5V TTL logic levels
- Bidirectional parallel port
- Command/response protocol
- Microsecond timing control
- Block 0: Directory and FAT
- Blocks 1+: File data (32KB each)
- Max Files: 60
- Max Filename: 127 characters
- Reading directory: ~30 seconds
- Uploading 1MB file: ~5 minutes
- Uploading full 32MB: ~2.5 hours
- Bad block scan: ~3-4 hours (32MB)
Version 107 (0x6B)
- Go 1.21 or later
- Arduino Mega 2560 or Uno
- arduino-cli (for flashing firmware)
git clone https://github.com/murdinc/pmp300
cd pmp300
make build
# Binary at: build/pmp300Or install to system:
make install
# Installs to $GOPATH/bin/pmp300# Install arduino-cli first
brew install arduino-cli # macOS
# or see: https://arduino.github.io/arduino-cli/
# Flash firmware (auto-detects board and port)
pmp300 flash# Set once per session
export PMP300_DEVICE=/dev/cu.usbmodem14201
# Or add to ~/.zshrc or ~/.bashrc
echo 'export PMP300_DEVICE=/dev/cu.usbmodem14201' >> ~/.zshrc# Test everything works
pmp300 test
# Check device info
pmp300 info
# Upload music to internal flash (default)
pmp300 upload ~/Music/*.mp3
# List files on internal flash
pmp300 list --verbose
# Check if SmartMedia card is inserted
pmp300 storage list
# Upload to SmartMedia card
pmp300 upload --external ~/Music/album/*.mp3
# List files on SmartMedia
pmp300 list --external
# Rearrange songs
pmp300 move 5 1 # Move track 5 to first position
# Download a file
pmp300 download "01 Song.mp3" --output ~/backup/
# Delete files
pmp300 delete old-song.mp3
pmp300 delete --all # Delete everything
# Format device (formats current storage)
pmp300 format| Register | Offset | Access | Description |
|---|---|---|---|
| Data | +0 | R/W | 8-bit data |
| Status | +1 | R | Device status (bits 3-7 used) |
| Control | +2 | R/W | Control signals (bits 2-3 used) |
Header (32 bytes):
- Entry count, free blocks, bad blocks, total blocks
- Timestamp, checksum, version
Entries (60 × 144 bytes):
- Block position, block count, total size
- Timestamp (YYMMDDHHMMSS)
- Filename (128 bytes, null-terminated)
FAT (8192 bytes):
- One byte per block
- 0x00 = Used, 0x0F = Bad, 0xFF = Free
Total: 32KB (one block)
Reading:
- Send read command (0xA0)
- Send 3-byte block address
- Wait for device ready
- Read 32KB data
Writing:
- Send write command (0xAB)
- Send 3-byte block address
- Write data in 512-byte chunks (64 chunks)
- Send checksum per chunk
- Wait for acknowledge per chunk
pmp300/
├── main.go # CLI entry point
├── cmd/ # CLI commands
├── pkg/
│ ├── arduino/ # Arduino bridge protocol
│ └── pmp300/ # PMP300 device protocol
├── arduino/ # Firmware and wiring docs
├── CLI_README.md # Complete CLI reference
├── QUICKSTART.md # 5-minute setup guide
└── Makefile # Build automation
- QUICKSTART.md - Get running in 5 minutes
- CLI_README.md - Complete command reference
- arduino/README.md - Firmware documentation
- arduino/PROTOCOL.md - Arduino bridge protocol
- arduino/WIRING.md - Wiring diagrams
# Find Arduino device
./scripts/find-device.sh
export PMP300_DEVICE=/dev/cu.usbmodem14201# Flash firmware first
pmp300 flash
# Check wiring
# Upload arduino/hardware_test/hardware_test.ino
# Use multimeter to verify connectionsThis is normal! Parallel port protocol is inherently slow:
- ~3.5 KB/second typical
- Limited by protocol, not implementation
- Original software had same speeds
- Check all 15 signal wires are connected
- Verify ground connection (critical!)
- Ensure PMP300 is powered on
- Try different USB cable for Arduino
- Press Arduino reset button
| Operation | Time |
|---|---|
| Read directory | ~30 seconds |
| Upload 1MB | ~5 minutes |
| Upload 32MB | ~2.5 hours |
| Download 1MB | ~5 minutes |
| Bad block scan (32MB) | ~3-4 hours |
git clone https://github.com/murdinc/pmp300
cd pmp300
make deps # Download dependencies
make build # Build CLI tool
make test # Run testsgo run main.go test
go run main.go listcmd/- Cobra CLI commandspkg/arduino/- Arduino bridge communicationpkg/pmp300/- PMP300 protocol implementationarduino/- Firmware and documentation
- Snowblind Alliance RIO Utility v1.07
- wfx_rio GitHub Repository
- OSDev Wiki - Parallel Port
- IEEE 1284 Standard
This documentation and software are provided for educational and preservation purposes. The PMP300 protocol is based on reverse-engineered information from open-source implementations.
Note: Direct hardware access requires elevated privileges. Use caution when working with hardware interfaces.


