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:

SlotAdresDRSlotAdresDR
1$C090-162405$C0D0-16176
2$C0A0-162246$C0E0-16160
3$C0B0-162087$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)

RefAantalWaardeOnderdeel / FootprintFunctie
A11Raspberry Pi Picoon 2 × 20 pin headersRP2040 module
U1174LVC32SOIC-14, 3.9 mm body/WRSEL strobe gate
U2174LVC245SOIC-20, 7.5 mm wide bodydata bus buffer
D111N5817DO-41 SchottkyApple +5 V naar kaart rail
R1, R2210 kΩaxialpull-ups op R/W en /DEVSEL
R3, R421 kΩaxialPWM low-pass, serie elementen
R5, R62100 kΩaxialgain selector poten
R711 kΩaxialgain selector stroombegrenzing
RV1120 kΩPiher PT-6 vertical trimmerPAM8403 volume
C1, C2222 nFceramic disc, 5 mm pitchPWM low-pass, shunt poten
C3110 µFradial electrolytic, 5 mmPWM DC block
C4, C52100 nFceramic discdecoupling bij U1 en U2
C61100 nFceramic discreset debounce, over SW1
C7110 µFradial electrolytic, 5 mmreservoir op 5 V kaart rail
C81100 nFceramic discdecoupling op 5 V kaart rail
SW116 mm tactile push buttonreset
SW214-position DIP slide switchMAX98357A gain
J11Apple II card-edge fingersslot connector
J2, J3, J431 × 7 pin header, 2.54 mmamplifier module sockets
J5, J621 × 2 pin headerspeaker, MAX98357A speaker output
J712 × 3 pin header + 2 shuntsspeaker 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-D7U2 A0-A7U2 B0-B7Pico GP0-GP7
  • /DEVSELU1 gate 1Pico GP8
  • R/WU1 gate 1Pico 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

PinNaamVerbinding
1DIR3.3 V (permanent Apple → Pico)
2–9A0–A7Apple D0–D7, slot pins 49 tot 42
10GNDGround
11–18B7–B0Pico GP7 tot GP0
19/OEGround (altijd ingeschakeld)
20VCC3.3 V

U1: 74LVC32

PinNaamVerbinding
11AApple /DEVSEL, slot pin 41, R2 10 kΩ naar 3.3 V
21BApple R/W, slot pin 18, R1 10 kΩ naar 3.3 V
31YPico GP8, direct
7GNDGround
14VCC3.3 V

(Niet-gebruikte inputs zijn bewust naar ground geleid om oscillatie te voorkomen).

Pico-verbindingen

FunctieGPIOFysieke pinVerbinding
D0–D7GP0–GP71, 2, 4, 5, 6, 7, 9, 10U2 B0–B7
/WRSELGP811U1 pin 3
I2S LRCLK / WSGP2127J2 pin 1 (MAX98357A)
I2S BCLKGP2026J2 pin 2 (MAX98357A)
I2S dataGP2229J2 pin 3 (MAX98357A)
PWM audioGP2834R3, naar low-pass filter
ResetRUN30SW1 en C6 naar ground
3.3 V out3V3_OUT36U1, U2, R1, R2, C4, C5
Card power inVSYS395 V kaart rail, D1 kathode
GroundGND3, 8, 13, 18, 23, 28, 38Common 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

RefPinsVerbinding
J1card edgeApple II slot
J21 × 7MAX98357A: 1 LRC, 2 BCLK, 3 DIN, 4 GAIN, 5 SD, 6 GND, 7 Vin
J61 × 2MAX98357A speaker output: 1 −, 2 +
J41 × 7PAM8403 input/power: 1 L in, 2 GND, 3 R in, 6 5 V, 7 GND
J31 × 7PAM8403 speaker output: 6 +, 7 −
J72 × 3Speaker bron-selector
J51 × 2De luidspreker: 1 +, 2 −

Build-instructies

De firmware is een target voor DECtalkMini. De broncode van DECtalkMini moet apart worden gedownload (zie licentie).

Bouwstappen:

  1. git clone https://github.com/dectalk/DECtalkMini
  2. cp -r pico-apple2 DECtalkMini/platforms/
  3. Stel PICOSDKPATH en PICOEXTRASPATH in.
  4. Ga naar DECtalkMini/platforms/pico-apple2.
  5. Gebruik cmake --preset pico-pwm-release (of pico-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:

PositieVerbinding GAIN naarGain
1ground via R5 (100 kΩ)15 dB
2ground direct12 dB
35 V via R7 (1 kΩ)6 dB
45 V via R6 (100 kΩ)3 dB
Geenfloating9 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.

ProgrammaFunctie
SPEAK.bas / APPLESPEECH.bas / PERFPAUL.basTyp een regel, hoor deze uitgesproken
DAISY.basZingt Daisy Bell in foneem-modus (~23 s)
ELIZA.basEen pratende Weizenbaum-stijl therapeut
SINGCOMP.basNegen stemmen houden een zangwedstrijd
YELSUB.basZingt Yellow Submarine (59 s)
VOICES.basVierstemmige begroeting, daarna introductie van 9 stemmen
HAL.basPaul omgevormd tot HAL 9000
MANGER.basAway in a Manger (58 s)
ANGELS.basAngels We Have Heard on High (35 s)
BLOWMAN.basBlow 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:

  1. Translate: tools/dt2applesoft.py zet het songbestand om naar een gepaced Applesoft-listing.
  2. Import: Met AppleCommander wordt de listing naar het .dsk image geschreven.
  3. 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

  1. Hand-wired prototype: Eerste werkende kaart op een prototyping board. Alleen PWM, geen filter, geen diode of resetknop.
  2. 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.
  3. 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 DECtalkMini core bevat propriëtaire notices van Force, Fonix Corporation en Digital Equipment Corporation. Daarom bevat deze repository geen DECtalk-broncode of gecompileerde .uf2 bestanden.
  • Apple-bestanden: De demo-disk bevat PRODOS.SYS en BASIC.SYSTEM, die eigendom zijn van Apple.