Perfect Paul ][
A DECtalk speech synthesizer card for the Apple II, built on a Raspberry Pi Pico. Named for DECtalk's default voice, [:np].
It speaks plain text, sings in DECtalk's phoneme mode, and holds a conversation. Drive it from BASIC with POKE.

Status: finished. The final revision 2 board has been fabricated, assembled and tested in an Apple II, and everything works. The card announces itself out loud at power-up, and both audio paths — I2S through a MAX98357A and PWM through a PAM8403 — are on the board, selected with a jumper. The Gerbers are published: pcb/gerbers-v2.zip.
Contents
- Watch it
- Talking to it
- How it works
- The card
- Schematic
- Build
- Audio
- Demo programs
- Assembly and first power-up
- Validation status
- Possible future changes
- Historical record
- Licensing
Watch it
Perfect Paul II on real hardware — the latest demo.
Earlier: Perfect Paul II - A New Speech Synthesizer For The Apple II — the card talking, singing Daisy Bell, and running ELIZA.
Talking to it
10 DR = -16192 : REM SLOT 4 20 T$ = "HELLO FROM DECTALK" 30 FOR I = 1 TO LEN(T$): POKE DR,ASC(MID$(T$,I,1)): NEXT I 40 POKE DR,13
That is the entire interface. Bytes written to the card's slot window are queued as text; a carriage return (13) speaks the line. Byte 144 ($90) stops speech already in progress, as does 3 (Ctrl-C). DECtalk inline commands are printable text, so "[:np]HELLO" is sent exactly the same way.
Any slot works
The card decodes no address lines. It relies entirely on /DEVSEL, which the motherboard asserts for whichever slot the card is in, so it works in any slot from 1 to 7 with no jumpers and no firmware change. Only the DR constant in BASIC changes:
| Slot | Address | DR | Slot | Address | DR | |
|---|---|---|---|---|---|---|
| 1 | $C090 | -16240 | 5 | $C0D0 | -16176 | |
| 2 | $C0A0 | -16224 | 6 | $C0E0 | -16160 | |
| 3 | $C0B0 | -16208 | 7 | $C0F0 | -16144 | |
| 4 | $C0C0 | -16192 |
The window is $C080 + 16 × slot. A0-A3 are intentionally not decoded, so all 16 addresses in it are mirrors of the same write-only register.
On an Apple II+ note that slot 0 holds the Language Card and slot 6 is almost certainly your Disk II, so 2, 4 or 5 are the practical choices.
How it works
Core 0 receives bytes from an Apple II slot write cycle using RP2040 PIO. Core 1 runs DECtalk synthesis and feeds the audio path. There is no slot ROM, no status register, and no read cycle — the card is write-only, which is what keeps the hardware down to two logic chips.
Apple D0-D7 -> U2 74LVC245 -> Pico GP0-GP7 /DEVSEL OR R/W -> U1 74LVC32 -> Pico GP8 (/WRSEL)
Both logic chips run from the Pico's 3.3 V rail, not the Apple's +5 V. LVC inputs carry no clamp diode to VCC and are specified to 5.5 V independent of VCC, so feeding them 5 V Apple TTL is the datasheet-supported case rather than a tolerated one. That is what removes the need for series resistors, and it means power sequencing does not matter.
The PIO program keeps the newest data sample taken wholly inside the /WRSEL low pulse and pushes it when the strobe rises. This matters: a 6502 does not drive valid data until well after /DEVSEL falls, so sampling at the start of the window would latch garbage. Sampling at the end is what conventional Apple II cards do with a '374.
The bus state machine runs on PIO1 and the I2S implementation on PIO0, so the two never contend for a state machine. The firmware disables the internal pulls on GP0-GP7 and enables a pull-up only on GP8.
... Read more »
Michael Wessel