Perfect Paul ][
De kaart kan platte tekst uitspreken, zingen in de foneem-modus van DECtalk en gesprekken voeren. De besturing vanuit BASIC gebeurt via POKE-commando's.
Status: Voltooid. De definitieve revisie 2-printplaat is gefabriceerd, geassembleerd en getest in een Apple II; alles werkt naar behoren. De kaart kondigt zichzelf luidkeels aan bij het inschakelen. Er zijn twee audiopaden aanwezig op de printplaat: I2S via een MAX98357A en PWM via een PAM8403. De keuze tussen deze twee wordt gemaakt met een jumper.
De Gerbers zijn gepubliceerd: pcb/gerbers-v2.zip.
Demonstraties
- Hardware-demo: Perfect Paul II op echte hardware (laatste demo).
- Eerdere demo's: De kaart in actie terwijl deze spreekt, het lied Daisy Bell zingt en ELIZA uitvoert.
Communicatie met de kaart
Het volgende BASIC-voorbeeld illustreert de interface:
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
Dit is de volledige interface. Bytes die naar het slot-window van de kaart worden geschreven, worden in een wachtrij geplaatst als tekst; een carriage return (13) activeert het uitspreken van de regel. Byte 144 ($90) stopt de huidige spraak, net als byte 3 (Ctrl-C). Inline-commando's van DECtalk zijn printbare tekst, dus [:np]HELLO wordt op exact dezelfde manier verzonden.
Slot-compatibiliteit
De kaart decodeert geen adreslijnen en vertrouwt volledig op /DEVSEL, die door het moederbord wordt geactiveerd voor het slot waarin de kaart zich bevindt. Hierdoor werkt de kaart in elk slot van 1 tot 7 zonder jumpers of wijzigingen in de firmware. Alleen de DR-constante in BASIC verandert:
| Slot | Adres | DR | Slot | Adres | DR |
|---|---|---|---|---|---|
| 1 | $C090 | -16240 | 5 | $C0D0 | -16176 |
| 2 | $C0A0 | -16224 | 6 | $C0E0 | -16160 |
| 3 | $C0B0 | -16208 | 7 | $C0F0 | -16144 |
| 4 | $C0C0 | -16192 |
Het window bevindt zich op $C080 + 16 × slot. A0-A3 worden bewust niet gedecodeerd, waardoor alle 16 adressen in het window spiegels zijn van hetzelfde write-only register.
Opmerking voor Apple II+: Slot 0 bevat meestal de Language Card en slot 6 is vrijwel altijd bezet door de Disk II, waardoor slots 2, 4 of 5 de meest praktische keuzes zijn.
Technische werking
Core 0 ontvangt bytes van een Apple II slot write-cyclus via RP2040 PIO. Core 1 voert de DECtalk-synthese uit en voedt het audiopad. De kaart heeft geen slot ROM, geen statusregister en geen read-cyclus; de kaart is write-only, wat de hardware beperkt tot slechts twee logische chips.
Signaalpad: Apple D0-D7 -> U2 74LVC245 -> Pico GP0-GP7 /DEVSEL OR R/W -> U1 74LVC32 -> Pico GP8 (/WRSEL)
Beide logische chips werken op de 3.3 V-rail van de Pico, niet op de +5 V van de Apple II. LVC-inputs hebben geen clamp-diode naar VCC en zijn gespecificeerd tot 5.5 V, onafhankelijk van VCC. Het voeden van 5 V Apple TTL is dus een door de fabrikant ondersteunde toepassing. Dit elimineert de noodzaak voor serieweerstanden en betekent dat de volgorde van het inschakelen van de voeding niet uitmaakt.
Het PIO-programma bewaart het nieuwste datasample volledig binnen de /WRSEL low-puls en pusht dit wanneer de strobe stijgt. Dit is cruciaal, omdat een 6502 pas valide data aanlevert ruim nadat /DEVSEL is gedaald. Door aan het einde van het window te samplen, wordt voorkomen dat er onjuiste data wordt vastgelegd.
De bus-state machine draait op PIO1 en de I2S-implementatie op PIO0, zodat ze nooit strijden om een state machine. De firmware schakelt de interne pull-ups op GP0-GP7 uit en activeert een pull-up alleen op GP8.
Hardware-specificaties
De kaart
Van links naar rechts aan de bovenkant: de luidspreker, de I2S GAIN DIP-switch (SW2) boven de MAX98357A I2S-versterker, de PAM VOLUME trimmer (RV1) boven de HW-104 PAM8403 klasse-D module, en de Raspberry Pi Pico met de resetknop (SW1) ernaast. Aan de onderkant: de luidspreker-selector (J7) met twee shunts uiterst links, de PWM-filter en gain-weerstanden, U2 (74LVC245, brede SOIC-20) en U1 (74LVC32, SOIC-14), en de supply Schottky-diode (D1) aan het rechteruiteinde. De slot-connector is J1.
De Pico en beide versterkermodules zijn aangesloten via pin-headers; alle overige componenten zijn direct op de printplaat gesoldeerd, inclusief de twee logische chips als SOIC-onderdelen.
Gerbers
De gefabriceerde revisie 2-printplaat (pcb/gerbers-v2.zip) is geëxporteerd vanuit KiCad:
- Afmetingen: 149.9 × 77.4 mm
- Lagen: 2, 1.6 mm
- Minimale track en clearance: 0.2 mm
- Kleinste boor: 0.3 mm
- Bestanden: Koper, mask, paste en silkscreen voor beide zijden, edge cuts, PTH en NPTH boor, KiCad job-bestand.
Bill of Materials (BOM)
| Ref | Aantal | Waarde | Onderdeel / Footprint | Functie |
|---|---|---|---|---|
| A1 | 1 | Raspberry Pi Pico | on 2 × 20 pin headers | RP2040 module |
| U1 | 1 | 74LVC32 | SOIC-14, 3.9 mm body | /WRSEL strobe gate |
| U2 | 1 | 74LVC245 | SOIC-20, 7.5 mm wide body | data bus buffer |
| D1 | 1 | 1N5817 | DO-41 Schottky | Apple +5 V naar kaart rail |
| R1, R2 | 2 | 10 kΩ | axial | pull-ups op R/W en /DEVSEL |
| R3, R4 | 2 | 1 kΩ | axial | PWM low-pass, serie elementen |
| R5, R6 | 2 | 100 kΩ | axial | gain selector poten |
| R7 | 1 | 1 kΩ | axial | gain selector stroombegrenzing |
| RV1 | 1 | 20 kΩ | Piher PT-6 vertical trimmer | PAM8403 volume |
| C1, C2 | 2 | 22 nF | ceramic disc, 5 mm pitch | PWM low-pass, shunt poten |
| C3 | 1 | 10 µF | radial electrolytic, 5 mm | PWM DC block |
| C4, C5 | 2 | 100 nF | ceramic disc | decoupling bij U1 en U2 |
| C6 | 1 | 100 nF | ceramic disc | reset debounce, over SW1 |
| C7 | 1 | 10 µF | radial electrolytic, 5 mm | reservoir op 5 V kaart rail |
| C8 | 1 | 100 nF | ceramic disc | decoupling op 5 V kaart rail |
| SW1 | 1 | — | 6 mm tactile push button | reset |
| SW2 | 1 | — | 4-position DIP slide switch | MAX98357A gain |
| J1 | 1 | — | Apple II card-edge fingers | slot connector |
| J2, J3, J4 | 3 | — | 1 × 7 pin header, 2.54 mm | amplifier module sockets |
| J5, J6 | 2 | — | 1 × 2 pin header | speaker, MAX98357A speaker output |
| J7 | 1 | — | 2 × 3 pin header + 2 shunts | speaker source selector |
Modules en externe onderdelen:
- 1x MAX98357A I2S-versterker breakout (Adafruit pinout; plugt in J2).
- 1x PAM8403 klasse-D module (HW-104; plugt in J4 en J3).
- 1x Kleine 4–8 Ω luidspreker (naar J5).
Elektrisch ontwerp
Benadering
Alles op de kaart, behalve de Apple-bus zelf en de voeding van de versterker, werkt op 3.3 V, afkomstig van de 3V3_OUT pin van de Pico (fysieke pin 36). U1 en U2 worden hierdoor gevoed.
De LVC-familie is hiervoor gekozen omdat de inputs geen clamp-diode naar VCC hebben. Dit betekent dat 5 V Apple TTL in een 3.3 V-gevoede LVC-input kan worden gepompt zonder schade. 74HC- of 74LV-onderdelen zouden niet werken, omdat hun clamp-diodes de Apple +5 V in de 3.3 V-rail zouden injecteren.
Voordelen van deze aanpak:
- Geen serieweerstanden nodig. De B-outputs van U2 zijn push-pull CMOS op dezelfde 3.3 V-rail als de Pico-inputs.
- Geen gevaar bij de volgorde van inschakelen.
- Lage belasting van de Apple-databus (enkele microamps per lijn).
- Spanningsdrempels sluiten direct aan zonder vertaal-trucs (LVC bij 3.0–3.6 V specificeert VIH = 2.0 V en VIL = 0.8 V, wat goed past bij Apple TTL).
Bus-interface
De verbindingen zijn als volgt:
- Apple D0-D7 → U2 A0-A7 → U2 B0-B7 → Pico GP0-GP7
- /DEVSEL → U1 gate 1 → Pico GP8
- R/W → U1 gate 1 → Pico GP8
De signaal /WRSEL (/DEVSEL OR R/W) is alleen 'low' bij een write-actie naar het device-window van het geselecteerde slot. De Pico ontvangt alleen bussignalen en stuurt de Apple II-databus nooit aan.
R1 en R2 (10 kΩ pull-ups naar 3.3 V) zijn essentieel. Omdat U1 wordt gevoed door de Pico, is deze actief zodra de Pico stroom heeft (bijv. via USB). Zonder pull-ups zouden /DEVSEL en R/W zweven, wat kan leiden tot onbedoelde activering van de synthesizer en ruis.
Pin-out details
U2: 74LVC245
| Pin | Naam | Verbinding |
|---|---|---|
| 1 | DIR | 3.3 V (permanent Apple → Pico) |
| 2–9 | A0–A7 | Apple D0–D7, slot pins 49 tot 42 |
| 10 | GND | Ground |
| 11–18 | B7–B0 | Pico GP7 tot GP0 |
| 19 | /OE | Ground (altijd ingeschakeld) |
| 20 | VCC | 3.3 V |
U1: 74LVC32
| Pin | Naam | Verbinding |
|---|---|---|
| 1 | 1A | Apple /DEVSEL, slot pin 41, R2 10 kΩ naar 3.3 V |
| 2 | 1B | Apple R/W, slot pin 18, R1 10 kΩ naar 3.3 V |
| 3 | 1Y | Pico GP8, direct |
| 7 | GND | Ground |
| 14 | VCC | 3.3 V |
(Niet-gebruikte inputs zijn bewust naar ground geleid om oscillatie te voorkomen).
Pico-verbindingen
| Functie | GPIO | Fysieke pin | Verbinding |
|---|---|---|---|
| D0–D7 | GP0–GP7 | 1, 2, 4, 5, 6, 7, 9, 10 | U2 B0–B7 |
| /WRSEL | GP8 | 11 | U1 pin 3 |
| I2S LRCLK / WS | GP21 | 27 | J2 pin 1 (MAX98357A) |
| I2S BCLK | GP20 | 26 | J2 pin 2 (MAX98357A) |
| I2S data | GP22 | 29 | J2 pin 3 (MAX98357A) |
| PWM audio | GP28 | 34 | R3, naar low-pass filter |
| Reset | RUN | 30 | SW1 en C6 naar ground |
| 3.3 V out | 3V3_OUT | 36 | U1, U2, R1, R2, C4, C5 |
| Card power in | VSYS | 39 | 5 V kaart rail, D1 kathode |
| Ground | GND | 3, 8, 13, 18, 23, 28, 38 | Common ground |
Waarschuwingen:
- Verbind nooit Apple +5 V met
3V3_OUT. - Raak pin 40 (
VBUS) niet aan bij het voeden via de Apple II; dit zou de +5 V rail van de Apple II via USB kunnen voeden.
Voeding en Reset
Voeding: Apple +5 V (pin 25) -> D1 (1N5817 Schottky) -> VCC (5 V kaart rail) De 5 V rail voedt de Pico VSYS, de MAX98357A en de PAM8403. De Schottky-diode voorkomt dat USB-stroom terugvloeit in de Apple II. De diode staat met de kathode (de band) weg van de slot-connector. C7 en C8 dienen als reservoircondensatoren om spanningsdippen bij luide passages te voorkomen.
Resetknop: SW1 verbindt de RUN pin van de Pico met ground. Bij het loslaten start de kaart opnieuw op en spreekt de ready-melding uit. C6 (100 nF) dient voor debouncing. Om de Pico in USB-bootloader modus te zetten: houd BOOTSEL ingedrukt, tik op SW1 en laat BOOTSEL dan los.
Connectoren
| Ref | Pins | Verbinding |
|---|---|---|
| J1 | card edge | Apple II slot |
| J2 | 1 × 7 | MAX98357A: 1 LRC, 2 BCLK, 3 DIN, 4 GAIN, 5 SD, 6 GND, 7 Vin |
| J6 | 1 × 2 | MAX98357A speaker output: 1 −, 2 + |
| J4 | 1 × 7 | PAM8403 input/power: 1 L in, 2 GND, 3 R in, 6 5 V, 7 GND |
| J3 | 1 × 7 | PAM8403 speaker output: 6 +, 7 − |
| J7 | 2 × 3 | Speaker bron-selector |
| J5 | 1 × 2 | De luidspreker: 1 +, 2 − |
Build-instructies
De firmware is een target voor DECtalkMini. De broncode van DECtalkMini moet apart worden gedownload (zie licentie).
Bouwstappen:
git clone https://github.com/dectalk/DECtalkMinicp -r pico-apple2 DECtalkMini/platforms/- Stel
PICOSDKPATHenPICOEXTRASPATHin. - Ga naar
DECtalkMini/platforms/pico-apple2. - Gebruik
cmake --preset pico-pwm-release(ofpico-i2s-release) en voer de build uit.
Er worden twee executables geproduceerd:
dectalk_apple2.uf2: De firmware voor de kaart.dectalk_selftest.uf2: Voor het testen van het audiopad zonder Apple II.
Terminal-interface
De firmware behoudt USB CDC als input via dezelfde protocol-lijn als het slot. Met tools/paul-say.sh kan de kaart direct vanaf een computer worden aangestuurd:
./tools/paul-say.sh "Hello from the terminal."./tools/paul-say.sh(interactief)./tools/paul-say.sh -l(alleen luisteren naar output)
Let op: Schakel hardware flow control uit in terminal-software zoals minicom, anders negeert de kaart de input. Gebruik geen 1200 baud, omdat dit de BOOTSEL-reset triggert.
Build-fouten
Bij oudere versies van DECtalkMini kan een RAM overflowed fout optreden omdat het woordenboek (390 KB) in .data terechtkomt in plaats van .rodata. Update in dat geval de DECtalkMini broncode.
De ready-melding
Bij het inschakelen zegt de kaart: "Perfect Paul Two ready." Dit is configureerbaar via DECTALKSPEAKSTARTUP_BANNER. In de code is het woord "perfect" fonemisch gespeld ([prrfihkt]) om te voorkomen dat DECtalk het als een werkwoord (per-FECT) uitspreekt.
Audio
Er zijn twee paden: PWM (GP28 via filter naar PAM8403) en I2S (GP20/21/22 naar MAX98357A). De kwaliteit is nagenoeg identiek. De keuze wordt bij het bouwen gemaakt (via de preset) en fysiek via J7.
PWM-outputfilter
Omdat DECtalk een 11025 Hz stream is zonder signalen boven 5.5 kHz, maar de Pico-PWM een ~353 kHz carrier heeft, is een sterk filter nodig. Er wordt een tweepolige low-pass filter gebruikt rond de 7 kHz, gevolgd door een DC-blokkerende condensator (C3) en een volumetrimmer (RV1).
Filter-componenten:
- R3, R4: 1 kΩ (serie elementen)
- C1, C2: 22 nF (shunt poten)
- C3: 10 µF (DC blok, + richting filter)
- RV1: 20 kΩ (volumetrimmer naar PAM8403)
Selectie van de versterker
Beide versterkers zijn bridge-tied-load klasse-D. Dit betekent dat de minus-terminal van de luidspreker niet verbonden is met ground.
- Waarschuwing: Verbind nooit een speaker-output met ground en verbind nooit de minus-outputs van de twee modules met elkaar.
De selector J7 (2 × 3 header) gebruikt shunts om de actieve versterker te kiezen:
- I2S (MAX98357A): Shunts op 1–3 en 2–4.
- PWM (PAM8403): Shunts op 3–5 en 4–6.
Gain selector (MAX98357A)
Via de DIP-switch SW2 kan een van de vijf gains worden gekozen:
| Positie | Verbinding GAIN naar | Gain |
|---|---|---|
| 1 | ground via R5 (100 kΩ) | 15 dB |
| 2 | ground direct | 12 dB |
| 3 | 5 V via R7 (1 kΩ) | 6 dB |
| 4 | 5 V via R6 (100 kΩ) | 3 dB |
| Geen | floating | 9 dB |
Clock- en voedingsnotities
- I2S build: Draait op de standaard 125 MHz.
- PWM build: Draait op 96 MHz. Bij 125 MHz zou de audio 2.6× te snel spelen.
- Stroomverbruik: Houd het luidspreker-volume bescheiden bij gebruik van de slot-voeding, vooral bij een Apple II+ waarvan de voeding al zwaar belast is door DRAM en een Language Card.
Demo-programma's
In de map basic/ staan diverse programma's. Een bootbaar image (disk/perfect-paul.dsk) bevat deze programma's.
| Programma | Functie |
|---|---|
SPEAK.bas / APPLESPEECH.bas / PERFPAUL.bas | Typ een regel, hoor deze uitgesproken |
DAISY.bas | Zingt Daisy Bell in foneem-modus (~23 s) |
ELIZA.bas | Een pratende Weizenbaum-stijl therapeut |
SINGCOMP.bas | Negen stemmen houden een zangwedstrijd |
YELSUB.bas | Zingt Yellow Submarine (59 s) |
VOICES.bas | Vierstemmige begroeting, daarna introductie van 9 stemmen |
HAL.bas | Paul omgevormd tot HAL 9000 |
MANGER.bas | Away in a Manger (58 s) |
ANGELS.bas | Angels We Have Heard on High (35 s) |
BLOWMAN.bas | Blow the Man Down (14 s) |
Pacing en timing
De kaart is write-only en heeft geen flow-control. De wachtrij houdt 8 uitingen vast. Als deze vol raakt, worden nieuwe writes simpelweg genegeerd, wat resulteert in vervormde spraak.
Om dit te voorkomen, gebruiken programma's als SINGCOMP en YELSUB pacing. De wachttijd wordt berekend als: 950 WT = MS .9 PF - LEN (S$) * SD
Hierbij is PF (default 0.9) een factor om de wachtrij netjes gevuld te houden voor gapeloze zang, en SD (default 3) een schatting van de tijd die de Applesoft-send-loop in beslag neemt.
Vertaling en import van songs
Het proces om een DECtalk song-bestand om te zetten naar een Apple II programma verloopt in drie stappen:
- Translate:
tools/dt2applesoft.pyzet het songbestand om naar een gepaced Applesoft-listing. - Import: Met
AppleCommanderwordt de listing naar het.dskimage geschreven. - Verify: Het resultaat wordt teruggelezen en vergeleken met de bron via
diff.
De translator (dt2applesoft.py) handelt complexe zaken af:
- Splitting: Uitingen worden gesplitst op witruimte om de limiet van 254 tekens (firmware) en 239 tekens (Applesoft) niet te overschrijden. Er wordt geprobeerd te splitsen waar een zanger normaal zou ademen.
- Timing: De lengte van elke uiting wordt gesommeerd uit de
<duration>velden. - Stemmen:
[:nv](gebruikersdefinitie) wordt vervangen door een bestaande stem. - Normalisatie: Diverse varianten van fonem-commando's worden genormaliseerd naar
[:phone arpa speak on].
Installatie en configuratie
Rebuilding the disk image
Bij het importeren van listings met AppleCommander, mag er nooit een "bare REM" (een commentaarregel zonder tekst) in de listing staan. De tokenizer van AppleCommander zou dan de volgende regel (vaak de DR assignatie) absorberen als commentaar, waardoor de kaart niet werkt.
Wijzigen van het slot
Alle demo's staan standaard op slot 4. Om dit te wijzigen, hoef je slechts één regel in de BASIC-code aan te passen: 30 DR = -16192 : REM SLOT 4
Vervang -16192 door de waarde uit de slot-tabel. Een betere methode voor eigen programma's is: 10 S = 5 : DR = -16256 + 16 * S
De firmware hoeft niet te worden aangepast bij het wisselen van slot, omdat de kaart geen adreslijnen decodeert.
Inline command gotcha
DECtalkMini accepteert stemmen alleen via naam (bijv. [:np]). De numerieke vorm (bijv. [:n0]) wordt geweigerd, wat resulteert in een hoorbare foutmelding van ongeveer 1.5 seconde.
Assemblage en validatie
Checklist voor eerste power-up
Voor het inschakelen:
- Controleer oriëntatie U1 en U2 (pin 1 is linksonder als de tekst leesbaar is).
- Controleer diode D1 (band wijst weg van de slot-connector).
- Controleer polariteit van C3 en C7.
- Plaats exact één paar J7-shunts verticaal en maximaal één SW2-positie.
- Cruciaal: Gebruik echte 74LVC-onderdelen. Met een multimeter (diode-test) moet de verbinding tussen VCC en input 'open' zijn. Een waarde van 0.6 V duidt op een HC, HCT of LV onderdeel, wat de 3.3 V-rail zou kunnen beschadigen.
Tijdens het inschakelen:
- U1 en U2 VCC moeten rond 3.3 V liggen.
- De 5 V kaart-rail moet de Pico VSYS bereiken.
- GP8 moet normaal gesproken 'high' zijn en alleen 'low' pulseren bij een write-actie.
Validatiestatus
De definitieve revisie 2-kaart is gevalideerd op echte hardware. Bevestigd is:
- De 74LVC-interface werkt correct zonder serieweerstanden.
- Het PIO-capture protocol werkt betrouwbaar; de bus-capaciteit houdt de byte lang genoeg vast.
- De scheiding tussen Core 0 (ontvangst) en Core 1 (synthese) werkt onder real-time busverkeer.
- De kaart werkt op zowel 96 MHz als 125 MHz systeemklokken.
Historiek en Licenties
Historiek
- Hand-wired prototype: Eerste werkende kaart op een prototyping board. Alleen PWM, geen filter, geen diode of resetknop.
- Revision 1 PCB: Eerste printplaat. Geen D1 (risico op back-feed via USB), geen speaker-selector, en een foutieve gain-DIP die kortsluiting kon veroorzaken.
- Revision 2 PCB: Definitieve versie met alle correcties (D1 toegevoegd, veilige gain-selector, speaker-selector, resetknop).
Licenties
De bestanden in deze repository (firmware-adapter, PIO-programma, Gerbers, documentatie, BASIC-programma's) zijn MIT-licensed.
Dit geldt niet voor:
- DECtalk: De
DECtalkMinicore bevat propriëtaire notices van Force, Fonix Corporation en Digital Equipment Corporation. Daarom bevat deze repository geen DECtalk-broncode of gecompileerde.uf2bestanden. - Apple-bestanden: De demo-disk bevat
PRODOS.SYSenBASIC.SYSTEM, die eigendom zijn van Apple.
Groetjes,